diff --git a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/model/MogoOCHTaxiModelNew.java b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/model/MogoOCHTaxiModelNew.java index b3470d6fe0..5f4c847dd1 100644 --- a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/model/MogoOCHTaxiModelNew.java +++ b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/model/MogoOCHTaxiModelNew.java @@ -24,6 +24,7 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager; +import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils; import com.mogo.eagle.core.utilcode.mogo.logger.Logger; import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr; import com.mogo.eagle.core.utilcode.mogo.toast.TipToast; @@ -134,7 +135,7 @@ public class MogoOCHTaxiModelNew { if (NetworkUtils.isConnected(mContext)) { // startOrStopOrderLoop(mOCHCarStatus == 1); - if (FunctionBuildConfig.appIdentityMode == 0x00) { + if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { queryCarStatus(); } } @@ -821,7 +822,7 @@ public class MogoOCHTaxiModelNew { Logger.d( TAG, "onIntentReceived = %s", intentStr ); if ( ConnectivityManager.CONNECTIVITY_ACTION.equals( intentStr ) ) { if ( NetworkUtils.isConnected( mContext ) ) { - if (FunctionBuildConfig.appIdentityMode == 0x00) { + if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { startOrStopOrderLoop(mOCHCarStatus == 1); queryCarStatus(); } @@ -941,7 +942,7 @@ public class MogoOCHTaxiModelNew { mPrevAPStatus = state; if (FunctionBuildConfig.isDemoMode - && FunctionBuildConfig.appIdentityMode == 0x01) { + && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { // 当美化模式(演示模式)开启时:且是乘客app、且未到终点时,维持自动驾驶icon开启状态 if (!arriveAtEnd) { return; @@ -955,7 +956,7 @@ public class MogoOCHTaxiModelNew { mPrevAPStatus = state; if (FunctionBuildConfig.isDemoMode - && FunctionBuildConfig.appIdentityMode == 0x01) { + && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { // 当美化模式(演示模式)开启时:且是乘客app、且未到终点时,维持自动驾驶icon开启状态 if (!arriveAtEnd) { return; @@ -981,7 +982,7 @@ public class MogoOCHTaxiModelNew { @Override public void onAutopilotArriveAtStation(@Nullable AutopilotStationInfo data) { if (FunctionBuildConfig.isDemoMode - && FunctionBuildConfig.appIdentityMode == 0x01) { + && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { arriveAtEnd = true; } diff --git a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/BaseOchTaxiTabFragment.java b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/BaseOchTaxiTabFragment.java index 413c1ee545..5abbbf58e4 100644 --- a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/BaseOchTaxiTabFragment.java +++ b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/BaseOchTaxiTabFragment.java @@ -30,6 +30,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; import com.mogo.eagle.core.function.call.map.CallerSmpManager; +import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils; import com.mogo.eagle.core.utilcode.mogo.logger.Logger; import com.mogo.map.listener.IMogoMapListener; import com.mogo.map.uicontroller.VisualAngleMode; @@ -133,7 +134,7 @@ public abstract class BaseOchTaxiTabFragment [AppIdentityModeUtils.java][AppIdentityModeUtils.java] -> [Demo][AppIdentityModeUtils.java] +``` + +// 判断是否是 司机身份 +AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) + +// 判断是否是 乘客身份 +AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) + + +// 判断是否是 小巴车 +AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) + +// 判断是否是 出租车 +AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) + +``` + + diff --git a/app/build.gradle b/app/build.gradle index eabcafae8f..a0c72dcba9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,9 +5,6 @@ apply plugin: 'kotlin-android-extensions' apply plugin: 'android-aspectjx' apply plugin: 'bugly' -if (!isAndroidTestBuild()) { - apply plugin: 'apm-plugin' -} //apply ByteX宿主 if (!isAndroidTestBuild()) { @@ -18,73 +15,78 @@ if (!isAndroidTestBuild()) { logLevel "DEBUG" } } - if (!isAndroidTestBuild()) { - apply plugin: 'bytex.threadOpt' - thread_opt { - enable true - enableInDebug true - rxJavaIoReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getIoPool@@()Ljava/util/concurrent/ExecutorService;' - rxJavaComputationReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getCpuPool@@()Ljava/util/concurrent/ExecutorService;' - coroutineIoReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getIoPool@@()Ljava/util/concurrent/ExecutorService;' - coroutineDefaultReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getCpuPool@@()Ljava/util/concurrent/ExecutorService;' - } - - /** - * 方便使用systrace工具,在工程侧打点,便于分析工程侧性能问题 - */ - apply plugin: 'bytex.systrace' - systrace { - /** - * 交付时要关闭,会有性能损耗 - */ - enable false - enableInDebug false - /** - * - 是否使用[Trace.beginAsyncSection(String, int)/Trace.endAsyncSection(String, int)]进行打点 - * - 默认使用[Trace.beginSection(String)/Trace.endSection()]进行打点 - */ - isTraceAsync false - /** - * - 是否在运行时只针对主线程打点,其它线程不打 - */ - isOnlyMainThread false - - /** - * - 是否忽略对类的静态构造方法打点 - * - 默认不忽略 - */ - isIgnoreClinitMethod false - - /** - * - 是否忽略对类中的简单方法打点 - * 简单方法定义: - * - 空方法 - * - get/set 方法 - * - 单独的方法,方法体内没有调用其它方法 - * - 默认不忽略 - */ - isIgnoreSampleMethod false - - /** - * - 针对特定类集合,配置打点白名单,在此集合中的类中的所有方法不打点 - * - 支持正则表达式 - */ - whiteListForClass = [] - - /** - * - 针对特定包名集合,配置打点白名单,所有类以此包名为前缀的类不打点 - * - 支持正则表达式 - */ - whiteListForPackage = [] + apply plugin: 'chain.log.hook' + hooklog{ + enableLoggerToServer true } } +//if (!isAndroidTestBuild()) { +// apply plugin: 'apm-plugin' +//} + +//if (!isAndroidTestBuild()) { +// apply plugin: 'bytex.threadOpt' +// thread_opt { +// enable true +// enableInDebug true +// rxJavaIoReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getIoPool@@()Ljava/util/concurrent/ExecutorService;' +// rxJavaComputationReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getCpuPool@@()Ljava/util/concurrent/ExecutorService;' +// coroutineIoReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getIoPool@@()Ljava/util/concurrent/ExecutorService;' +// coroutineDefaultReplacer 'com/mogo/eagle/core/utilcode/util/ThreadUtils@@getCpuPool@@()Ljava/util/concurrent/ExecutorService;' +// } +// +// /** +// * 方便使用systrace工具,在工程侧打点,便于分析工程侧性能问题 +// */ +// apply plugin: 'bytex.systrace' +// systrace { +// /** +// * 交付时要关闭,会有性能损耗 +// */ +// enable false +// enableInDebug false +// /** +// * - 是否使用[Trace.beginAsyncSection(String, int)/Trace.endAsyncSection(String, int)]进行打点 +// * - 默认使用[Trace.beginSection(String)/Trace.endSection()]进行打点 +// */ +// isTraceAsync false +// /** +// * - 是否在运行时只针对主线程打点,其它线程不打 +// */ +// isOnlyMainThread false +// +// /** +// * - 是否忽略对类的静态构造方法打点 +// * - 默认不忽略 +// */ +// isIgnoreClinitMethod false +// +// /** +// * - 是否忽略对类中的简单方法打点 +// * 简单方法定义: +// * - 空方法 +// * - get/set 方法 +// * - 单独的方法,方法体内没有调用其它方法 +// * - 默认不忽略 +// */ +// isIgnoreSampleMethod false +// +// /** +// * - 针对特定类集合,配置打点白名单,在此集合中的类中的所有方法不打点 +// * - 支持正则表达式 +// */ +// whiteListForClass = [] +// +// /** +// * - 针对特定包名集合,配置打点白名单,所有类以此包名为前缀的类不打点 +// * - 支持正则表达式 +// */ +// whiteListForPackage = [] +// } +//} -/*apply plugin: 'chain.log.hook' -hooklog{ - enableLoggerToServer true -}*/ bugly { appId = 'ac71228f85' // 注册时分配的App ID appKey = '3c736249-d6be-4066-b577-b7a6dc975cf7' // 注册时分配的App Key @@ -254,31 +256,31 @@ dependencies { androidTestImplementation rootProject.ext.dependencies.androidx_espresso_core } -if (!isAndroidTestBuild()) { - ApmPlugin { - // 是否进行插桩 - enable true - // 是否在Debug包插桩,默认不插桩 - enableInDebug true - // DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"); - // INFO 级别Log会汇总所有被插桩处理的类供查看,路径 app/build/ByteX/ApmPlugin - logLevel "DEBUG" - // 启动分析开关:监控App启动耗时,需要同时开启pageLoadSwitch - startSwitch = true - // 页面响应开关:监控Activity的生命周期耗时 - pageLoadSwitch = true - // 网络监控开关:监控okhttp3的网络请求 - okHttp3Switch = true - // 白名单下的包进行插桩,需要填写要插装类所在的包名,支持前缀配置 - whiteList = [ - "com.mogo" - ] - // 黑名单包下类不进行插桩,可以配置包名和类名,没有可以填空 - blackList = [ - - ] - } -} +//if (!isAndroidTestBuild()) { +// ApmPlugin { +// // 是否进行插桩 +// enable true +// // 是否在Debug包插桩,默认不插桩 +// enableInDebug true +// // DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"); +// // INFO 级别Log会汇总所有被插桩处理的类供查看,路径 app/build/ByteX/ApmPlugin +// logLevel "DEBUG" +// // 启动分析开关:监控App启动耗时,需要同时开启pageLoadSwitch +// startSwitch = true +// // 页面响应开关:监控Activity的生命周期耗时 +// pageLoadSwitch = true +// // 网络监控开关:监控okhttp3的网络请求 +// okHttp3Switch = true +// // 白名单下的包进行插桩,需要填写要插装类所在的包名,支持前缀配置 +// whiteList = [ +// "com.mogo" +// ] +// // 黑名单包下类不进行插桩,可以配置包名和类名,没有可以填空 +// blackList = [ +// +// ] +// } +//} android.applicationVariants.all { variant -> def buildTime = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08:00")) diff --git a/app/productFlavors/fPadLenovo.gradle b/app/productFlavors/fPadLenovo.gradle index cd72bc87d6..31335d67d8 100644 --- a/app/productFlavors/fPadLenovo.gradle +++ b/app/productFlavors/fPadLenovo.gradle @@ -29,7 +29,7 @@ project.android.productFlavors { // 构建的应用身份类型,司机|乘客 buildConfigField 'int', 'APP_IDENTITY_MODE', "0x02" // 连接的工控机IP地址 - buildConfigField 'String', 'ADAS_CONNECT_IP', "\"192.168.1.102\"" + buildConfigField 'String', 'ADAS_CONNECT_IP', "\"192.168.1.104\"" // 构建的是否是演示(美化)模式 buildConfigField 'boolean', 'IS_DEMO_MODE', 'true' } diff --git a/app/productFlavors/fPadLenovoOchBus.gradle b/app/productFlavors/fPadLenovoOchBus.gradle index 0e65bd1c47..481187896d 100644 --- a/app/productFlavors/fPadLenovoOchBus.gradle +++ b/app/productFlavors/fPadLenovoOchBus.gradle @@ -28,8 +28,8 @@ project.android.productFlavors { // GPS数据提供源: 0-Android系统,1-工控机,2-OBU buildConfigField 'int', 'GPS_PROVIDER', "1" - // 构建的应用身份类型,司机|乘客 - buildConfigField 'int', 'APP_IDENTITY_MODE', "0x00" + // 构建的应用身份类型,出租车0|小巴A-司机|乘客 + buildConfigField 'int', 'APP_IDENTITY_MODE', "0xA0" // 连接的工控机IP地址 buildConfigField 'String', 'ADAS_CONNECT_IP', "\"192.168.8.102\"" // 构建的是否是演示(美化)模式 diff --git a/app/productFlavors/fPadLenovoOchBusPassenger.gradle b/app/productFlavors/fPadLenovoOchBusPassenger.gradle index 4b7b299e78..74487113d3 100644 --- a/app/productFlavors/fPadLenovoOchBusPassenger.gradle +++ b/app/productFlavors/fPadLenovoOchBusPassenger.gradle @@ -26,8 +26,8 @@ project.android.productFlavors { // GPS数据提供源: 0-Android系统,1-工控机,2-OBU buildConfigField 'int', 'GPS_PROVIDER', "1" - // 构建的应用身份类型,司机0|乘客1 - buildConfigField 'int', 'APP_IDENTITY_MODE', "0x01" + // 构建的应用身份类型,出租车0|小巴A-司机0|乘客1 + buildConfigField 'int', 'APP_IDENTITY_MODE', "0xA1" // 连接的工控机IP地址 buildConfigField 'String', 'ADAS_CONNECT_IP', "\"192.168.8.103\"" // 构建的是否是演示(美化)模式 diff --git a/app/productFlavors/fPadLenovoOchTaxi.gradle b/app/productFlavors/fPadLenovoOchTaxi.gradle index 4d92c20f68..7a583209e6 100644 --- a/app/productFlavors/fPadLenovoOchTaxi.gradle +++ b/app/productFlavors/fPadLenovoOchTaxi.gradle @@ -29,7 +29,7 @@ project.android.productFlavors { // GPS数据提供源: 0-Android系统,1-工控机,2-OBU buildConfigField 'int', 'GPS_PROVIDER', "1" - // 构建的应用身份类型,司机|乘客 + // 构建的应用身份类型,出租车0|小巴A-司机|乘客 buildConfigField 'int', 'APP_IDENTITY_MODE', "0x00" // 连接的工控机IP地址 buildConfigField 'String', 'ADAS_CONNECT_IP', "\"192.168.1.102\"" diff --git a/app/productFlavors/fPadLenovoOchTaxiPassenger.gradle b/app/productFlavors/fPadLenovoOchTaxiPassenger.gradle index b69be39466..2c4ad036b9 100644 --- a/app/productFlavors/fPadLenovoOchTaxiPassenger.gradle +++ b/app/productFlavors/fPadLenovoOchTaxiPassenger.gradle @@ -28,7 +28,7 @@ project.android.productFlavors { // GPS数据提供源: 0-Android系统,1-工控机,2-OBU buildConfigField 'int', 'GPS_PROVIDER', "1" - // 构建的应用身份类型,司机0|乘客1 + // 构建的应用身份类型,出租车0|小巴A-司机0|乘客1 buildConfigField 'int', 'APP_IDENTITY_MODE', "0x01" // 连接的工控机IP地址 buildConfigField 'String', 'ADAS_CONNECT_IP', "\"192.168.1.103\"" diff --git a/app/src/androidTest/java/com/mogo/functions/test/TipToastLeakTest.kt b/app/src/androidTest/java/com/mogo/functions/test/TipToastLeakTest.kt new file mode 100644 index 0000000000..49b38265e5 --- /dev/null +++ b/app/src/androidTest/java/com/mogo/functions/test/TipToastLeakTest.kt @@ -0,0 +1,71 @@ +package com.mogo.functions.test + +import androidx.test.core.app.ActivityScenario +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.LargeTest +import com.mogo.eagle.core.function.hmi.ui.MoGoHmiFragment +import com.mogo.eagle.core.function.main.MainLauncherActivity +import com.mogo.eagle.core.utilcode.mogo.toast.TipToast +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.suspendCancellableCoroutine +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeUnit.MILLISECONDS + +@RunWith(AndroidJUnit4::class) +@LargeTest +class TipToastLeakTest { + + + lateinit var launch: ActivityScenario + + @Before + fun before() { + launch = ActivityScenario.launch(MainLauncherActivity::class.java) + + } + + @Test + fun test() = runBlocking(Dispatchers.Main) { + val f = ensureMoGoHmiFragmentShow() + var index = 0 + while (index < 50) { + delay(TimeUnit.SECONDS.toMillis(4)) + TipToast.shortTip("toast-> $index" ) + index ++ + } + delay(TimeUnit.SECONDS.toMillis(1)) + f.activity?.finish() + delay(TimeUnit.SECONDS.toMillis(2)) + } + + private suspend fun ensureMoGoHmiFragmentShow(): MoGoHmiFragment = suspendCancellableCoroutine { + launch.onActivity { itx -> + val executor = Executors.newSingleThreadScheduledExecutor() + executor.scheduleAtFixedRate({ + var find = + itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment + while (find == null) { + find = + itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment + + } + while (!find.isResumed) { + Thread.sleep(500) + } + it.resumeWith(Result.success(find)) + try { + Thread.sleep(500) + executor.shutdownNow() + } catch (e: Throwable) { + e.printStackTrace() + } + }, 50, 500, MILLISECONDS) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/MogoApplication.java b/app/src/main/java/com/mogo/launcher/MogoApplication.java index 46fb18b8dc..f7700b1668 100644 --- a/app/src/main/java/com/mogo/launcher/MogoApplication.java +++ b/app/src/main/java/com/mogo/launcher/MogoApplication.java @@ -89,6 +89,7 @@ public class MogoApplication extends MainMoGoApplication { HmiBuildConfig.isShowPerspectiveSwitchView = false; HmiBuildConfig.isShowToolsView = false; HmiBuildConfig.isShowBadCaseView = false; + HmiBuildConfig.isShowUpgradeTipsView = false; //业务端可以根据需要控制是否展示刹车和转向灯的ui // HmiBuildConfig.isShowBrakeLightView = false; // HmiBuildConfig.isShowTurnLightView = false; diff --git a/build.gradle b/build.gradle index aa98125141..1615fa6dd6 100644 --- a/build.gradle +++ b/build.gradle @@ -35,9 +35,7 @@ buildscript { classpath 'com.volcengine:apm_insight_plugin:1.4.1' classpath 'com.mogo.cloud:thread_opt:1.0.1' classpath 'com.mogo.cloud:systrace:1.0.1' - -// classpath "com.bytedance.android.byteX:base-plugin:0.3.0" -// classpath "com.mogo.cloud:hook:${HOOK_LOG_VERSION}" + classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.8' // classpath ("com.tencent.matrix:matrix-gradle-plugin:0.6.6") { changing = true } } diff --git a/config.gradle b/config.gradle index fd0958357f..3ace774d82 100644 --- a/config.gradle +++ b/config.gradle @@ -114,7 +114,7 @@ ext { obusdk : "com.zhidao.enterprise.smartv2x:smartv2x:1.0.0.3", mogoobu : 'com.zhidao.support.obu:mogoobu:1.0.0.19', mogoami : 'com.zhidao.support.obu.ami:mogoami:1.0.0.10', - adasHigh : 'com.zhidao.support.adas:high:1.2.1.2_bate21', + adasHigh : 'com.zhidao.support.adas:high:1.2.1.2_bate25', // google googlezxing : "com.google.zxing:core:3.3.3", @@ -222,6 +222,7 @@ ext { mogoaicloudtanlu : "com.mogo.cloud:tanlu:${MOGO_TANLU_VERSION}", mogoaicloudtrafficlive : "com.mogo.cloud:trafficlive:${MOGO_TRAFFICLIVE_VERSION}", mogoaicloudlocation : "com.mogo.cloud:location:${MOGO_LOCATION_VERSION}", + mogoaicloudtelematic : "com.mogo.cloud:telematic:${MOGO_TELEMATIC_VERSION}", //========================= 新架构的 Maven 版本管理 ========================= mogo_core_function_autopilot : "com.mogo.eagle.core.function.impl:autopilot:${MOGO_CORE_FUNCTION_AUTOPILOT_VERSION}", @@ -237,13 +238,14 @@ ext { mogo_core_function_v2x : "com.mogo.eagle.core.function.impl:v2x:${MOGO_CORE_FUNCTION_V2X_VERSION}", mogo_core_function_api : "com.mogo.eagle.core.function:api:${MOGO_CORE_FUNCTION_API_VERSION}", mogo_core_function_call : "com.mogo.eagle.core.function:call:${MOGO_CORE_FUNCTION_CALL_VERSION}", + mogo_core_function_carcorder : "com.mogo.eagle.core.function:carcorder:${MOGO_CORE_FUNCTION_CARCORDER_VERSION}", mogo_core_data : "com.mogo.eagle.core:data:${MOGO_CORE_DATA_VERSION}", mogo_core_res : "com.mogo.eagle.core:res:${MOGO_CORE_RES_VERSION}", mogo_core_utils : "com.mogo.eagle.core:utils:${MOGO_CORE_UTILS_VERSION}", mogo_core_network : "com.mogo.eagle.core:network:${MOGO_CORE_NETWORK_VERSION}", //========================= V2X SDK ========================= - mogo_v2x : "com.mogo.v2x:v2x:${MOGO_V2X_SDK_VERSION}", + mogo_v2x : "com.mogo.v2x:v2x:${MOGO_V2X_SDK_VERSION}", life_cycle_scope : "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0", view_model_scope : "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0", diff --git a/core/README.md b/core/README.md index ba2ca3c14f..180e9b16db 100644 --- a/core/README.md +++ b/core/README.md @@ -2,25 +2,25 @@ 本模块用来编写鹰眼核型功能 - function-impl 目录下编写的都是对mogo-core-function-api定的功能实现, - - mogo-core-function-check 程序及车辆检测模块 - - mogo-core-function-devatools 开发工具模块 - - mogo-core-function-hmi UI呈现及交互模块 - - mogo-core-function-main 主入口 - - mogo-core-function-map 地图相关的模块 - - mogo-core-function-monitoring 远距离监控查看,路测摄像头、前车直播 - - mogo-core-function-notice 云端公告、调度相关模块 - - mogo-core-function-obu-mogo 自研OBU预警模块 - - mogo-core-function-smp 小地图模块 - - mogo-core-function-v2x 自车+云端预警模块 + - check 程序及车辆检测模块 + - devatools 开发工具模块:日志采集、BadCase、 + - hmi UI呈现及交互模块 + - main 主入口(模块加载、后台服务启动、多进程启动等) + - map 地图相关的模块 + - monitoring 行车超视距模块,路测摄像头、前车直播 + - notice 云端公告、调度相关模块 + - obu-mogo 自研OBU预警模块 + - smp 小地图模块 + - v2x 自车+云端预警模块 - mogo-core-data:定义基础业务所需要的数据结构 - -- mogo-core-function-res:这里只存放公共资源,图片,布局,动画等 + +- mogo-core-network:公共网络请求 - mogo-core-function-api:定义基础业务功能的接口 - mogo-core-function-call:定义基础业务暴露给外部调用的接口,对function-impl的二次封装,只将能对外调用的功能进行封装 -- mogo-core-res:程序中涉及到的图片及布局资源,同一管理,并通过设置不同的目录指定是那个模块的资源 +- mogo-core-res:程序中涉及到的图片及布局资源,同一管理,并通过设置不同的目录指定是那个模块的资源,这里只存放公共资源,图片,布局,动画等 - mogo-core-utils:基于成熟的工具类开源框架下沉的,这里可以增添针对我们业务上的一些工具类 diff --git a/core/function-impl/mogo-core-function-autopilot/build.gradle b/core/function-impl/mogo-core-function-autopilot/build.gradle index 0dd305e15c..7bab1ff8fd 100644 --- a/core/function-impl/mogo-core-function-autopilot/build.gradle +++ b/core/function-impl/mogo-core-function-autopilot/build.gradle @@ -51,18 +51,20 @@ dependencies { kapt rootProject.ext.dependencies.aroutercompiler - implementation rootProject.ext.dependencies.adasHigh + implementation rootProject.ext.dependencies.mogochainbase implementation rootProject.ext.dependencies.mogoami + implementation rootProject.ext.dependencies.mogoaicloudtelematic if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { + implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.modulecommon implementation rootProject.ext.dependencies.moduleservice - implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogo_core_network implementation rootProject.ext.dependencies.mogo_core_function_api implementation rootProject.ext.dependencies.mogo_core_function_call + implementation rootProject.ext.dependencies.adasHigh } else { implementation project(':modules:mogo-module-common') implementation project(':modules:mogo-module-service') @@ -72,6 +74,7 @@ dependencies { implementation project(':core:mogo-core-network') implementation project(':core:mogo-core-function-api') implementation project(':core:mogo-core-function-call') + implementation project(':libraries:mogo-adas') } } diff --git a/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/MoGoAutopilotProvider.kt b/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/MoGoAutopilotProvider.kt index fc67de4c1f..e53b4013f3 100644 --- a/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/MoGoAutopilotProvider.kt +++ b/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/MoGoAutopilotProvider.kt @@ -4,6 +4,7 @@ import android.Manifest.permission import android.content.Context import androidx.annotation.RequiresPermission import com.alibaba.android.arouter.facade.annotation.Route +import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.eagle.core.data.autopilot.AutopilotControlCmdParameter import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters import com.mogo.eagle.core.data.config.FunctionBuildConfig @@ -21,10 +22,12 @@ import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr import com.mogo.eagle.core.utilcode.util.GsonUtils import com.mogo.eagle.core.utilcode.util.ThreadUtils import com.zhidao.support.adas.high.AdasManager +import com.zhidao.support.adas.high.AdasOptions import com.zhidao.support.adas.high.bean.IPCUpgradeInfo import com.zhidao.support.adas.high.common.CupidLogUtils import java.util.concurrent.TimeUnit + /** * @author xiaoyuzhou * @date 2021/9/22 8:43 下午 @@ -32,7 +35,7 @@ import java.util.concurrent.TimeUnit */ @Route(path = MogoServicePaths.PATH_AUTO_PILOT) class MoGoAutopilotProvider : - IMoGoAutopilotProvider, IMoGoMapDataCollectProvider.OnMapCollectCmdListener { + IMoGoAutopilotProvider, IMoGoMapDataCollectProvider.OnMapCollectCmdListener { private val TAG = "MoGoAutoPilotProvider" private var mContext: Context? = null @@ -50,24 +53,121 @@ class MoGoAutopilotProvider : when (FunctionBuildConfig.appIdentityMode) { 0x00 -> // 司机 { + // 注册地图采集功能 CallerMapDataCollectorManager.registerOnMapCollectTaskListener(this) - AdasManager.getInstance().create(context, FunctionBuildConfig.adasConnectIP) + // "192.168.1.102" + val options = AdasOptions.Builder() + .setIPCIp(FunctionBuildConfig.adasConnectIP) + .setClient(false) + .build() + + AdasManager.getInstance().create(context, options) +// NSDNettyManager.getInstance().startNSDNettyServer(context, object : NettyServerListener { +// override fun onMessageResponseServer(msg: MogoProtocolMsg?, channel: Channel?) { +// Logger.d(TAG, "Receive client data is:${msg?.toString()}") +// } +// +// override fun onStartServer() { +// ToastUtils.showShort("司机端服务启动成功!") +// Logger.d(TAG, "onStartServer") +// } +// +// override fun onStopServer() { +// ToastUtils.showLong("司机端服务停止!") +// Logger.d(TAG, "onStopServer") +// } +// +// override fun onChannelConnect(channel: Channel?) { +// NSDNettyManager.getInstance().selectChannel(channel) +// val socketAddress = channel?.remoteAddress().toString() +// Logger.d(TAG, "Client ip is:${socketAddress}") +// } +// +// override fun onChannelDisConnect(channel: Channel?) { +// Logger.d(TAG, "onChannelDisConnect") +// } +// }) } 0x01 -> // 乘客 { // 乘客端默认接收绘制全局路径+引导线 //FunctionBuildConfig.isDemoMode = true //FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true - AdasManager.getInstance().create(context, FunctionBuildConfig.adasConnectIP) + // "192.168.1.102" + val options = AdasOptions + .Builder() + .setClient(true) + .build() + AdasManager.getInstance().create(context, options) +// NSDNettyManager.getInstance().searchAndConnectServer(context, MoGoAiCloudClientConfig.getInstance().sn, object : NettyClientListener { +// override fun onMessageResponseClient(msg: MogoProtocolMsg?, sign: String?) { +// Logger.d(TAG, "收到司机端的数据!") +// // 乘客端收到adas数据直接解析,后续分发解析后的数据流程同司机端 +// msg?.let { +// AdasManager.getInstance().parseIPCData(it.body) +// Logger.d(TAG, "解析司机端数据完毕!") +// } +// } +// +// override fun onClientStatusConnectChanged(statusCode: Int, sign: String?) { +// when (statusCode) { +// ConnectState.STATUS_CONNECT_SUCCESS -> Logger.d(TAG, "乘客端连接司机端服务成功! sign is:${sign}") +// else -> { +// ToastUtils.showLong("和司机端连接异常!") +// Logger.d(TAG, "client statusCode is:${statusCode}") +// } +// } +// } +// }) } + // else -> // 默认采用UDP寻址方式 - AdasManager.getInstance().create(context) + { + val options = AdasOptions.Builder() + .setClient(false) + .setIPCIp(FunctionBuildConfig.adasConnectIP) + .build() + AdasManager.getInstance().create(context, options) + } } //////////////////////////////////注意先后顺序,AdasManager.getInstance().create后才可以设置监听///////////////////////////////////////////// // 监听 adas 连接状态 - AdasManager.getInstance().setOnAdasConnectStatusListener(MoGoAdasMsgConnectStatusListenerImpl()) - // 监听ADAS-SDK获取到的工控机数据 + AdasManager.getInstance() + .setOnAdasConnectStatusListener(MoGoAdasMsgConnectStatusListenerImpl()) + // 监听ADAS-SDK获取到的工控机数据(乘客也需注册) AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl()) +// // 司机端监听 +// if (FunctionBuildConfig.appIdentityMode == 0) { +// AdasManager.getInstance().setOnMultiDeviceListener { bytes -> +// Logger.d( +// TAG, +// "司机端接收到工控机吐出来的数据为:${Arrays.toString(bytes)}" +// ) +// // 发送数据给乘客端 +// if (NSDNettyManager.getInstance().isServerStart) { +// Logger.d( +// TAG, +// "司机端透传数据给乘客端!" +// ) +// NSDNettyManager.getInstance().sendMsgToAllClients(MogoProtocolMsg(NORMAL_DATA, bytes.size, bytes)) +//// NSDNettyManager.getInstance().sendMogoProtocolMsgToClient(MogoProtocolMsg(NORMAL_DATA, bytes.size, bytes)) { channelFuture: ChannelFuture -> +//// if (channelFuture.isSuccess) { +//// Logger.d( +//// TAG, +//// "Send data to client is success." +//// ) +//// } else { +//// Logger.d( +//// TAG, +//// "Send data to client is failure." +//// ) +//// } +//// } +// } else { +// Logger.d(TAG, "司机端Server未启动!") +// } +// } +// } // 同步数据给工控机的服务 AsyncDataToAutopilotServer.INSTANCE.initServer() // 同步是否开启美化模式 @@ -87,7 +187,9 @@ class MoGoAutopilotProvider : @RequiresPermission(permission.INTERNET) override fun doInBackground(): String { // 保存本地 AutoPilot IP地址 - mContext?.let { SharedPrefsMgr.getInstance(it).putString(MoGoConfig.AUTOPILOT_IP, autoPilotIp) } + mContext?.let { + SharedPrefsMgr.getInstance(it).putString(MoGoConfig.AUTOPILOT_IP, autoPilotIp) + } // 设置IP地址 AdasManager.getInstance().setIPCIp(autoPilotIp) // 打开通讯连接 @@ -134,7 +236,7 @@ class MoGoAutopilotProvider : override fun recordPackage(): Boolean { return AdasManager.getInstance() - .recordPackage(1, (System.currentTimeMillis() / 1000).toInt()) + .recordPackage(1, (System.currentTimeMillis() / 1000).toInt()) } override fun recordPackage(type: Int, id: Int): Boolean { diff --git a/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.java b/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.java index a2b9997f1f..6e36a13d5d 100644 --- a/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.java +++ b/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.java @@ -1,5 +1,17 @@ package com.mogo.eagle.core.function.autopilot.adapter; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ARRIVE; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_GUARDIAN; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_RECORD; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ROUTE; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_STATUS; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_TRAJECTORY; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_WARN; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_STATE; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_ADAS_MESSAGE_RECT_DATA; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_ADAS; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_DATA; + import android.util.Log; import androidx.annotation.Nullable; @@ -42,6 +54,8 @@ import com.zhidao.support.adas.high.bean.WarnMessageInfo; import com.zhidao.support.adas.high.bean.guardian.AutopilotGuardianInfo; import com.zhidao.support.adas.high.bean.record.AutopilotRecordResult; import com.zhidao.support.obu.ami.AmiClientManager; +import com.zhjt.service.chain.ChainLog; +import com.zhjt.service.chain.TracingConstants; import org.json.JSONObject; @@ -57,7 +71,12 @@ import java.util.List; public class MoGoAdasListenerImpl implements OnAdasListener { private final String TAG = "OnAdasListenerAdapter"; - +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_RECT_DATA, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void onRectData(RectInfo rectInfo) { if (HdMapBuildConfig.isMapLoaded) { @@ -66,6 +85,12 @@ public class MoGoAdasListenerImpl implements OnAdasListener { } } +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_STATE, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void onCarStateData(CarStateInfo carStateInfo) { if (HdMapBuildConfig.isMapLoaded) { @@ -145,6 +170,12 @@ public class MoGoAdasListenerImpl implements OnAdasListener { } } +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_STATUS, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void autopilotStatus(AutopilotStatus autopilotStatus) { if (HdMapBuildConfig.isMapLoaded) { @@ -177,10 +208,16 @@ public class MoGoAdasListenerImpl implements OnAdasListener { } } +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ARRIVE, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void autopilotArrive(AutopilotWayArrive autopilotWayArrive) { if (HdMapBuildConfig.isMapLoaded) { - Logger.d(TAG, "autopilotArrive : " + autopilotWayArrive); +// Logger.d(TAG, "autopilotArrive : " + autopilotWayArrive); if (autopilotWayArrive != null) { AutopilotWayArrive.ResultBean result = autopilotWayArrive.getResult(); if (result != null) { @@ -195,19 +232,30 @@ public class MoGoAdasListenerImpl implements OnAdasListener { } } +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ROUTE, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void onAutopilotRoute(AutopilotRoute route) { if (HdMapBuildConfig.isMapLoaded) { - Logger.d(TAG, "onAutopilotRoute : " + route.toString()); +// Logger.d(TAG, "onAutopilotRoute : " + route.toString()); AutopilotRouteInfo autopilotRoute = AdasObjectConvertUtils.INSTANCE.fromAdasAutopilotRoute(route); CallerAutopilotPlanningListenerManager.INSTANCE.invokeAutopilotRotting(autopilotRoute); } } +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_TRAJECTORY, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void onAutopilotTrajectory(List trajectoryList) { if (HdMapBuildConfig.isMapLoaded) { - Logger.d(TAG, "onAutopilotTrajectory : " + trajectoryList); +// Logger.d(TAG, "onAutopilotTrajectory : " + trajectoryList); ArrayList trajectoryInfoArrayList = new ArrayList<>(); if (trajectoryList != null && trajectoryList.size() > 0) { for (TrajectoryInfo trajectory : trajectoryList) { @@ -223,7 +271,7 @@ public class MoGoAdasListenerImpl implements OnAdasListener { adasTrajectoryInfo.setTheta(trajectory.getTheta()); trajectoryInfoArrayList.add(adasTrajectoryInfo); } - Log.e(TAG, "time:" + System.currentTimeMillis() + "trajectoryInfoArrayList:" + trajectoryInfoArrayList); +// Log.e(TAG, "time:" + System.currentTimeMillis() + "trajectoryInfoArrayList:" + trajectoryInfoArrayList); } CallerAutopilotPlanningListenerManager.INSTANCE.invokeAutopilotTrajectory(trajectoryInfoArrayList); } @@ -234,6 +282,12 @@ public class MoGoAdasListenerImpl implements OnAdasListener { CallerAutoPilotStatusListenerManager.INSTANCE.invokeAutopilotSNRequest(); } +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_GUARDIAN, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void onAutopilotGuardian(AutopilotGuardianInfo guardianInfo) { if (HdMapBuildConfig.isMapLoaded) { @@ -242,6 +296,12 @@ public class MoGoAdasListenerImpl implements OnAdasListener { } } +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_RECORD, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void onAutopilotRecord(AutopilotRecordResult result) { if (result != null) { @@ -276,7 +336,12 @@ public class MoGoAdasListenerImpl implements OnAdasListener { } - +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_WARN, +// paramIndexes = {0}, +// clientPkFileName = "sn") @Override public void onWarnMessage(WarnMessageInfo warnMessageInfo) { final AutopilotWarnMessage warnMessage = AdasObjectConvertUtils.INSTANCE.fromAdasObject(warnMessageInfo); diff --git a/core/function-impl/mogo-core-function-carcorder/.gitignore b/core/function-impl/mogo-core-function-carcorder/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/core/function-impl/mogo-core-function-carcorder/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-carcorder/build.gradle b/core/function-impl/mogo-core-function-carcorder/build.gradle new file mode 100644 index 0000000000..d612fd342f --- /dev/null +++ b/core/function-impl/mogo-core-function-carcorder/build.gradle @@ -0,0 +1,75 @@ +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'kotlin-android-extensions' + id 'kotlin-kapt' + id 'com.alibaba.arouter' +} + +android { + compileSdkVersion rootProject.ext.android.compileSdkVersion + // buildToolsVersion rootProject.ext.android.buildToolsVersion + defaultConfig { + minSdkVersion rootProject.ext.android.minSdkVersion + targetSdkVersion rootProject.ext.android.targetSdkVersion + versionCode Integer.valueOf(VERSION_CODE) + versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + + //ARouter apt 参数 + kapt { + useBuildCache = false + arguments { + arg("AROUTER_MODULE_NAME", project.getName()) + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation rootProject.ext.dependencies.kotlinstdlibjdk7 + implementation rootProject.ext.dependencies.coroutinescore + implementation rootProject.ext.dependencies.arouter + kapt rootProject.ext.dependencies.aroutercompiler + implementation rootProject.ext.dependencies.mogologlib + + if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { + implementation rootProject.ext.dependencies.mogoserviceapi + implementation rootProject.ext.dependencies.modulecommon + + implementation project(':libraries:map-usbcamera') + + implementation rootProject.ext.dependencies.mogo_core_utils + implementation rootProject.ext.dependencies.mogo_core_function_api + implementation rootProject.ext.dependencies.mogo_core_function_call + implementation rootProject.ext.dependencies.mogo_core_data + }else { + implementation project(':services:mogo-service-api') + implementation project(':modules:mogo-module-common') + + implementation project(':libraries:map-usbcamera') + + implementation project(':core:mogo-core-utils') + implementation project(':core:mogo-core-function-api') + implementation project(':core:mogo-core-function-call') + implementation project(':core:mogo-core-data') + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-carcorder/gradle.properties b/core/function-impl/mogo-core-function-carcorder/gradle.properties new file mode 100644 index 0000000000..ba1462e8ad --- /dev/null +++ b/core/function-impl/mogo-core-function-carcorder/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.eagle.core.function.impl +POM_ARTIFACT_ID=carcorder +VERSION_CODE=1 diff --git a/core/function-impl/mogo-core-function-carcorder/proguard-rules.pro b/core/function-impl/mogo-core-function-carcorder/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/core/function-impl/mogo-core-function-carcorder/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-carcorder/src/main/AndroidManifest.xml b/core/function-impl/mogo-core-function-carcorder/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..6c1ea8112e --- /dev/null +++ b/core/function-impl/mogo-core-function-carcorder/src/main/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-carcorder/src/main/java/com/mogo/eagle/core/function/carcorder/service/CarcorderService.kt b/core/function-impl/mogo-core-function-carcorder/src/main/java/com/mogo/eagle/core/function/carcorder/service/CarcorderService.kt new file mode 100644 index 0000000000..c355159e07 --- /dev/null +++ b/core/function-impl/mogo-core-function-carcorder/src/main/java/com/mogo/eagle/core/function/carcorder/service/CarcorderService.kt @@ -0,0 +1,162 @@ +package com.mogo.eagle.core.function.carcorder.service + +import android.content.Intent +import android.hardware.usb.UsbDevice +import android.os.IBinder +import android.util.Log +import com.mogo.eagle.core.utilcode.mogo.logger.Logger +import com.mogo.usbcamera.UVCCameraHelper +import com.serenegiant.usb.IFrameCallback +import com.serenegiant.usb.USBMonitor +import com.serenegiant.usb.USBMonitor.OnDeviceConnectListener +import com.serenegiant.usb.USBMonitor.UsbControlBlock +import com.serenegiant.usb.UVCCamera +import com.serenegiant.usb.common.BaseService +import com.serenegiant.usb.encoder.MediaVideoBufferEncoder + +/** + * 行车记录仪服务 + * @author donghongyu + */ +class CarcorderService : BaseService() { + private val DEBUG = true + val TAG = CarcorderService::class.java.name + + // 挂载的USB设备集合 + private var mDeviceList: List? = null + + // USB 设备连接工具 + private var mUSBMonitor: USBMonitor? = null + + // 用于接入UVC摄像机 + private var mUVCCamera: UVCCamera? = null + + // 相机控制 + private var mCtrlBlock: UsbControlBlock? = null + + /** + * 配置相机基本按书 + */ + private val previewWidth = 640 + private val previewHeight = 480 + + // Default using MJPEG + // if your device is connected,but have no images + // please try to change it to FRAME_FORMAT_YUYV + val FRAME_FORMAT_MJPEG: Int = UVCCamera.FRAME_FORMAT_MJPEG + val MODE_BRIGHTNESS = UVCCamera.PU_BRIGHTNESS + val MODE_CONTRAST = UVCCamera.PU_CONTRAST + private val mFrameFormat = UVCCameraHelper.FRAME_FORMAT_MJPEG + + override fun onCreate() { + super.onCreate() + if (DEBUG) { + Logger.d(TAG, "onCreate……") + } + if (mUSBMonitor == null) { + mUSBMonitor = USBMonitor(applicationContext, mOnDeviceConnectListener) + mUSBMonitor!!.register() + mDeviceList = mUSBMonitor!!.deviceList + } + + } + + override fun onDestroy() { + super.onDestroy() + if (DEBUG) Log.d(TAG, "onDestroy:") + if (mUSBMonitor != null) { + mUSBMonitor!!.unregister() + mUSBMonitor = null + } + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + return super.onStartCommand(intent, flags, startId) + } + + + override fun onBind(intent: Intent): IBinder? { + return null + } + + override fun onRebind(intent: Intent) { + if (DEBUG) Log.d(TAG, "onRebind:$intent") + } + + + override fun onUnbind(intent: Intent): Boolean { + if (DEBUG) Log.d(TAG, "onUnbind:$intent") + + if (DEBUG) Log.d(TAG, "onUnbind:finished") + return true + } + + //********************************************************************************************************************************** + private val mSync: Any = Any() + + private val mVideoEncoder: MediaVideoBufferEncoder? = null + + + /** + * USB 设备连接监听 + */ + private val mOnDeviceConnectListener: OnDeviceConnectListener = object : OnDeviceConnectListener { + override fun onAttach(device: UsbDevice) { + if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onAttach:${device.deviceName}---mDeviceList:${mDeviceList?.size}") + mUSBMonitor!!.requestPermission(device) + } + + override fun onConnect(device: UsbDevice, ctrlBlock: UsbControlBlock, createNew: Boolean) { + if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onConnect:${device.deviceName}") + openCamera(device, ctrlBlock, createNew) + } + + override fun onDisconnect(device: UsbDevice, ctrlBlock: UsbControlBlock) { + if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onDisconnect:${device.deviceName}") + } + + override fun onDettach(device: UsbDevice) { + if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onDettach:${device.deviceName}") + } + + override fun onCancel(device: UsbDevice) { + if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onCancel:${device.deviceName}") + } + } + + /** + * 连接相机 + */ + private fun openCamera(device: UsbDevice, ctrlBlock: UsbControlBlock, createNew: Boolean) { + if (mUVCCamera == null) { + mUVCCamera = UVCCamera() + mUVCCamera!!.open(ctrlBlock) + mUVCCamera!!.setStatusCallback { statusClass, event, selector, statusAttribute, data -> + if (DEBUG) Log.d(TAG, "IStatusCallback#onStatus(statusClass=${statusClass},event=${event},selector=${selector},statusAttribute=${statusAttribute},data=${data})") + } + + try { + mUVCCamera!!.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.FRAME_FORMAT_MJPEG) + } catch (e: Exception) { + e.printStackTrace() + try { + mUVCCamera!!.setPreviewSize(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, UVCCamera.DEFAULT_PREVIEW_MODE) + } catch (e: Exception) { + e.printStackTrace() + mUVCCamera!!.destroy() + } + } + + mUVCCamera!!.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_YUV420SP) + mUVCCamera!!.startPreview() + } + } + + /** + * 视频帧回掉 + */ + private val mIFrameCallback = IFrameCallback { frame -> + if (DEBUG) Log.d(TAG, "IFrameCallback#onFrame:${frame}") + } + +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-carcorder/src/main/java/com/mogo/eagle/core/function/carcorder/service/LivePushService.kt b/core/function-impl/mogo-core-function-carcorder/src/main/java/com/mogo/eagle/core/function/carcorder/service/LivePushService.kt new file mode 100644 index 0000000000..3940a4c9ee --- /dev/null +++ b/core/function-impl/mogo-core-function-carcorder/src/main/java/com/mogo/eagle/core/function/carcorder/service/LivePushService.kt @@ -0,0 +1,53 @@ +package com.mogo.eagle.core.function.carcorder.service + +import android.content.Intent +import android.os.IBinder +import android.util.Log +import com.mogo.eagle.core.utilcode.mogo.logger.Logger +import com.serenegiant.usb.common.BaseService + +/** + * 行车记录仪服务 + * @author donghongyu + */ +class LivePushService : BaseService() { + private val DEBUG = true + val TAG = LivePushService::class.java.name + + override fun onCreate() { + super.onCreate() + if (DEBUG) { + Logger.d(TAG, "onCreate……") + } + + } + + override fun onDestroy() { + super.onDestroy() + if (DEBUG) Log.d(TAG, "onDestroy:") + + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + return super.onStartCommand(intent, flags, startId) + } + + + override fun onBind(intent: Intent): IBinder? { + return null + } + + override fun onRebind(intent: Intent) { + if (DEBUG) Log.d(TAG, "onRebind:$intent") + } + + + override fun onUnbind(intent: Intent): Boolean { + if (DEBUG) Log.d(TAG, "onUnbind:$intent") + + if (DEBUG) Log.d(TAG, "onUnbind:finished") + return true + } + + +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/build.gradle b/core/function-impl/mogo-core-function-devatools/build.gradle index f909f820b5..56c8d2e062 100644 --- a/core/function-impl/mogo-core-function-devatools/build.gradle +++ b/core/function-impl/mogo-core-function-devatools/build.gradle @@ -48,6 +48,7 @@ dependencies { implementation rootProject.ext.dependencies.arouter kapt rootProject.ext.dependencies.aroutercompiler implementation rootProject.ext.dependencies.mogologlib + implementation rootProject.ext.dependencies.mogochainbase if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { implementation rootProject.ext.dependencies.mogoserviceapi diff --git a/core/function-impl/mogo-core-function-devatools/src/main/AndroidManifest.xml b/core/function-impl/mogo-core-function-devatools/src/main/AndroidManifest.xml index 4ba99103af..7a02e164bc 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/AndroidManifest.xml +++ b/core/function-impl/mogo-core-function-devatools/src/main/AndroidManifest.xml @@ -1,4 +1,7 @@ + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt index b8ddf3e5f4..ca79afe0be 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt @@ -1,29 +1,105 @@ package com.zhjt.mogo_core_function_devatools +import android.annotation.SuppressLint import android.content.Context import com.alibaba.android.arouter.facade.annotation.Route +import com.mogo.cloud.passport.MoGoAiCloudClientConfig +import com.mogo.eagle.core.data.chain.ChainConstant.Companion.CHAIN_LINK_LOG_ADAS_INIT +import com.mogo.eagle.core.data.chain.ChainConstant.Companion.CHAIN_LINK_LOG_ADAS_MSG +import com.mogo.eagle.core.data.chain.ChainConstant.Companion.CHAIN_LINK_LOG_CONNECT_STATUS +import com.mogo.eagle.core.data.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_DATA +import com.mogo.eagle.core.data.chain.ChainLogParam +import com.mogo.eagle.core.data.constants.MoGoConfig import com.mogo.eagle.core.data.constants.MogoServicePaths import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider +import com.mogo.eagle.core.utilcode.mogo.logger.Logger +import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr +import com.mogo.eagle.core.utilcode.util.DeviceUtils +import com.mogo.eagle.core.utilcode.util.Utils +import com.zhidao.loglib.fw.FileWriteManager +import com.zhidao.loglib.fw.FwBuild import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchManager +import com.zhjt.service.chain.core.ChainTraceStarter @Route(path = MogoServicePaths.PATH_DEVA_TOOLS) class DevaToolsProvider : IDevaToolsProvider { + private val traceInfoCache = hashMapOf() + private val fwBuildMap: MutableMap = HashMap() + override val functionName: String get() = "DevaToolsProvider" override fun init(context: Context) { MogoLogCatchManager.init(context) + logCheck(context) + initTrace(context) + } + + private fun logCheck(context: Context) { + val logger = SharedPrefsMgr.getInstance(context).getBoolean(MoGoConfig.CATCH_LOG, false) + val loggerTime = SharedPrefsMgr.getInstance(context).getLong(MoGoConfig.CATCH_LOG_TIME, 0) + val logCatchDuration = (System.currentTimeMillis() - loggerTime) / 1000 / 60 + if (logger && loggerTime > 0) { + val logTime: Int = if (10 - logCatchDuration < 1) { + 1 + } else { + 10 - logCatchDuration.toInt() + } + MogoLogCatchManager.startCatchLog(logTime) + } else { + Logger.d( + functionName, + "logCheck logger : $logger , logCatchDuration : $logCatchDuration" + ) + } } override fun startLogCatch() { MogoLogCatchManager.startCatchLog() } + override fun startLogCatch(duration: Int) { + MogoLogCatchManager.startCatchLog(duration) + } + override fun stopLogCatch() { MogoLogCatchManager.stopCatchLog() } + private fun initTrace(context: Context) { + // 初始化Trace抓取服务 + val pkgName = Utils.getApp().packageName + ChainTraceStarter.start(pkgName, DeviceUtils.getMacAddress(), BuildConfig.DEBUG) + + // Trace过程中进行日志抓取,对日志进行配置 + fwBuildMap[CHAIN_LINK_LOG_CONNECT_STATUS] = + FwBuild(true, pkgName + CHAIN_LINK_LOG_ADAS_INIT, 5_000) + fwBuildMap[CHAIN_LINK_LOG_WEB_SOCKET_DATA] = + FwBuild(false, pkgName + CHAIN_LINK_LOG_ADAS_MSG, 500) + + traceInfoCache[CHAIN_LINK_LOG_CONNECT_STATUS] = ChainLogParam(true, "ADAS连接状态") + traceInfoCache[CHAIN_LINK_LOG_WEB_SOCKET_DATA] = ChainLogParam(false, "ADAS长链数据") + FileWriteManager.getInstance() + .init(context, MoGoAiCloudClientConfig.getInstance().sn, pkgName, fwBuildMap) + } + + override fun getTraceInfo(): HashMap { + return traceInfoCache + } + + @SuppressLint("NewApi") + override fun refreshTraceInfo(map: HashMap) { + map.forEach { (type, param) -> + val fwBuild = this.fwBuildMap[type] + fwBuild?.let { + Logger.d(functionName, "param : ${param.des} , record : ${param.record}") + it.isRecord = param.record + } + } + FileWriteManager.getInstance().operateChainMap(fwBuildMap) + } + override fun onDestroy() { MogoLogCatchManager.onDestroy() } diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/logcatch/MogoLogCatchManager.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/logcatch/MogoLogCatchManager.kt index cdff9714ed..3e6c352fd1 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/logcatch/MogoLogCatchManager.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/logcatch/MogoLogCatchManager.kt @@ -7,13 +7,14 @@ import android.os.Message import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.commons.AbsMogoApplication import com.mogo.commons.debug.DebugConfig +import com.mogo.eagle.core.data.constants.MoGoConfig import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager import com.mogo.eagle.core.network.NetConfig import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel import com.mogo.eagle.core.utilcode.mogo.logger.Logger +import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr import com.mogo.eagle.core.utilcode.mogo.toast.TipToast import com.mogo.eagle.core.utilcode.util.ThreadUtils -import com.mogo.eagle.core.utilcode.util.TimeUtils import com.mogo.module.common.MogoApisHandler import com.mogo.service.cloud.socket.IMogoOnMessageListener import com.zhidao.loglib.bean.RemoteLogPushContent @@ -25,7 +26,6 @@ import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companio import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companion.LOG_PUSH_TYPE import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companion.START_CATCH_LOG import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companion.STOP_CATCH_LOG -import java.io.File @SuppressLint("StaticFieldLeak") object MogoLogCatchManager : IMogoOnMessageListener, Handler.Callback, @@ -47,7 +47,6 @@ object MogoLogCatchManager : IMogoOnMessageListener, Handl MogoApisHandler.getInstance().apis .getSocketManagerApi(AbsMogoApplication.getApp().applicationContext) .registerOnMessageListener(LOG_PUSH_TYPE, this) - manualContent.duration = 10 manualContent.pkgName = context.packageName } @@ -80,12 +79,13 @@ object MogoLogCatchManager : IMogoOnMessageListener, Handl return false } - fun startCatchLog() { + fun startCatchLog(duration:Int = 10) { if (catchingList.contains(MANUAL_CATCH_PKG_NAME)) { TipToast.shortTip("已经在抓取日志了,请稍后再试") } else { - Logger.d(TAG, "开始抓取日志====") + Logger.d(TAG, "开始抓取日志==== duration : $duration") manualContent.type = START_CATCH_LOG + manualContent.duration = duration startCatchLog(manualContent) } } @@ -101,20 +101,28 @@ object MogoLogCatchManager : IMogoOnMessageListener, Handl var delay = (content.duration).toLong() handler.removeMessages(MSG_TRY_CLOSE_LOG) if (delay <= 0) { - // 如果push 下来的delay小于等于0,那就给个默认最大值一小时 + // 如果push 下来的delay小于等于0,那就给个默认值 delay = 10 } handler.sendEmptyMessageDelayed(MSG_TRY_CLOSE_LOG, delay * 1000L * 60) + openLoggerLevel() + logInfoManager = LogInfoManagerFactory.createPushLogInfoManager( mContext, - MoGoAiCloudClientConfig.getInstance().sn + File.separator + TimeUtils.formatYMD(System.currentTimeMillis()), - content, this + MoGoAiCloudClientConfig.getInstance().sn, + content, + this ) + logInfoManager?.start() logInfoManager?.registerLogOutListener { lineLog -> CallerDevaToolsListenerManager.invokeDevaToolsLogCatchLines(lineLog) } + + SharedPrefsMgr.getInstance(mContext!!).putBoolean(MoGoConfig.CATCH_LOG, true) + SharedPrefsMgr.getInstance(mContext!!) + .putLong(MoGoConfig.CATCH_LOG_TIME, System.currentTimeMillis()) } private fun stopCatchLog(content: RemoteLogPushContent) { @@ -125,6 +133,9 @@ object MogoLogCatchManager : IMogoOnMessageListener, Handl logInfoManager?.stop() logInfoManager = null closeLoggerLevel() + + SharedPrefsMgr.getInstance(mContext!!).putBoolean(MoGoConfig.CATCH_LOG, false) + SharedPrefsMgr.getInstance(mContext!!).putLong(MoGoConfig.CATCH_LOG_TIME, 0) } /** @@ -152,6 +163,10 @@ object MogoLogCatchManager : IMogoOnMessageListener, Handl override fun onClose(pkgName: String?) { ThreadUtils.runOnUiThread { + + SharedPrefsMgr.getInstance(mContext!!).putBoolean(MoGoConfig.CATCH_LOG, false) + SharedPrefsMgr.getInstance(mContext!!).putLong(MoGoConfig.CATCH_LOG_TIME, 0) + CallerDevaToolsListenerManager.invokeDevaToolsLogCatchClose() TipToast.shortTip("日志抓取默认计时结束") } diff --git a/core/function-impl/mogo-core-function-hmi/build.gradle b/core/function-impl/mogo-core-function-hmi/build.gradle index a6f481b4a8..eacd9256cd 100644 --- a/core/function-impl/mogo-core-function-hmi/build.gradle +++ b/core/function-impl/mogo-core-function-hmi/build.gradle @@ -59,8 +59,8 @@ dependencies { if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { - implementation rootProject.ext.dependencies.androidxrecyclerview implementation rootProject.ext.dependencies.modulecommon + compileOnly rootProject.ext.dependencies.mogoserviceapi implementation project(':libraries:map-usbcamera') implementation rootProject.ext.dependencies.mogo_core_res @@ -76,7 +76,7 @@ dependencies { implementation project(':core:mogo-core-res') implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-utils') - implementation project(':core:mogo-core-res') + implementation project(':core:mogo-core-network') implementation project(':core:mogo-core-function-api') implementation project(':core:mogo-core-function-call') } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index 952cc5fe00..bcd0564a1d 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -5,12 +5,16 @@ import android.os.Bundle import android.os.Handler import android.text.TextUtils import android.util.Log -import android.view.* +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager import android.view.animation.OvershootInterpolator import androidx.lifecycle.Lifecycle.Event.ON_DESTROY import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.lifecycleScope -import androidx.transition.* +import androidx.transition.AutoTransition +import androidx.transition.TransitionManager import com.alibaba.android.arouter.facade.annotation.Route import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.commons.mvp.MvpFragment @@ -37,7 +41,6 @@ import com.mogo.eagle.core.function.hmi.notification.WarningFloat import com.mogo.eagle.core.function.hmi.notification.anim.DefaultAnimator import com.mogo.eagle.core.function.hmi.notification.enums.SidePattern import com.mogo.eagle.core.function.hmi.ui.camera.CameraListView -import com.mogo.eagle.core.function.hmi.ui.carcorder.CarcorderPreviewView import com.mogo.eagle.core.function.hmi.ui.notice.NoticeBannerView import com.mogo.eagle.core.function.hmi.ui.notice.NoticeNormalBannerView import com.mogo.eagle.core.function.hmi.ui.setting.DebugSettingView @@ -99,6 +102,8 @@ class MoGoHmiFragment : MvpFragment private var onBadCaseShow: (() -> View)? = null private var onBadCaseHide: (() -> Unit)? = null + private var upgradeTipsView: (() -> View)? = null + companion object { private const val MSG_WHAT_DISMISS_BAD_CASE_ENTRY = 0x1010 private val CASE_EXPIRE_DURATION = TimeUnit.HOURS.toMillis(4) @@ -117,7 +122,8 @@ class MoGoHmiFragment : MvpFragment Log.d("QQQ", "-- step -- 1 --") var oldT = try { old?.timestamp?.takeIf { it.isNotBlank() }?.let { - SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).parse(it)?.time ?: 0L + SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).parse(it)?.time + ?: 0L } ?: 0L } catch (t: Throwable) { t.printStackTrace() @@ -127,30 +133,31 @@ class MoGoHmiFragment : MvpFragment var newT = try { it.receive()?.also { record = it }?.timestamp?.takeIf { it.isNotBlank() }?.let { SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).parse(it)?.time - ?: 0L + ?: 0L } ?: 0L } catch (t: Throwable) { t.printStackTrace() 0L } - if (oldT == 0L || (newT > 0L && (newT - oldT > 0L) && (newT - oldT) < CASE_EXPIRE_DURATION)) { + if (oldT == 0L || (newT > 0L && (newT - oldT > 0L) && (newT - oldT) < CASE_EXPIRE_DURATION)) { Log.d("QQQ", "-- step -- 2 --") record?.takeIf { it.key != old?.key && it.timestamp != old?.timestamp }?.also { - Log.d("QQQ", "record: [$record] is displaying and consuming ~~~" ) + Log.d("QQQ", "record: [$record] is displaying and consuming ~~~") showBadCaseEntrance(it) } continue } while (oldT != 0L && newT != 0L && (newT - oldT) >= CASE_EXPIRE_DURATION) { - Log.d("QQQ", "record: [$record] has been discarded, because it has been timeout." ) + Log.d("QQQ", "record: [$record] has been discarded, because it has been timeout.") oldT = newT newT = try { it.receive()?.also { record = it }?.timestamp?.takeIf { it.isNotBlank() }?.let { - SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).parse(it)?.time ?: 0L + SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).parse(it)?.time + ?: 0L } ?: 0L } catch (t: Throwable) { t.printStackTrace() @@ -158,7 +165,7 @@ class MoGoHmiFragment : MvpFragment } } record?.takeIf { it.key != old?.key && it.timestamp != old?.timestamp }?.also { - Log.d("QQQ", "record: [$record] is displaying for rest ..." ) + Log.d("QQQ", "record: [$record] is displaying for rest ...") showBadCaseEntrance(it) } } else { @@ -170,7 +177,7 @@ class MoGoHmiFragment : MvpFragment it.visibility = View.VISIBLE } } - Log.d("QQQ", "record: [$old] hasn't been consumed~~~~" ) + Log.d("QQQ", "record: [$old] hasn't been consumed~~~~") } } finally { delay(1000) @@ -232,10 +239,10 @@ class MoGoHmiFragment : MvpFragment } } - ivCameraIcon?.setOnLongClickListener { + /*ivCameraIcon?.setOnLongClickListener { activity?.let { it1 -> CarcorderPreviewView.show(it1) } true - } + }*/ ivToolsIcon?.setOnClickListener { if (toolsViewFloat == null) { @@ -265,6 +272,11 @@ class MoGoHmiFragment : MvpFragment } } } + + /*// TODO 这里后面需要改成独立进程通讯后台获取YUV + view.postDelayed({ + activity?.let { CarcorderPreviewView.show(it) } + }, 1000)*/ } @OptIn(ExperimentalCoroutinesApi::class) @@ -352,21 +364,29 @@ class MoGoHmiFragment : MvpFragment onBadCaseHide = onHide } + /** + *注册工控机升级提示圆点View的回调 + * @param 提示圆点View + */ + override fun registerUpgradeTipsCallback(tipsView: () -> View) { + upgradeTipsView = tipsView + } + /** * 工控机重启返回结果 * @param code * @param msg */ override fun showDockerRebootResult(code: Int, msg: String) { - ThreadUtils.runOnUiThread{ - if(code>=-1){ + ThreadUtils.runOnUiThread { + if (code >= -1) { //重启成功 ToastUtils.showShort("重启成功") - }else{ + } else { //重启失败 msg?.let { ToastUtils.showShort(it) - } + } } } } @@ -378,7 +398,7 @@ class MoGoHmiFragment : MvpFragment if (autoPilotBadCaseView == null) { autoPilotBadCaseView = AutoPilotBadCaseView(it).also { itx -> val record = - autoPilotBadCaseEntrance?.getTag(R.id.autopilot_badcase_record) as? AutoPilotRecordResult + autoPilotBadCaseEntrance?.getTag(R.id.autopilot_badcase_record) as? AutoPilotRecordResult itx.tag = record itx.onDismiss { dismissBadCaseFloatView() @@ -389,12 +409,13 @@ class MoGoHmiFragment : MvpFragment val params = mutableMapOf() autoPilotBadCaseEntrance?.apply { params["carLicense"] = - MoGoAiCloudClientConfig.getInstance().sn + MoGoAiCloudClientConfig.getInstance().sn params["filename"] = record?.fileName ?: "" params["filesize"] = record?.total.toString() params["key"] = record?.key ?: "" params["reason"] = it.reason ?: "" - params["duration"] = record?.duration?.toInt()?.toString() ?: "" + params["duration"] = record?.duration?.toInt()?.toString() + ?: "" params["timestamp"] = record?.timestamp ?: "" } val response = post(params) @@ -409,9 +430,9 @@ class MoGoHmiFragment : MvpFragment dismissBadCaseFloatView() dismiss?.invoke() CallerAutoPilotManager.recordCause( - record?.key, - record?.fileName, - it.id, it.reason) + record?.key, + record?.fileName, + it.id, it.reason) ToastUtils.showShort("接管反馈成功~") record?.also { it.consumed = true @@ -437,39 +458,39 @@ class MoGoHmiFragment : MvpFragment } } autoPilotToolsFloat = WarningFloat.with(it) - .setTag("BadCaseCollectFloat") - .setLayout(autoPilotBadCaseView!!) - .setSidePattern(SidePattern.LEFT) - .setGravity(Gravity.LEFT, offsetY = 72) - .setImmersionStatusBar(true) - .setAnimator(object : DefaultAnimator() { - override fun enterAnim( - view: View, - params: WindowManager.LayoutParams, - windowManager: WindowManager, - sidePattern: SidePattern - ): Animator? = - super.enterAnim(view, params, windowManager, sidePattern) - ?.apply { - interpolator = OvershootInterpolator() - } + .setTag("BadCaseCollectFloat") + .setLayout(autoPilotBadCaseView!!) + .setSidePattern(SidePattern.LEFT) + .setGravity(Gravity.LEFT, offsetY = 72) + .setImmersionStatusBar(true) + .setAnimator(object : DefaultAnimator() { + override fun enterAnim( + view: View, + params: WindowManager.LayoutParams, + windowManager: WindowManager, + sidePattern: SidePattern + ): Animator? = + super.enterAnim(view, params, windowManager, sidePattern) + ?.apply { + interpolator = OvershootInterpolator() + } - override fun exitAnim( - view: View, - params: WindowManager.LayoutParams, - windowManager: WindowManager, - sidePattern: SidePattern - ): Animator? = - super.exitAnim(view, params, windowManager, sidePattern) - ?.setDuration(200) - }) - .addWarningStatusListener(object : IMoGoWarningStatusListener { - override fun onDismiss() { - autoPilotToolsFloat = null - autoPilotBadCaseView = null - } - }) - .show() + override fun exitAnim( + view: View, + params: WindowManager.LayoutParams, + windowManager: WindowManager, + sidePattern: SidePattern + ): Animator? = + super.exitAnim(view, params, windowManager, sidePattern) + ?.setDuration(200) + }) + .addWarningStatusListener(object : IMoGoWarningStatusListener { + override fun onDismiss() { + autoPilotToolsFloat = null + autoPilotBadCaseView = null + } + }) + .show() } else { autoPilotToolsFloat?.show() } @@ -669,7 +690,8 @@ class MoGoHmiFragment : MvpFragment if (floatWindow == null || TextUtils.isEmpty(showTag) || !floatWindow.isShow() || floatWindow.config.floatTag != tag) { val notificationView = V2XNotificationView(it) notificationView.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType.toString())) - val warningContent = alertContent ?: EventTypeEnum.getWarningContent(v2xType.toString()) + val warningContent = alertContent + ?: EventTypeEnum.getWarningContent(v2xType.toString()) if (warningContent.isEmpty()) { Logger.e(TAG, "Show warningContent is null or empty!") return@launchWhenResumed @@ -680,48 +702,48 @@ class MoGoHmiFragment : MvpFragment WarningFloat.dismiss(floatWindow.config.floatTag, true) } mWarningFloat = WarningFloat.with(it) - .setTag(tag) - .setLayout(notificationView) - .setSidePattern(SidePattern.RESULT_TOP) - .setCountDownTime(expireTime) - .setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110) - .setImmersionStatusBar(true) - .isEnqueue(true) - .addWarningStatusListener(listenerIMoGo) - .addWarningStatusListener(object : IMoGoWarningStatusListener { - override fun onShow() { - // 创建弹窗成功才进行TTS播报 - Logger.d( - "MoGoWarningFragment", - "mWarningFloat = $mWarningFloat---ttsContent = $ttsContent" - ) - if (mWarningFloat != null && !TextUtils.isEmpty(ttsContent) && playTts) { - Logger.d("MoGoWarningFragment", "---> ttsContent = $ttsContent") - AIAssist.getInstance(activity) - .speakTTSVoice(ttsContent) - } - } - }) - .setAnimator(object : DefaultAnimator() { - override fun enterAnim( - view: View, - params: WindowManager.LayoutParams, - windowManager: WindowManager, - sidePattern: SidePattern - ): Animator? = - super.enterAnim(view, params, windowManager, sidePattern)?.apply { - interpolator = OvershootInterpolator() + .setTag(tag) + .setLayout(notificationView) + .setSidePattern(SidePattern.RESULT_TOP) + .setCountDownTime(expireTime) + .setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110) + .setImmersionStatusBar(true) + .isEnqueue(true) + .addWarningStatusListener(listenerIMoGo) + .addWarningStatusListener(object : IMoGoWarningStatusListener { + override fun onShow() { + // 创建弹窗成功才进行TTS播报 + Logger.d( + "MoGoWarningFragment", + "mWarningFloat = $mWarningFloat---ttsContent = $ttsContent" + ) + if (mWarningFloat != null && !TextUtils.isEmpty(ttsContent) && playTts) { + Logger.d("MoGoWarningFragment", "---> ttsContent = $ttsContent") + AIAssist.getInstance(activity) + .speakTTSVoice(ttsContent) + } } + }) + .setAnimator(object : DefaultAnimator() { + override fun enterAnim( + view: View, + params: WindowManager.LayoutParams, + windowManager: WindowManager, + sidePattern: SidePattern + ): Animator? = + super.enterAnim(view, params, windowManager, sidePattern)?.apply { + interpolator = OvershootInterpolator() + } - override fun exitAnim( - view: View, - params: WindowManager.LayoutParams, - windowManager: WindowManager, - sidePattern: SidePattern - ): Animator? = - super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200) - }) - .show() + override fun exitAnim( + view: View, + params: WindowManager.LayoutParams, + windowManager: WindowManager, + sidePattern: SidePattern + ): Animator? = + super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200) + }) + .show() } else { val notification = floatWindow.config.layoutView as? V2XNotificationView if (alertContent?.isNotEmpty() == true) { @@ -1073,22 +1095,32 @@ class MoGoHmiFragment : MvpFragment * @param upgradeStatus 升级状态 */ override fun showAdUpgradeStatus( - upgradeMode: Int, - downloadStatus: Int, - currentProgress: Int, - totalProgress: Int, - downloadVersion: String, - upgradeStatus: Int + upgradeMode: Int, + downloadStatus: Int, + currentProgress: Int, + totalProgress: Int, + downloadVersion: String, + upgradeStatus: Int ) { - ThreadUtils.runOnUiThread{ + ThreadUtils.runOnUiThread { + val tipsView = upgradeTipsView?.invoke() //如果工控机处于“下载中”、“可升级(下载完成)”、“升级中”、“升级失败”状态时,工具箱入口显示红色角标 - if(AdUpgradeStateHelper.showUpgradeTips(downloadStatus, upgradeStatus)){ - viewUpgradeTips.visibility = View.VISIBLE - }else{ - viewUpgradeTips.visibility = View.GONE + if (AdUpgradeStateHelper.showUpgradeTips(downloadStatus, upgradeStatus)) { + if (HmiBuildConfig.isShowUpgradeTipsView){ + viewUpgradeTips?.visibility = View.VISIBLE + }else{ + tipsView?.let { + it.visibility = View.VISIBLE + } + } + } else { + viewUpgradeTips?.visibility = View.GONE + tipsView?.let { + it.visibility = View.GONE + } } //将状态同步到工具箱 - toolsView?.showAdUpgradeStatus(upgradeMode,downloadStatus, currentProgress, totalProgress, downloadVersion, upgradeStatus) + toolsView?.showAdUpgradeStatus(upgradeMode, downloadStatus, currentProgress, totalProgress, downloadVersion, upgradeStatus) } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/carcorder/CarcorderPreviewView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/carcorder/CarcorderPreviewView.kt index 52b9fb36a5..b67917db9c 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/carcorder/CarcorderPreviewView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/carcorder/CarcorderPreviewView.kt @@ -8,7 +8,9 @@ import android.os.Looper import android.util.Log import android.view.* import android.view.animation.OvershootInterpolator -import android.widget.Toast +import com.mogo.cloud.live.manager.ILiveStreamManager +import com.mogo.cloud.live.manager.LiveStreamManagerImpl +import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.function.hmi.notification.WarningFloat import com.mogo.eagle.core.function.hmi.notification.anim.DefaultAnimator @@ -39,6 +41,8 @@ class CarcorderPreviewView private constructor( private var isRequest = false private var isPreview = false + private var liveStreamManager: ILiveStreamManager? = null + init { LayoutInflater.from(context).inflate(R.layout.view_carcorder_preview, this, true) } @@ -70,7 +74,7 @@ class CarcorderPreviewView private constructor( .setTag("CarcorderPreviewView") .setLayout(carcorderPreviewVie) .setSidePattern(SidePattern.RIGHT) - .setGravity(Gravity.RIGHT, offsetY = 200) + .setGravity(Gravity.RIGHT, offsetY = 250) .setImmersionStatusBar(true) .setAnimator(object : DefaultAnimator() { override fun enterAnim( @@ -160,6 +164,10 @@ class CarcorderPreviewView private constructor( Log.d(TAG, "onDisConnectDev") showShortMsg("相机断开连接") } + + override fun onCancelDev(device: UsbDevice?) { + Log.d(TAG, "onCancelDev:" + device?.deviceName) + } } @@ -174,7 +182,14 @@ class CarcorderPreviewView private constructor( mCameraHelper?.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_MJPEG) mCameraHelper?.initUSBMonitor(context as Activity, carcorderPreview, listener) - mCameraHelper?.setOnPreviewFrameListener { nv21Yuv -> Log.d(TAG, "onPreviewResult: " + nv21Yuv.size) } + mCameraHelper?.setOnPreviewFrameListener { nv21Yuv -> + Log.d(TAG, "onPreviewResult: " + nv21Yuv.size) + //Log.i(TAG, "onVideoFrame byte length: " + bytesLength); + if (liveStreamManager != null) { + // 将摄像头采集的YUV数据推送到ZEGO + liveStreamManager!!.notifyYUVData(nv21Yuv, 640, 480, 2) + } + } } @@ -185,6 +200,19 @@ class CarcorderPreviewView private constructor( if (mCameraHelper != null) { mCameraHelper!!.registerUSB() } + // 初始化直播流管理 + // 初始化直播流管理 + liveStreamManager = LiveStreamManagerImpl.getInstance((context as Activity).application, + MoGoAiCloudClientConfig.getInstance().sn, true) + + // 设置状态回调 + liveStreamManager!!.setLiveStatusChangeCallback { status -> + if (status == 0) { + Logger.d(TAG, "直播中……") + } else { + Logger.d(TAG, "直播结束……") + } + } } override fun onDetachedFromWindow() { @@ -193,6 +221,13 @@ class CarcorderPreviewView private constructor( if (mCameraHelper != null) { mCameraHelper!!.unregisterUSB() } + + if (liveStreamManager != null) { + // 停止 + liveStreamManager!!.stopLiveStream() + // 释放资源 + liveStreamManager!!.release() + } } override fun onSurfaceCreated(view: CameraViewInterface?, surface: Surface?) { diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/AbsLogView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/AbsLogView.kt index 8af3873f7b..b83074ecb1 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/AbsLogView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/AbsLogView.kt @@ -68,7 +68,6 @@ abstract class AbsLogView : ILogView, TouchProxy.OnTouchEventListener { fun show(context: Context) { if (isShow) { - Log.d("EmArrow", "isShow : $isShow") return } performCreate(context) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/LogInfoView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/LogInfoView.kt index 6a8e8bf27c..30495732c2 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/LogInfoView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/logcatch/LogInfoView.kt @@ -244,7 +244,6 @@ class LogInfoView : AbsLogView() { mLogHint!!.visibility = View.VISIBLE mLogRvWrap!!.visibility = View.GONE val layoutParams = systemLayoutParams ?: return - Log.d("EmArrow", "minimize , layoutParams is not null") layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt index 7a428474e1..7cce805b60 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt @@ -11,6 +11,7 @@ import com.mogo.commons.AbsMogoApplication import com.mogo.commons.debug.DebugConfig import com.mogo.eagle.core.data.app.AppConfigInfo import com.mogo.eagle.core.data.autopilot.* +import com.mogo.eagle.core.data.chain.ChainConstant import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.data.constants.MoGoConfig import com.mogo.eagle.core.data.map.MogoLocation @@ -35,11 +36,20 @@ import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.function.hmi.ui.logcatch.ILogViewListener import com.mogo.eagle.core.function.hmi.ui.logcatch.LogInfoView +import com.mogo.eagle.core.utilcode.kotlin.onClick import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel import com.mogo.eagle.core.utilcode.mogo.logger.Logger import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr import com.mogo.eagle.core.utilcode.util.* import com.mogo.map.MogoMap +import com.mogo.map.uicontroller.VisualAngleMode +import com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_300 +import com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_CROSS +import com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_TOP +import com.mogo.map.uicontroller.VisualAngleMode.MODE_CLOSE_SIGHT +import com.mogo.map.uicontroller.VisualAngleMode.MODE_LONG_SIGHT +import com.mogo.map.uicontroller.VisualAngleMode.MODE_MEDIUM_SIGHT +import com.mogo.module.common.MogoApisHandler import kotlinx.android.synthetic.main.view_debug_setting.view.* import java.util.* @@ -50,13 +60,13 @@ import java.util.* * 展示 本机、网络、工控机、OBU等状态信息,支持设置IP,等参数进行调试 */ class DebugSettingView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoObuStatusListener, - IMoGoAutopilotStatusListener, IMoGoAutopilotCarStateListener, - IMoGoMapLocationListener, IMoGoAutopilotIdentifyListener, - IMoGoAutopilotPlanningListener { + IMoGoAutopilotStatusListener, IMoGoAutopilotCarStateListener, + IMoGoMapLocationListener, IMoGoAutopilotIdentifyListener, + IMoGoAutopilotPlanningListener { private val TAG = "DebugSettingView" @@ -75,6 +85,12 @@ class DebugSettingView @JvmOverloads constructor( // 全局路径规划点个数 private var mRouteInfoSize = 0 + private val mapUiController by lazy { + MogoApisHandler.getInstance().apis?.mapServiceApi?.mapUIController + } + + private var lastVisualAngleMode: VisualAngleMode? = null + init { LayoutInflater.from(context).inflate(R.layout.view_debug_setting, this, true) initView() @@ -204,21 +220,40 @@ class DebugSettingView @JvmOverloads constructor( } } - changesight_top_btn.setOnClickListener { - CallerHDMapManager.setMapDAngle(0); + lastVisualAngleMode = mapUiController?.currentMapVisualAngle + + changesight_top_btn.onClick { + mapUiController?.changeMapVisualAngle(MAP_STYLE_VR_ANGLE_TOP, null) } + changesight_back_btn?.onClick { + mapUiController?.changeMapVisualAngle(MAP_STYLE_VR_ANGLE_300, null) + } + + changesight_cross_btn?.onClick { + mapUiController?.changeMapVisualAngle(MAP_STYLE_VR_ANGLE_CROSS, null) + } + + changesight_far_btn?.onClick { + mapUiController?.changeMapVisualAngle(MODE_LONG_SIGHT, null) + } + + reset_changesight?.onClick { + lastVisualAngleMode?.let { + mapUiController?.changeMapVisualAngle(it, null) + } + } tvObuInfo.text = CallerObuListenerManager.getObuStatusInfoJsonString() tvAutopilotInfo.text = - CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfoJsonString() + CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfoJsonString() // 绘制应用基本信息 drawAppInfo() // 初始化OBU IP信息 val ipAddress = - SharedPrefsMgr.getInstance(context).getString(MoGoConfig.OBU_IP, "192.168.1.199") + SharedPrefsMgr.getInstance(context).getString(MoGoConfig.OBU_IP, "192.168.1.199") etObuIP.setText(ipAddress) etObuIP.text?.let { etObuIP.setSelection(it.length) } @@ -255,18 +290,18 @@ class DebugSettingView @JvmOverloads constructor( // 初始化 GSP数据源 数据 rgGpsProvider.check( - when (FunctionBuildConfig.gpsProvider) { - 0 -> { - R.id.rbGpsProviderAndroid - } - 1 -> { - R.id.rbGpsProviderRTK - } - 2 -> { - R.id.rbGpsProviderOBU - } - else -> R.id.rbGpsProviderAndroid + when (FunctionBuildConfig.gpsProvider) { + 0 -> { + R.id.rbGpsProviderAndroid } + 1 -> { + R.id.rbGpsProviderRTK + } + 2 -> { + R.id.rbGpsProviderOBU + } + else -> R.id.rbGpsProviderAndroid + } ) rgGpsProvider.setOnCheckedChangeListener { group, checkedId -> when (checkedId) { @@ -350,31 +385,29 @@ class DebugSettingView @JvmOverloads constructor( } tbLogCatch.isChecked = - SharedPrefsMgr.getInstance(context).getBoolean(MoGoConfig.CATCH_LOG, false) + SharedPrefsMgr.getInstance(context).getBoolean(MoGoConfig.CATCH_LOG, false) tbLogCatch.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { CallerDevaToolsManager.startCatchLog() - SharedPrefsMgr.getInstance(context).putBoolean(MoGoConfig.CATCH_LOG, true) } else { CallerDevaToolsManager.stopCatchLog() - SharedPrefsMgr.getInstance(context).putBoolean(MoGoConfig.CATCH_LOG, false) } } CallerDevaToolsListenerManager.registerDevaToolsLogCatchListener(TAG, - object : IMoGoDevaToolsListener { - override fun onLogCatchClose() { - super.onLogCatchClose() - tbLogCatch.isChecked = false - } + object : IMoGoDevaToolsListener { + override fun onLogCatchClose() { + super.onLogCatchClose() + tbLogCatch.isChecked = false + } - override fun onLogCatch(lineLog: String) { - logInfoView?.let { - if (logViewAttach) { - it.onLogCatch(lineLog) - } + override fun onLogCatch(lineLog: String) { + logInfoView?.let { + if (logViewAttach) { + it.onLogCatch(lineLog) } } - }) + } + }) tbLogDebugView.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { logInfoView = LogInfoView() @@ -394,6 +427,15 @@ class DebugSettingView @JvmOverloads constructor( logViewDestroy() } } + tbLogTraceView.setOnCheckedChangeListener { _, isChecked -> + val traceInfoMap = CallerDevaToolsManager.getTraceInfo() + val chainLogParam = traceInfoMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_DATA] + chainLogParam?.let { + it.record = isChecked + traceInfoMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_DATA] = chainLogParam + CallerDevaToolsManager.refreshTraceInfo(traceInfoMap) + } + } } private fun logViewDestroy() { @@ -428,15 +470,15 @@ class DebugSettingView @JvmOverloads constructor( tvAutopilotInfo.text = GsonUtils.toJson(mAutoPilotStatusInfo) tvCarInfo.text = - "GPS时间:${mAutoPilotCarStateInfo?.values?.satelliteTime}\n" + - "自车经纬度:\n${mAutoPilotCarStateInfo?.values?.lon}\n${mAutoPilotCarStateInfo?.values?.lat}\n" + "GPS时间:${mAutoPilotCarStateInfo?.values?.satelliteTime}\n" + + "自车经纬度:\n${mAutoPilotCarStateInfo?.values?.lon}\n${mAutoPilotCarStateInfo?.values?.lat}\n" tvIdentifyInfo.text = - "感知数据个数:${mIdentifyDataSize}" + "感知数据个数:${mIdentifyDataSize}" tvTrajectoryInfoSize.text = - "引导线点个数:${mTrajectoryInfoSize}" + "引导线点个数:${mTrajectoryInfoSize}" tvRouteInfoSize.text = - "全局路径规划点个数:${mRouteInfoSize}" + "全局路径规划点个数:${mRouteInfoSize}" // 用完之后重制为0,防止节点回掉突然没数据,导致页面显示还是之前的数据情况 mIdentifyDataSize = 0 diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt index 8f7d97bdf1..587bac0de2 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/tools/AutoPilotAndCheckView.kt @@ -8,11 +8,13 @@ import android.view.View import android.widget.FrameLayout import com.mogo.eagle.core.data.autopilot.AutopilotGuardianStatusInfo import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo +import com.mogo.eagle.core.data.config.FunctionBuildConfig import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.hmi.R import com.mogo.eagle.core.function.hmi.ui.utils.KeyBoardUtil +import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils import com.mogo.eagle.core.utilcode.util.ToastUtils import kotlinx.android.synthetic.main.view_auto_pilot_check.view.* import kotlinx.android.synthetic.main.view_check_system.view.* @@ -102,6 +104,7 @@ class AutoPilotAndCheckView @JvmOverloads constructor( return@setOnTouchListener false } } + updateSpeedSettingViews() // // 比如需要设置默认速度 // val speed = "30" // etInputSpeed.setText(speed) @@ -112,6 +115,22 @@ class AutoPilotAndCheckView @JvmOverloads constructor( this.clickListener = clickListener } + /** + * Bus不可设置自动驾驶速度,而Taxi可以 + */ + private fun updateSpeedSettingViews() { + when { + AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) -> { + tvSpeedTitle.visibility = View.GONE + llSpeedPosition.visibility = View.GONE + } + else -> { + tvSpeedTitle.visibility = View.VISIBLE + llSpeedPosition.visibility = View.VISIBLE + } + } + } + /** * 展示工控机下载、升级状态信息 * @param upgradeMode 升级模式(提示升级、静默升级) diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SystemVersionView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SystemVersionView.kt index cab7baf628..52faf45bb8 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SystemVersionView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/SystemVersionView.kt @@ -71,6 +71,12 @@ class SystemVersionView @JvmOverloads constructor( if(AdUpgradeStateHelper.isDownloading(downloadStatus)){ //点击Toast提示:下载剩余时间 ToastUtils.showShort("预计"+AdUpgradeStateHelper.getRemainingTime(totalProgress,previousProgress,currentProgress)+"下载完成") + }else if(AdUpgradeStateHelper.getUpgradeStatus()){ + //工控机状态为“升级中” + ToastUtils.showShort("新版本升级中,预计5分钟升级完成") + }else if(AdUpgradeStateHelper.isUpgradeFailed(upgradeStatus)){ + //如果升级失败,则Toast提示:升级失败,请联系运维人员 + ToastUtils.showShort("升级失败,请联系运维人员") }else if(AdUpgradeStateHelper.isHintUpgradeMode(upgradeMode) && AdUpgradeStateHelper.isDownloadFinish(downloadStatus,upgradeStatus)){ //如果升级模式为“提示升级”,并且下载状态为已经下载完成,点击弹出升级确认弹窗 if(adUpgradeDialog == null){ @@ -86,6 +92,10 @@ class SystemVersionView @JvmOverloads constructor( //设置当前状态为“升级中” AdUpgradeStateHelper.setUpgradeStatus(true) CallerAutoPilotManager.setIPCUpgradeAffirm() + //将角标设为升级中 + ivAdStatus?.setImageResource(R.drawable.icon_upgrading) + adCircularProgressView?.visibility = View.GONE + ivAdVersion?.setBackgroundResource(R.drawable.version_latest_background) } } @@ -99,12 +109,6 @@ class SystemVersionView @JvmOverloads constructor( }) } adUpgradeDialog?.showUpgradeDialog() - }else if(AdUpgradeStateHelper.getUpgradeStatus()){ - //工控机状态为“升级中” - ToastUtils.showShort("新版本升级中,预计5分钟升级完成") - }else if(AdUpgradeStateHelper.isUpgradeFailed(upgradeStatus)){ - //如果升级失败,则Toast提示:升级失败,请联系运维人员 - ToastUtils.showShort("升级失败,请联系运维人员") } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml index ddc8434d76..fbbc1af7f3 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml @@ -112,8 +112,8 @@ + android:layout_height="@dimen/dp_432"> + + diff --git a/core/function-impl/mogo-core-function-main/build.gradle b/core/function-impl/mogo-core-function-main/build.gradle index dfc2b92c2b..f24479d0cd 100644 --- a/core/function-impl/mogo-core-function-main/build.gradle +++ b/core/function-impl/mogo-core-function-main/build.gradle @@ -68,7 +68,6 @@ dependencies { api rootProject.ext.dependencies.mogocommons api rootProject.ext.dependencies.modulecommon api rootProject.ext.dependencies.mogoservice - api rootProject.ext.dependencies.moduleshare api rootProject.ext.dependencies.moduleextensions api rootProject.ext.dependencies.callchat api rootProject.ext.dependencies.callchatprovider diff --git a/core/function-impl/mogo-core-function-main/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java b/core/function-impl/mogo-core-function-main/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java index e00bbd4713..05e39daa4c 100644 --- a/core/function-impl/mogo-core-function-main/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java +++ b/core/function-impl/mogo-core-function-main/src/main/java/com/mogo/eagle/core/function/main/MainMoGoApplication.java @@ -61,7 +61,6 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { return; } start = System.currentTimeMillis(); - ChainTraceStarter.start("com.mogo.launcher.f", DeviceUtils.getMacAddress()); // Crash 日志收集 initCrashConfig(); initLogConfig(); @@ -153,7 +152,7 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { // 设置是否输出日志 clientConfig.setShowDebugLog(true); // 设置是否是直播推流的主播 - clientConfig.setAnchor(false); + clientConfig.setAnchor(true); // 设置从蘑菇AI开放平台获取的APPKey switch (DebugConfig.getCarMachineType()) { // 比亚迪 @@ -178,8 +177,8 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { // 设置AI云平台分配给三方应用的签名密钥,需要从AI云平台申请 // 设置车机设备的唯一标识(这些表识必须是通过后台录入的设备) clientConfig.setThirdPartyDeviceId(Utils.getDevicesId()); - // 设置循环检测间隔时间 - clientConfig.setLoopCheckDelay(60 * 60 * 24 * 1000); + // 设置循环检测间隔时间(每隔2小时loop一次httpDnsConfig) + clientConfig.setLoopCheckDelay(60 * 60 * 2 * 1000); //连接ami connectAmiIp(); @@ -249,7 +248,7 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { */ private void connectAmiIp() { String ipAddress = SharedPrefsMgr.getInstance(AbsMogoApplication.getApp().getBaseContext()).getString(MoGoConfig.OBU_IP, "192.168.1.199"); - Logger.d("OnAdasListenerAdapter", "application --ipAddress = " + ipAddress); + //Logger.d("OnAdasListenerAdapter", "application --ipAddress = " + ipAddress); AmiClientManager.getInstance().setObuIp(ipAddress); } @@ -302,7 +301,8 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { private void initModules() { Logger.d(TAG, "initModules"); - + //mogo deva tools + MogoModulePaths.addModuleFunctionServer(new MogoModule(MogoServicePaths.PATH_DEVA_TOOLS, "IMoGoDevaToolsProvider")); // 初始化 bugly 升级 MogoModulePaths.addBaseModule(new MogoModule(UpgradeReportConstants.PATH, UpgradeReportConstants.NAME)); // 初始化 apm 日志采集 @@ -312,9 +312,8 @@ public abstract class MainMoGoApplication extends AbsMogoApplication { MogoModulePaths.addBaseModule(new MogoModule(MapApiPath.PATH, "CustomMapApiBuilder")); MogoModulePaths.addBaseModule(new MogoModule(ServiceConst.PATH_REFRESH_STRATEGY, ServiceConst.PATH_REFRESH_STRATEGY)); - // MogoModulePaths.addBaseModule(new MogoModule(V2XConst.PATH_V2X_UI, V2XConst.MODULE_NAME)); - //mogo deva tools - MogoModulePaths.addModuleFunctionServer(new MogoModule(MogoServicePaths.PATH_DEVA_TOOLS, "IMoGoDevaToolsProvider")); + // MogoModulePaths.addBaseModule(new MogoModule(V2XConst.PATH_V2X_UI, V2XConst.MODULE_NAME)); + // 域控制器模块(新) MogoModulePaths.addModuleFunctionServer(new MogoModule(MogoServicePaths.PATH_AUTO_PILOT, "IMoGoAutoPilotProvider")); // OBU 模块 diff --git a/core/function-impl/mogo-core-function-map/build.gradle b/core/function-impl/mogo-core-function-map/build.gradle index 7600662cfe..a3a65d41fa 100644 --- a/core/function-impl/mogo-core-function-map/build.gradle +++ b/core/function-impl/mogo-core-function-map/build.gradle @@ -50,7 +50,7 @@ dependencies { implementation rootProject.ext.dependencies.rxandroid kapt rootProject.ext.dependencies.aroutercompiler - implementation rootProject.ext.dependencies.adasHigh + //implementation rootProject.ext.dependencies.adasHigh implementation rootProject.ext.dependencies.mogocustommapoperational if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { implementation rootProject.ext.dependencies.mogoserviceapi @@ -74,6 +74,8 @@ dependencies { implementation project(":libraries:mogo-map") implementation project(":libraries:mogo-map-api") + + implementation project(':libraries:mogo-adas') } } diff --git a/core/function-impl/mogo-core-function-v2x/build.gradle b/core/function-impl/mogo-core-function-v2x/build.gradle index e8df059182..5ec1a4c322 100644 --- a/core/function-impl/mogo-core-function-v2x/build.gradle +++ b/core/function-impl/mogo-core-function-v2x/build.gradle @@ -53,7 +53,7 @@ dependencies { implementation rootProject.ext.dependencies.flexbox kapt rootProject.ext.dependencies.aroutercompiler - implementation rootProject.ext.dependencies.adasHigh +// implementation rootProject.ext.dependencies.adasHigh implementation rootProject.ext.dependencies.mogo_v2x implementation rootProject.ext.dependencies.mogoaicloudtrafficlive if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { @@ -75,6 +75,8 @@ dependencies { implementation project(':modules:mogo-module-carchattingprovider') implementation project(':core:mogo-core-res') + implementation project(':libraries:mogo-adas') + } } diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/widgets/SurroundingEventView.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/widgets/SurroundingEventView.java deleted file mode 100644 index afcfdf13b2..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/widgets/SurroundingEventView.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.widgets; - -import com.mogo.commons.mvp.IView; -import com.mogo.module.common.entity.MarkerExploreWay; - -import java.util.List; - -/** - * @author lixiaopeng - * @description - * @since 2020/7/29 - */ -public interface SurroundingEventView extends IView { - - void showSurroudingData(List exploreWayList); -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/widgets/SurroundingMarginDecoration.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/widgets/SurroundingMarginDecoration.java deleted file mode 100644 index 858dcf5e51..0000000000 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/widgets/SurroundingMarginDecoration.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.mogo.eagle.core.function.v2x.events.widgets; - -import android.graphics.Rect; -import android.view.View; - -import androidx.recyclerview.widget.RecyclerView; - -/** - * @author lixiaopeng - * @description - * @since 2020/8/11 - */ -public class SurroundingMarginDecoration extends RecyclerView.ItemDecoration { - private int margin ; - private int marginLeft ; - - public SurroundingMarginDecoration(int space, int left) { - margin = space; - marginLeft = left; - } - - @Override - public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { - outRect.bottom = margin; - - //由于每行都只有2个,所以第一个都是2的倍数 - if (parent.getChildLayoutPosition(view) % 2 == 0) { - outRect.left = marginLeft; - outRect.right = margin / 2; - } else { - outRect.left = margin / 2; - outRect.right = marginLeft; - } - } - -} diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/trafficlight/TrafficLightConst.kt b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/trafficlight/TrafficLightConst.kt index bb1dc56689..b8faf87b28 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/trafficlight/TrafficLightConst.kt +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/trafficlight/TrafficLightConst.kt @@ -1,25 +1,10 @@ package com.mogo.eagle.core.function.v2x.trafficlight -import com.mogo.commons.debug.DebugConfig - class TrafficLightConst { companion object { const val MODULE_NAME = "MODULE_V2X_TRAFFIC_LIGHT" - private const val HOST_DEV = "http://dzt-test.zhidaozhixing.com" - private const val HOST_TEST = "http://dzt-test.zhidaozhixing.com" - private const val HOST_DEMO = "http://dzt-show.zhidaozhixing.com" - private const val HOST_PRODUCT = "http://dzt.zhidaozhixing.com" - - fun getNetHost(): String { - return when (DebugConfig.getNetMode()) { - DebugConfig.NET_MODE_DEV -> HOST_DEV - DebugConfig.NET_MODE_QA -> HOST_TEST - DebugConfig.NET_MODE_DEMO -> HOST_DEMO - else -> HOST_PRODUCT - } - } } } diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AdUpgradeStateHelper.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AdUpgradeStateHelper.kt index 0edea8699b..61c79e7ec3 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AdUpgradeStateHelper.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AdUpgradeStateHelper.kt @@ -1,8 +1,5 @@ package com.mogo.eagle.core.data.autopilot -import android.util.Log -import java.util.logging.Logger - /** * @author XuXinChao * @description 工控机升级状态实体类 @@ -32,6 +29,7 @@ class AdUpgradeStateHelper { * @param downloadStatus 下载状态 * @param upgradeStatus 升级状态 */ + @JvmStatic fun showUpgradeTips(downloadStatus: Int,upgradeStatus: Int) : Boolean{ return isDownloading(downloadStatus) || isDownloadFinish(downloadStatus,upgradeStatus) || getUpgradeStatus() || isUpgradeFailed(upgradeStatus) } @@ -41,6 +39,7 @@ class AdUpgradeStateHelper { * @param downloadStatus 下载状态 * @param upgradeStatus 升级状态 */ + @JvmStatic fun showCannotReboot(downloadStatus: Int,upgradeStatus: Int): Boolean{ return isDownloading(downloadStatus)|| isDownloadFinish(downloadStatus,upgradeStatus) || getUpgradeStatus() } @@ -49,6 +48,7 @@ class AdUpgradeStateHelper { * 工控机是否处于“下载中”状态 * @param downloadStatus 下载状态 */ + @JvmStatic fun isDownloading(downloadStatus: Int) : Boolean{ return downloadStatus == DOWNLOAD_START } @@ -58,6 +58,7 @@ class AdUpgradeStateHelper { * @param downloadStatus 下载状态 * @param upgradeStatus 升级状态 */ + @JvmStatic fun isDownloadFinish(downloadStatus: Int,upgradeStatus: Int) : Boolean{ return downloadStatus == DOWNLOAD_FINISH && upgradeStatus == USER_AFFIRM } @@ -66,6 +67,7 @@ class AdUpgradeStateHelper { * 工控机是否处于“下载失败”状态 * @param downloadStatus 下载状态 */ + @JvmStatic fun isDownloadFailed(downloadStatus: Int) : Boolean{ return downloadStatus == DOWNLOAD_FAILED } @@ -74,6 +76,7 @@ class AdUpgradeStateHelper { * 工控机是否处于“升级成功”状态 * @param upgradeStatus 升级状态 */ + @JvmStatic fun isUpgradeSuccess(upgradeStatus: Int) : Boolean{ return upgradeStatus == UPGRADE_SUCCEED } @@ -82,6 +85,7 @@ class AdUpgradeStateHelper { * 工控机是否处于“升级失败”状态 * @param upgradeStatus 升级状态 */ + @JvmStatic fun isUpgradeFailed(upgradeStatus: Int) : Boolean{ return upgradeStatus == UPGRADE_FAILED } @@ -91,6 +95,7 @@ class AdUpgradeStateHelper { * @param currentProgress 当前已下载包体大小 * @param totalProgress 包体总大小 */ + @JvmStatic fun downloadProgress(currentProgress: Int,totalProgress: Int) : Int{ return (currentProgress.toDouble()/totalProgress.toDouble()*100).toInt() } @@ -99,6 +104,7 @@ class AdUpgradeStateHelper { * 工控机升级模式是否是静默升级 * @param upgradeMode 升级模式 */ + @JvmStatic fun isQuietUpgradeMode(upgradeMode: Int) : Boolean{ return upgradeMode == UPGRADE_QUIET } @@ -107,6 +113,7 @@ class AdUpgradeStateHelper { * 工控机升级模式是否是提示升级 * @param upgradeMode 升级模式 */ + @JvmStatic fun isHintUpgradeMode(upgradeMode: Int) : Boolean{ return upgradeMode == UPGRADE_HINT } @@ -114,6 +121,7 @@ class AdUpgradeStateHelper { /** * 获取是否处于“升级中”状态 */ + @JvmStatic fun getUpgradeStatus() : Boolean{ return UPGRADING } @@ -122,6 +130,7 @@ class AdUpgradeStateHelper { * 设置是否处于“升级中”状态 * @param upgrading 是否是升级中 */ + @JvmStatic fun setUpgradeStatus(upgrading: Boolean){ UPGRADING = upgrading } @@ -129,6 +138,7 @@ class AdUpgradeStateHelper { /** * 获取工控机包体下载剩余时间 */ + @JvmStatic fun getRemainingTime(totalProgress: Int,previousProgress: Int,currentProgress: Int) : String{ //剩余包体大小 val remainingSize = totalProgress - currentProgress @@ -139,14 +149,14 @@ class AdUpgradeStateHelper { //转换为分秒格式返回 val minute = time/60 val second = time%60 - if(minute>0 && second>0){ - return minute.toString()+"分钟"+second+"秒" + return if(minute>0 && second>0){ + minute.toString()+"分钟"+second+"秒" }else if(minute>0){ - return minute.toString()+"分钟" + minute.toString()+"分钟" }else if(second>0){ - return second.toString()+"秒" + second.toString()+"秒" }else{ - return "" + "" } } diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/chain/ChainConstant.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/chain/ChainConstant.kt new file mode 100644 index 0000000000..77321383e3 --- /dev/null +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/chain/ChainConstant.kt @@ -0,0 +1,31 @@ +package com.mogo.eagle.core.data.chain + +class ChainConstant { + + companion object{ + + const val CHAIN_LINK_CLOUD_SHOW = 0 + const val CHAIN_LINK_ADAS = 1 + + const val CHAIN_LINK_LOG_CONNECT_STATUS = 0 + const val CHAIN_LINK_LOG_WEB_SOCKET_DATA = 1 + + const val CHAIN_LINK_LOG_ADAS_INIT = "-adasInitStatus" + const val CHAIN_LINK_LOG_ADAS_MSG = "-adasWsMsg" + + const val CHAIN_ALIAS_CODE_UDP_INIT = "PAD_ADAS_UDP_INIT" + const val CHAIN_ALIAS_CODE_UDP_CONNECT_ADDRESS = "PAD_ADAS_UDP_CONNECT_ADDRESS" + const val CHAIN_ALIAS_CODE_WEB_SOCKET_OPEN = "PAD_ADAS_WEB_SOCKET_OPEN" + const val CHAIN_ALIAS_CODE_WEB_SOCKET_MESSAGE_JSON = "PAD_ADAS_WEB_SOCKET_MESSAGE_JSON" + const val CHAIN_ALIAS_CODE_WEB_SOCKET_MESSAGE_BYTE = "PAD_ADAS_WEB_SOCKET_MESSAGE_BYTE" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_RECT_DATA = "PAD_ADAS_MESSAGE_AUTOPILOT_RECT_DATA" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_STATE = "PAD_ADAS_MESSAGE_AUTOPILOT_CAR_STATE" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_STATUS = "PAD_ADAS_MESSAGE_AUTOPILOT_STATUS" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ARRIVE = "PAD_ADAS_MESSAGE_AUTOPILOT_ARRIVE" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ROUTE = "PAD_ADAS_MESSAGE_AUTOPILOT_ROUTE" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_TRAJECTORY = "PAD_ADAS_MESSAGE_AUTOPILOT_TRAJECTORY" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_GUARDIAN = "PAD_ADAS_MESSAGE_AUTOPILOT_GUARDIAN" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_RECORD = "PAD_ADAS_MESSAGE_AUTOPILOT_RECORD" + const val CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_WARN = "PAD_ADAS_MESSAGE_AUTOPILOT_WARN" + } +} \ No newline at end of file diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/chain/ChainLogParam.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/chain/ChainLogParam.kt new file mode 100644 index 0000000000..a840e24497 --- /dev/null +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/chain/ChainLogParam.kt @@ -0,0 +1,13 @@ +package com.mogo.eagle.core.data.chain + +class ChainLogParam { + + var record: Boolean = false + var des: String? = null + + constructor(record: Boolean, des: String) { + this.record = record + this.des = des + } + +} \ No newline at end of file diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt index 966fd42ec1..9d0ed0520d 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/HmiBuildConfig.kt @@ -36,6 +36,12 @@ object HmiBuildConfig { @JvmField var isShowBadCaseView = true + /** + * 是否展示工控机升级提示UI + */ + @JvmField + var isShowUpgradeTipsView = true + /** * 是否展示转向灯ui */ diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/constants/MoGoConfig.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/constants/MoGoConfig.kt index 582dd3262f..ab33038541 100644 --- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/constants/MoGoConfig.kt +++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/constants/MoGoConfig.kt @@ -14,6 +14,8 @@ object MoGoConfig { // CMD全量日志抓取 const val CATCH_LOG = "CATCH_LOG" + // CMD全量日志抓取当时时间 + const val CATCH_LOG_TIME = "CATCH_LOG_TIME" // 是否是演示(美化)模式,会存在SP中,方便做现场恢复 const val IS_DEMO_MODE = "IS_DEMO_MODE" diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt index f2567433fc..18d9f6b400 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt @@ -1,5 +1,6 @@ package com.mogo.eagle.core.function.api.devatools +import com.mogo.eagle.core.data.chain.ChainLogParam import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider /** @@ -9,5 +10,12 @@ interface IDevaToolsProvider : IMoGoFunctionServerProvider { fun startLogCatch() + fun startLogCatch(duration: Int) + fun stopLogCatch() + + fun getTraceInfo():HashMap + + fun refreshTraceInfo(map: HashMap) + } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt index a24202a0dd..3f0f3304a4 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt @@ -193,6 +193,12 @@ interface IMoGoWaringProvider { */ fun registerBadCaseCallback(onShow:() -> View, onHide: (() -> Unit)?) + /** + *注册工控机升级提示圆点View的回调 + * @param 提示圆点View + */ + fun registerUpgradeTipsCallback(tipsView:() -> View) + /** * 工控机重启返回结果 * @param code diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt index deadeb95e3..2765d0d12c 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt @@ -1,8 +1,10 @@ package com.mogo.eagle.core.function.call.devatools import com.alibaba.android.arouter.launcher.ARouter +import com.mogo.eagle.core.data.chain.ChainLogParam import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_DEVA_TOOLS import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider +import com.mogo.eagle.core.utilcode.util.SnackbarUtils object CallerDevaToolsManager { @@ -17,10 +19,32 @@ object CallerDevaToolsManager { devaToolsProviderApi.startLogCatch() } + /** + * 开始抓取全量日志 + * duration 分钟数 + */ + fun startCatchLog(duration: Int){ + devaToolsProviderApi.startLogCatch(duration) + } + /** * 停止抓取全量日志 */ fun stopCatchLog() { devaToolsProviderApi.stopLogCatch() } + + /** + * 更新链路节点信息,是否写入 + */ + fun refreshTraceInfo(map: HashMap) { + devaToolsProviderApi.refreshTraceInfo(map) + } + + /** + * 获取链路节点信息 + */ + fun getTraceInfo():HashMap{ + return devaToolsProviderApi.getTraceInfo() + } } \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt index f7a25198d8..a7f5173590 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt @@ -273,6 +273,14 @@ object CallerHmiManager : CallerBase() { waringProviderApi?.registerBadCaseCallback(onShow, onHide) } + /** + *注册工控机升级提示圆点View的回调 + * @param 提示圆点View + */ + fun registerUpgradeTipsCallback(tipsView:() -> View){ + waringProviderApi?.registerUpgradeTipsCallback(tipsView) + } + /** * 工控机重启返回结果 * @param code diff --git a/core/mogo-core-utils/src/main/AndroidManifest.xml b/core/mogo-core-utils/src/main/AndroidManifest.xml index c953b8a6ce..11c86de1fd 100644 --- a/core/mogo-core-utils/src/main/AndroidManifest.xml +++ b/core/mogo-core-utils/src/main/AndroidManifest.xml @@ -1,6 +1,8 @@ + + { synchronized ( sSyncObject ) { - if ( context == null ) { return; } - - if ( sToast != null ) { - sToast.cancel(); + if ( sToast != null) { + View view = sToast.getView(); + if (view != null && ViewCompat.isAttachedToWindow(view)) { + sToast.cancel(); + } } - if ( sGenerator == null ) { sToast = Toast.makeText( context, msg, duration ); } else { sToast = new Toast( context ); final View view = sGenerator.make( context, msg, tipDrawable ); + if ( view != null ) { sToast.setView( view ); sToast.setGravity( sGenerator.gravity(), sGenerator.xOffset(), sGenerator.yOffset() ); @@ -187,6 +195,15 @@ public final class TipToast { sToast = Toast.makeText( context, msg, duration ); } } + View view = sToast.getView(); + if (view != null) { + LifecycleOwner lifecycleOwner = ExtensionsKt.getLifecycleOwner(view); + lifecycleOwner.getLifecycle().addObserver((LifecycleEventObserver) (source, event) -> { + if (event == Lifecycle.Event.ON_DESTROY) { + sToast = null; + } + }); + } if ( sToast != null ) { sToast.show(); } diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DeviceIdUtils.java b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DeviceIdUtils.java index 2ba89bf273..8bfe7fe99e 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DeviceIdUtils.java +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/DeviceIdUtils.java @@ -3,38 +3,40 @@ package com.mogo.eagle.core.utilcode.util; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; +import android.media.MediaDrm; import android.os.Build; import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.TextUtils; -import com.elegant.utils.storage.SharedPrefsMgr; - import androidx.core.content.ContextCompat; +import com.elegant.utils.storage.SharedPrefsMgr; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.UUID; public final class DeviceIdUtils { public static final String KEY_DEVICE_ID = "deviceId"; - private DeviceIdUtils() {} + private DeviceIdUtils() { + } - private static void saveDeviceId( Context context, String deviceId){ + private static void saveDeviceId(Context context, String deviceId) { SharedPrefsMgr.getInstance(context).putString(KEY_DEVICE_ID, deviceId); } - public static String getDeviceId( Context context) { - if(context == null){ + public static String getDeviceId(Context context) { + if (context == null) { throw new NullPointerException("context must not be null."); } final Context appContext = context.getApplicationContext(); - String deviceId = SharedPrefsMgr.getInstance( context ).getString( KEY_DEVICE_ID ); + String deviceId = SharedPrefsMgr.getInstance(context).getString(KEY_DEVICE_ID); - if ( TextUtils.isEmpty( deviceId )) { + if (TextUtils.isEmpty(deviceId)) { deviceId = getDeviceIdInternal(appContext); if (TextUtils.isEmpty(deviceId)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -54,35 +56,37 @@ public final class DeviceIdUtils { } } } - saveDeviceId(appContext,deviceId); + saveDeviceId(appContext, deviceId); } return deviceId; } - private static String getDeviceIdInternal( Context context) { + private static String getDeviceIdInternal(Context context) { String id = ""; - if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) { - if ( ContextCompat.checkSelfPermission( context, Manifest.permission.READ_PHONE_STATE ) != PackageManager.PERMISSION_GRANTED ) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { return id; } } - TelephonyManager telephonymanager = ( TelephonyManager ) context.getSystemService( Context.TELEPHONY_SERVICE); + TelephonyManager telephonymanager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (telephonymanager != null) { id = telephonymanager.getDeviceId(); - if ( TextUtils.isEmpty(id)) + if (TextUtils.isEmpty(id)) { id = ""; + } } return id; } - private static String getAndroidId( Context context) { + private static String getAndroidId(Context context) { String s = ""; s = Settings.Secure.getString(context.getContentResolver(), "android_id"); - if ( TextUtils.isEmpty(s)) + if (TextUtils.isEmpty(s)) { s = ""; + } return s; } @@ -95,16 +99,63 @@ public final class DeviceIdUtils { if (!method.isAccessible()) { method.setAccessible(true); } - serial = ( String ) method.invoke(new Build(), "ro.serialno"); - } catch ( ClassNotFoundException e) { + serial = (String) method.invoke(new Build(), "ro.serialno"); + } catch (ClassNotFoundException e) { e.printStackTrace(); - } catch ( NoSuchMethodException e) { + } catch (NoSuchMethodException e) { e.printStackTrace(); - } catch ( InvocationTargetException e) { + } catch (InvocationTargetException e) { e.printStackTrace(); - } catch ( IllegalAccessException e) { + } catch (IllegalAccessException e) { e.printStackTrace(); } return serial; } + + /** + * 获取数字版权管理设备ID + * + * @return WidevineID,可能为空 + */ + public static String getWidevineID(Context context) { + try { + //See https://stackoverflow.com/questions/16369818/how-to-get-crypto-scheme-uuid + //You can find some UUIDs in the https://github.com/google/ExoPlayer source code + final UUID WIDEVINE_UUID = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL); + MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID); + byte[] widevineId = mediaDrm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID); + if (widevineId == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (byte aByte : widevineId) { + sb.append(String.format("%02x", aByte)); + } + return sb.toString(); + } catch (Exception | Error e) { + e.printStackTrace(); + } + return ""; + } + + /** + * 获取数字版权管理设备ID,进行MD5加密,获取32位的唯一标记,给后台生成SN + * + * @return WidevineID,可能为空 + */ + public static String getWidevineIDWithMd5(Context context) { + try { + String widevineId = getWidevineID(context); + if (!TextUtils.isEmpty(widevineId)) { + widevineId = EncryptUtils.encryptHmacMD5ToString(widevineId, "MoGoAuto"); + return widevineId; + } else { + return getDeviceId(context); + } + } catch (Exception | Error e) { + e.printStackTrace(); + } + return getDeviceId(context); + } + } \ No newline at end of file diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/TimeUtils.java b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/TimeUtils.java index b8bed29b54..67f5a97a88 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/TimeUtils.java +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/util/TimeUtils.java @@ -55,14 +55,6 @@ public final class TimeUtils { throw new UnsupportedOperationException("u can't instantiate me..."); } - @SuppressLint("SimpleDateFormat") - public static String formatYMD(long time){ - Date date = new Date(time); - String strDateFormat = "yyyy-MM-dd"; - SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat); - return sdf.format(date); - } - /** * Milliseconds to the formatted time string. *

The pattern is {@code yyyy-MM-dd HH:mm:ss}.

@@ -1532,8 +1524,8 @@ public final class TimeUtils { return CHINESE_ZODIAC[year % 12]; } - private static final int[] ZODIAC_FLAGS = {20, 19, 21, 21, 21, 22, 23, 23, 23, 24, 23, 22}; - private static final String[] ZODIAC = { + private static final int[] ZODIAC_FLAGS = {20, 19, 21, 21, 21, 22, 23, 23, 23, 24, 23, 22}; + private static final String[] ZODIAC = { "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座" }; diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java index 89ebda028a..afe552723b 100644 --- a/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java @@ -179,13 +179,12 @@ public abstract class AbsMogoApplication extends Application { */ protected void registerSocketHttpDnsTTL(String host) { sApis.addressChangedListener(map -> { - Logger.d("TEST-SOCKET", "ttl callBack ,ready to getCache Dns IP"); String dnsCacheIp = sApis.getCachedHttpDnsIps(host, HTTP_DNS_ADDRESS_TYPE_HTTP); if (dnsCacheIp == null) { return; } - Logger.d("TEST-SOCKET", "获取缓存Dns IP : " + dnsCacheIp + " , 原缓存 IP : " + cacheIp); if (!dnsCacheIp.equals(cacheIp)) { + Logger.d("TEST-SOCKET", "获取缓存Dns IP : " + dnsCacheIp + " , 原缓存 IP : " + cacheIp); socketTTL(); this.cacheIp = dnsCacheIp; } diff --git a/gradle.properties b/gradle.properties index 66ce6dd990..4fc8fbe279 100644 --- a/gradle.properties +++ b/gradle.properties @@ -32,12 +32,12 @@ kapt.include.compile.classpath=false # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true # AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK +# Android operating system, and which are packaged with your app'protoc_platforms APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -android.jetifier.blacklist=module-service-2.1.16.8.aar +android.jetifier.blacklist=module-service-2.1.16.10.aar ## maven 配置 RELEASE_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-releases/ SNAPSHOT_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-snapshots/ @@ -56,28 +56,30 @@ bytex.forbidUseLenientMutationDuringGetArtifact=true bytex.verifyProguardConfigurationChanged=false bytex.ASM_API=ASM7 -HOOK_LOG_VERSION=1.4.109 -SERVICE_CHAIN_VERSION=1.0.43 +HOOK_LOG_VERSION=1.5.17 +SERVICE_CHAIN_VERSION=1.0.53 ################ 外部依赖引用 ################ # loglib -LOGLIB_VERSION=1.1.18 +LOGLIB_VERSION=1.2.8 ######## MogoAiCloudSDK Version ######## # 网络请求 -MOGO_NETWORK_VERSION=1.3.18 +MOGO_NETWORK_VERSION=1.3.30 # 鉴权 -MOGO_PASSPORT_VERSION=1.3.18 +MOGO_PASSPORT_VERSION=1.3.30 # 常链接 -MOGO_SOCKET_VERSION=1.3.18 +MOGO_SOCKET_VERSION=1.3.30 # 数据采集 -MOGO_REALTIME_VERSION=1.3.18 +MOGO_REALTIME_VERSION=1.3.30 # 探路,道路事件发布,获取 -MOGO_TANLU_VERSION=1.3.18 +MOGO_TANLU_VERSION=1.3.30 # 直播推流 -MOGO_LIVE_VERSION=1.3.18 +MOGO_LIVE_VERSION=1.3.30 # 直播拉流 -MOGO_TRAFFICLIVE_VERSION=1.3.18 +MOGO_TRAFFICLIVE_VERSION=1.3.30 # 定位服务 -MOGO_LOCATION_VERSION=1.3.18 +MOGO_LOCATION_VERSION=1.3.30 +# 远程通讯模块 +MOGO_TELEMATIC_VERSION=1.3.30 ######## MogoAiCloudSDK Version ######## # 自研地图 MAP_SDK_VERSION=2.0.5.1 @@ -92,105 +94,107 @@ versionCode=80008 versionName=2.5.1 ################# 新架构模块Maven版本管理 ################# -MOGO_CORE_FUNCTION_AUTOPILOT_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_CHECK_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_HMI_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_MAIN_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_MAP_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_MONITORING_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_NOTICE_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_OBU_MOGO_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_SMP_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_V2X_VERSION=0.0.58.8 -MOGO_CORE_DATA_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_API_VERSION=0.0.58.8 -MOGO_CORE_FUNCTION_CALL_VERSION=0.0.58.8 -MOGO_CORE_RES_VERSION=0.0.58.8 -MOGO_CORE_UTILS_VERSION=0.0.58.8 -MOGO_CORE_NETWORK_VERSION=0.0.58.8 +MOGO_CORE_FUNCTION_AUTOPILOT_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_CHECK_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_HMI_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_MAIN_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_MAP_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_MONITORING_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_NOTICE_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_OBU_MOGO_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_SMP_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_V2X_VERSION=0.0.58.10 +MOGO_CORE_DATA_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_API_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_CALL_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_CARCORDER_VERSION=0.0.58.10 +MOGO_CORE_FUNCTION_DEVATOOLS_VERSION=0.0.58.10 +MOGO_CORE_RES_VERSION=0.0.58.10 +MOGO_CORE_UTILS_VERSION=0.0.58.10 +MOGO_CORE_NETWORK_VERSION=0.0.58.10 ################# 旧版本架构模块版本 ################# ## 工程内模块 -MOGO_COMMONS_VERSION=2.1.16.8 -MOGO_UTILS_VERSION=2.1.16.8 -MAP_AMAP_VERSION=2.1.16.8 -MAP_AUTONAVI_VERSION=2.1.16.8 -MOGO_MAP_VERSION=2.1.16.8 -MOGO_MAP_API_VERSION=2.1.16.8 -MOGO_SERVICE_VERSION=2.1.16.8 -MOGO_SERVICE_API_VERSION=2.1.16.8 -MOGO_CONNECTION_VERSION=2.1.16.8 -MOGO_MODULE_APPS_VERSION=2.1.16.8 -MOGO_MODULE_NAVI_VERSION=2.1.16.8 -MOGO_MODULE_SHARE_VERSION=2.1.16.8 -MOGO_MODULE_COMMON_VERSION=2.1.16.8 -MOGO_MODULE_MAIN_VERSION=2.1.16.8 -MOGO_MODULE_MAP_VERSION=2.1.16.8 -MOGO_MODULE_SERVICE_VERSION=2.1.16.8 -MOGO_MODULE_EXTENSIONS_VERSION=2.1.16.8 -MOGO_MODULE_SEARCH_VERSION=2.1.16.8 -MOGO_MODULE_BACK_VERSION=2.1.16.8 -MOGO_MODULE_V2X_VERSION=2.1.16.8 +MOGO_COMMONS_VERSION=2.1.16.10 +MOGO_UTILS_VERSION=2.1.16.10 +MAP_AMAP_VERSION=2.1.16.10 +MAP_AUTONAVI_VERSION=2.1.16.10 +MOGO_MAP_VERSION=2.1.16.10 +MOGO_MAP_API_VERSION=2.1.16.10 +MOGO_SERVICE_VERSION=2.1.16.10 +MOGO_SERVICE_API_VERSION=2.1.16.10 +MOGO_CONNECTION_VERSION=2.1.16.10 +MOGO_MODULE_APPS_VERSION=2.1.16.10 +MOGO_MODULE_NAVI_VERSION=2.1.16.10 +MOGO_MODULE_SHARE_VERSION=2.1.16.10 +MOGO_MODULE_COMMON_VERSION=2.1.16.10 +MOGO_MODULE_MAIN_VERSION=2.1.16.10 +MOGO_MODULE_MAP_VERSION=2.1.16.10 +MOGO_MODULE_SERVICE_VERSION=2.1.16.10 +MOGO_MODULE_EXTENSIONS_VERSION=2.1.16.10 +MOGO_MODULE_SEARCH_VERSION=2.1.16.10 +MOGO_MODULE_BACK_VERSION=2.1.16.10 +MOGO_MODULE_V2X_VERSION=2.1.16.10 # 探路 -MOGO_MODULE_TANLU_VERSION=2.1.16.8 +MOGO_MODULE_TANLU_VERSION=2.1.16.10 # 推送 -MOGO_MODULE_PUSH_VERSION=2.1.16.8 -MOGO_MODULE_PUSH_BASE_VERSION=2.1.16.8 -MOGO_MODULE_PUSH_NOOP_VERSION=2.1.16.8 +MOGO_MODULE_PUSH_VERSION=2.1.16.10 +MOGO_MODULE_PUSH_BASE_VERSION=2.1.16.10 +MOGO_MODULE_PUSH_NOOP_VERSION=2.1.16.10 # 探路上报和分享模块 -TANLULIB_VERSION=2.1.16.8 -MOGO_TANLU_API_VERSION=2.1.16.8 +TANLULIB_VERSION=2.1.16.10 +MOGO_TANLU_API_VERSION=2.1.16.10 #左侧面板模块 -MOGO_MODULE_LEFT_PANEL_VERSION=2.1.16.8 -MOGO_MODULE_LEFT_PANEL_NOOP_VERSION=2.1.16.8 +MOGO_MODULE_LEFT_PANEL_VERSION=2.1.16.10 +MOGO_MODULE_LEFT_PANEL_NOOP_VERSION=2.1.16.10 # 小控件 -MOGO_MODULE_WIDGETS_VERSION=2.1.16.8 +MOGO_MODULE_WIDGETS_VERSION=2.1.16.10 # obu -MOGO_MODULE_OBU_VERSION=2.1.16.8 -MOGO_MODULE_OBU_MOGO_VERSION=2.1.16.8 +MOGO_MODULE_OBU_VERSION=2.1.16.10 +MOGO_MODULE_OBU_MOGO_VERSION=2.1.16.10 # monitor -MOGO_MODULE_MONITOR_VERSION=2.1.16.8 +MOGO_MODULE_MONITOR_VERSION=2.1.16.10 # bugly -CRASHREPORT_VERSION=2.1.16.8 -CRASHREPORT_BUGLY_VERSION=2.1.16.8 -CRASHREPORT_NOOP_VERSION=2.1.16.8 -CRASHREPORT_APMBYTE_VERSION=2.1.16.8 -CRASHREPORT_UPGRADE_VERSION=2.1.16.8 +CRASHREPORT_VERSION=2.1.16.10 +CRASHREPORT_BUGLY_VERSION=2.1.16.10 +CRASHREPORT_NOOP_VERSION=2.1.16.10 +CRASHREPORT_APMBYTE_VERSION=2.1.16.10 +CRASHREPORT_UPGRADE_VERSION=2.1.16.10 ## tts -TTS_BASE_VERSION=2.1.16.8 -TTS_DI_VERSION=2.1.16.8 -TTS_ZHI_VERSION=2.1.16.8 -TTS_PAD_VERSION=2.1.16.8 -TTS_NOOP_VERSION=2.1.16.8 +TTS_BASE_VERSION=2.1.16.10 +TTS_DI_VERSION=2.1.16.10 +TTS_ZHI_VERSION=2.1.16.10 +TTS_PAD_VERSION=2.1.16.10 +TTS_NOOP_VERSION=2.1.16.10 # 自研地图 -MAP_CUSTOM_VERSION=2.1.16.8 -MOGO_MODULE_ADAS_VERSION=2.1.16.8 +MAP_CUSTOM_VERSION=2.1.16.10 +MOGO_MODULE_ADAS_VERSION=2.1.16.10 # 基础服务实现:passport、socket、location -MOGO_BASE_WEBSOCKET_SDK_VERSION=2.1.16.8 -MOGO_BASE_SERVICES_APK_VERSION=2.1.16.8 -MOGO_BASE_SERVICES_SDK_VERSION=2.1.16.8 -MOGO_MODULE_CHAT_VERSION=2.1.16.8 +MOGO_BASE_WEBSOCKET_SDK_VERSION=2.1.16.10 +MOGO_BASE_SERVICES_APK_VERSION=2.1.16.10 +MOGO_BASE_SERVICES_SDK_VERSION=2.1.16.10 +MOGO_MODULE_CHAT_VERSION=2.1.16.10 # 车聊聊 -MOGO_MODULE_CARCHATTING_VERSION=2.1.16.8 +MOGO_MODULE_CARCHATTING_VERSION=2.1.16.10 # 车聊聊接口 -MOGO_MODULE_CARCHATTINGPROVIDER_VERSION=2.1.16.8 +MOGO_MODULE_CARCHATTINGPROVIDER_VERSION=2.1.16.10 # 皮肤 -MOGO_SKIN_SUPPORT_VERSION=2.1.16.8 -MOGO_SKIN_LIGHT_VERSION=2.1.16.8 -MOGO_SKIN_SUPPORT_IMPL_VERSION=2.1.16.8 -MOGO_SKIN_SUPPORT_NOOP_VERSION=2.1.16.8 -SKIN_SUPPORT_VERSION=2.1.16.8 -SKIN_SUPPORT_APPCOMPAT_VERSION=2.1.16.8 -SKIN_SUPPORT_CARDVIEW_VERSION=2.1.16.8 -SKIN_SUPPORT_CONSTRAINT_LAYOUT_VERSION=2.1.16.8 -SKIN_SUPPORT_DESIGN_VERSION=2.1.16.8 +MOGO_SKIN_SUPPORT_VERSION=2.1.16.10 +MOGO_SKIN_LIGHT_VERSION=2.1.16.10 +MOGO_SKIN_SUPPORT_IMPL_VERSION=2.1.16.10 +MOGO_SKIN_SUPPORT_NOOP_VERSION=2.1.16.10 +SKIN_SUPPORT_VERSION=2.1.16.10 +SKIN_SUPPORT_APPCOMPAT_VERSION=2.1.16.10 +SKIN_SUPPORT_CARDVIEW_VERSION=2.1.16.10 +SKIN_SUPPORT_CONSTRAINT_LAYOUT_VERSION=2.1.16.10 +SKIN_SUPPORT_DESIGN_VERSION=2.1.16.10 # OCH -MOGO_OCH_VERSION=2.1.16.8-test +MOGO_OCH_VERSION=2.1.16.10-test MOGO_OCH_BUS_VERSION=2.0.66 MOGO_OCH_NOOP_VERSION=2.0.66 MOGO_OCH_TAXI_VERSION=2.0.66 # mogoAiCloud sdk services -MOGO_AICLOUD_SERVICES_SDK_VERSION=2.1.16.8 +MOGO_AICLOUD_SERVICES_SDK_VERSION=2.1.16.10 # v2x-sdk -MOGO_V2X_SDK_VERSION=1.0.1 +MOGO_V2X_SDK_VERSION=1.3.30 ################# 旧版本架构模块版本 ################# diff --git a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java index 760195fb3e..eb3575736e 100644 --- a/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java +++ b/libraries/map-custom/src/main/java/com/mogo/map/impl/custom/AMapViewWrapper.java @@ -1,5 +1,8 @@ package com.mogo.map.impl.custom; +import static com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_300; +import static com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_CROSS; +import static com.mogo.map.uicontroller.VisualAngleMode.MAP_STYLE_VR_ANGLE_TOP; import static com.mogo.map.uicontroller.VisualAngleMode.MODE_CLOSE_SIGHT; import static com.mogo.map.uicontroller.VisualAngleMode.MODE_LONG_SIGHT; import static com.mogo.map.uicontroller.VisualAngleMode.MODE_MEDIUM_SIGHT; @@ -767,6 +770,12 @@ public class AMapViewWrapper implements IMogoMapView, return MODE_MEDIUM_SIGHT; case 2: return MODE_LONG_SIGHT; + case 3: + return MAP_STYLE_VR_ANGLE_300; + case 4: + return MAP_STYLE_VR_ANGLE_TOP; + case 5: + return MAP_STYLE_VR_ANGLE_CROSS; default: throw new IllegalStateException("mode is unCorrect"); } diff --git a/libraries/map-usbcamera/build.gradle b/libraries/map-usbcamera/build.gradle index 77459969fe..2616caa0ec 100644 --- a/libraries/map-usbcamera/build.gradle +++ b/libraries/map-usbcamera/build.gradle @@ -62,7 +62,6 @@ dependencies { implementation rootProject.ext.dependencies.androidxconstraintlayout implementation rootProject.ext.dependencies.arouter kapt rootProject.ext.dependencies.aroutercompiler - //implementation(name: 'common-4.1.1', ext: 'aar') if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { diff --git a/libraries/map-usbcamera/src/main/java/com/mogo/usbcamera/USBCameraHelper.java b/libraries/map-usbcamera/src/main/java/com/mogo/usbcamera/USBCameraHelper.java new file mode 100644 index 0000000000..e61d6478d0 --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/mogo/usbcamera/USBCameraHelper.java @@ -0,0 +1,39 @@ +package com.mogo.usbcamera; + +import com.serenegiant.usb.USBMonitor; + +/** + * @author donghongyu + * USB摄像头方案,获取权限、获取YUV数据 + */ +public class USBCameraHelper { + private static USBCameraHelper mCameraHelper; + /** + * USB Manager + */ + private USBMonitor mUSBMonitor; + + private USBCameraHelper() { + } + + public static USBCameraHelper getInstance() { + if (mCameraHelper == null) { + mCameraHelper = new USBCameraHelper(); + } + return mCameraHelper; + } + + + + public void registerUSB() { + if (mUSBMonitor != null) { + mUSBMonitor.register(); + } + } + + public void unregisterUSB() { + if (mUSBMonitor != null) { + mUSBMonitor.unregister(); + } + } +} diff --git a/libraries/map-usbcamera/src/main/java/com/mogo/usbcamera/UVCCameraHelper.java b/libraries/map-usbcamera/src/main/java/com/mogo/usbcamera/UVCCameraHelper.java index da4d005ea8..4a14cd62f3 100644 --- a/libraries/map-usbcamera/src/main/java/com/mogo/usbcamera/UVCCameraHelper.java +++ b/libraries/map-usbcamera/src/main/java/com/mogo/usbcamera/UVCCameraHelper.java @@ -22,10 +22,7 @@ import java.util.Objects; /** * UVCCamera Helper class - *

- * Created by jiangdongguo on 2017/9/30. */ - public class UVCCameraHelper { public static final String ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator; @@ -77,6 +74,9 @@ public class UVCCameraHelper { void onConnectDev(UsbDevice device, boolean isConnected); void onDisConnectDev(UsbDevice device); + + void onCancelDev(UsbDevice device); + } public void initUSBMonitor(Activity activity, CameraViewInterface cameraView, final OnMyDevConnectListener listener) { @@ -109,18 +109,15 @@ public class UVCCameraHelper { public void onConnect(final UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock, boolean createNew) { mCtrlBlock = ctrlBlock; openCamera(ctrlBlock); - new Thread(new Runnable() { - @Override - public void run() { - // wait for camera created - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - // start previewing - startPreview(mCamView); + new Thread(() -> { + // wait for camera created + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); } + // start previewing + startPreview(mCamView); }).start(); if (listener != null) { listener.onConnectDev(device, true); @@ -138,6 +135,9 @@ public class UVCCameraHelper { @Override public void onCancel(UsbDevice device) { + if (listener != null) { + listener.onCancelDev(device); + } } }); @@ -252,7 +252,6 @@ public class UVCCameraHelper { public void capturePicture(String savePath, AbstractUVCCameraHandler.OnCaptureListener listener) { if (mCameraHandler != null && mCameraHandler.isOpened()) { - File file = new File(savePath); if (!Objects.requireNonNull(file.getParentFile()).exists()) { file.getParentFile().mkdirs(); diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/DialogFragmentEx.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/DialogFragmentEx.java new file mode 100644 index 0000000000..d1a390497c --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/DialogFragmentEx.java @@ -0,0 +1,23 @@ +package com.serenegiant.dialog; + +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; + +public abstract class DialogFragmentEx extends DialogFragment { + protected static final String ARGS_KEY_REQUEST_CODE = "requestCode"; + protected static final String ARGS_KEY_ID_TITLE = "title"; + protected static final String ARGS_KEY_ID_MESSAGE = "message"; + protected static final String ARGS_KEY_TAG = "tag"; + + @Override + public void onSaveInstanceState(@NonNull final Bundle outState) { + super.onSaveInstanceState(outState); + final Bundle args = getArguments(); + if (args != null) { + outState.putAll(args); + } + } + +} diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/MessageDialogFragment.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/MessageDialogFragment.java new file mode 100644 index 0000000000..bfdf3595f1 --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/MessageDialogFragment.java @@ -0,0 +1,136 @@ +package com.serenegiant.dialog; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.Fragment; +import android.content.DialogInterface; +import android.os.Bundle; +import android.util.Log; + +import com.serenegiant.utils.BuildCheck; + +/** + * パーミッション要求前に説明用のダイアログを表示するためのDialogFragment + */ +@SuppressWarnings("deprecation") +@Deprecated +public class MessageDialogFragment extends DialogFragment { +// private static final boolean DEBUG = false; // FIXME 実働時はfalseにすること + private static final String TAG = MessageDialogFragment.class.getSimpleName(); + + public static interface MessageDialogListener { + public void onMessageDialogResult(final MessageDialogFragment dialog, final int requestCode, final String[] permissions, final boolean result); + } + + public static MessageDialogFragment showDialog(final Activity parent, final int requestCode, final int id_title, final int id_message, final String[] permissions) { + final MessageDialogFragment dialog = newInstance(requestCode, id_title, id_message, permissions); + dialog.show(parent.getFragmentManager(), TAG); + return dialog; + } + + public static MessageDialogFragment showDialog(final Fragment parent, final int requestCode, final int id_title, final int id_message, final String[] permissions) { + final MessageDialogFragment dialog = newInstance(requestCode, id_title, id_message, permissions); + dialog.setTargetFragment(parent, parent.getId()); + dialog.show(parent.getFragmentManager(), TAG); + return dialog; + } + + public static MessageDialogFragment newInstance(final int requestCode, final int id_title, final int id_message, final String[] permissions) { + final MessageDialogFragment fragment = new MessageDialogFragment(); + final Bundle args = new Bundle(); + // ここでパラメータをセットする + args.putInt("requestCode", requestCode); + args.putInt("title", id_title); + args.putInt("message", id_message); + args.putStringArray("permissions", permissions != null ? permissions : new String[]{}); + fragment.setArguments(args); + return fragment; + } + + private MessageDialogListener mDialogListener; + + public MessageDialogFragment() { + super(); + // デフォルトコンストラクタが必要 + } + + @SuppressLint("NewApi") + @Override + public void onAttach(final Activity activity) { + super.onAttach(activity); + // コールバックインターフェースを取得 + if (activity instanceof MessageDialogListener) { + mDialogListener = (MessageDialogListener)activity; + } + if (mDialogListener == null) { + final Fragment fragment = getTargetFragment(); + if (fragment instanceof MessageDialogListener) { + mDialogListener = (MessageDialogListener)fragment; + } + } + if (mDialogListener == null) { + if (BuildCheck.isAndroid4_2()) { + final Fragment target = getParentFragment(); + if (target instanceof MessageDialogListener) { + mDialogListener = (MessageDialogListener)target; + } + } + } + if (mDialogListener == null) { +// Log.w(TAG, "caller activity/fragment must implement PermissionDetailDialogFragmentListener"); + throw new ClassCastException(activity.toString()); + } + } + +// @Override +// public void onCreate(final Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// final Bundle args = savedInstanceState != null ? savedInstanceState : getArguments(); +// } + + @Override + public Dialog onCreateDialog(final Bundle savedInstanceState) { + final Bundle args = savedInstanceState != null ? savedInstanceState : getArguments(); + final int requestCode = getArguments().getInt("requestCode"); + final int id_title = getArguments().getInt("title"); + final int id_message = getArguments().getInt("message"); + final String[] permissions = args.getStringArray("permissions"); + + + return new AlertDialog.Builder(getActivity()) + .setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(id_title) + .setMessage(id_message) + .setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int whichButton) { + // 本当はここでパーミッション要求をしたいだけどこのダイアログがdismissしてしまって結果を受け取れないので + // 呼び出し側へ返してそこでパーミッション要求する。なのでこのダイアログは単にメッセージを表示するだけ + try { + mDialogListener.onMessageDialogResult(MessageDialogFragment.this, requestCode, permissions, true); + } catch (final Exception e) { + Log.w(TAG, e); + } + } + } + ) + .setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, int whichButton) { + try { + mDialogListener.onMessageDialogResult(MessageDialogFragment.this, requestCode, permissions, false); + } catch (final Exception e) { + Log.w(TAG, e); + } + } + } + ) + .create(); + } + +} diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/MessageDialogFragmentV4.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/MessageDialogFragmentV4.java new file mode 100644 index 0000000000..b55b276159 --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/dialog/MessageDialogFragmentV4.java @@ -0,0 +1,213 @@ +package com.serenegiant.dialog; +/* + * libcommon + * utility/helper classes for myself + * + * Copyright (c) 2014-2018 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; + +import com.serenegiant.utils.BuildCheck; + +public class MessageDialogFragmentV4 extends DialogFragmentEx { +// private static final boolean DEBUG = false; // FIXME 実働時はfalseにすること + private static final String TAG = MessageDialogFragmentV4.class.getSimpleName(); + + private static final String ARGS_KEY_PERMISSIONS = "permissions"; + + /** + * ダイアログの表示結果を受け取るためのコールバックリスナー + */ + public static interface MessageDialogListener { + public void onMessageDialogResult( + @NonNull final MessageDialogFragmentV4 dialog, final int requestCode, + @NonNull final String[] permissions, final boolean result); + } + + /** + * ダイアログ表示のためのヘルパーメソッド + * @param parent + * @param requestCode + * @param id_title + * @param id_message + * @param permissions + * @return + * @throws IllegalStateException + */ + public static MessageDialogFragmentV4 showDialog( + @NonNull final FragmentActivity parent, final int requestCode, + @StringRes final int id_title, @StringRes final int id_message, + @NonNull final String[] permissions) throws IllegalStateException { + + final MessageDialogFragmentV4 dialog + = newInstance(requestCode, id_title, id_message, permissions); + dialog.show(parent.getSupportFragmentManager(), TAG); + return dialog; + } + + /** + * ダイアログ表示のためのヘルパーメソッド + * @param parent + * @param requestCode + * @param id_title + * @param id_message + * @param permissions + * @return + * @throws IllegalStateException + */ + public static MessageDialogFragmentV4 showDialog( + @NonNull final Fragment parent, final int requestCode, + @StringRes final int id_title, @StringRes final int id_message, + @NonNull final String[] permissions) throws IllegalStateException { + + final MessageDialogFragmentV4 dialog + = newInstance(requestCode, id_title, id_message, permissions); + dialog.setTargetFragment(parent, parent.getId()); + dialog.show(parent.requireFragmentManager(), TAG); + return dialog; + } + + /** + * ダイアログ生成のためのヘルパーメソッド + * ダイアログ自体を直接生成せずにこのメソッドを呼び出すこと + * @param requestCode + * @param id_title + * @param id_message + * @param permissions + * @return + */ + public static MessageDialogFragmentV4 newInstance( + final int requestCode, + @StringRes final int id_title, @StringRes final int id_message, + @NonNull final String[] permissions) { + + final MessageDialogFragmentV4 fragment = new MessageDialogFragmentV4(); + final Bundle args = new Bundle(); + // ここでパラメータをセットする + args.putInt(ARGS_KEY_REQUEST_CODE, requestCode); + args.putInt(ARGS_KEY_ID_TITLE, id_title); + args.putInt(ARGS_KEY_ID_MESSAGE, id_message); + args.putStringArray(ARGS_KEY_PERMISSIONS, permissions); + fragment.setArguments(args); + return fragment; + } + + private MessageDialogListener mDialogListener; + + /** + * コンストラクタ, 直接生成せずに#newInstanceを使うこと + */ + public MessageDialogFragmentV4() { + super(); + // デフォルトコンストラクタが必要 + } + + @Override + public void onAttach(final Context context) { + super.onAttach(context); + // コールバックインターフェースを取得 + if (context instanceof MessageDialogListener) { + mDialogListener = (MessageDialogListener)context; + } + if (mDialogListener == null) { + final Fragment fragment = getTargetFragment(); + if (fragment instanceof MessageDialogListener) { + mDialogListener = (MessageDialogListener)fragment; + } + } + if (mDialogListener == null) { + if (BuildCheck.isAndroid4_2()) { + final Fragment target = getParentFragment(); + if (target instanceof MessageDialogListener) { + mDialogListener = (MessageDialogListener)target; + } + } + } + if (mDialogListener == null) { +// Log.w(TAG, "caller activity/fragment must implement PermissionDetailDialogFragmentListener"); + throw new ClassCastException(context.toString()); + } + } + +// @Override +// public void onCreate(final Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// final Bundle args = savedInstanceState != null ? savedInstanceState : getArguments(); +// } + + @NonNull + @Override + public Dialog onCreateDialog(final Bundle savedInstanceState) { + final Bundle args = savedInstanceState != null ? savedInstanceState : requireArguments(); + final int id_title = args.getInt(ARGS_KEY_ID_TITLE); + final int id_message = args.getInt(ARGS_KEY_ID_MESSAGE); + + final Activity activity = requireActivity(); + return new AlertDialog.Builder(activity) + .setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(id_title) + .setMessage(id_message) + .setPositiveButton(android.R.string.ok, mOnClickListener) + .setNegativeButton(android.R.string.cancel, mOnClickListener) + .create(); + } + + private final DialogInterface.OnClickListener mOnClickListener + = new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int which) { + // 本当はここでパーミッション要求をしたいだけどこのダイアログがdismissしてしまって結果を受け取れないので + // 呼び出し側へ返してそこでパーミッション要求する。なのでこのダイアログは単にメッセージを表示するだけ + callOnMessageDialogResult(which == DialogInterface.BUTTON_POSITIVE); + } + }; + + @Override + public void onCancel(final DialogInterface dialog) { + super.onCancel(dialog); + callOnMessageDialogResult(false); + } + + /** + * コールバックリスナー呼び出しのためのヘルパーメソッド + * @param result + */ + private void callOnMessageDialogResult(final boolean result) + throws IllegalStateException { + + final Bundle args = requireArguments(); + final int requestCode = args.getInt(ARGS_KEY_REQUEST_CODE); + final String[] permissions = args.getStringArray(ARGS_KEY_PERMISSIONS); + try { + mDialogListener.onMessageDialogResult( + MessageDialogFragmentV4.this, + requestCode, permissions, result); + } catch (final Exception e) { + Log.w(TAG, e); + } + } +} diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/CameraDialog.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/CameraDialog.java index 53269a658f..dfad92686f 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/CameraDialog.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/CameraDialog.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb; import android.app.Activity; @@ -24,199 +47,192 @@ import java.util.ArrayList; import java.util.List; public class CameraDialog extends DialogFragment { - private static final String TAG = CameraDialog.class.getSimpleName(); + private static final String TAG = CameraDialog.class.getSimpleName(); - public interface CameraDialogParent { - public USBMonitor getUSBMonitor(); + public interface CameraDialogParent { + public USBMonitor getUSBMonitor(); + public void onDialogResult(boolean canceled); + } + + /** + * Helper method + * @param parent FragmentActivity + * @return + */ + public static CameraDialog showDialog(final Activity parent/* add parameters here if you need */) { + CameraDialog dialog = newInstance(/* add parameters here if you need */); + try { + dialog.show(parent.getFragmentManager(), TAG); + } catch (final IllegalStateException e) { + dialog = null; + } + return dialog; + } - public void onDialogResult(boolean canceled); - } + public static CameraDialog newInstance(/* add parameters here if you need */) { + final CameraDialog dialog = new CameraDialog(); + final Bundle args = new Bundle(); + // add parameters here if you need + dialog.setArguments(args); + return dialog; + } - /** - * Helper method - * - * @param parent FragmentActivity - * @return - */ - public static CameraDialog showDialog(final Activity parent/* add parameters here if you need */) { - CameraDialog dialog = newInstance(/* add parameters here if you need */); + protected USBMonitor mUSBMonitor; + private Spinner mSpinner; + private DeviceListAdapter mDeviceListAdapter; + + public CameraDialog(/* no arguments */) { + // Fragment need default constructor + } + + @SuppressWarnings("deprecation") + @Override + public void onAttach(final Activity activity) { + super.onAttach(activity); + if (mUSBMonitor == null) try { - dialog.show(parent.getFragmentManager(), TAG); - } catch (final IllegalStateException e) { - dialog = null; + mUSBMonitor = ((CameraDialogParent)activity).getUSBMonitor(); + } catch (final ClassCastException e) { + } catch (final NullPointerException e) { } - return dialog; - } + if (mUSBMonitor == null) { + throw new ClassCastException(activity.toString() + " must implement CameraDialogParent#getUSBController"); + } + } - public static CameraDialog newInstance(/* add parameters here if you need */) { - final CameraDialog dialog = new CameraDialog(); - final Bundle args = new Bundle(); - // add parameters here if you need - dialog.setArguments(args); - return dialog; - } - - protected USBMonitor mUSBMonitor; - private Spinner mSpinner; - private DeviceListAdapter mDeviceListAdapter; - - public CameraDialog(/* no arguments */) { - // Fragment need default constructor - } - - @SuppressWarnings("deprecation") - @Override - public void onAttach(final Activity activity) { - super.onAttach(activity); - if (mUSBMonitor == null) { - try { - mUSBMonitor = ((CameraDialogParent) activity).getUSBMonitor(); - } catch (final NullPointerException | ClassCastException e) { - e.printStackTrace(); - } - } - if (mUSBMonitor == null) { - throw new ClassCastException(activity.toString() + " must implement CameraDialogParent#getUSBController"); - } - } - - @Override + @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (savedInstanceState == null) { - savedInstanceState = getArguments(); - } - } + super.onCreate(savedInstanceState); + if (savedInstanceState == null) + savedInstanceState = getArguments(); + } - @Override - public void onSaveInstanceState(final Bundle saveInstanceState) { - final Bundle args = getArguments(); - if (args != null) { - saveInstanceState.putAll(args); - } - super.onSaveInstanceState(saveInstanceState); - } + @Override + public void onSaveInstanceState(final Bundle saveInstanceState) { + final Bundle args = getArguments(); + if (args != null) + saveInstanceState.putAll(args); + super.onSaveInstanceState(saveInstanceState); + } - @Override + @Override public Dialog onCreateDialog(final Bundle savedInstanceState) { - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setView(initView()); - builder.setTitle(R.string.select); - builder.setPositiveButton(android.R.string.ok, mOnDialogClickListener); - builder.setNegativeButton(android.R.string.cancel, mOnDialogClickListener); - builder.setNeutralButton(R.string.refresh, null); - final Dialog dialog = builder.create(); - dialog.setCancelable(true); - dialog.setCanceledOnTouchOutside(true); + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setView(initView()); + builder.setTitle(R.string.select); + builder.setPositiveButton(android.R.string.ok, mOnDialogClickListener); + builder.setNegativeButton(android.R.string.cancel , mOnDialogClickListener); + builder.setNeutralButton(R.string.refresh, null); + final Dialog dialog = builder.create(); + dialog.setCancelable(true); + dialog.setCanceledOnTouchOutside(true); return dialog; - } + } - /** - * create view that this fragment shows - * - * @return - */ - private final View initView() { - final View rootView = getActivity().getLayoutInflater().inflate(R.layout.dialog_camera, null); - mSpinner = (Spinner) rootView.findViewById(R.id.spinner1); - final View empty = rootView.findViewById(android.R.id.empty); - mSpinner.setEmptyView(empty); - return rootView; - } + /** + * create view that this fragment shows + * @return + */ + private final View initView() { + final View rootView = getActivity().getLayoutInflater().inflate(R.layout.dialog_camera, null); + mSpinner = (Spinner)rootView.findViewById(R.id.spinner1); + final View empty = rootView.findViewById(android.R.id.empty); + mSpinner.setEmptyView(empty); + return rootView; + } - @Override - public void onResume() { - super.onResume(); - updateDevices(); - final Button button = (Button) getDialog().findViewById(android.R.id.button3); - if (button != null) { - button.setOnClickListener(mOnClickListener); - } - } + @Override + public void onResume() { + super.onResume(); + updateDevices(); + final Button button = (Button)getDialog().findViewById(android.R.id.button3); + if (button != null) { + button.setOnClickListener(mOnClickListener); + } + } - private final OnClickListener mOnClickListener = new OnClickListener() { - @Override - public void onClick(final View v) { - switch (v.getId()) { - case android.R.id.button3: - updateDevices(); - break; - } - } - }; + private final OnClickListener mOnClickListener = new OnClickListener() { + @Override + public void onClick(final View v) { + switch (v.getId()) { + case android.R.id.button3: + updateDevices(); + break; + } + } + }; - private final DialogInterface.OnClickListener mOnDialogClickListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - final Object item = mSpinner.getSelectedItem(); - if (item instanceof UsbDevice) { - mUSBMonitor.requestPermission((UsbDevice) item); - ((CameraDialogParent) getActivity()).onDialogResult(false); - } - break; - case DialogInterface.BUTTON_NEGATIVE: - ((CameraDialogParent) getActivity()).onDialogResult(true); - break; - } - } - }; + private final DialogInterface.OnClickListener mOnDialogClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + final Object item = mSpinner.getSelectedItem(); + if (item instanceof UsbDevice) { + mUSBMonitor.requestPermission((UsbDevice)item); + ((CameraDialogParent)getActivity()).onDialogResult(false); + } + break; + case DialogInterface.BUTTON_NEGATIVE: + ((CameraDialogParent)getActivity()).onDialogResult(true); + break; + } + } + }; - @Override - public void onCancel(final DialogInterface dialog) { - ((CameraDialogParent) getActivity()).onDialogResult(true); - super.onCancel(dialog); - } + @Override + public void onCancel(final DialogInterface dialog) { + ((CameraDialogParent)getActivity()).onDialogResult(true); + super.onCancel(dialog); + } - public void updateDevices() { + public void updateDevices() { // mUSBMonitor.dumpDevices(); - final List filter = DeviceFilter.getDeviceFilters(getActivity(), R.xml.device_filter); - mDeviceListAdapter = new DeviceListAdapter(getActivity(), mUSBMonitor.getDeviceList(filter.get(0))); - mSpinner.setAdapter(mDeviceListAdapter); - } + final List filter = DeviceFilter.getDeviceFilters(getActivity(), R.xml.device_filter); + mDeviceListAdapter = new DeviceListAdapter(getActivity(), mUSBMonitor.getDeviceList(filter.get(0))); + mSpinner.setAdapter(mDeviceListAdapter); + } - private static final class DeviceListAdapter extends BaseAdapter { + private static final class DeviceListAdapter extends BaseAdapter { - private final LayoutInflater mInflater; - private final List mList; + private final LayoutInflater mInflater; + private final List mList; - public DeviceListAdapter(final Context context, final List list) { - mInflater = LayoutInflater.from(context); - mList = list != null ? list : new ArrayList(); - } + public DeviceListAdapter(final Context context, final Listlist) { + mInflater = LayoutInflater.from(context); + mList = list != null ? list : new ArrayList(); + } - @Override - public int getCount() { - return mList.size(); - } + @Override + public int getCount() { + return mList.size(); + } - @Override - public UsbDevice getItem(final int position) { - if ((position >= 0) && (position < mList.size())) { - return mList.get(position); - } else { - return null; - } - } + @Override + public UsbDevice getItem(final int position) { + if ((position >= 0) && (position < mList.size())) + return mList.get(position); + else + return null; + } - @Override - public long getItemId(final int position) { - return position; - } + @Override + public long getItemId(final int position) { + return position; + } - @Override - public View getView(final int position, View convertView, final ViewGroup parent) { - if (convertView == null) { - convertView = mInflater.inflate(R.layout.listitem_device, parent, false); - } - if (convertView instanceof CheckedTextView) { - final UsbDevice device = getItem(position); - ((CheckedTextView) convertView).setText( - String.format("UVC Camera:(%x:%x:%s)", device.getVendorId(), device.getProductId(), device.getDeviceName())); - } - return convertView; - } - } + @Override + public View getView(final int position, View convertView, final ViewGroup parent) { + if (convertView == null) { + convertView = mInflater.inflate(R.layout.listitem_device, parent, false); + } + if (convertView instanceof CheckedTextView) { + final UsbDevice device = getItem(position); + ((CheckedTextView)convertView).setText( + String.format("UVC Camera:(%x:%x:%s)", device.getVendorId(), device.getProductId(), device.getDeviceName())); + } + return convertView; + } + } } diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/DeviceFilter.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/DeviceFilter.java index 61b9c09d61..2e94263c92 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/DeviceFilter.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/DeviceFilter.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb; import android.content.Context; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/IFrameCallback.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/IFrameCallback.java index 3d00d77d29..f6aee755e0 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/IFrameCallback.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/IFrameCallback.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb; import java.nio.ByteBuffer; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/Size.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/Size.java index 55bf0b19b7..963a805398 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/Size.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/Size.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb; import android.os.Parcel; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java index 1eea770006..b46ee9f4a6 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb; import android.annotation.SuppressLint; @@ -97,20 +120,15 @@ public final class USBMonitor { } public USBMonitor(final Context context, final OnDeviceConnectListener listener) { - if (DEBUG) { - Log.v(TAG, "USBMonitor:Constructor"); - } - if (listener == null) { + if (DEBUG) Log.v(TAG, "USBMonitor:Constructor"); + if (listener == null) throw new IllegalArgumentException("OnDeviceConnectListener should not null."); - } mWeakContext = new WeakReference(context); mUsbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE); mOnDeviceConnectListener = listener; mAsyncHandler = HandlerThreadHandler.createHandler(TAG); destroyed = false; - if (DEBUG) { - Log.v(TAG, "USBMonitor:mUsbManager=" + mUsbManager); - } + if (DEBUG) Log.v(TAG, "USBMonitor:mUsbManager=" + mUsbManager); } /** @@ -118,9 +136,7 @@ public final class USBMonitor { * never reuse again */ public void destroy() { - if (DEBUG) { - Log.i(TAG, "destroy:"); - } + if (DEBUG) Log.i(TAG, "destroy:"); unregister(); if (!destroyed) { destroyed = true; @@ -153,13 +169,9 @@ public final class USBMonitor { * @throws IllegalStateException */ public synchronized void register() throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); if (mPermissionIntent == null) { - if (DEBUG) { - Log.i(TAG, "register:"); - } + if (DEBUG) Log.i(TAG, "register:"); final Context context = mWeakContext.get(); if (context != null) { mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0); @@ -209,9 +221,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public void setDeviceFilter(final DeviceFilter filter) throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); mDeviceFilters.clear(); mDeviceFilters.add(filter); } @@ -222,9 +232,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public void addDeviceFilter(final DeviceFilter filter) throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); mDeviceFilters.add(filter); } @@ -234,9 +242,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public void removeDeviceFilter(final DeviceFilter filter) throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); mDeviceFilters.remove(filter); } @@ -246,9 +252,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public void setDeviceFilter(final List filters) throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); mDeviceFilters.clear(); mDeviceFilters.addAll(filters); } @@ -259,9 +263,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public void addDeviceFilter(final List filters) throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); mDeviceFilters.addAll(filters); } @@ -270,9 +272,7 @@ public final class USBMonitor { * @param filters */ public void removeDeviceFilter(final List filters) throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); mDeviceFilters.removeAll(filters); } @@ -282,9 +282,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public int getDeviceCount() throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); return getDeviceList().size(); } @@ -294,9 +292,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public List getDeviceList() throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); return getDeviceList(mDeviceFilters); } @@ -307,9 +303,7 @@ public final class USBMonitor { * @throws IllegalStateException */ public List getDeviceList(final List filters) throws IllegalStateException { - if (destroyed) { - throw new IllegalStateException("already destroyed"); - } + if (destroyed) throw new IllegalStateException("already destroyed"); // get detected devices final HashMap deviceList = mUsbManager.getDeviceList(); // store those devices info before matching filter xml file @@ -353,8 +347,8 @@ public final class USBMonitor { break; } else { // collection failed dev's class and subclass - String devModel = android.os.Build.MODEL; - String devSystemVersion = android.os.Build.VERSION.RELEASE; + String devModel = Build.MODEL; + String devSystemVersion = Build.VERSION.RELEASE; String devClass = String.valueOf(device.getDeviceClass()); String subClass = String.valueOf(device.getDeviceSubclass()); try{ diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBVendorId.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBVendorId.java index f2577935a6..d354b66ca7 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBVendorId.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/USBVendorId.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb; import android.util.SparseArray; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/UVCCamera.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/UVCCamera.java index b73940d1b6..15a4180b75 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/UVCCamera.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/UVCCamera.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb; import android.graphics.SurfaceTexture; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java index 00aa36d45a..992d1cf562 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java @@ -2,9 +2,7 @@ package com.serenegiant.usb.common; import android.annotation.TargetApi; import android.app.Activity; -import android.content.Context; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Rect; import android.graphics.SurfaceTexture; @@ -22,7 +20,6 @@ import android.view.Surface; import android.view.SurfaceHolder; import com.serenegiant.usb.IFrameCallback; -import com.serenegiant.usb.ParentPreviewConstraintLayout; import com.serenegiant.usb.Size; import com.serenegiant.usb.USBMonitor; import com.serenegiant.usb.UVCCamera; @@ -52,7 +49,6 @@ import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; -import java.util.Locale; import java.util.Objects; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -68,19 +64,19 @@ public abstract class AbstractUVCCameraHandler extends Handler { // 对外回调接口 public interface CameraCallback { - void onOpen(); + public void onOpen(); - void onClose(); + public void onClose(); - void onStartPreview(); + public void onStartPreview(); - void onStopPreview(); + public void onStopPreview(); - void onStartRecording(); + public void onStartRecording(); - void onStopRecording(); + public void onStopRecording(); - void onError(final Exception e); + public void onError(final Exception e); } public static OnEncodeResultListener mListener; @@ -180,16 +176,12 @@ public abstract class AbstractUVCCameraHandler extends Handler { } public void close() { - if (DEBUG) { - Log.v(TAG, "close:"); - } + if (DEBUG) Log.v(TAG, "close:"); if (isOpened()) { stopPreview(); sendEmptyMessage(MSG_CLOSE); } - if (DEBUG) { - Log.v(TAG, "close:finished"); - } + if (DEBUG) Log.v(TAG, "close:finished"); } // 切换分辨率 @@ -214,18 +206,14 @@ public abstract class AbstractUVCCameraHandler extends Handler { // 关闭Camera预览 public void stopPreview() { - if (DEBUG) { - Log.v(TAG, "stopPreview:"); - } + if (DEBUG) Log.v(TAG, "stopPreview:"); removeMessages(MSG_PREVIEW_START); if (isRecording()) { stopRecording(); } if (isPreviewing()) { final CameraThread thread = mWeakThread.get(); - if (thread == null) { - return; - } + if (thread == null) return; synchronized (thread.mSync) { sendEmptyMessage(MSG_PREVIEW_STOP); if (!isCameraThread()) { @@ -239,12 +227,10 @@ public abstract class AbstractUVCCameraHandler extends Handler { } } } - if (DEBUG) { - Log.v(TAG, "stopPreview:finished"); - } + if (DEBUG) Log.v(TAG, "stopPreview:finished"); } - public void captureStill(final String path, AbstractUVCCameraHandler.OnCaptureListener listener) { + public void captureStill(final String path, OnCaptureListener listener) { AbstractUVCCameraHandler.mCaptureListener = listener; checkReleased(); sendMessage(obtainMessage(MSG_CAPTURE_STILL, path)); @@ -366,9 +352,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { @Override public void handleMessage(final Message msg) { final CameraThread thread = mWeakThread.get(); - if (thread == null) { - return; - } + if (thread == null) return; switch (msg.what) { case MSG_OPEN: thread.handleOpen((USBMonitor.UsbControlBlock) msg.obj); @@ -472,17 +456,13 @@ public abstract class AbstractUVCCameraHandler extends Handler { } public AbstractUVCCameraHandler getHandler() { - if (DEBUG) { - Log.v(TAG_THREAD, "getHandler:"); - } + if (DEBUG) Log.v(TAG_THREAD, "getHandler:"); synchronized (mSync) { - if (mHandler == null) { + if (mHandler == null) try { mSync.wait(); } catch (final InterruptedException e) { - e.printStackTrace(); } - } } return mHandler; } @@ -528,9 +508,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { } public void handleOpen(final USBMonitor.UsbControlBlock ctrlBlock) { - if (DEBUG) { - Log.v(TAG_THREAD, "handleOpen:"); - } + if (DEBUG) Log.v(TAG_THREAD, "handleOpen:"); handleClose(); try { final UVCCamera camera = new UVCCamera(); @@ -542,15 +520,12 @@ public abstract class AbstractUVCCameraHandler extends Handler { } catch (final Exception e) { callOnError(e); } - if (DEBUG) { + if (DEBUG) Log.i(TAG, "supportedSize:" + (mUVCCamera != null ? mUVCCamera.getSupportedSize() : null)); - } } public void handleClose() { - if (DEBUG) { - Log.v(TAG_THREAD, "handleClose:"); - } + if (DEBUG) Log.v(TAG_THREAD, "handleClose:"); handleStopPusher(); final UVCCamera camera; synchronized (mSync) { @@ -565,12 +540,8 @@ public abstract class AbstractUVCCameraHandler extends Handler { } public void handleStartPreview(final Object surface) { - if (DEBUG) { - Log.v(TAG_THREAD, "handleStartPreview:"); - } - if ((mUVCCamera == null) || mIsPreviewing) { - return; - } + if (DEBUG) Log.v(TAG_THREAD, "handleStartPreview:"); + if ((mUVCCamera == null) || mIsPreviewing) return; try { mUVCCamera.setPreviewSize(mWidth, mHeight, 1, 31, mPreviewMode, mBandwidthFactor); // 获取USB Camera预览数据,使用NV21颜色会失真 @@ -603,9 +574,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { } public void handleStopPreview() { - if (DEBUG) { - Log.v(TAG_THREAD, "handleStopPreview:"); - } + if (DEBUG) Log.v(TAG_THREAD, "handleStopPreview:"); if (mIsPreviewing) { if (mUVCCamera != null) { mUVCCamera.stopPreview(); @@ -617,20 +586,14 @@ public abstract class AbstractUVCCameraHandler extends Handler { } callOnStopPreview(); } - if (DEBUG) { - Log.v(TAG_THREAD, "handleStopPreview:finished"); - } + if (DEBUG) Log.v(TAG_THREAD, "handleStopPreview:finished"); } // 捕获静态图片 public void handleCaptureStill(final String path) { - if (DEBUG) { - Log.v(TAG_THREAD, "handleCaptureStill:"); - } + if (DEBUG) Log.v(TAG_THREAD, "handleCaptureStill:"); final Activity parent = mWeakParent.get(); - if (parent == null) { - return; - } + if (parent == null) return; // mSoundPool.play(mSoundId, 0.2f, 0.2f, 0, 0, 1.0f); // play shutter sound try { final Bitmap bitmap = mWeakCameraView.get().captureStillImage(mWidth, mHeight); @@ -647,7 +610,6 @@ public abstract class AbstractUVCCameraHandler extends Handler { os.flush(); mHandler.sendMessage(mHandler.obtainMessage(MSG_MEDIA_UPDATE, outputFile.getPath())); } catch (final IOException e) { - e.printStackTrace(); } } finally { os.close(); @@ -706,9 +668,8 @@ public abstract class AbstractUVCCameraHandler extends Handler { private H264EncodeConsumer mH264Consumer; public void handleStartPusher(RecordParams params) { - if ((mUVCCamera == null) || (mH264Consumer != null)) { + if ((mUVCCamera == null) || (mH264Consumer != null)) return; - } // // 获取USB Camera预览数据 // mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_NV21); @@ -747,9 +708,8 @@ public abstract class AbstractUVCCameraHandler extends Handler { // 停止音视频编码线程 stopAudioRecord(); stopVideoRecord(); - if(isSupportOverlay) { + if(isSupportOverlay) TxtOverlay.getInstance().release(); - } // // 停止捕获视频数据 // if (mUVCCamera != null) { // mUVCCamera.stopCapture(); @@ -915,23 +875,18 @@ public abstract class AbstractUVCCameraHandler extends Handler { @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public void handleUpdateMedia(final String path) { - if (DEBUG) { - Log.v(TAG_THREAD, "handleUpdateMedia:path=" + path); - } + if (DEBUG) Log.v(TAG_THREAD, "handleUpdateMedia:path=" + path); final Activity parent = mWeakParent.get(); final boolean released = (mHandler == null) || mHandler.mReleased; if (parent != null && parent.getApplicationContext() != null) { try { - if (DEBUG) { - Log.i(TAG, "MediaScannerConnection#scanFile"); - } + if (DEBUG) Log.i(TAG, "MediaScannerConnection#scanFile"); MediaScannerConnection.scanFile(parent.getApplicationContext(), new String[]{path}, null, null); } catch (final Exception e) { Log.e(TAG, "handleUpdateMedia:", e); } - if (released || parent.isDestroyed()) { + if (released || parent.isDestroyed()) handleRelease(); - } } else { Log.w(TAG, "MainActivity already destroyed"); // give up to add this movie to MediaStore now. @@ -941,71 +896,57 @@ public abstract class AbstractUVCCameraHandler extends Handler { } public void handleRelease() { - if (DEBUG) { - Log.v(TAG_THREAD, "handleRelease:mIsRecording=" + mIsRecording); - } + if (DEBUG) Log.v(TAG_THREAD, "handleRelease:mIsRecording=" + mIsRecording); handleClose(); mCallbacks.clear(); if (!mIsRecording) { mHandler.mReleased = true; Looper.myLooper().quit(); } - if (DEBUG) { - Log.v(TAG_THREAD, "handleRelease:finished"); - } + if (DEBUG) Log.v(TAG_THREAD, "handleRelease:finished"); } // 自动对焦 public void handleCameraFoucs() { - if (DEBUG) { - Log.v(TAG_THREAD, "handleStartPreview:"); - } - if ((mUVCCamera == null) || !mIsPreviewing) { + if (DEBUG) Log.v(TAG_THREAD, "handleStartPreview:"); + if ((mUVCCamera == null) || !mIsPreviewing) return; - } mUVCCamera.setAutoFocus(true); } // 获取支持的分辨率 public List getSupportedSizes() { - if ((mUVCCamera == null) || !mIsPreviewing) { + if ((mUVCCamera == null) || !mIsPreviewing) return null; - } return mUVCCamera.getSupportedSizeList(); } private final MediaEncoder.MediaEncoderListener mMediaEncoderListener = new MediaEncoder.MediaEncoderListener() { @Override public void onPrepared(final MediaEncoder encoder) { - if (DEBUG) { - Log.v(TAG, "onPrepared:encoder=" + encoder); - } + if (DEBUG) Log.v(TAG, "onPrepared:encoder=" + encoder); mIsRecording = true; - if (encoder instanceof MediaVideoEncoder) { + if (encoder instanceof MediaVideoEncoder) try { mWeakCameraView.get().setVideoEncoder((MediaVideoEncoder) encoder); } catch (final Exception e) { Log.e(TAG, "onPrepared:", e); } - } - if (encoder instanceof MediaSurfaceEncoder) { + if (encoder instanceof MediaSurfaceEncoder) try { mWeakCameraView.get().setVideoEncoder((MediaSurfaceEncoder) encoder); mUVCCamera.startCapture(((MediaSurfaceEncoder) encoder).getInputSurface()); } catch (final Exception e) { Log.e(TAG, "onPrepared:", e); } - } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @Override public void onStopped(final MediaEncoder encoder) { - if (DEBUG) { - Log.v(TAG_THREAD, "onStopped:encoder=" + encoder); - } + if (DEBUG) Log.v(TAG_THREAD, "onStopped:encoder=" + encoder); if ((encoder instanceof MediaVideoEncoder) - || (encoder instanceof MediaSurfaceEncoder)) { + || (encoder instanceof MediaSurfaceEncoder)) try { mIsRecording = false; final Activity parent = mWeakParent.get(); @@ -1027,7 +968,6 @@ public abstract class AbstractUVCCameraHandler extends Handler { } catch (final Exception e) { Log.e(TAG, "onPrepared:", e); } - } } @Override diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseActivity.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseActivity.java new file mode 100644 index 0000000000..8a446cd2a8 --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseActivity.java @@ -0,0 +1,321 @@ +package com.serenegiant.usb.common; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.appcompat.app.AppCompatActivity; + +import com.mogo.usbcamera.R; +import com.serenegiant.dialog.MessageDialogFragmentV4; +import com.serenegiant.utils.BuildCheck; +import com.serenegiant.utils.HandlerThreadHandler; +import com.serenegiant.utils.PermissionCheck; + +/** + * Created by saki on 2016/11/18. + * + */ +public class BaseActivity extends AppCompatActivity + implements MessageDialogFragmentV4.MessageDialogListener { + + private static boolean DEBUG = false; // FIXME 実働時はfalseにセットすること + private static final String TAG = BaseActivity.class.getSimpleName(); + + /** UI操作のためのHandler */ + private final Handler mUIHandler = new Handler(Looper.getMainLooper()); + private final Thread mUiThread = mUIHandler.getLooper().getThread(); + /** ワーカースレッド上で処理するためのHandler */ + private Handler mWorkerHandler; + private long mWorkerThreadID = -1; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // ワーカースレッドを生成 + if (mWorkerHandler == null) { + mWorkerHandler = HandlerThreadHandler.createHandler(TAG); + mWorkerThreadID = mWorkerHandler.getLooper().getThread().getId(); + } + } + + @Override + protected void onPause() { + clearToast(); + super.onPause(); + } + + @Override + protected synchronized void onDestroy() { + // ワーカースレッドを破棄 + if (mWorkerHandler != null) { + try { + mWorkerHandler.getLooper().quit(); + } catch (final Exception e) { + // + } + mWorkerHandler = null; + } + super.onDestroy(); + } + +//================================================================================ + /** + * UIスレッドでRunnableを実行するためのヘルパーメソッド + * @param task + * @param duration + */ + public final void runOnUiThread(final Runnable task, final long duration) { + if (task == null) { + return; + } + mUIHandler.removeCallbacks(task); + if ((duration > 0) || Thread.currentThread() != mUiThread) { + mUIHandler.postDelayed(task, duration); + } else { + try { + task.run(); + } catch (final Exception e) { + Log.w(TAG, e); + } + } + } + + /** + * UIスレッド上で指定したRunnableが実行待ちしていれば実行待ちを解除する + * @param task + */ + public final void removeFromUiThread(final Runnable task) { + if (task == null) { + return; + } + mUIHandler.removeCallbacks(task); + } + + /** + * ワーカースレッド上で指定したRunnableを実行する + * 未実行の同じRunnableがあればキャンセルされる(後から指定した方のみ実行される) + * @param task + * @param delayMillis + */ + protected final synchronized void queueEvent(final Runnable task, final long delayMillis) { + if ((task == null) || (mWorkerHandler == null)) { + return; + } + try { + mWorkerHandler.removeCallbacks(task); + if (delayMillis > 0) { + mWorkerHandler.postDelayed(task, delayMillis); + } else if (mWorkerThreadID == Thread.currentThread().getId()) { + task.run(); + } else { + mWorkerHandler.post(task); + } + } catch (final Exception e) { + // ignore + } + } + + /** + * 指定したRunnableをワーカースレッド上で実行予定であればキャンセルする + * @param task + */ + protected final synchronized void removeEvent(final Runnable task) { + if (task == null) { + return; + } + try { + mWorkerHandler.removeCallbacks(task); + } catch (final Exception e) { + // ignore + } + } + +//================================================================================ + private Toast mToast; + /** + * Toastでメッセージを表示 + * @param msg + */ + protected void showToast(@StringRes final int msg, final Object... args) { + removeFromUiThread(mShowToastTask); + mShowToastTask = new ShowToastTask(msg, args); + runOnUiThread(mShowToastTask, 0); + } + + /** + * Toastが表示されていればキャンセルする + */ + protected void clearToast() { + removeFromUiThread(mShowToastTask); + mShowToastTask = null; + try { + if (mToast != null) { + mToast.cancel(); + mToast = null; + } + } catch (final Exception e) { + // ignore + } + } + + private ShowToastTask mShowToastTask; + private final class ShowToastTask implements Runnable { + final int msg; + final Object args; + private ShowToastTask(@StringRes final int msg, final Object... args) { + this.msg = msg; + this.args = args; + } + + @Override + public void run() { + try { + if (mToast != null) { + mToast.cancel(); + mToast = null; + } + final String _msg = (args != null) ? getString(msg, args) : getString(msg); + mToast = Toast.makeText(BaseActivity.this, _msg, Toast.LENGTH_SHORT); + mToast.show(); + } catch (final Exception e) { + // ignore + } + } + } + +//================================================================================ + /** + * MessageDialogFragmentメッセージダイアログからのコールバックリスナー + * @param dialog + * @param requestCode + * @param permissions + * @param result + */ + @SuppressLint("NewApi") + @Override + public void onMessageDialogResult(final MessageDialogFragmentV4 dialog, final int requestCode, final String[] permissions, final boolean result) { + if (result) { + // メッセージダイアログでOKを押された時はパーミッション要求する + if (BuildCheck.isMarshmallow()) { + requestPermissions(permissions, requestCode); + return; + } + } + // メッセージダイアログでキャンセルされた時とAndroid6でない時は自前でチェックして#checkPermissionResultを呼び出す + for (final String permission: permissions) { + checkPermissionResult(requestCode, permission, PermissionCheck.hasPermission(this, permission)); + } + } + + /** + * パーミッション要求結果を受け取るためのメソッド + * @param requestCode + * @param permissions + * @param grantResults + */ + @Override + public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); // 何もしてないけど一応呼んどく + final int n = Math.min(permissions.length, grantResults.length); + for (int i = 0; i < n; i++) { + checkPermissionResult(requestCode, permissions[i], grantResults[i] == PackageManager.PERMISSION_GRANTED); + } + } + + /** + * パーミッション要求の結果をチェック + * ここではパーミッションを取得できなかった時にToastでメッセージ表示するだけ + * @param requestCode + * @param permission + * @param result + */ + protected void checkPermissionResult(final int requestCode, final String permission, final boolean result) { + // パーミッションがないときにはメッセージを表示する + if (!result && (permission != null)) { + if (Manifest.permission.RECORD_AUDIO.equals(permission)) { + showToast(R.string.permission_audio); + } + if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) { + showToast(R.string.permission_ext_storage); + } + if (Manifest.permission.INTERNET.equals(permission)) { + showToast(R.string.permission_network); + } + } + } + + // 動的パーミッション要求時の要求コード + protected static final int REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE = 0x12345; + protected static final int REQUEST_PERMISSION_AUDIO_RECORDING = 0x234567; + protected static final int REQUEST_PERMISSION_NETWORK = 0x345678; + protected static final int REQUEST_PERMISSION_CAMERA = 0x537642; + + /** + * 外部ストレージへの書き込みパーミッションが有るかどうかをチェック + * なければ説明ダイアログを表示する + * @return true 外部ストレージへの書き込みパーミッションが有る + */ + protected boolean checkPermissionWriteExternalStorage() { + if (!PermissionCheck.hasWriteExternalStorage(this)) { + MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE, + R.string.permission_title, R.string.permission_ext_storage_request, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}); + return false; + } + return true; + } + + /** + * 録音のパーミッションが有るかどうかをチェック + * なければ説明ダイアログを表示する + * @return true 録音のパーミッションが有る + */ + protected boolean checkPermissionAudio() { + if (!PermissionCheck.hasAudio(this)) { + MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_AUDIO_RECORDING, + R.string.permission_title, R.string.permission_audio_recording_request, + new String[]{Manifest.permission.RECORD_AUDIO}); + return false; + } + return true; + } + + /** + * ネットワークアクセスのパーミッションが有るかどうかをチェック + * なければ説明ダイアログを表示する + * @return true ネットワークアクセスのパーミッションが有る + */ + protected boolean checkPermissionNetwork() { + if (!PermissionCheck.hasNetwork(this)) { + MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_NETWORK, + R.string.permission_title, R.string.permission_network_request, + new String[]{Manifest.permission.INTERNET}); + return false; + } + return true; + } + + /** + * カメラアクセスのパーミッションがあるかどうかをチェック + * なければ説明ダイアログを表示する + * @return true カメラアクセスのパーミッションが有る + */ + protected boolean checkPermissionCamera() { + if (!PermissionCheck.hasCamera(this)) { + MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_CAMERA, + R.string.permission_title, R.string.permission_camera_request, + new String[]{Manifest.permission.CAMERA}); + return false; + } + return true; + } + +} diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseFragment.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseFragment.java new file mode 100644 index 0000000000..4e883ce185 --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseFragment.java @@ -0,0 +1,348 @@ +package com.serenegiant.usb.common; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Fragment; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + +import com.mogo.usbcamera.R; +import com.serenegiant.dialog.MessageDialogFragment; +import com.serenegiant.utils.BuildCheck; +import com.serenegiant.utils.HandlerThreadHandler; +import com.serenegiant.utils.PermissionCheck; + +/** + * Created by saki on 2016/11/19. + */ +public class BaseFragment extends Fragment + implements MessageDialogFragment.MessageDialogListener { + + private static boolean DEBUG = false; // FIXME 実働時はfalseにセットすること + private static final String TAG = BaseFragment.class.getSimpleName(); + + /** + * UI操作のためのHandler + */ + private final Handler mUIHandler = new Handler(Looper.getMainLooper()); + private final Thread mUiThread = mUIHandler.getLooper().getThread(); + /** + * ワーカースレッド上で処理するためのHandler + */ + private Handler mWorkerHandler; + private long mWorkerThreadID = -1; + + public BaseFragment() { + super(); + } + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // ワーカースレッドを生成 + if (mWorkerHandler == null) { + mWorkerHandler = HandlerThreadHandler.createHandler(TAG); + mWorkerThreadID = mWorkerHandler.getLooper().getThread().getId(); + } + } + + @Override + public void onPause() { + clearToast(); + super.onPause(); + } + + @Override + public synchronized void onDestroy() { + // ワーカースレッドを破棄 + if (mWorkerHandler != null) { + try { + mWorkerHandler.getLooper().quit(); + } catch (final Exception e) { + // + } + mWorkerHandler = null; + } + super.onDestroy(); + } + +//================================================================================ + + /** + * UIスレッドでRunnableを実行するためのヘルパーメソッド + * + * @param task + * @param duration + */ + public final void runOnUiThread(final Runnable task, final long duration) { + if (task == null) { + return; + } + mUIHandler.removeCallbacks(task); + if ((duration > 0) || Thread.currentThread() != mUiThread) { + mUIHandler.postDelayed(task, duration); + } else { + try { + task.run(); + } catch (final Exception e) { + Log.w(TAG, e); + } + } + } + + /** + * UIスレッド上で指定したRunnableが実行待ちしていれば実行待ちを解除する + * + * @param task + */ + public final void removeFromUiThread(final Runnable task) { + if (task == null) { + return; + } + mUIHandler.removeCallbacks(task); + } + + /** + * ワーカースレッド上で指定したRunnableを実行する + * 未実行の同じRunnableがあればキャンセルされる(後から指定した方のみ実行される) + * + * @param task + * @param delayMillis + */ + protected final synchronized void queueEvent(final Runnable task, final long delayMillis) { + if ((task == null) || (mWorkerHandler == null)) { + return; + } + try { + mWorkerHandler.removeCallbacks(task); + if (delayMillis > 0) { + mWorkerHandler.postDelayed(task, delayMillis); + } else if (mWorkerThreadID == Thread.currentThread().getId()) { + task.run(); + } else { + mWorkerHandler.post(task); + } + } catch (final Exception e) { + // ignore + } + } + + /** + * 指定したRunnableをワーカースレッド上で実行予定であればキャンセルする + * + * @param task + */ + protected final synchronized void removeEvent(final Runnable task) { + if (task == null) { + return; + } + try { + mWorkerHandler.removeCallbacks(task); + } catch (final Exception e) { + // ignore + } + } + + //================================================================================ + private Toast mToast; + + /** + * Toastでメッセージを表示 + * + * @param msg + */ + protected void showToast(@StringRes final int msg, final Object... args) { + removeFromUiThread(mShowToastTask); + mShowToastTask = new ShowToastTask(msg, args); + runOnUiThread(mShowToastTask, 0); + } + + /** + * Toastが表示されていればキャンセルする + */ + protected void clearToast() { + removeFromUiThread(mShowToastTask); + mShowToastTask = null; + try { + if (mToast != null) { + mToast.cancel(); + mToast = null; + } + } catch (final Exception e) { + // ignore + } + } + + private ShowToastTask mShowToastTask; + + private final class ShowToastTask implements Runnable { + final int msg; + final Object args; + + private ShowToastTask(@StringRes final int msg, final Object... args) { + this.msg = msg; + this.args = args; + } + + @Override + public void run() { + try { + if (mToast != null) { + mToast.cancel(); + mToast = null; + } + if (args != null) { + final String _msg = getString(msg, args); + mToast = Toast.makeText(getActivity(), _msg, Toast.LENGTH_SHORT); + } else { + mToast = Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT); + } + mToast.show(); + } catch (final Exception e) { + // ignore + } + } + } + +//================================================================================ + + /** + * MessageDialogFragmentメッセージダイアログからのコールバックリスナー + * + * @param dialog + * @param requestCode + * @param permissions + * @param result + */ + @SuppressLint("NewApi") + @Override + public void onMessageDialogResult(final MessageDialogFragment dialog, final int requestCode, final String[] permissions, final boolean result) { + if (result) { + // メッセージダイアログでOKを押された時はパーミッション要求する + if (BuildCheck.isMarshmallow()) { + requestPermissions(permissions, requestCode); + return; + } + } + // メッセージダイアログでキャンセルされた時とAndroid6でない時は自前でチェックして#checkPermissionResultを呼び出す + for (final String permission : permissions) { + checkPermissionResult(requestCode, permission, PermissionCheck.hasPermission(getActivity(), permission)); + } + } + + /** + * パーミッション要求結果を受け取るためのメソッド + * + * @param requestCode + * @param permissions + * @param grantResults + */ + @Override + public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); // 何もしてないけど一応呼んどく + final int n = Math.min(permissions.length, grantResults.length); + for (int i = 0; i < n; i++) { + checkPermissionResult(requestCode, permissions[i], grantResults[i] == PackageManager.PERMISSION_GRANTED); + } + } + + /** + * パーミッション要求の結果をチェック + * ここではパーミッションを取得できなかった時にToastでメッセージ表示するだけ + * + * @param requestCode + * @param permission + * @param result + */ + protected void checkPermissionResult(final int requestCode, final String permission, final boolean result) { + // パーミッションがないときにはメッセージを表示する + if (!result && (permission != null)) { + if (Manifest.permission.RECORD_AUDIO.equals(permission)) { + showToast(R.string.permission_audio); + } + if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) { + showToast(R.string.permission_ext_storage); + } + if (Manifest.permission.INTERNET.equals(permission)) { + showToast(R.string.permission_network); + } + } + } + + // 動的パーミッション要求時の要求コード + protected static final int REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE = 0x12345; + protected static final int REQUEST_PERMISSION_AUDIO_RECORDING = 0x234567; + protected static final int REQUEST_PERMISSION_NETWORK = 0x345678; + protected static final int REQUEST_PERMISSION_CAMERA = 0x537642; + + /** + * 外部ストレージへの書き込みパーミッションが有るかどうかをチェック + * なければ説明ダイアログを表示する + * + * @return true 外部ストレージへの書き込みパーミッションが有る + */ + protected boolean checkPermissionWriteExternalStorage() { + if (!PermissionCheck.hasWriteExternalStorage(getActivity())) { + MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE, + R.string.permission_title, R.string.permission_ext_storage_request, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}); + return false; + } + return true; + } + + /** + * 録音のパーミッションが有るかどうかをチェック + * なければ説明ダイアログを表示する + * + * @return true 録音のパーミッションが有る + */ + protected boolean checkPermissionAudio() { + if (!PermissionCheck.hasAudio(getActivity())) { + MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_AUDIO_RECORDING, + R.string.permission_title, R.string.permission_audio_recording_request, + new String[]{Manifest.permission.RECORD_AUDIO}); + return false; + } + return true; + } + + /** + * ネットワークアクセスのパーミッションが有るかどうかをチェック + * なければ説明ダイアログを表示する + * + * @return true ネットワークアクセスのパーミッションが有る + */ + protected boolean checkPermissionNetwork() { + if (!PermissionCheck.hasNetwork(getActivity())) { + MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_NETWORK, + R.string.permission_title, R.string.permission_network_request, + new String[]{Manifest.permission.INTERNET}); + return false; + } + return true; + } + + /** + * カメラアクセスのパーミッションがあるかどうかをチェック + * なければ説明ダイアログを表示する + * + * @return true カメラアクセスのパーミッションが有る + */ + protected boolean checkPermissionCamera() { + if (!PermissionCheck.hasCamera(getActivity())) { + MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_CAMERA, + R.string.permission_title, R.string.permission_camera_request, + new String[]{Manifest.permission.CAMERA}); + return false; + } + return true; + } +} diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseService.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseService.java new file mode 100644 index 0000000000..78a2307af6 --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/BaseService.java @@ -0,0 +1,108 @@ +package com.serenegiant.usb.common; + +import android.app.Service; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import com.serenegiant.utils.HandlerThreadHandler; + +public abstract class BaseService extends Service { + private static boolean DEBUG = false; // FIXME 実働時はfalseにセットすること + private static final String TAG = BaseService.class.getSimpleName(); + + /** UI操作のためのHandler */ + private final Handler mUIHandler = new Handler(Looper.getMainLooper()); + private final Thread mUiThread = mUIHandler.getLooper().getThread(); + /** ワーカースレッド上で処理するためのHandler */ + private Handler mWorkerHandler; + private long mWorkerThreadID = -1; + + @Override + public void onCreate() { + super.onCreate(); + // ワーカースレッドを生成 + if (mWorkerHandler == null) { + mWorkerHandler = HandlerThreadHandler.createHandler(TAG); + mWorkerThreadID = mWorkerHandler.getLooper().getThread().getId(); + } + } + + @Override + public synchronized void onDestroy() { + // ワーカースレッドを破棄 + if (mWorkerHandler != null) { + try { + mWorkerHandler.getLooper().quit(); + } catch (final Exception e) { + // + } + mWorkerHandler = null; + } + super.onDestroy(); + } + +//================================================================================ + /** + * UIスレッドでRunnableを実行するためのヘルパーメソッド + * @param task + * @param duration + */ + public final void runOnUiThread(final Runnable task, final long duration) { + if (task == null) return; + mUIHandler.removeCallbacks(task); + if ((duration > 0) || Thread.currentThread() != mUiThread) { + mUIHandler.postDelayed(task, duration); + } else { + try { + task.run(); + } catch (final Exception e) { + Log.w(TAG, e); + } + } + } + + /** + * UIスレッド上で指定したRunnableが実行待ちしていれば実行待ちを解除する + * @param task + */ + public final void removeFromUiThread(final Runnable task) { + if (task == null) return; + mUIHandler.removeCallbacks(task); + } + + /** + * ワーカースレッド上で指定したRunnableを実行する + * 未実行の同じRunnableがあればキャンセルされる(後から指定した方のみ実行される) + * @param task + * @param delayMillis + */ + protected final synchronized void queueEvent(final Runnable task, final long delayMillis) { + if ((task == null) || (mWorkerHandler == null)) return; + try { + mWorkerHandler.removeCallbacks(task); + if (delayMillis > 0) { + mWorkerHandler.postDelayed(task, delayMillis); + } else if (mWorkerThreadID == Thread.currentThread().getId()) { + task.run(); + } else { + mWorkerHandler.post(task); + } + } catch (final Exception e) { + // ignore + } + } + + /** + * 指定したRunnableをワーカースレッド上で実行予定であればキャンセルする + * @param task + */ + protected final synchronized void removeEvent(final Runnable task) { + if (task == null) return; + try { + mWorkerHandler.removeCallbacks(task); + } catch (final Exception e) { + // ignore + } + } +} diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java index b102139d6d..2d01f1cd25 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java @@ -1,9 +1,30 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb.common; import android.app.Activity; -import android.content.Context; -import com.serenegiant.usb.ParentPreviewConstraintLayout; import com.serenegiant.usb.UVCCamera; import com.serenegiant.usb.widget.CameraViewInterface; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java index 7619d39df4..d8df6c26d1 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java @@ -1,10 +1,32 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb.common; import android.app.Activity; import android.view.Surface; import com.serenegiant.glutils.RendererHolder; -import com.serenegiant.usb.ParentPreviewConstraintLayout; import com.serenegiant.usb.UVCCamera; import com.serenegiant.usb.widget.CameraViewInterface; @@ -101,7 +123,6 @@ public class UVCCameraHandlerMultiSurface extends AbstractUVCCameraHandler { mRendererHolder = new RendererHolder(thread.getWidth(), thread.getHeight(), null); } - @Override public synchronized void release() { if (mRendererHolder != null) { mRendererHolder.release(); @@ -110,8 +131,7 @@ public class UVCCameraHandlerMultiSurface extends AbstractUVCCameraHandler { super.release(); } - @Override - public synchronized void resize(final int width, final int height) { + public synchronized void resize(final int width, final int height) { super.resize(width, height); if (mRendererHolder != null) { mRendererHolder.resize(width, height); diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IAudioEncoder.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IAudioEncoder.java index eef9858a73..9a0c0bdb7e 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IAudioEncoder.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IAudioEncoder.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb.encoder; public interface IAudioEncoder { diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IVideoEncoder.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IVideoEncoder.java index 24370c80ff..7b8429d262 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IVideoEncoder.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/IVideoEncoder.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb.encoder; public interface IVideoEncoder { diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaAudioEncoder.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaAudioEncoder.java index 761419aa50..3246364cff 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaAudioEncoder.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaAudioEncoder.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb.encoder; import android.media.AudioFormat; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaSurfaceEncoder.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaSurfaceEncoder.java index fc3e0a38ce..47eb607e08 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaSurfaceEncoder.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaSurfaceEncoder.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb.encoder; import android.media.MediaCodec; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaVideoBufferEncoder.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaVideoBufferEncoder.java index 30d3242bb9..40d26bfaa0 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaVideoBufferEncoder.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/MediaVideoBufferEncoder.java @@ -1,3 +1,26 @@ +/* + * UVCCamera + * library and sample to access to UVC web camera on non-rooted Android device + * + * Copyright (c) 2014-2017 saki t_saki@serenegiant.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * All files in the folder are under this Apache License, Version 2.0. + * Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder + * may have a different license, see the respective files. + */ + package com.serenegiant.usb.encoder; import android.media.MediaCodec; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java index 159218211a..0265cac1ea 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java @@ -1,8 +1,10 @@ package com.serenegiant.usb.encoder; -/** - * 录制参数 +/** 录制参数 + * + * Created by jiangdongguo on 2017/10/19. */ + public class RecordParams { private String recordPath; private int recordDuration; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/AACEncodeConsumer.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/AACEncodeConsumer.java index 0cbf441869..69319e9b7d 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/AACEncodeConsumer.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/AACEncodeConsumer.java @@ -19,10 +19,12 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ShortBuffer; -/** - * 将PCM编码为AAC +/**将PCM编码为AAC + * + * Created by jianddongguo on 2017/7/21. */ -public class AACEncodeConsumer extends Thread { + +public class AACEncodeConsumer extends Thread{ private static final boolean DEBUG = false; private static final String TAG = "TMPU"; private static final String MIME_TYPE = "audio/mp4a-latm"; @@ -38,7 +40,7 @@ public class AACEncodeConsumer extends Thread { private AudioRecord mAudioRecord; // 音频采集 private MediaCodec mAudioEncoder; // 音频编码 private OnAACEncodeResultListener listener; - private int mSamplingRateIndex = 0;//ADTS + private int mSamplingRateIndex = 0;//ADTS private boolean isEncoderStart = false; private boolean isRecMp3 = false; private boolean isExit = false; @@ -46,7 +48,7 @@ public class AACEncodeConsumer extends Thread { private WeakReference mMuxerRef; private MediaFormat newFormat; - private static final int[] AUDIO_SOURCES = new int[]{ + private static final int[] AUDIO_SOURCES = new int[] { MediaRecorder.AudioSource.DEFAULT, MediaRecorder.AudioSource.MIC, MediaRecorder.AudioSource.CAMCORDER, @@ -54,7 +56,7 @@ public class AACEncodeConsumer extends Thread { /** * There are 13 supported frequencies by ADTS. **/ - public static final int[] AUDIO_SAMPLING_RATES = {96000, // 0 + public static final int[] AUDIO_SAMPLING_RATES = { 96000, // 0 88200, // 1 64000, // 2 48000, // 3 @@ -75,13 +77,13 @@ public class AACEncodeConsumer extends Thread { private FileOutputStream fops; // 编码流结果回调接口 - public interface OnAACEncodeResultListener { + public interface OnAACEncodeResultListener{ void onEncodeResult(byte[] data, int offset, int length, long timestamp); } - public AACEncodeConsumer() { - for (int i = 0; i < AUDIO_SAMPLING_RATES.length; i++) { + public AACEncodeConsumer(){ + for (int i=0;i < AUDIO_SAMPLING_RATES.length; i++) { if (AUDIO_SAMPLING_RATES[i] == SAMPLE_RATE) { mSamplingRateIndex = i; break; @@ -89,16 +91,16 @@ public class AACEncodeConsumer extends Thread { } } - public void setOnAACEncodeResultListener(OnAACEncodeResultListener listener) { + public void setOnAACEncodeResultListener(OnAACEncodeResultListener listener){ this.listener = listener; } - public void exit() { + public void exit(){ isExit = true; } - public synchronized void setTmpuMuxer(Mp4MediaMuxer mMuxer) { - this.mMuxerRef = new WeakReference<>(mMuxer); + public synchronized void setTmpuMuxer(Mp4MediaMuxer mMuxer){ + this.mMuxerRef = new WeakReference<>(mMuxer); Mp4MediaMuxer muxer = mMuxerRef.get(); if (muxer != null && newFormat != null) { muxer.addTrack(newFormat, false); @@ -108,7 +110,7 @@ public class AACEncodeConsumer extends Thread { @Override public void run() { // 开启音频采集、编码 - if (!isEncoderStart) { + if(! isEncoderStart){ initAudioRecord(); initMediaCodec(); } @@ -116,16 +118,16 @@ public class AACEncodeConsumer extends Thread { byte[] mp3Buffer = new byte[1024]; // 这里有问题,当本地录制结束后,没有写入 - while (!isExit) { + while(! isExit){ byte[] audioBuffer = new byte[2048]; // 采集音频 - int readBytes = mAudioRecord.read(audioBuffer, 0, BUFFER_SIZE); + int readBytes = mAudioRecord.read(audioBuffer,0,BUFFER_SIZE); - if (DEBUG) - Log.i(TAG, "采集音频readBytes = " + readBytes); + if(DEBUG) + Log.i(TAG,"采集音频readBytes = "+readBytes); // 编码音频 - if (readBytes > 0) { - encodeBytes(audioBuffer, readBytes); + if(readBytes > 0){ + encodeBytes(audioBuffer,readBytes); } } // 停止音频采集、编码 @@ -140,81 +142,81 @@ public class AACEncodeConsumer extends Thread { ByteBuffer[] outputBuffers = mAudioEncoder.getOutputBuffers(); //返回编码器的一个输入缓存区句柄,-1表示当前没有可用的输入缓存区 int inputBufferIndex = mAudioEncoder.dequeueInputBuffer(TIMES_OUT); - if (inputBufferIndex >= 0) { + if(inputBufferIndex >= 0){ // 绑定一个被空的、可写的输入缓存区inputBuffer到客户端 - ByteBuffer inputBuffer = null; - if (!isLollipop()) { + ByteBuffer inputBuffer = null; + if(!isLollipop()){ inputBuffer = inputBuffers[inputBufferIndex]; - } else { + }else{ inputBuffer = mAudioEncoder.getInputBuffer(inputBufferIndex); } // 向输入缓存区写入有效原始数据,并提交到编码器中进行编码处理 - if (audioBuf == null || readBytes <= 0) { - mAudioEncoder.queueInputBuffer(inputBufferIndex, 0, 0, getPTSUs(), MediaCodec.BUFFER_FLAG_END_OF_STREAM); - } else { + if(audioBuf==null || readBytes<=0){ + mAudioEncoder.queueInputBuffer(inputBufferIndex,0,0,getPTSUs(),MediaCodec.BUFFER_FLAG_END_OF_STREAM); + }else{ inputBuffer.clear(); inputBuffer.put(audioBuf); - mAudioEncoder.queueInputBuffer(inputBufferIndex, 0, readBytes, getPTSUs(), 0); + mAudioEncoder.queueInputBuffer(inputBufferIndex,0,readBytes,getPTSUs(),0); } } // 返回一个输出缓存区句柄,当为-1时表示当前没有可用的输出缓存区 // mBufferInfo参数包含被编码好的数据,timesOut参数为超时等待的时间 - MediaCodec.BufferInfo mBufferInfo = new MediaCodec.BufferInfo(); + MediaCodec.BufferInfo mBufferInfo = new MediaCodec.BufferInfo(); int outputBufferIndex = -1; - do { - outputBufferIndex = mAudioEncoder.dequeueOutputBuffer(mBufferInfo, TIMES_OUT); - if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { - if (DEBUG) - Log.i(TAG, "获得编码器输出缓存区超时"); - } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { + do{ + outputBufferIndex = mAudioEncoder.dequeueOutputBuffer(mBufferInfo,TIMES_OUT); + if(outputBufferIndex == MediaCodec. INFO_TRY_AGAIN_LATER){ + if(DEBUG) + Log.i(TAG,"获得编码器输出缓存区超时"); + }else if(outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED){ // 如果API小于21,APP需要重新绑定编码器的输入缓存区; // 如果API大于21,则无需处理INFO_OUTPUT_BUFFERS_CHANGED - if (!isLollipop()) { + if(!isLollipop()){ outputBuffers = mAudioEncoder.getOutputBuffers(); } - } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { + }else if(outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED){ // 编码器输出缓存区格式改变,通常在存储数据之前且只会改变一次 // 这里设置混合器视频轨道,如果音频已经添加则启动混合器(保证音视频同步) - if (DEBUG) - Log.i(TAG, "编码器输出缓存区格式改变,添加视频轨道到混合器"); + if(DEBUG) + Log.i(TAG,"编码器输出缓存区格式改变,添加视频轨道到混合器"); synchronized (AACEncodeConsumer.this) { newFormat = mAudioEncoder.getOutputFormat(); - if (mMuxerRef != null) { + if(mMuxerRef != null){ Mp4MediaMuxer muxer = mMuxerRef.get(); if (muxer != null) { muxer.addTrack(newFormat, false); } } } - } else { + }else{ // 当flag属性置为BUFFER_FLAG_CODEC_CONFIG后,说明输出缓存区的数据已经被消费了 - if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { - if (DEBUG) - Log.i(TAG, "编码数据被消费,BufferInfo的size属性置0"); + if((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0){ + if(DEBUG) + Log.i(TAG,"编码数据被消费,BufferInfo的size属性置0"); mBufferInfo.size = 0; } // 数据流结束标志,结束本次循环 - if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { - if (DEBUG) - Log.i(TAG, "数据流结束,退出循环"); + if((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0){ + if(DEBUG) + Log.i(TAG,"数据流结束,退出循环"); break; } // 获取一个只读的输出缓存区inputBuffer ,它包含被编码好的数据 ByteBuffer mBuffer = ByteBuffer.allocate(10240); ByteBuffer outputBuffer = null; - if (!isLollipop()) { - outputBuffer = outputBuffers[outputBufferIndex]; - } else { - outputBuffer = mAudioEncoder.getOutputBuffer(outputBufferIndex); + if(!isLollipop()){ + outputBuffer = outputBuffers[outputBufferIndex]; + }else{ + outputBuffer = mAudioEncoder.getOutputBuffer(outputBufferIndex); } - if (mBufferInfo.size != 0) { + if(mBufferInfo.size != 0){ // 获取输出缓存区失败,抛出异常 - if (outputBuffer == null) { - throw new RuntimeException("encodecOutputBuffer" + outputBufferIndex + "was null"); + if(outputBuffer == null){ + throw new RuntimeException("encodecOutputBuffer"+outputBufferIndex+"was null"); } // 添加视频流到混合器 - if (mMuxerRef != null) { + if(mMuxerRef != null){ Mp4MediaMuxer muxer = mMuxerRef.get(); if (muxer != null) { muxer.pumpStream(outputBuffer, mBufferInfo, false); @@ -228,25 +230,25 @@ public class AACEncodeConsumer extends Thread { addADTStoPacket(mBuffer.array(), mBufferInfo.size + 7); mBuffer.flip(); // 将AAC回调给MainModelImpl进行push - if (listener != null) { - Log.i(TAG, "----->得到aac数据流<-----"); - listener.onEncodeResult(mBuffer.array(), 0, mBufferInfo.size + 7, mBufferInfo.presentationTimeUs / 1000); + if(listener != null){ + Log.i(TAG,"----->得到aac数据流<-----"); + listener.onEncodeResult(mBuffer.array(),0, mBufferInfo.size + 7, mBufferInfo.presentationTimeUs / 1000); } } // 处理结束,释放输出缓存区资源 - mAudioEncoder.releaseOutputBuffer(outputBufferIndex, false); + mAudioEncoder.releaseOutputBuffer(outputBufferIndex,false); } - } while (outputBufferIndex >= 0); + }while (outputBufferIndex >= 0); } - private void initAudioRecord() { - if (DEBUG) - Log.d(TAG, "AACEncodeConsumer-->开始采集音频"); + private void initAudioRecord(){ + if(DEBUG) + Log.d(TAG,"AACEncodeConsumer-->开始采集音频"); // 设置进程优先级 Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO); int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); - for (final int src : AUDIO_SOURCES) { + for (final int src: AUDIO_SOURCES) { try { mAudioRecord = new AudioRecord(src, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); @@ -266,18 +268,18 @@ public class AACEncodeConsumer extends Thread { mAudioRecord.startRecording(); } - private void initMediaCodec() { - if (DEBUG) - Log.d(TAG, "AACEncodeConsumer-->开始编码音频"); + private void initMediaCodec(){ + if(DEBUG) + Log.d(TAG,"AACEncodeConsumer-->开始编码音频"); MediaCodecInfo mCodecInfo = selectSupportCodec(MIME_TYPE); - if (mCodecInfo == null) { - Log.e(TAG, "编码器不支持" + MIME_TYPE + "类型"); + if(mCodecInfo == null){ + Log.e(TAG,"编码器不支持"+MIME_TYPE+"类型"); return; } - try { + try{ mAudioEncoder = MediaCodec.createByCodecName(mCodecInfo.getName()); - } catch (IOException e) { - Log.e(TAG, "创建编码器失败" + e.getMessage()); + }catch(IOException e){ + Log.e(TAG,"创建编码器失败"+e.getMessage()); e.printStackTrace(); } MediaFormat format = new MediaFormat(); @@ -293,9 +295,9 @@ public class AACEncodeConsumer extends Thread { } private void stopAudioRecord() { - if (DEBUG) - Log.d(TAG, "AACEncodeConsumer-->停止采集音频"); - if (mAudioRecord != null) { + if(DEBUG) + Log.d(TAG,"AACEncodeConsumer-->停止采集音频"); + if(mAudioRecord != null){ mAudioRecord.stop(); mAudioRecord.release(); mAudioRecord = null; @@ -303,9 +305,9 @@ public class AACEncodeConsumer extends Thread { } private void stopMediaCodec() { - if (DEBUG) - Log.d(TAG, "AACEncodeConsumer-->停止编码音频"); - if (mAudioEncoder != null) { + if(DEBUG) + Log.d(TAG,"AACEncodeConsumer-->停止编码音频"); + if(mAudioEncoder != null){ mAudioEncoder.stop(); mAudioEncoder.release(); mAudioEncoder = null; @@ -314,28 +316,28 @@ public class AACEncodeConsumer extends Thread { } // API>=21 - private boolean isLollipop() { + private boolean isLollipop(){ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; } // API<=19 - private boolean isKITKAT() { + private boolean isKITKAT(){ return Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT; } - private long getPTSUs() { - long result = System.nanoTime() / 1000; - if (result < prevPresentationTimes) { - result = (prevPresentationTimes - result) + result; + private long getPTSUs(){ + long result = System.nanoTime()/1000; + if(result < prevPresentationTimes){ + result = (prevPresentationTimes - result ) + result; } return result; } /** * 遍历所有编解码器,返回第一个与指定MIME类型匹配的编码器 - * 判断是否有支持指定mime类型的编码器 - */ - private MediaCodecInfo selectSupportCodec(String mimeType) { + * 判断是否有支持指定mime类型的编码器 + * */ + private MediaCodecInfo selectSupportCodec(String mimeType){ int numCodecs = MediaCodecList.getCodecCount(); for (int i = 0; i < numCodecs; i++) { MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); @@ -365,7 +367,7 @@ public class AACEncodeConsumer extends Thread { } - private short[] transferByte2Short(byte[] data, int readBytes) { + private short[] transferByte2Short(byte[] data,int readBytes){ // byte[] 转 short[],数组长度缩减一半 int shortLen = readBytes / 2; // 将byte[]数组装如ByteBuffer缓冲区 diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java index 8ccd36026a..9310ce1ae4 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java @@ -17,7 +17,9 @@ import java.nio.ByteBuffer; /** * 对YUV视频流进行编码 + * Created by jiangdongguo on 2017/5/6. */ + @SuppressWarnings("deprecation") public class H264EncodeConsumer extends Thread { private static final boolean DEBUG = false; diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java index 1b2fc40c5b..64307af008 100644 --- a/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java @@ -10,9 +10,11 @@ import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; -/** - * Mp4封装混合器 +/**Mp4封装混合器 + * + * Created by jianddongguo on 2017/7/28. */ + public class Mp4MediaMuxer { private static final boolean VERBOSE = false; private static final String TAG = Mp4MediaMuxer.class.getSimpleName(); diff --git a/libraries/map-usbcamera/src/main/java/com/serenegiant/utils/PermissionCheck.java b/libraries/map-usbcamera/src/main/java/com/serenegiant/utils/PermissionCheck.java new file mode 100644 index 0000000000..f3409fb84e --- /dev/null +++ b/libraries/map-usbcamera/src/main/java/com/serenegiant/utils/PermissionCheck.java @@ -0,0 +1,186 @@ +package com.serenegiant.utils; + +import android.Manifest.permission; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PermissionGroupInfo; +import android.net.Uri; +import android.provider.Settings; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public final class PermissionCheck { + + public static final void dumpPermissions(@Nullable final Context context) { + if (context == null) return; + try { + final PackageManager pm = context.getPackageManager(); + final List list = pm.getAllPermissionGroups(PackageManager.GET_META_DATA); + for (final PermissionGroupInfo info : list) { + Log.d("PermissionCheck", info.name); + } + } catch (final Exception e) { + Log.w("", e); + } + } + + /** + * パーミッションを確認 + * @param context + * @param permissionName + * @return 指定したパーミッションがあればtrue + */ + @SuppressLint("NewApi") + public static boolean hasPermission(@Nullable final Context context, final String permissionName) { + if (context == null) return false; + boolean result = false; + try { + final int check; + if (BuildCheck.isMarshmallow()) { + check = context.checkSelfPermission(permissionName); + } else { + final PackageManager pm = context.getPackageManager(); + check = pm.checkPermission(permissionName, context.getPackageName()); + } + switch (check) { + case PackageManager.PERMISSION_DENIED: + break; + case PackageManager.PERMISSION_GRANTED: + result = true; + break; + } + } catch (final Exception e) { + Log.w("", e); + } + return result; + } + + /** + * 録音のミッションがあるかどうかを確認 + * @param context + * @return 録音のパーミッションがあればtrue + */ + public static boolean hasAudio(@Nullable final Context context) { + return hasPermission(context, permission.RECORD_AUDIO); + } + + /** + * ネットワークへのアクセスパーミッションがあるかどうかを確認 + * @param context + * @return ネットワークへのアクセスパーミッションがあればtrue + */ + public static boolean hasNetwork(@Nullable final Context context) { + return hasPermission(context, permission.INTERNET); + } + + /** + * 外部ストレージへの書き込みパーミッションがあるかどうかを確認 + * @param context + * @return 外部ストレージへの書き込みパーミッションがあればtrue + */ + public static boolean hasWriteExternalStorage(@Nullable final Context context) { + return hasPermission(context, permission.WRITE_EXTERNAL_STORAGE); + } + + /** + * 外部ストレージからの読み込みパーミッションがあるかどうかを確認 + * @param context + * @return 外部ストレージへの読み込みパーミッションがあればtrue + */ + @SuppressLint("InlinedApi") + public static boolean hasReadExternalStorage(@Nullable final Context context) { + if (BuildCheck.isAndroid4()) + return hasPermission(context, permission.READ_EXTERNAL_STORAGE); + else + return hasPermission(context, permission.WRITE_EXTERNAL_STORAGE); + } + + /** + * 位置情報アクセスのパーミッションが有るかどうかを確認 + * @param context + * @return + */ + public static boolean hasAccessLocation(@Nullable final Context context) { + return hasPermission(context, permission.ACCESS_COARSE_LOCATION) + && hasPermission(context, permission.ACCESS_FINE_LOCATION); + } + + /** + * 低精度位置情報アクセスのパーミッションが有るかどうかを確認 + * @param context + * @return + */ + public static boolean hasAccessCoarseLocation(@Nullable final Context context) { + return hasPermission(context, permission.ACCESS_COARSE_LOCATION); + } + + /** + * 高精度位置情報アクセスのパーミッションが有るかどうかを確認 + * @param context + * @return + */ + public static boolean hasAccessFineLocation(@Nullable final Context context) { + return hasPermission(context, permission.ACCESS_FINE_LOCATION); + } + + /** + * カメラへアクセス可能かどうか + * @param context + * @return + */ + public static boolean hasCamera(@Nullable final Context context) { + return hasPermission(context, permission.CAMERA); + } + + /** + * アプリの詳細設定へ遷移させる(パーミッションを取得できなかった時など) + * @param context + */ + public static void openSettings(@NonNull final Context context) { + final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + final Uri uri = Uri.fromParts("package", context.getPackageName(), null); + intent.setData(uri); + context.startActivity(intent); + } + + /** + * AndroidManifest.xmlに設定されているはずのパーミッションをチェックする + * @param context + * @param expectations + * @return 空リストなら全てのパーミッションが入っていた, + * @throws IllegalArgumentException + * @throws PackageManager.NameNotFoundException + */ + public static List missingPermissions(@NonNull final Context context, @NonNull final String[] expectations) throws IllegalArgumentException, PackageManager.NameNotFoundException { + return missingPermissions(context, new ArrayList(Arrays.asList(expectations))); + } + + /** + * AndroidManifest.xmlに設定されているはずのパーミッションをチェックする + * @param context + * @param expectations + * @return 空リストなら全てのパーミッションが入っていた, + * @throws IllegalArgumentException + * @throws PackageManager.NameNotFoundException + */ + public static List missingPermissions(@NonNull final Context context, @NonNull final List expectations) throws IllegalArgumentException, PackageManager.NameNotFoundException { + final PackageManager pm = context.getPackageManager(); + final PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS); + final String[] info = pi.requestedPermissions; + if (info != null) { + for (String i : info) { + expectations.remove(i); + } + } + return expectations; + } +} diff --git a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libUVCCamera.so b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libUVCCamera.so index 2c9b394b63..6b4d9fdfc4 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libUVCCamera.so and b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libUVCCamera.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libjpeg-turbo1500.so b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libjpeg-turbo1500.so index 6e7e70e2e0..7965444d8e 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libjpeg-turbo1500.so and b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libjpeg-turbo1500.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libusb100.so b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libusb100.so index 370d63d45a..c27d595219 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libusb100.so and b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libusb100.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libuvc.so b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libuvc.so index 03830b267c..1f2486a5f6 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libuvc.so and b/libraries/map-usbcamera/src/main/jniLibs/arm64-v8a/libuvc.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libUVCCamera.so b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libUVCCamera.so index a07bbbc70f..b6bf9769a5 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libUVCCamera.so and b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libUVCCamera.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libjpeg-turbo1500.so b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libjpeg-turbo1500.so index d1e7b07021..97408c6d46 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libjpeg-turbo1500.so and b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libjpeg-turbo1500.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libusb100.so b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libusb100.so index f0df5b052b..4f2603950e 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libusb100.so and b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libusb100.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libuvc.so b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libuvc.so index 564d932313..ba68f84d05 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libuvc.so and b/libraries/map-usbcamera/src/main/jniLibs/armeabi-v7a/libuvc.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86/libUVCCamera.so b/libraries/map-usbcamera/src/main/jniLibs/x86/libUVCCamera.so index 7cb48799f9..df770e4e3a 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86/libUVCCamera.so and b/libraries/map-usbcamera/src/main/jniLibs/x86/libUVCCamera.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86/libjpeg-turbo1500.so b/libraries/map-usbcamera/src/main/jniLibs/x86/libjpeg-turbo1500.so index ce788243ba..d4b67c637c 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86/libjpeg-turbo1500.so and b/libraries/map-usbcamera/src/main/jniLibs/x86/libjpeg-turbo1500.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86/libusb100.so b/libraries/map-usbcamera/src/main/jniLibs/x86/libusb100.so index 6b771d31ae..59d8f256cb 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86/libusb100.so and b/libraries/map-usbcamera/src/main/jniLibs/x86/libusb100.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86/libuvc.so b/libraries/map-usbcamera/src/main/jniLibs/x86/libuvc.so index deba66615e..fdf4318185 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86/libuvc.so and b/libraries/map-usbcamera/src/main/jniLibs/x86/libuvc.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libUVCCamera.so b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libUVCCamera.so index 33057578d1..4c1ea8ab15 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libUVCCamera.so and b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libUVCCamera.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libjpeg-turbo1500.so b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libjpeg-turbo1500.so index 36b3f76a58..ee0ff7afe8 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libjpeg-turbo1500.so and b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libjpeg-turbo1500.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libusb100.so b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libusb100.so index 05431ef82d..0c7cf3a9ae 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libusb100.so and b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libusb100.so differ diff --git a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libuvc.so b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libuvc.so index 0b37d34a94..1c4eb3ecb8 100644 Binary files a/libraries/map-usbcamera/src/main/jniLibs/x86_64/libuvc.so and b/libraries/map-usbcamera/src/main/jniLibs/x86_64/libuvc.so differ diff --git a/libraries/map-usbcamera/src/main/res/values/strings_permissions.xml b/libraries/map-usbcamera/src/main/res/values/strings_permissions.xml new file mode 100644 index 0000000000..9d7e54bfd7 --- /dev/null +++ b/libraries/map-usbcamera/src/main/res/values/strings_permissions.xml @@ -0,0 +1,32 @@ + + + Regarding permission + + No audio recording permission. \nAll audio function is disabled + Audio recording permission is necessary for movie capture with audio. + Audio recording permission is necessary for movie capture with audio. + Audio recording permission is necessary for streaming with audio. + Audio recording permission is necessary for streaming with audio. + + No permission of writing external storage. \nMovie/still image capturing are disabled. + Permission of writing external storage is necessary for movie/still image capturing. + Permission of writing external storage is necessary for movie/still image capturing. + No writing external storage permission. \nApp will finish soon + + No network access permission. + Network access permission is necessary for streaming. + Network access permission is necessary for streaming. + No network access permission. \nApp will finish soon + + No location access permission + Location access permission is necessary for %s + Location access permission is necessary for %s + No location access permission. \nApp will finish soon + + No camera access permission + No camera access permission. \nApp will finish soon + Camera access permission is necessary for fallback to built in camera. + Camera access permission is necessary for fallback to built in camera. + + Permission to access phone state/hardware id necessary for calling. + \ No newline at end of file diff --git a/libraries/mogo-adas/.gitignore b/libraries/mogo-adas/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/libraries/mogo-adas/.gitignore @@ -0,0 +1 @@ +/build diff --git a/libraries/mogo-adas/README.md b/libraries/mogo-adas/README.md new file mode 100644 index 0000000000..d8f81fc2da --- /dev/null +++ b/libraries/mogo-adas/README.md @@ -0,0 +1,14 @@ +#### 说明 +# ADAS LIB +## 与工控机交互LIB +RSA密钥 +privateBase64=MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA127FFvuPolaxYTBg5wkyDIrEbcNKXoIjf0bK7QUQ991Lsbv5Ktv/XM2F6qJFssVF1KTkStVBSQGxJB1eZLwJEwIDAQABAkBM39AgpV/Z1Amz3qmVh+h+JT521ItDMjksf7yF25r0dzGjOfGLQmMAqQXT68B+cQX5HSoFMwk/rE1hnXgifyNBAiEA6uNE2TfPj51mPOZztGy1Q8p4exWohfotiy64g/CyVeMCIQDqy9e7bGeZEi6p1zemEgFVtwgZZvLn/BOP4UO7NjJnEQIhAJBnprUwha/SYb+BIpNC3fHOcWGigBfWJdfSomejO9BnAiEApfojLqKbOWHZCsbQ19yyhN02JH7aB5PyYCtlrdnKF4ECIHR1P2LOQLddXO8PwgoF6gtCTO2sxIqdvu8fUruWyouQ +publicBase64=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANduxRb7j6JWsWEwYOcJMgyKxG3DSl6CI39Gyu0FEPfdS7G7+Srb/1zNheqiRbLFRdSk5ErVQUkBsSQdXmS8CRMCAwEAAQ== + +工控机SSH +账号:titan +密码:mogo@ZHIDAO10 + +加密后的密码:Lz71dnr3eEbcXbuRqSBuLPTk9N7vfqL1lkV1FvAzrLE45OslTvAmm0ekjXIuvOz3jw4hh/saV5pxc3ywNubnjQ== + + diff --git a/libraries/mogo-adas/build.gradle b/libraries/mogo-adas/build.gradle new file mode 100644 index 0000000000..0b151aaf9f --- /dev/null +++ b/libraries/mogo-adas/build.gradle @@ -0,0 +1,114 @@ +plugins { + id 'com.android.library' + id 'com.google.protobuf' +// id 'maven' +} +ext { + //自动驾驶产品版本号 + AP_VERSION = "2.2.1" +} +android { + compileSdkVersion rootProject.ext.android.compileSdkVersion + // buildToolsVersion rootProject.ext.android.buildToolsVersion + + + defaultConfig { + minSdkVersion rootProject.ext.android.minSdkVersion + targetSdkVersion rootProject.ext.android.targetSdkVersion + versionCode Integer.valueOf(VERSION_CODE) + def name = getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") + versionName name +// buildConfigField "String", "VERSION_NAME", "\"${name}\"" + buildConfigField "String", "AP_VERSION", "\"${AP_VERSION}\"" + + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + sourceSets { + main { + java { + srcDir 'src/main/java' + } + + proto { + srcDir 'src/main/proto' + include '**/*.proto' + } + } + } + + protobuf { + protoc { + artifact = 'com.google.protobuf:protoc:3.6.1:osx-x86_64' + } + + generateProtoTasks { + all().each { task -> + task.builtins { + remove java + } + task.builtins { + java {} + } + } + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation rootProject.ext.dependencies.mogochainbase + //okhttp3的依赖 + implementation 'com.squareup.okhttp3:okhttp:3.12.3' + // parser + implementation rootProject.ext.dependencies.gson + // logger + //implementation 'com.orhanobut:logger:2.2.0' + //ProtoBuf + implementation 'com.google.protobuf:protobuf-java:3.6.1' + implementation 'com.google.protobuf:protoc:3.6.1' + implementation 'com.google.protobuf:protobuf-java-util:3.6.1' + implementation 'com.jcraft:jsch:0.1.55' +// api project(path: ':lib_recorder') + api "com.zhidao.support.recorder:recorder:1.0.0.3" + + if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { + implementation rootProject.ext.dependencies.mogo_core_data + } else { + implementation project(':core:mogo-core-data') + } +} + +//task androidSourcesJar(type: Jar) { +// classifier = 'sources' +// from android.sourceSets.main.java.srcDirs +//} +////配置需要上传到maven仓库的文件 +//artifacts { +// archives androidSourcesJar +//} +// +//uploadArchives { +// repositories.mavenDeployer { +// repository(url: RELEASE_REPO_URL) { +// authentication(userName: NAME, password: PASSWORD) +// } +// snapshotRepository(url: SNAPSHOT_REPOSITORY_URL) { +// authentication(userName: NAME, password: PASSWORD) +// } +// pom.groupId = GROUP +// pom.artifactId = POM_ARTIFACT_ID +// pom.version = VERSION +// } +//} \ No newline at end of file diff --git a/libraries/mogo-adas/consumer-rules.pro b/libraries/mogo-adas/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libraries/mogo-adas/gradle.properties b/libraries/mogo-adas/gradle.properties new file mode 100644 index 0000000000..0d60ce4aee --- /dev/null +++ b/libraries/mogo-adas/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.adas +POM_ARTIFACT_ID=mogo-adas +VERSION_CODE=1 \ No newline at end of file diff --git a/libraries/mogo-adas/proguard-rules.pro b/libraries/mogo-adas/proguard-rules.pro new file mode 100644 index 0000000000..f10712073b --- /dev/null +++ b/libraries/mogo-adas/proguard-rules.pro @@ -0,0 +1,26 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile + +#-----MogoMap----- +-keep class com.mogo.map.MogoNavi{ + private (); +} diff --git a/libraries/mogo-adas/src/main/AndroidManifest.xml b/libraries/mogo-adas/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..d0a6ae62d1 --- /dev/null +++ b/libraries/mogo-adas/src/main/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java new file mode 100644 index 0000000000..d8226d09c3 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java @@ -0,0 +1,791 @@ +package com.zhidao.support.adas.high; + +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_UDP_CONNECT_ADDRESS; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_ADAS; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS; +import static com.zhidao.support.adas.high.common.ActionTypeReceive.ACTION_WS_AUTOPILOT_CONTROL; +import static com.zhidao.support.adas.high.udp.CupidUdpConstract.VIDEO_RENDER_IMAGE_UDP; + +import android.content.Context; +import android.text.TextUtils; + +import com.google.gson.Gson; +import com.google.protobuf.InvalidProtocolBufferException; +import com.zhidao.support.adas.high.bean.AdasConfig; +import com.zhidao.support.adas.high.bean.AutopilotControl; +import com.zhidao.support.adas.high.bean.AutopilotSpeedParam; +import com.zhidao.support.adas.high.bean.BaseInfo; +import com.zhidao.support.adas.high.bean.BasicInfo; +import com.zhidao.support.adas.high.bean.ConfigInfo; +import com.zhidao.support.adas.high.bean.DemoModeInfo; +import com.zhidao.support.adas.high.bean.FaceLoginResponse; +import com.zhidao.support.adas.high.bean.MapLocationInfo; +import com.zhidao.support.adas.high.bean.SSHResult; +import com.zhidao.support.adas.high.bean.record.RecordCauseParam; +import com.zhidao.support.adas.high.bean.record.RecordDataParam; +import com.zhidao.support.adas.high.common.ActionTypeReceive; +import com.zhidao.support.adas.high.common.AppPreferenceHelper; +import com.zhidao.support.adas.high.common.Base64; +import com.zhidao.support.adas.high.common.Constants; +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.common.MgContextUtils; +import com.zhidao.support.adas.high.common.RSATool; +import com.zhidao.support.adas.high.common.SSH; +import com.zhidao.support.adas.high.common.ThreadPoolManager; +import com.zhidao.support.adas.high.msg.MyMessageFactory; +import com.zhidao.support.adas.high.queue.UdpQueueManager; +import com.zhidao.support.adas.high.queue.WSByteQueueManager; +import com.zhidao.support.adas.high.queue.WebSocketQueueManager; +import com.zhidao.support.adas.high.socket.FpgaSocket; +import com.zhidao.support.adas.high.socket.read.OriginReadData; +import com.zhidao.support.adas.high.socket.read.SocketReader; +import com.zhidao.support.adas.high.udp.CupidUdpConstract; +import com.zhidao.support.adas.high.udp.IConnectRtpListener; +import com.zhidao.support.adas.high.udp.IGetH264Data; +import com.zhjt.service.chain.ChainLog; +import com.zhjt.service.chain.TracingConstants; + +import org.json.JSONObject; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import mogo.webproto.WebsocketHeader; +import okhttp3.WebSocket; +import okio.ByteString; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high + * @ClassName: AdasChannel + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/7 13:32 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/7 13:32 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnectListener, IConnectRtpListener, IGetH264Data { + private static final String TAG = AdasChannel.class.getSimpleName(); + + private FpgaSocket mSocket; + private SocketReader socketReader; + private JSONObject jsonObject; + /** + * udp server + */ + private CupidUdpConstract udpConstract; + + /** + * ============是否运行 + */ + private volatile boolean isRunning; + private volatile boolean isConnected; + private volatile boolean flag = false; + + private JSONObject location; + //是否使用队列处理数据 + public static final boolean isUseQueue = false; + //录包信息 + private RecordDataParam recordDataParam = null; + /** + * 配置信息同步接口只调用一次 + */ + private List configInfo; + /** + * 序列化rect + */ + private Gson gson; + /** + * 消息工厂 + */ + private MyMessageFactory myMessageFactory; + private AutopilotSpeedParam speedParam; + /** + * 工控机IP + */ + private String ipcIp; + private RecordCauseParam recordCauseParam; + private SSH ssh; + /** + * 是否是客户端 + */ + private boolean isClient = true; + private OnMultiDeviceListener onMultiDeviceListener; + + public void setOnMultiDeviceListener(OnMultiDeviceListener onMultiDeviceListener) { + this.onMultiDeviceListener = onMultiDeviceListener; + } + + @Override + public void setIPCIp(String ipcIp) { + this.ipcIp = ipcIp; + } + + AdasChannel(Context context, AdasOptions options) { + initData(context); + if (options != null) { + this.isClient = options.isClient(); + this.ipcIp = options.getIpcIp(); + } + if (!isClient) { + initSocket(); + if (TextUtils.isEmpty(ipcIp)) + initUdpServer(); + } + } + + private void initData(Context context) { + //原始数据解析类 + socketReader = new SocketReader(); + MgContextUtils.setContext(context.getApplicationContext()); + //消息工厂 + myMessageFactory = new MyMessageFactory(); + FaceLoginResponse.DataBean dataBean = AppPreferenceHelper.getInstance(context).getUserInfo(); + if (dataBean != null) { + configInfo = dataBean.getConfigInfoHistory(); + } + jsonObject = new JSONObject(); + location = new JSONObject(); + if (gson == null) { + gson = new Gson(); + } + } + + /** + * 初始化udp + */ + private void initUdpServer() { + if (isUseQueue) { + UdpQueueManager.getInstance().registerAdasChannel(this); + UdpQueueManager.getInstance().initDector(); + } + udpConstract = new CupidUdpConstract(VIDEO_RENDER_IMAGE_UDP); + udpConstract.setOnReceiverH264Data(this); + udpConstract.setOnConnectListener(this); + isRunning = true; + if (gson == null) { + gson = new Gson(); + } + } + + private void initSocket() { + mSocket = new FpgaSocket(); + mSocket.setWebSocketListener(this); + if (isUseQueue) { + WebSocketQueueManager.getInstance().registerWebSocketListener(this); + WebSocketQueueManager.getInstance().initDector(); + WSByteQueueManager.getInstance().registerWebSocketListener(this); + WSByteQueueManager.getInstance().initDector(); + } + //TODO 写死IP + if (!TextUtils.isEmpty(ipcIp)) { + isRunning = true; + getOnConnectionAddress(ipcIp); + } + } + +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_CONNECT_STATUS, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_UDP_CONNECT_ADDRESS, +// paramIndexes = {0}, +// clientPkFileName = "sn") + private void connectSocket(String address) { + if (mSocket != null) + mSocket.connectWebSocket(address); + } + + public void closeSocket() { + if (mSocket != null) + mSocket.closeWebSocket(); + } + + public void sendLocation(MapLocationInfo mapLocationInfo) { + if (!isConnected) { + return; + } + CupidLogUtils.e(mapLocationInfo.toString()); + //locationType + /* + TODO + 一次过滤: + mAMapLocation.getLocationType(); //通过以上方法获取定位类型,如果对定位类型要求比较高,可以过滤掉基站定位(类型6)结果。 + 二次过滤: + mAMapLocation. getAccuracy(); //通过以上方法获取定位精度,例如超过500M精度的定位结果可以考虑不在业务场景里使用。 + 6 基站定位结果 纯粹依赖移动、联通、电信等移动网络定位,定位精度在500米-5000米之间。 + 5 Wifi定位结果 属于网络定位,定位精度相对基站定位会更好,定位精度较高,在5米-200米之间。 + 4 缓存定位结果 返回一段时间前设备在同样的位置缓存下来的网络定位结果 + 1 GPS定位结果 通过设备GPS定位模块返回的定位结果,精度较高,在10米-100米左右 + */ + //纬度 + double currentLat = mapLocationInfo.getLatitude(); + //经度 + double currentLng = mapLocationInfo.getLongitude(); + //瞬时速度 m/s + float speed = mapLocationInfo.getSpeed(); + /*if (BuildConfig.DEBUG) { + speed = 60.0f; + }*/ + try { + //位置信息 action是2 + jsonObject.put("action", ActionTypeReceive.ACTION_WS_GPS_TYPE.getmActionType()); + location.put("latitude", currentLat + ""); + location.put("longitude", currentLng + ""); + location.put("speed", speed + ""); + location.put("bearing", mapLocationInfo.getBearing() + ""); + jsonObject.put("location", location); + + sendWsMessage(jsonObject.toString()); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 基础信息 + * + * @param basicInfo + */ + public void sendWsBasicInfo(BasicInfo basicInfo) { + if (basicInfo == null) { + return; + } + String msg = gson.toJson(basicInfo); + sendWsMessage(msg); + } + + /** + * 向工控机发送数据 + * + * @param info + */ + @Override + public void sendBaseInfo(BaseInfo info) { + if (info == null) { + return; + } + String msg = gson.toJson(info); + sendWsMessage(msg); + } + + private void sendIPCCmd(final String cmd) { + if (ssh == null) { +// String ip = ipcIp; + if (TextUtils.isEmpty(ipcIp)) { + //尝试从缓存中获取工控机IP +// String ip = AppPreferenceHelper.getInstance(MgContextUtils.getContext()).getUdpClientAddress(); +// if (TextUtils.isEmpty(ip)) { + if (mAdasListener != null) { + mAdasListener.onSSHResult(new SSHResult(SSHResult.RESULT_CODE.IP_UNKNOWN, cmd, "IPC IP未知")); + } + return; +// } + } + ThreadPoolManager.getsInstance().execute(new Runnable() { + @Override + public void run() { + ssh = new SSH(); + String encodePwd = "Lz71dnr3eEbcXbuRqSBuLPTk9N7vfqL1lkV1FvAzrLE45OslTvAmm0ekjXIuvOz3jw4hh/saV5pxc3ywNubnjQ=="; + String privateKey = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA127FFvuPolaxYTBg5wkyDIrEbcNKXoIjf0bK7QUQ991Lsbv5Ktv/XM2F6qJFssVF1KTkStVBSQGxJB1eZLwJEwIDAQABAkBM39AgpV/Z1Amz3qmVh+h+JT521ItDMjksf7yF25r0dzGjOfGLQmMAqQXT68B+cQX5HSoFMwk/rE1hnXgifyNBAiEA6uNE2TfPj51mPOZztGy1Q8p4exWohfotiy64g/CyVeMCIQDqy9e7bGeZEi6p1zemEgFVtwgZZvLn/BOP4UO7NjJnEQIhAJBnprUwha/SYb+BIpNC3fHOcWGigBfWJdfSomejO9BnAiEApfojLqKbOWHZCsbQ19yyhN02JH7aB5PyYCtlrdnKF4ECIHR1P2LOQLddXO8PwgoF6gtCTO2sxIqdvu8fUruWyouQ"; + try { + String pwd = RSATool.decodeByPrivateKey(encodePwd, Base64.decodeBase64(privateKey)); + ssh.connect(ipcIp, 22, "titan", pwd); + SSHResult result = ssh.exec(cmd, pwd); + if (mAdasListener != null) + mAdasListener.onSSHResult(result); + } catch (Exception e) { + if (mAdasListener != null) + mAdasListener.onSSHResult(new SSHResult(SSHResult.RESULT_CODE.ERROR, cmd, e.getMessage())); + e.printStackTrace(); + } + ssh.disConnect(); + ssh = null; + } + }); + } + } + + @Override + public void shutdownIPC() { + sendIPCCmd("sudo -S shutdown -h now"); + } + + @Override + public void rebootIPC() { + sendIPCCmd("sudo -S reboot"); + } + + @Override + public void rebootAPDocker() { + sendIPCCmd("docker restart autocar_default_1"); + } + + @Override + public boolean isClient() { + return isClient; + } + + @Override + public void enableDemoMode() { + sendBaseInfo(DemoModeInfo.enable()); + } + + @Override + public void disableDemoMode() { + sendBaseInfo(DemoModeInfo.disable()); + } + + /** + * 配置信息 + * + * @param configInfo + */ + public void sendWsConfigMessage(ConfigInfo configInfo) { + if (configInfo == null) { + return; + } + String msg = gson.toJson(configInfo); + sendWsMessage(msg); + } + + /** + * 发送ws消息 + * + * @param msg 消息 + */ + public boolean sendWsMessage(String msg) { + return mSocket != null && mSocket.sendDataWebSocket(msg); + } + + /** + * 线程标志 + */ + public void onResume() { + CupidLogUtils.e(TAG, "===>onResume isRunning===>" + isRunning); + if (!isRunning) { + isRunning = true; + if (TextUtils.isEmpty(ipcIp)) { + initUdpServer(); + } else { + getOnConnectionAddress(ipcIp); + } + } + } + + /** + * 暂停 + */ + public void onPause() { + isRunning = false; + if (udpConstract != null) + udpConstract.release(); + if (isUseQueue) { + UdpQueueManager.getInstance().release(); + } + } + + public void onDestory() { + onPause(); + if (mSocket != null) + mSocket.closeWebSocket(); + if (configInfo != null) { + configInfo.clear(); + configInfo = null; + } + if (location != null) { + location = null; + } + if (jsonObject != null) { + jsonObject = null; + } + } + + /** + * 重置buffer + */ + public void resetBuffer() { + if (udpConstract != null) { + udpConstract.resetBuffer(); + } + } + + /** + * 初始化webSocket + */ + public void setUdpIsFirstInit() { + if (udpConstract != null) + udpConstract.setUdpIsFirstInit(); + } + + /** + * 处理webSocket text数据 + * + * @param text + */ + private void handlerWSMsg(String text) { + try { + JSONObject jsonObjectWs = new JSONObject(text); + String action = jsonObjectWs.optString("action"); + if (TextUtils.isEmpty(action)) { + CupidLogUtils.w("--->action is null"); + return; + } + myMessageFactory.createMessage(action).handlerMsg(gson, mAdasListener, text); + } catch (Exception e) { + e.printStackTrace(); + } + // TODO 临时接续Json数据传递添加的Header 0x00表示PB数据 0x01表示Json数据 + if (!isClient && onMultiDeviceListener != null) { + byte[] bytes = text.getBytes(StandardCharsets.UTF_8); + byte[] temp = new byte[bytes.length + 1]; + System.arraycopy(bytes, 0, temp, 1, bytes.length); + temp[0] = 0x01; + onMultiDeviceListener.onForwardingIPCMessage(temp); + } + + } + + /** + * 解析工控机发送过来PB的数据 + * + * @param bytes 数据 + */ + @Override + public void parseIPCData(byte[] bytes) { + if (bytes == null || bytes.length == 0) { + return; + } + //TODO 临时将Json数据转发并解析 0x00表示PB数据 0x01表示Json数据 + if (isClient) { + byte header = bytes[0]; + byte[] temp = new byte[bytes.length - 1]; + System.arraycopy(bytes, 1, temp, 0, temp.length); + bytes = temp; + if (header != 0x00) { + //Json 解析 + handlerWSMsg(new String(bytes, StandardCharsets.UTF_8)); + return; + } + } + //PB解析 + ByteString byteString = ByteString.of(bytes); + try { + if (socketReader != null) { + OriginReadData read = socketReader.read(byteString); + if (read == null) { + //read 解析为空 默认解析view + CupidLogUtils.w("--->websocket byte read null, analysis view"); + myMessageFactory.createMessage(0x101).handlerMsg(gson, mAdasListener, bytes); + return; + } + WebsocketHeader.Header_websock header = WebsocketHeader.Header_websock.parseFrom(read.getHeader()); + int headerType = header.getMsgType(); + CupidLogUtils.w("--->websocket byte read header = " + headerType); + myMessageFactory.createMessage(headerType).handlerMsg(gson, mAdasListener, read.getPayload()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void handlerWSMsg(ByteString bytes) { + byte[] bytes1 = bytes.toByteArray(); + parseIPCData(bytes1); + if (!isClient && onMultiDeviceListener != null) { + // TODO 临时接续Json数据传递添加的Header 0x00表示PB数据 0x01表示Json数据 + byte[] temp = new byte[bytes1.length + 1]; + System.arraycopy(bytes1, 0, temp, 1, bytes1.length); + temp[0] = 0x00; + onMultiDeviceListener.onForwardingIPCMessage(temp); + } + } + + + @Override + public void onWebSocketConnectSuccess(WebSocket webSocket) { + isConnected = true; + CupidLogUtils.e("--->onWebSocketConnectSuccess"); + if (mAdasMsgConnectStatusListener != null) { + mAdasMsgConnectStatusListener.onWebSocketConnectSuccess(); + queryCarConfig(); + } + } + + @Override + public void onWebSocketConnectFailed(WebSocket webSocket, String t) { + isConnected = false; + CupidLogUtils.e("--->onWebSocketConnectFailed"); + setUdpIsFirstInit(); + if (mAdasMsgConnectStatusListener != null) { + mAdasMsgConnectStatusListener.onWebSocketConnectFailed(t); + } + } + + @Override + public void onMessage(String message) { + handlerWSMsg(message); + } + + @Override + public void onMessage(ByteString bytes) throws InvalidProtocolBufferException { + handlerWSMsg(bytes); + } + + @Override + public void onConnectionSuccessRtp() { + CupidLogUtils.e(TAG, "--->onConnectionSuccessRtp"); + } + + @Override + public void onConnectionFailedRtp(String reason) { + CupidLogUtils.e(TAG, "--->onConnectionFailedRtp:" + reason); + // TODO 暂时注释 测试完成添加 +// closeSocket(); + setUdpIsFirstInit(); + /*if (mRenderImageListener != null) { + mRenderImageListener.onConnectionFailedRtp(reason); + }*/ + } + + @Override + public void getOnConnectionAddress(String address) { + ipcIp = address; + CupidLogUtils.e(TAG, "--->getOnConnectionAddress" + address); + AppPreferenceHelper.getInstance(MgContextUtils.getContext()).saveUdpClientAddress(address); + connectSocket(address); + if (flag) { + flag = false; + if (configInfo != null && configInfo.size() > 0) { + if (isConnected) { + if (mSocket != null) + mSocket.doConfigChanged(configInfo); + } + } + } + + } + + @Override + public void onDisconnectRtp() { + CupidLogUtils.e(TAG, "--->onDisconnectRtp"); + setUdpIsFirstInit(); + } + + @Override + public void getH264Data(byte[] data, long receiverDataTimeUdp) { + //处理数据 + String content = new String(data).trim(); + CupidLogUtils.e("--->udp数据回调:" + content); + if (isUseQueue) { + UdpQueueManager.getInstance().addQueueData(content); + } else { + udpDataManage(content); + } + } + + /** + * 处理udp数据 + * + * @param content + */ + public void udpDataManage(String content) { + if (!TextUtils.isEmpty(content)) { + if (gson == null) { + gson = new Gson(); + } + try { + JSONObject jsonObject = new JSONObject(content); + String udpRenderAction = jsonObject.getString("action"); + if (!TextUtils.isEmpty(udpRenderAction)) { + //udp消息处理 + myMessageFactory.createMessage(udpRenderAction).handlerMsg(gson, mAdasListener, content); + } + } catch (Exception e) { + CupidLogUtils.e("--->json数据解析异常-换用protoBuf:" + e.toString()); + myMessageFactory.createMessage("view").handlerMsg(gson, mAdasListener, content); + e.printStackTrace(); + } + } + } + + private OnAdasListener mAdasListener; + //连接状态listener + private OnAdasMsgConnectStatusListener mAdasMsgConnectStatusListener; + + void setOnAdasListener(OnAdasListener adasListener) { + mAdasListener = adasListener; + } + + void setOnAdasMsgConnectStatusListener(OnAdasMsgConnectStatusListener adasMsgConnectStatusListener) { + mAdasMsgConnectStatusListener = adasMsgConnectStatusListener; + } + + @Override + public boolean controlAutopilotCarAuto() { + AutopilotControl autopilotControl = new AutopilotControl(); + autopilotControl.setAction(ACTION_WS_AUTOPILOT_CONTROL.getmActionType()); + AutopilotControl.ValuesBean autopilotControlValues = new AutopilotControl.ValuesBean(); + autopilotControlValues.setMode(1); + autopilotControl.setValues(autopilotControlValues); + return sendWsMessage(gson.toJson(autopilotControl)); + } + + @Override + public boolean controlAutopilotCarHead() { + AutopilotControl autopilotControl = new AutopilotControl(); + autopilotControl.setAction(ACTION_WS_AUTOPILOT_CONTROL.getmActionType()); + AutopilotControl.ValuesBean autopilotControlValues = new AutopilotControl.ValuesBean(); + autopilotControlValues.setMode(0); + autopilotControl.setValues(autopilotControlValues); + return sendWsMessage(gson.toJson(autopilotControl)); + } + + @Override + public boolean isSocketConnect() { + return mSocket != null && mSocket.getWebSocket() != null; + } + + @Override + public AdasConfig getAdasConfig() { + String address = AppPreferenceHelper.getInstance(MgContextUtils.getContext()).getUdpClientAddress(); + String dockConfig = AppPreferenceHelper.getInstance(MgContextUtils.getContext()).getDockConfig(); + if (TextUtils.isEmpty(dockConfig)) { + queryCarConfig(); + } + AdasConfig adasConfig = new AdasConfig(); + adasConfig.setAddress(address); + adasConfig.setDockVersion(dockConfig); + return adasConfig; + } + + /** + * 查询config信息 + */ + private void queryCarConfig() { + sendWsMessage(Constants.QUERY_CAR_CONFIG); + } + + @Override + public boolean aiCloudToAdasData(String msg) { + //位置信息 action是aiCloudToStartAutopilot + if (!TextUtils.isEmpty(msg)) { + return sendWsMessage(msg); + } + return false; + } + + @Override + public boolean queryAutopilotRoute() { + //查询自动驾驶路径 + return sendWsMessage(Constants.QUERY_GLOBAL_PATH); + } + + @Override + public boolean queryAutopilotGuardian() { + //查询节点信息 + return sendWsMessage(Constants.QUERY_GUARDIAN); + } + + @Override + public boolean recordPackage(int type, int id) { + return recordBag(true, type, id, 0); + } + + @Override + public boolean recordPackage(int type, int id, int duration) { + return recordBag(true, type, id, duration); + } + + @Override + public boolean stopRecord(int type, int id) { + return recordBag(false, type, id, 0); + } + + @Override + public boolean recordCause(String key, String name, String id, String reason) { + if (recordCauseParam == null) { + recordCauseParam = new RecordCauseParam(); + } + RecordCauseParam.Result result = new RecordCauseParam.Result(); + result.setKey(key); + result.setFilename(name); + result.setReason(reason); + result.setId(id); + recordCauseParam.setResult(result); + return sendWsMessage(gson.toJson(recordCauseParam)); + } + + @Override + public boolean setSpeed(int speed) { + if (speedParam == null) { + speedParam = new AutopilotSpeedParam(); + } + speedParam.setSpeed(speed); + String speedJson = gson.toJson(speedParam); + return sendWsMessage(speedJson); + } +// TODO 需求暂停 待讨论 +// @Override +// public boolean getRoutes() { +// return sendWsMessage(Constants.QUERY_ROUTES); +// } + + /** + * 主动录制Bag包 + * + * @param isRecord + * @param type + * @param id + * @param duration + * @return + */ + private boolean recordBag(boolean isRecord, int type, int id, int duration) { + if (recordDataParam == null) { + recordDataParam = new RecordDataParam(); + } + RecordDataParam.Result result = new RecordDataParam.Result(); + result.setIsRecord(isRecord); + result.setType(type); + result.setId(id); + if (isRecord == true) { + if (duration > 0) { + result.setSustain(false); + result.setDuration(duration); + } else { + result.setSustain(true); + } + } + recordDataParam.setResult(result); + String param = gson.toJson(recordDataParam); + return sendWsMessage(param); + + } + + /** + * 接管原因 + */ + + + /** + * log是否显示 + * + * @param isEnableLog + */ + public void setEnableLog(boolean isEnableLog) { + CupidLogUtils.setEnableLog(isEnableLog); + } + + /** + * log是否写入本地 + * + * @param isWriteLog + */ + public void setIsWriteLog(boolean isWriteLog) { + CupidLogUtils.setIsWriteLog(isWriteLog); + } + +} + diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java new file mode 100644 index 0000000000..114ed5062a --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java @@ -0,0 +1,350 @@ +package com.zhidao.support.adas.high; + +import android.content.Context; + +import com.zhidao.support.adas.high.bean.AdasConfig; +import com.zhidao.support.adas.high.bean.BaseInfo; +import com.zhidao.support.adas.high.bean.BasicInfo; +import com.zhidao.support.adas.high.bean.ConfigInfo; +import com.zhidao.support.adas.high.bean.MapLocationInfo; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high + * @ClassName: AdasManager + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/7 13:13 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/7 13:13 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public class AdasManager implements IAdasNetCommApi { + private static volatile AdasManager ourInstance; + + public void init(Context context) { + //登录信息,空默认配置 + + } + + public static AdasManager getInstance() { + if (ourInstance == null) { + synchronized (AdasManager.class) { + if (ourInstance == null) { + ourInstance = new AdasManager(); + } + } + } + return ourInstance; + } + + private AdasChannel mChannel; + + private AdasManager() { + + } + + public void setOnMultiDeviceListener(OnMultiDeviceListener l) { + if (mChannel != null) { + mChannel.setOnMultiDeviceListener(l); + } + } + + public void setOnAdasListener(OnAdasListener l) { + if (mChannel != null) { + mChannel.setOnAdasListener(l); + } + } + + /** + * 获取 adas 连接状态 + * + * @param onAdasConnectStatusListener + */ + public void setOnAdasConnectStatusListener(OnAdasMsgConnectStatusListener onAdasConnectStatusListener) { + if (mChannel != null) { + mChannel.setOnAdasMsgConnectStatusListener(onAdasConnectStatusListener); + } + } + + public synchronized void create(Context context, AdasOptions options) { + if (mChannel == null) { + mChannel = new AdasChannel(context, options); + } + } + + + public void pause() { + if (mChannel != null) { + mChannel.onPause(); + } + } + + public void resume() { + if (mChannel != null) { + mChannel.onResume(); + } + } + + public synchronized void destory() { + if (mChannel != null) { + mChannel.onDisconnectRtp(); + mChannel.onPause(); + mChannel.onDestory(); + mChannel = null; + } + } + + /** + * 发送速度信息 + * + * @param mapLocationInfo + */ + public void sendMapLocation(MapLocationInfo mapLocationInfo) { + if (mChannel != null) { + mChannel.sendLocation(mapLocationInfo); + } + } + + /** + * 发送信息 + * + * @param msg + */ + public void sendMessage(String msg) { + if (mChannel != null) { + mChannel.sendWsMessage(msg); + } + } + + /** + * 发送基础信息 + * + * @param basicInfo + */ + public void setBasicInfo(BasicInfo basicInfo) { + if (mChannel != null) { + mChannel.sendWsBasicInfo(basicInfo); + } + } + + /** + * 发送配置信息 + * + * @param configMsg + */ + public void setConfigMsg(ConfigInfo configMsg) { + if (mChannel != null) { + mChannel.sendWsConfigMessage(configMsg); + } + } + + /** + * 关闭socket连接 + */ + public void closeSocket() { + if (mChannel != null) { + mChannel.closeSocket(); + } + } + + /** + * 关闭所有通信 + */ + public void closeAllMsg() { + if (mChannel != null) { + mChannel.closeSocket(); + } + pause(); + } + + /** + * 启动所有的通信 + */ + public void startAllMsg() { + resume(); + } + + + @Override + public boolean controlAutopilotCarAuto() { + if (mChannel != null) { + return mChannel.controlAutopilotCarAuto(); + } + return false; + } + + @Override + public boolean controlAutopilotCarHead() { + if (mChannel != null) { + return mChannel.controlAutopilotCarHead(); + } + return false; + } + + @Override + public boolean isSocketConnect() { + if (mChannel != null) { + return mChannel.isSocketConnect(); + } + return false; + } + + @Override + public AdasConfig getAdasConfig() { + if (mChannel != null) { + return mChannel.getAdasConfig(); + } + return null; + } + + @Override + public boolean aiCloudToAdasData(String msg) { + if (mChannel != null) { + return mChannel.aiCloudToAdasData(msg); + } + return false; + } + + @Override + public boolean queryAutopilotRoute() { + if (mChannel != null) { + return mChannel.queryAutopilotRoute(); + } + return false; + } + + @Override + public boolean queryAutopilotGuardian() { + if (mChannel != null) { + return mChannel.queryAutopilotGuardian(); + } + return false; + } + + @Override + public boolean recordPackage(int type, int id) { + if (mChannel != null) { + return mChannel.recordPackage(type, id); + } + return false; + } + + @Override + public boolean recordPackage(int type, int id, int duration) { + if (mChannel != null) { + return mChannel.recordPackage(type, id, duration); + } + return false; + } + + @Override + public boolean stopRecord(int type, int id) { + if (mChannel != null) { + return mChannel.stopRecord(type, id); + } + return false; + } + + @Override + public boolean recordCause(String key, String name, String id, String reason) { + return mChannel.recordCause(key, name, id, reason); + } + + @Override + public boolean setSpeed(int speed) { + if (mChannel != null) { + return mChannel.setSpeed(speed); + } + return false; + } +// TODO 需求暂停 待讨论 获取车辆轨迹文件 +// @Override +// public boolean getRoutes() { +// if (mChannel!=null){ +// return mChannel.getRoutes(); +// } +// return false; +// } + + @Override + public void setEnableLog(boolean isEnableLog) { + if (mChannel != null) { + mChannel.setEnableLog(isEnableLog); + } + } + + @Override + public void setIsWriteLog(boolean isWriteLog) { + if (mChannel != null) { + mChannel.setIsWriteLog(isWriteLog); + } + } + + @Override + public void setIPCIp(String ipAddr) { + if (mChannel != null) { + mChannel.setIPCIp(ipAddr); + } + } + + /** + * 向工控机发送数据 + * + * @param info + */ + @Override + public void sendBaseInfo(BaseInfo info) { + if (mChannel != null) { + mChannel.sendBaseInfo(info); + } + } + + @Override + public void shutdownIPC() { + if (mChannel != null) { + mChannel.shutdownIPC(); + } + } + + @Override + public void rebootIPC() { + if (mChannel != null) { + mChannel.rebootIPC(); + } + } + + @Override + public void rebootAPDocker() { + if (mChannel != null) { + mChannel.rebootAPDocker(); + } + } + + @Override + public void parseIPCData(byte[] bytes) { + if (mChannel != null) { + mChannel.parseIPCData(bytes); + } + } + + @Override + public boolean isClient() { + return mChannel == null || mChannel.isClient(); + } + + @Override + public void enableDemoMode() { + if (mChannel != null) { + mChannel.enableDemoMode(); + } + } + + @Override + public void disableDemoMode() { + if (mChannel != null) { + mChannel.disableDemoMode(); + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasOptions.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasOptions.java new file mode 100644 index 0000000000..023290c748 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasOptions.java @@ -0,0 +1,84 @@ +package com.zhidao.support.adas.high; + +/** + * Date:2019/5/31。 + * Note: Adas相关配置。 + */ +public class AdasOptions { + + + /** + * 是否是客户端 + */ + private boolean isClient; + /** + * 工控机IP + */ + private String ipcIp; + + private AdasOptions() { + } + + /** + * 静态内部类 + */ + public static class Builder { + AdasOptions options; + + // 首先获得一个默认的配置 + public Builder() { + this(getDefaultOptions()); + } + + public Builder(AdasOptions defaultOptions) { + options = defaultOptions; + } + + /** + * 设置当前是客户端还是服务端 + * + * @param isClient true:客户度 false:服务端 + * @return + */ + public Builder setClient(boolean isClient) { + options.isClient = isClient; + return this; + } + + /** + * 设置IPC主机地址 + * + * @param ipcIp + * @return + */ + public Builder setIPCIp(String ipcIp) { + options.ipcIp = ipcIp; + return this; + } + + + public AdasOptions build() { + return options; + } + } + + /** + * 获取默认的配置 + * + * @return + */ + public static AdasOptions getDefaultOptions() { + AdasOptions options = new AdasOptions(); + options.isClient = true; + options.ipcIp = null; + return options; + } + + public boolean isClient() { + return isClient; + } + + public String getIpcIp() { + return ipcIp; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java new file mode 100644 index 0000000000..4aec3644ff --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java @@ -0,0 +1,146 @@ +package com.zhidao.support.adas.high; + +import com.zhidao.support.adas.high.bean.AdasConfig; +import com.zhidao.support.adas.high.bean.BaseInfo; + +/** + * @author nie yunlong + * @des adas 网络通信api + * @date 2020/7/14 + */ +public interface IAdasNetCommApi { + /** + * 控制自动驾驶车辆 自动模式 自动驾驶 + */ + boolean controlAutopilotCarAuto(); + + /** + * 控制自动驾驶车辆 手动模式 + */ + boolean controlAutopilotCarHead(); + + /** + * socket 是否连接状态 + * + * @return + */ + boolean isSocketConnect(); + + /** + * 基础信息 + */ + AdasConfig getAdasConfig(); + + /** + * ai云 + * + * @param msg + */ + boolean aiCloudToAdasData(String msg); + + /** + * 查询自动驾驶路径 + */ + boolean queryAutopilotRoute(); + + /** + * 查询节点监控信息 + */ + boolean queryAutopilotGuardian(); + + /** + * 数据采集 + */ + boolean recordPackage(int type, int id); + + boolean recordPackage(int type, int id, int duration); + + boolean stopRecord(int type, int id); + + /** + * 采集类型 + * + * @param key 工控机返回的 + * @param name 文件名称 也是工控机返回 + * @param id 接管原因id + * @param reason 接管原因 + * @return + */ + boolean recordCause(String key, String name, String id, String reason); + + /** + * 设置车速 + * speed km/h + */ + boolean setSpeed(int speed); + + /** + * 查询轨迹文件 + * + */ +// TODO 需求暂停 待讨论 +// boolean getRoutes(); + + /** + * log是否显示 + */ + void setEnableLog(boolean isEnableLog); + + /** + * log是否写入 + */ + void setIsWriteLog(boolean isWriteLog); + + /** + * 设置工控机IP 如设置IP将不会执行自动搜索方式链接 + * + * @param ipAddr + */ + void setIPCIp(String ipAddr); + + /** + * 向工控机发送数据 + * + * @param info + */ + void sendBaseInfo(BaseInfo info); + + /** + * 向工控机发送关机命令 + */ + void shutdownIPC(); + + /** + * 向工控机发送重启命令 + */ + void rebootIPC(); + + /** + * 向工控机发送重启自动驾驶Docker命令 + */ + void rebootAPDocker(); + + /** + * 解析工控机发送过来的数据 + * + * @param bytes 数据 + */ + void parseIPCData(byte[] bytes); + + /** + * 是否是客户端 + * + * @return true:客户度 false:服务端 + */ + boolean isClient(); + + /** + * 打开演示模式 + */ + void enableDemoMode(); + + /** + * 关闭演示模式 + */ + void disableDemoMode(); +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java new file mode 100644 index 0000000000..37529065f5 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java @@ -0,0 +1,149 @@ +package com.zhidao.support.adas.high; + +import com.zhidao.support.adas.high.bean.AutopilotRoute; +import com.zhidao.support.adas.high.bean.AutopilotStatus; +import com.zhidao.support.adas.high.bean.AutopilotWayArrive; +import com.zhidao.support.adas.high.bean.CarLaneInfo; +import com.zhidao.support.adas.high.bean.CarStateInfo; +import com.zhidao.support.adas.high.bean.SSHResult; +import com.zhidao.support.adas.high.bean.IPCUpgradeStateInfo; +import com.zhidao.support.adas.high.bean.LightStatueInfo; +import com.zhidao.support.adas.high.bean.ObstaclesInfo; +import com.zhidao.support.adas.high.bean.RectInfo; +import com.zhidao.support.adas.high.bean.TrajectoryInfo; +import com.zhidao.support.adas.high.bean.WarnMessageInfo; +import com.zhidao.support.adas.high.bean.guardian.AutopilotGuardianInfo; +import com.zhidao.support.adas.high.bean.record.AutopilotRecordResult; + +import java.util.List; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high + * @ClassName: OnAdasListener + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/9 20:28 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/9 20:28 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public interface OnAdasListener { + /** + * 报警信息 + * + * @param warnMessageInfo + */ + void onWarnMessage(WarnMessageInfo warnMessageInfo); + + /** + * 视频宽高 + * + * @param width + * @param height + */ + void onVideoSize(int width, int height); + + /** + * 车框 + * + * @param rectInfo + */ + void onRectData(RectInfo rectInfo); + + /** + * 车辆状态数据 + * + * @param carStateInfo + */ + void onCarStateData(CarStateInfo carStateInfo); + + /** + * 红绿灯状态 + * + * @param lightStatueInfo + */ + void onLightStateData(LightStatueInfo lightStatueInfo); + + /** + * 周边渲染 + * + * @param obstaclesInfo + */ + void onObstaclesInfo(ObstaclesInfo obstaclesInfo); + + /** + * 车道线渲染 + * + * @param carLaneInfo + */ + void onCarLaneInfo(CarLaneInfo carLaneInfo); + + /** + * 自动驾驶状态 + * + * @param autopilotStatus + */ + void autopilotStatus(AutopilotStatus autopilotStatus); + + /** + * 自动驾驶到站 + * + * @param autopilotWayArrive + */ + void autopilotArrive(AutopilotWayArrive autopilotWayArrive); + /** + * 接收到FPGA端发来的数据 + * + * @param msg json格式 + */ + //void onMessage(String msg); + + /** + * 自动驾驶路径 + * + * @param route + */ + void onAutopilotRoute(AutopilotRoute route); + + /** + * 自动驾驶局部轨迹 + * + * @param trajectoryList + */ + void onAutopilotTrajectory(List trajectoryList); + + /** + * 工控机获取SN + * + * @param + */ + void onAutopilotSNRequest(); + + /** + * 工控机监控节点 + */ + void onAutopilotGuardian(AutopilotGuardianInfo guardianInfo); + + /** + * 数据采集结果 + */ + void onAutopilotRecord(AutopilotRecordResult result); + + /** + * 向IPC发送命令返回结果 + * + * @param info + */ + void onSSHResult(SSHResult info); + + /** + * 升级状态 + * + * @param info + */ + void onUpgradeStateInfo(IPCUpgradeStateInfo info); + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasMsgConnectStatusListener.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasMsgConnectStatusListener.java new file mode 100644 index 0000000000..0ecb9a2b6c --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasMsgConnectStatusListener.java @@ -0,0 +1,18 @@ +package com.zhidao.support.adas.high; + +/** + * @author nie yunlong + * @des 消息通信连接状态 回掉 + * @date 2020/3/20 + */ +public interface OnAdasMsgConnectStatusListener { + /** + * ws 连接成功 + */ + void onWebSocketConnectSuccess(); + + /** + * ws 连接失败 + */ + void onWebSocketConnectFailed(String t); +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnMultiDeviceListener.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnMultiDeviceListener.java new file mode 100644 index 0000000000..1206f837d6 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnMultiDeviceListener.java @@ -0,0 +1,16 @@ +package com.zhidao.support.adas.high; + +/** + * 多设备监听 + * 服务端实现此监听,将工控机发送过来的数据通过其他方式传递出去 + */ +public interface OnMultiDeviceListener { + + /** + * 转发工控机消息 + * 如果是客户端此回调不会被调用 + * + * @param bytes 数据 + */ + void onForwardingIPCMessage(byte[] bytes); +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AdasConfig.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AdasConfig.java new file mode 100644 index 0000000000..7184cd7732 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AdasConfig.java @@ -0,0 +1,49 @@ +package com.zhidao.support.adas.high.bean; + +import com.zhidao.support.adas.high.BuildConfig; + +/** + * @author song kenan + * @des + * @date 2021/10/13 + */ +public class AdasConfig { + private static final String VERSION = BuildConfig.VERSION_NAME; + private static final String AP_VERSION = BuildConfig.AP_VERSION; + private String address; + private String dockVersion; + + /** + * MoGo-AP 版本 + * + * @return + */ + public String getAPVersion() { + return AP_VERSION; + } + + /** + * SDK版本 + * + * @return + */ + public String getVersion() { + return VERSION; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getDockVersion() { + return dockVersion; + } + + public void setDockVersion(String dockVersion) { + this.dockVersion = dockVersion; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotConfig.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotConfig.java new file mode 100644 index 0000000000..e8a2e76925 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotConfig.java @@ -0,0 +1,46 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @des + * @date 2020/7/14 + */ + +public class AutopilotConfig implements Serializable { + + private String action; + private ResultBean result; + + public String getAction() { + return action; + } + + public ResultBean getResult() { + return result; + } + + @Override + public String toString() { + return "AutopilotWayArrive{" + + "action='" + action + '\'' + + ", result=" + result + + '}'; + } + + public static class ResultBean { + private String dock_version; + + public String getDock_version() { + return dock_version; + } + + @Override + public String toString() { + return "ResultBean{" + + "dock_version='" + dock_version + '\'' + + '}'; + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotControl.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotControl.java new file mode 100644 index 0000000000..f7e6ec1136 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotControl.java @@ -0,0 +1,53 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @des mode 0是手动 1是自动 + * @date 2020/7/14 + */ + +public class AutopilotControl implements Serializable { + + /** + * action : autopilotmode + * values : {"mode":0} + */ + + private String action; + private ValuesBean values; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ValuesBean getValues() { + return values; + } + + public void setValues(ValuesBean values) { + this.values = values; + } + + public static class ValuesBean { + /** + * mode : 0 + */ + + private int mode; + + public int getMode() { + return mode; + } + + public void setMode(int mode) { + this.mode = mode; + } + } +} + diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotRoute.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotRoute.java new file mode 100644 index 0000000000..1de9990c8b --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotRoute.java @@ -0,0 +1,75 @@ +package com.zhidao.support.adas.high.bean; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * @author song kenan + * @des + * @date 2021/6/21 + */ + +public class AutopilotRoute { + + @SerializedName("action") + private String action; + @SerializedName("models") + private List models; + + public static class RouteModels { + @SerializedName("lat") + private Double lat; + @SerializedName("lon") + private Double lon; + + public Double getLat() { + return lat; + } + + public void setLat(Double lat) { + this.lat = lat; + } + + public Double getLon() { + return lon; + } + + public void setLon(Double lon) { + this.lon = lon; + } + + @Override + public String toString() { + return "RouteModels{" + + "lat=" + lat + + ", lon=" + lon + + '}'; + } + + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getModels() { + return models; + } + + public void setModels(List models) { + this.models = models; + } + + @Override + public String toString() { + return "AutopilotRoute{" + + "action='" + action + '\'' + + ", models=" + models + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotSnRequest.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotSnRequest.java new file mode 100644 index 0000000000..1ad4199bd5 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotSnRequest.java @@ -0,0 +1,29 @@ +package com.zhidao.support.adas.high.bean; + +/** + * @author song kenan + * @des + * @date 2021/7/2 + */ +public class AutopilotSnRequest { + private String action; + private String models; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getModels() { + return models; + } + + public void setModels(String models) { + this.models = models; + } + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotSpeedParam.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotSpeedParam.java new file mode 100644 index 0000000000..ec4e8c0c16 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotSpeedParam.java @@ -0,0 +1,39 @@ +package com.zhidao.support.adas.high.bean; + +import com.zhidao.support.adas.high.common.CupidLogUtils; + +/** + * @author song kenan + * @des + * @date 2021/12/6 + */ +public class AutopilotSpeedParam { + private final String action = "autospeed"; + private SpeedParam result; + + public String getAction() { + return action; + } + + public void setSpeed(int speed){ + if (result==null){ + result = new SpeedParam(); + } + result.setSpeed(speed); + } + + public static class SpeedParam { + //车辆速度 m/s + private double speed; + + public double getSpeed() { + return speed; + } + + public void setSpeed(int speed) { + // speed km/h + // this.speed m/s + this.speed = speed/3.6; + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotStatus.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotStatus.java new file mode 100644 index 0000000000..6339c25f09 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotStatus.java @@ -0,0 +1,139 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @des + * @date 2020/7/14 + */ +public class AutopilotStatus implements Serializable { + + /** + * action : autopilotstate + * values : {"state":0,"reason":""} + */ + + private String action; + private ValuesBean values; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ValuesBean getValues() { + return values; + } + + public void setValues(ValuesBean values) { + this.values = values; + } + + public static class ValuesBean { + /** + * 0是不可用 1是ready 2是自动驾驶start + * + * @return + */ + private int state; + /** + * 车速 m/s + */ + private float speed; + /** + * 不可用原因 + */ + private String reason; + /** + * 摄像头状态 1代表开启,0代表关闭 + */ + private int camera; + /** + * 雷达状态 1代表开启,0代表关闭 + */ + private int radar; + /** + * RTK状态 1代表开启,0代表关闭 + */ + private int rtk; + /** + * 自动驾驶状态 0非自动驾驶,1自动驾驶 + */ + private int pilotmode; + + /** + * 自动驾驶车控状态 + */ + private int control_pilotmode; + + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + public int getCamera() { + return camera; + } + + public int getRadar() { + return radar; + } + + public int getRtk() { + return rtk; + } + + public int getPilotmode() { + return pilotmode; + } + + public int getControl_pilotmode() { + return control_pilotmode; + } + + @Override + public String toString() { + return "ValuesBean{" + + "state=" + state + + ", speed=" + speed + + ", reason='" + reason + '\'' + + ", camera=" + camera + + ", radar=" + radar + + ", rtk=" + rtk + + ", pilotmode=" + pilotmode + + ", control_pilotmode=" + control_pilotmode + + '}'; + } + } + + @Override + public String toString() { + return "AutopilotStatus{" + + "action='" + action + '\'' + + ", values=" + values + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotTrajectory.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotTrajectory.java new file mode 100644 index 0000000000..079db7b0bc --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotTrajectory.java @@ -0,0 +1,34 @@ +package com.zhidao.support.adas.high.bean; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * @author song kenan + * @des + * @date 2021/10/19 + */ +public class AutopilotTrajectory { + + @SerializedName("action") + private String action; + @SerializedName("models") + private List models; + + public String getAction() { + return action; + } + + public List getModels() { + return models; + } + + @Override + public String toString() { + return "AutopilotTrajectory{" + + "action='" + action + '\'' + + ", models=" + models + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotWayArrive.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotWayArrive.java new file mode 100644 index 0000000000..a81c22ddf5 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/AutopilotWayArrive.java @@ -0,0 +1,115 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @des + * @date 2020/7/14 + */ + +public class AutopilotWayArrive implements Serializable { + + + /** + * action : autopilotArrive + * result : {"carType":0,"endLatLon":{"lat":116.7559675438664,"lon":116.7559675438664}} + */ + + private String action; + private ResultBean result; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ResultBean getResult() { + return result; + } + + public void setResult(ResultBean result) { + this.result = result; + } + + @Override + public String toString() { + return "AutopilotWayArrive{" + + "action='" + action + '\'' + + ", result=" + result + + '}'; + } + + public static class ResultBean { + /** + * carType : 0 + * endLatLon : {"lat":116.7559675438664,"lon":116.7559675438664} + */ + + private int carType; + private EndLatLonBean endLatLon; + + + public int getCarType() { + return carType; + } + + public void setCarType(int carType) { + this.carType = carType; + } + + public EndLatLonBean getEndLatLon() { + return endLatLon; + } + + public void setEndLatLon(EndLatLonBean endLatLon) { + this.endLatLon = endLatLon; + } + + @Override + public String toString() { + return "ResultBean{" + + "carType=" + carType + + ", endLatLon=" + endLatLon + + '}'; + } + + public static class EndLatLonBean { + /** + * lat : 116.7559675438664 + * lon : 116.7559675438664 + */ + + private double lat; + private double lon; + + + public double getLat() { + return lat; + } + + public void setLat(double lat) { + this.lat = lat; + } + + public double getLon() { + return lon; + } + + public void setLon(double lon) { + this.lon = lon; + } + + @Override + public String toString() { + return "EndLatLonBean{" + + "lat=" + lat + + ", lon=" + lon + + '}'; + } + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/BaseInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/BaseInfo.java new file mode 100644 index 0000000000..4e660e1f69 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/BaseInfo.java @@ -0,0 +1,23 @@ +package com.zhidao.support.adas.high.bean; + +public abstract class BaseInfo { + protected String action; + protected T values; + + + public BaseInfo(String action) { + this.action = action; + } + + public String getAction() { + return action; + } + + public T getValues() { + return values; + } + + public void setValues(T values) { + this.values = values; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/BasicInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/BasicInfo.java new file mode 100644 index 0000000000..f9d08ced0c --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/BasicInfo.java @@ -0,0 +1,61 @@ +package com.zhidao.support.adas.high.bean; + +/** + * 7.5. 自动驾驶设备基础信息 + */ +public class BasicInfo { + private String action = "basicinfo"; + private Values values; + + public void setSn(String sn) { + if (values == null) { + values = new Values(); + } + values.setSn(sn); + } + + public void setTileid(String tileid) { + if (values == null) { + values = new Values(); + } + values.setTileid(tileid); + } + + public void setNetEnvironment(int environment) { + if (values == null) { + values = new Values(); + } + values.setNetEnvironment(environment); + } + + private static class Values { + private String sn; + private String tileid; + //研发环境 1;测试环境 2;生产环境 3;演示环境 4; + private int netEnvironment; + + public String getSn() { + return sn; + } + + public void setSn(String sn) { + this.sn = sn; + } + + public String getTileid() { + return tileid; + } + + public void setTileid(String tileid) { + this.tileid = tileid; + } + + public int getNetEnvironment() { + return netEnvironment; + } + + public void setNetEnvironment(int environment) { + this.netEnvironment = environment; + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/CarLaneInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/CarLaneInfo.java new file mode 100644 index 0000000000..0a4aa775db --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/CarLaneInfo.java @@ -0,0 +1,63 @@ +package com.zhidao.support.adas.high.bean; + +import java.util.List; + +/** + * @author nie yunlong + * @des 车道线 + * @date 2020/4/24 + */ +public class CarLaneInfo { + + private String action; + + private List models; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getModels() { + return models; + } + + public void setModels(List models) { + this.models = models; + } + + public static class CarLaneDetailInfo { + private String id; //50~55, 50左黄,51左红,(52左白),53右黄,54右红,(55右白) + private String type; + private int color; //0白色,1黄色 + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } + } + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/CarStateInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/CarStateInfo.java new file mode 100644 index 0000000000..928a17aa3a --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/CarStateInfo.java @@ -0,0 +1,279 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @des 车辆状态 + * @date 2020/3/12 + */ +public class CarStateInfo implements Serializable { + + + /** + * action : “state” + * values : {"lon":116.8,"lat":39.4,"alt":22.3,"heading":87.5,"acceleration":0.5,"yaw_rate":0.3} + */ + + private String action; + private ValuesBean values; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ValuesBean getValues() { + return values; + } + + public void setValues(ValuesBean values) { + this.values = values; + } + + public static class ValuesBean { + /** + * lon : 116.8 + * lat : 39.4 + * alt : 22.3 + * heading : 87.5 + * acceleration : 0.5 + * yaw_rate : 0.3 + */ + + private double lon; + private double lat; + private double alt; + private double heading; + private double acceleration; + private double yaw_rate; + //惯导车速 m/s + private float gnss_speed; + //车辆车速 m/s + private float vehicle_speed; + //gps时间 + private String satelliteTime; + //UTC时间差 + private long utcTimeDiffer; + //系统时间 + private String systemTime; + //接收到数据的时间 + private long receiverDataTime; + //接收到gps时间 + private String adasSatelliteTime; + //开始接收数据时间 + private String startReceiverDataTime; + //时间延迟 + private long timeDiff = 0; + private int turn_light; //转向灯状态 0是正常 1是左转 2是右转 + private int flash_light; //双闪灯状态 + private int brake_light; //刹车灯状态 + private int frame_num;//统计发包个数 + /** + * 常开 常关 转向灯 + * 0 --关 + * 1 --左转 + * 2 --右转 + */ + private int turnLightOften = 0; + + + public int getFrame_num() { + return frame_num; + } + + public void setFrame_num(int frame_num) { + this.frame_num = frame_num; + } + + public int getTurnLightOften() { + return turnLightOften; + } + + public void setTurnLightOften(int turnLightOften) { + this.turnLightOften = turnLightOften; + } + + public long getTimeDiff() { + return timeDiff; + } + + public void setTimeDiff(long timeDiff) { + this.timeDiff = timeDiff; + } + + public long getReceiverDataTime() { + return receiverDataTime; + } + + public void setReceiverDataTime(long receiverDataTime) { + this.receiverDataTime = receiverDataTime; + } + + public String getAdasSatelliteTime() { + return adasSatelliteTime; + } + + public void setAdasSatelliteTime(String adasSatelliteTime) { + this.adasSatelliteTime = adasSatelliteTime; + } + + public String getSystemTime() { + return systemTime; + } + + public void setSystemTime(String systemTime) { + this.systemTime = systemTime; + } + + public float getGnss_speed() { + return gnss_speed; + } + + public void setGnss_speed(float gnss_speed) { + this.gnss_speed = gnss_speed; + } + + public float getVehicle_speed() { + return vehicle_speed; + } + + public void setVehicle_speed(float vehicle_speed) { + this.vehicle_speed = vehicle_speed; + } + + public int getTurn_light() { + return turn_light; + } + + public void setTurn_light(int turn_light) { + this.turn_light = turn_light; + } + + public int getFlash_light() { + return flash_light; + } + + public void setFlash_light(int flash_light) { + this.flash_light = flash_light; + } + + public int getBrake_light() { + return brake_light; + } + + public void setBrake_light(int brake_light) { + this.brake_light = brake_light; + } + + public double getLon() { + return lon; + } + + public void setLon(double lon) { + this.lon = lon; + } + + public double getLat() { + return lat; + } + + public void setLat(double lat) { + this.lat = lat; + } + + public double getAlt() { + return alt; + } + + public void setAlt(double alt) { + this.alt = alt; + } + + public double getHeading() { + return heading; + } + + public void setHeading(double heading) { + this.heading = heading; + } + + public double getAcceleration() { + return acceleration; + } + + public void setAcceleration(double acceleration) { + this.acceleration = acceleration; + } + + public double getYaw_rate() { + return yaw_rate; + } + + public void setYaw_rate(double yaw_rate) { + this.yaw_rate = yaw_rate; + } + + public String getSatelliteTime() { + return satelliteTime; + } + + public void setSatelliteTime(String satelliteTime) { + this.satelliteTime = satelliteTime; + } + + public long getUtcTimeDiffer() { + return utcTimeDiffer; + } + + public void setUtcTimeDiffer(long utcTimeDiffer) { + this.utcTimeDiffer = utcTimeDiffer; + } + + public String getStartReceiverDataTime() { + return startReceiverDataTime; + } + + public void setStartReceiverDataTime(String startReceiverDataTime) { + this.startReceiverDataTime = startReceiverDataTime; + } + + + @Override + public String toString() { + return "ValuesBean{" + + "lon=" + lon + + ", lat=" + lat + + ", alt=" + alt + + ", heading=" + heading + + ", acceleration=" + acceleration + + ", yaw_rate=" + yaw_rate + + ", gnss_speed=" + gnss_speed + + ", vehicle_speed=" + vehicle_speed + + ", satelliteTime='" + satelliteTime + '\'' + + ", utcTimeDiffer=" + utcTimeDiffer + + ", systemTime='" + systemTime + '\'' + + ", receiverDataTime='" + receiverDataTime + '\'' + + ", adasSatelliteTime='" + adasSatelliteTime + '\'' + + ", startReceiverDataTime='" + startReceiverDataTime + '\'' + + ", timeDiff=" + timeDiff + + ", turn_light=" + turn_light + + ", flash_light=" + flash_light + + ", brake_light=" + brake_light + + ", frame_num=" + frame_num + + ", turnLightOften=" + turnLightOften + + '}'; + } + } + + @Override + public String toString() { + return "CarStateInfo{" + + "action='" + action + '\'' + + ", values=" + values + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/ConfigInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/ConfigInfo.java new file mode 100644 index 0000000000..7f1793f875 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/ConfigInfo.java @@ -0,0 +1,129 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @des 配置信息 + * json 摄像头类型 enum "0=小霸王 1=汇影" + * 车型 enum "0=小轿车 1=SUV 2=中巴车 3=大巴车 4=大货车" + * 安装高度 float 1.2~1.5米 + * FCW报警等级 enum "0=关闭 1=近距离报警(不敏感) 2=远距离报警(敏感)" + * LDW报警等级 enum "0=关闭 1=打开" + * Stop&Go提醒等级 enum "0=关闭 1=打开" + * 自动驾驶状态 enum "0=人工驾驶 1=自动驾驶" + * 车辆速度 float 0~130km/h + * @date 2020/3/12 + */ +public class ConfigInfo implements Serializable { + + /** + * action : config + * values : {"camera":0,"vehicle_type":"car","height":1.2,"fcw":1,"ldw":1,"stop_go":0} + */ + + private String action; + private ValuesBean values; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ValuesBean getValues() { + return values; + } + + public void setValues(ValuesBean values) { + this.values = values; + } + + @Override + public String toString() { + return "ConfigInfo{" + + "action='" + action + '\'' + + ", values=" + values + + '}'; + } + + public static class ValuesBean { + /** + * camera : 0 + * vehicle_type : car + * height : 1.2 + * fcw : 1 + * ldw : 1 + * stop_go : 0 + */ + + private int camera; + private String vehicle_type; + private double height; + private int fcw; + private int ldw; + private int stop_go; + + public int getCamera() { + return camera; + } + + public void setCamera(int camera) { + this.camera = camera; + } + + public String getVehicle_type() { + return vehicle_type; + } + + public void setVehicle_type(String vehicle_type) { + this.vehicle_type = vehicle_type; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public int getFcw() { + return fcw; + } + + public void setFcw(int fcw) { + this.fcw = fcw; + } + + public int getLdw() { + return ldw; + } + + public void setLdw(int ldw) { + this.ldw = ldw; + } + + public int getStop_go() { + return stop_go; + } + + public void setStop_go(int stop_go) { + this.stop_go = stop_go; + } + + @Override + public String toString() { + return "ValuesBean{" + + "camera=" + camera + + ", vehicle_type='" + vehicle_type + '\'' + + ", height=" + height + + ", fcw=" + fcw + + ", ldw=" + ldw + + ", stop_go=" + stop_go + + '}'; + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/DemoModeInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/DemoModeInfo.java new file mode 100644 index 0000000000..04deffb0ee --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/DemoModeInfo.java @@ -0,0 +1,30 @@ +package com.zhidao.support.adas.high.bean; + +/** + * 演示模式 + */ +public class DemoModeInfo extends BaseInfo { + public DemoModeInfo(String action) { + super(action); + } + + /** + * 开启演示模式 + * + * @return + */ + public static DemoModeInfo enable() { + return new DemoModeInfo("enable_demo_pilot"); + } + + /** + * 关闭演示模式 + * + * @return + */ + public static DemoModeInfo disable() { + return new DemoModeInfo("disable_demo_pilot"); + } + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/FaceLoginResponse.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/FaceLoginResponse.java new file mode 100644 index 0000000000..9f1d1c24f4 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/FaceLoginResponse.java @@ -0,0 +1,417 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; +import java.util.List; + +/** + * Created by wanglirong on 2018/2/4. + */ + +public class FaceLoginResponse implements Serializable { + + + /** + * data : {"configInfoHistory":[{"kCode":"d_fcw_touch","kName":"前车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"3.7","userId":1068446492234686466},{"kCode":"d_fcw_start","kName":"前车启动提醒","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_driver","kName":"驾驶员疲劳/危险预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_person","kName":"行人碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_sliding","kName":"溜车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_ldw_out","kName":"车道线偏离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5.9","userId":1068446492234686466},{"kCode":"d_hmw_follow","kName":"跟车距离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"2.8","userId":1068446492234686466},{"kCode":"d_volume_size","kName":"音量大小","kOrder":1,"kType":"aided_driving_dic","kVal":"40.6","userId":1068446492234686466},{"kCode":"is_use_ar_navBar","kName":"是否使用AR导航","kOrder":0,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_touch","kName":"前车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_start","kName":"前车启动提醒","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_driver","kName":"驾驶员疲劳/危险预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_person","kName":"行人碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_sliding","kName":"溜车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_ldw_out","kName":"车道线偏离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hmw_follow","kName":"跟车距离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_volume_size","kName":"音量大小","kOrder":1,"kType":"aided_driving_dic","kVal":"60","userId":1068446492234686466},{"kCode":"is_use_ar_navBar","kName":"是否使用AR导航","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_touch","kName":"前车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_start","kName":"前车启动提醒","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_driver","kName":"驾驶员疲劳/危险预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_person","kName":"行人碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_sliding","kName":"溜车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_ldw_out","kName":"车道线偏离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hmw_follow","kName":"跟车距离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_volume_size","kName":"音量大小","kOrder":1,"kType":"aided_driving_dic","kVal":"60","userId":1068446492234686466},{"kCode":"is_use_ar_navBar","kName":"是否使用AR导航","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466}],"currentHeadImageUrl":"http://d2.yiche.com/xvideo-rest/longRunnerDriver.png","medalType":"","navPreferenceConfigHistory":[{"kCode":"avoid_block","kName":"躲避拥堵","kOrder":1,"kType":"aided_navigate_dic","kVal":"1","userId":1068446492234686466},{"kCode":"avoid_pay","kName":"躲避收费","kOrder":1,"kType":"aided_navigate_dic","kVal":"0","userId":1068446492234686466},{"kCode":"avoid_freeway","kName":"不走高速","kOrder":1,"kType":"aided_navigate_dic","kVal":"0","userId":1068446492234686466},{"kCode":"first_freeway","kName":"高速优先","kOrder":1,"kType":"aided_navigate_dic","kVal":"0","userId":1068446492234686466}],"upgrade":false,"userHaunts":[{"latitude":"40.0708","longtitude":"116.336116","otherName":"address","poId":"BV10013514","realName":"回龙观(地铁站)","serialNum":1068449529778237441,"userId":1068446492234686466}],"userMedalDetails":[{"headImageUrl":"http://d2.yiche.com/xvideo-rest/longRunnerDriver.png","medalDescribe":"使用AR导航的次数","medalName":"驰骋⻋主","score":26,"stage":2,"type":"longRunnerDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/caringDriver.png","medalDescribe":"右转道礼让行人","medalName":"爱心⻋主","score":0,"stage":0,"type":"caringDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/curiosityDriver.png","medalDescribe":"使用抓拍功能的次数","medalName":"好奇⻋主","score":2,"stage":0,"type":"curiosityDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/attentionDriver.png","medalDescribe":"连续X天驾驶出行但 未触发X预警","medalName":"安全⻋主","score":1,"stage":0,"type":"attentionDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/carFansDriver.png","medalDescribe":"拍照⻋型照片次数","medalName":"⻋迷⻋主","score":0,"stage":0,"type":"carFansDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/lookForward.png","medalDescribe":"待开发","medalName":"敬请期待","score":0,"stage":0,"type":"lookForward","upgrade":false,"userId":1068446492234686466}]} + * errorCode : 10000 + * errorMsg : OK + */ + + private DataBean data; + private int errorCode; + private String errorMsg; + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public int getErrorCode() { + return errorCode; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } + + public static class DataBean implements Serializable { + /** + * configInfoHistory : [{"kCode":"d_fcw_touch","kName":"前车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"3.7","userId":1068446492234686466},{"kCode":"d_fcw_start","kName":"前车启动提醒","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_driver","kName":"驾驶员疲劳/危险预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_person","kName":"行人碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_sliding","kName":"溜车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_ldw_out","kName":"车道线偏离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5.9","userId":1068446492234686466},{"kCode":"d_hmw_follow","kName":"跟车距离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"2.8","userId":1068446492234686466},{"kCode":"d_volume_size","kName":"音量大小","kOrder":1,"kType":"aided_driving_dic","kVal":"40.6","userId":1068446492234686466},{"kCode":"is_use_ar_navBar","kName":"是否使用AR导航","kOrder":0,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_touch","kName":"前车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_start","kName":"前车启动提醒","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_driver","kName":"驾驶员疲劳/危险预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_person","kName":"行人碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_sliding","kName":"溜车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_ldw_out","kName":"车道线偏离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hmw_follow","kName":"跟车距离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_volume_size","kName":"音量大小","kOrder":1,"kType":"aided_driving_dic","kVal":"60","userId":1068446492234686466},{"kCode":"is_use_ar_navBar","kName":"是否使用AR导航","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_touch","kName":"前车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_start","kName":"前车启动提醒","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_driver","kName":"驾驶员疲劳/危险预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_fcw_person","kName":"行人碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hdw_sliding","kName":"溜车碰撞预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_ldw_out","kName":"车道线偏离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_hmw_follow","kName":"跟车距离预警","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466},{"kCode":"d_volume_size","kName":"音量大小","kOrder":1,"kType":"aided_driving_dic","kVal":"60","userId":1068446492234686466},{"kCode":"is_use_ar_navBar","kName":"是否使用AR导航","kOrder":1,"kType":"aided_driving_dic","kVal":"5","userId":1068446492234686466}] + * currentHeadImageUrl : http://d2.yiche.com/xvideo-rest/longRunnerDriver.png + * medalType : + * navPreferenceConfigHistory : [{"kCode":"avoid_block","kName":"躲避拥堵","kOrder":1,"kType":"aided_navigate_dic","kVal":"1","userId":1068446492234686466},{"kCode":"avoid_pay","kName":"躲避收费","kOrder":1,"kType":"aided_navigate_dic","kVal":"0","userId":1068446492234686466},{"kCode":"avoid_freeway","kName":"不走高速","kOrder":1,"kType":"aided_navigate_dic","kVal":"0","userId":1068446492234686466},{"kCode":"first_freeway","kName":"高速优先","kOrder":1,"kType":"aided_navigate_dic","kVal":"0","userId":1068446492234686466}] + * upgrade : false + * userHaunts : [{"latitude":"40.0708","longtitude":"116.336116","otherName":"address","poId":"BV10013514","realName":"回龙观(地铁站)","serialNum":1068449529778237441,"userId":1068446492234686466}] + * userMedalDetails : [{"headImageUrl":"http://d2.yiche.com/xvideo-rest/longRunnerDriver.png","medalDescribe":"使用AR导航的次数","medalName":"驰骋⻋主","score":26,"stage":2,"type":"longRunnerDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/caringDriver.png","medalDescribe":"右转道礼让行人","medalName":"爱心⻋主","score":0,"stage":0,"type":"caringDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/curiosityDriver.png","medalDescribe":"使用抓拍功能的次数","medalName":"好奇⻋主","score":2,"stage":0,"type":"curiosityDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/attentionDriver.png","medalDescribe":"连续X天驾驶出行但 未触发X预警","medalName":"安全⻋主","score":1,"stage":0,"type":"attentionDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/carFansDriver.png","medalDescribe":"拍照⻋型照片次数","medalName":"⻋迷⻋主","score":0,"stage":0,"type":"carFansDriver","upgrade":false,"userId":1068446492234686466},{"headImageUrl":"http://d2.yiche.com/xvideo-rest/lookForward.png","medalDescribe":"待开发","medalName":"敬请期待","score":0,"stage":0,"type":"lookForward","upgrade":false,"userId":1068446492234686466}] + */ + + private String currentHeadImageUrl; + private String medalType; + private String name; + private boolean upgrade; + private List configInfoHistory; + private List userHaunts; + private List userMedalDetails; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCurrentHeadImageUrl() { + return currentHeadImageUrl; + } + + public void setCurrentHeadImageUrl(String currentHeadImageUrl) { + this.currentHeadImageUrl = currentHeadImageUrl; + } + + public String getMedalType() { + return medalType; + } + + public void setMedalType(String medalType) { + this.medalType = medalType; + } + + public boolean isUpgrade() { + return upgrade; + } + + public void setUpgrade(boolean upgrade) { + this.upgrade = upgrade; + } + + public List getConfigInfoHistory() { + return configInfoHistory; + } + + public void setConfigInfoHistory(List configInfoHistory) { + this.configInfoHistory = configInfoHistory; + } + + public List getUserHaunts() { + return userHaunts; + } + + public void setUserHaunts(List userHaunts) { + this.userHaunts = userHaunts; + } + + public List getUserMedalDetails() { + return userMedalDetails; + } + + public void setUserMedalDetails(List userMedalDetails) { + this.userMedalDetails = userMedalDetails; + } + + @Override + public String toString() { + return "DataBean{" + + "currentHeadImageUrl='" + currentHeadImageUrl + '\'' + + ", medalType='" + medalType + '\'' + + ", name='" + name + '\'' + + ", upgrade=" + upgrade + + ", configInfoHistory=" + configInfoHistory + + ", userHaunts=" + userHaunts + + ", userMedalDetails=" + userMedalDetails + + '}'; + } + + public static class ConfigInfoHistoryBean implements Serializable { + /** + * kCode : d_fcw_touch + * kName : 前车碰撞预警 + * kOrder : 1 + * kType : aided_driving_dic + * kVal : 3.7 + * userId : 1068446492234686466 + */ + + private String kCode; + private String kName; + private int kOrder; + private String kType; + private String kVal; + private String userId; + + public String getKCode() { + return kCode; + } + + public void setKCode(String kCode) { + this.kCode = kCode; + } + + public String getKName() { + return kName; + } + + public void setKName(String kName) { + this.kName = kName; + } + + public int getKOrder() { + return kOrder; + } + + public void setKOrder(int kOrder) { + this.kOrder = kOrder; + } + + public String getKType() { + return kType; + } + + public void setKType(String kType) { + this.kType = kType; + } + + public String getKVal() { + return kVal; + } + + public void setKVal(String kVal) { + this.kVal = kVal; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getkCode() { + return kCode; + } + + public void setkCode(String kCode) { + this.kCode = kCode; + } + + public String getkName() { + return kName; + } + + public void setkName(String kName) { + this.kName = kName; + } + + public int getkOrder() { + return kOrder; + } + + public void setkOrder(int kOrder) { + this.kOrder = kOrder; + } + + public String getkType() { + return kType; + } + + public void setkType(String kType) { + this.kType = kType; + } + + public String getkVal() { + return kVal; + } + + public void setkVal(String kVal) { + this.kVal = kVal; + } + + @Override + public String toString() { + return "ConfigInfoHistoryBean{" + + "kCode='" + kCode + '\'' + + ", kName='" + kName + '\'' + + ", kOrder=" + kOrder + + ", kType='" + kType + '\'' + + ", kVal='" + kVal + '\'' + + ", userId='" + userId + '\'' + + '}'; + } + } + + + + public static class UserHauntsBean implements Serializable { + /** + * latitude : 40.0708 + * longtitude : 116.336116 + * otherName : address + * poId : BV10013514 + * realName : 回龙观(地铁站) + * serialNum : 1068449529778237441 + * userId : 1068446492234686466 + */ + + private String latitude; + private String longtitude; + private String otherName; + private String poId; + private String realName; + private String serialNum; + private String userId; + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongtitude() { + return longtitude; + } + + public void setLongtitude(String longtitude) { + this.longtitude = longtitude; + } + + public String getOtherName() { + return otherName; + } + + public void setOtherName(String otherName) { + this.otherName = otherName; + } + + public String getPoId() { + return poId; + } + + public void setPoId(String poId) { + this.poId = poId; + } + + public String getRealName() { + return realName; + } + + public void setRealName(String realName) { + this.realName = realName; + } + + public String getSerialNum() { + return serialNum; + } + + public void setSerialNum(String serialNum) { + this.serialNum = serialNum; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + + public static class UserMedalDetailsBean implements Serializable { + /** + * headImageUrl : http://d2.yiche.com/xvideo-rest/longRunnerDriver.png + * medalDescribe : 使用AR导航的次数 + * medalName : 驰骋⻋主 + * score : 26 + * stage : 2 + * type : longRunnerDriver + * upgrade : false + * userId : 1068446492234686466 + */ + + private String headImageUrl; + private String medalDescribe; + private String medalName; + private int score; + private int stage; + private String type; + private boolean upgrade; + private String userId; + + public String getHeadImageUrl() { + return headImageUrl; + } + + public void setHeadImageUrl(String headImageUrl) { + this.headImageUrl = headImageUrl; + } + + public String getMedalDescribe() { + return medalDescribe; + } + + public void setMedalDescribe(String medalDescribe) { + this.medalDescribe = medalDescribe; + } + + public String getMedalName() { + return medalName; + } + + public void setMedalName(String medalName) { + this.medalName = medalName; + } + + public int getScore() { + return score; + } + + public void setScore(int score) { + this.score = score; + } + + public int getStage() { + return stage; + } + + public void setStage(int stage) { + this.stage = stage; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isUpgrade() { + return upgrade; + } + + public void setUpgrade(boolean upgrade) { + this.upgrade = upgrade; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/IPCUpgradeInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/IPCUpgradeInfo.java new file mode 100644 index 0000000000..8772a2f105 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/IPCUpgradeInfo.java @@ -0,0 +1,50 @@ +package com.zhidao.support.adas.high.bean; + +/** + * 工控机升级 + */ +public class IPCUpgradeInfo extends BaseInfo { + public IPCUpgradeInfo() { + super("ipc_upgrade"); + } + + /** + * 用户不同意升级 + * + * @return + */ + public static IPCUpgradeInfo cancel() { + IPCUpgradeInfo info = new IPCUpgradeInfo(); + info.values = new IPCUpgradeInfo.Values(); + info.values.state = 0; + return info; + } + + /** + * 用户同意升级 + * + * @return + */ + public static IPCUpgradeInfo affirm() { + IPCUpgradeInfo info = new IPCUpgradeInfo(); + info.values = new IPCUpgradeInfo.Values(); + info.values.state = 1; + return info; + } + + public static class Values { + /** + * 0 不同意升级 + * 1 同意升级 + */ + private int state; + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/IPCUpgradeStateInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/IPCUpgradeStateInfo.java new file mode 100644 index 0000000000..4e82b55e0f --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/IPCUpgradeStateInfo.java @@ -0,0 +1,282 @@ +package com.zhidao.support.adas.high.bean; + +import com.google.gson.annotations.SerializedName; + +/** + * 工控机升级 + */ +public class IPCUpgradeStateInfo extends BaseInfo { + /** + * 升级模式 + */ + public enum UpgradeMode { + /** + * 0:静默升级 + * 3:提示升级 + */ + DATA_NULL(-1, "数据为NULL"), + QUIET(0, "静默升级"), + HINT(3, "提示升级"); + public final int code; + public final String describe; + + private UpgradeMode(int code, String describe) { + this.code = code; + this.describe = describe; + } + + public static UpgradeMode getStatus(int code) { + switch (code) { + default: + case -1: + return DATA_NULL; + case 0: + return QUIET; + case 3: + return HINT; + + } + } + + @Override + public String toString() { + return "{" + + "code=" + code + + ", describe='" + describe + '\'' + + '}'; + } + } + + /** + * 下载状态 + */ + public enum DownloadStatus { + /** + * 30:开始下载 + * 31:下载完成 + * 32:下载失败 + */ + DATA_NULL(-1, "数据为NULL"), + START(30, "开始下载"), + FINISH(31, "下载完成"), + FAILED(32, "下载失败"); + public final int code; + public final String describe; + + private DownloadStatus(int code, String describe) { + this.code = code; + this.describe = describe; + } + + public static DownloadStatus getStatus(int code) { + switch (code) { + default: + case -1: + return DATA_NULL; + case 30: + return START; + case 31: + return FINISH; + case 32: + return FAILED; + } + } + + @Override + public String toString() { + return "{" + + "code=" + code + + ", describe='" + describe + '\'' + + '}'; + } + } + + /** + * 下载状态 + */ + public enum UpgradeStatus { + /** + * 60:是否升级 + * 61:升级成功 + * 62:升级失败 + * 63:用户确认 + * 64:用户取消 + */ + DATA_NULL(-1, "数据为NULL"), + AFFIRM(60, "是否升级"), + SUCCEED(61, "升级成功"), + FAILED(62, "升级失败"), + USER_AFFIRM(63, "用户确认"), + USER_CANCEL(64, "用户取消"); + public final int code; + public final String describe; + + private UpgradeStatus(int code, String describe) { + this.code = code; + this.describe = describe; + } + + public static UpgradeStatus getStatus(int code) { + switch (code) { + default: + case -1: + return DATA_NULL; + case 60: + return AFFIRM; + case 61: + return SUCCEED; + case 62: + return FAILED; + case 63: + return USER_AFFIRM; + case 64: + return USER_CANCEL; + } + } + + @Override + public String toString() { + return "{" + + "code=" + code + + ", describe='" + describe + '\'' + + '}'; + } + } + + public IPCUpgradeStateInfo(String action) { + super(action); + } + + /** + * 获取升级包下载进度 + * + * @return + */ + public Values.Progress getProgress() { + if (this.values == null) return null;//数据或解析异常 + return this.values.progress; + } + + /** + * 获取下载状态 + * + * @return + */ + public int getDownloadStatus() { + if (this.values == null) return -1;//数据或解析异常 + return this.values.downloadStatus; + } + + /** + * 获取升级状态 + * + * @return + */ + public int getUpgradeStatus() { + if (this.values == null) return -1;//数据或解析异常 + return this.values.upgradeStatus; + } + + /** + * 获取升级模式 + * + * @return + */ + public int getUpgradeMode() { + if (this.values == null) return -1;//数据或解析异常 + return this.values.upgradeMode; + } + + /** + * 获取版本号 + * + * @return + */ + public String getImages() { + if (this.values == null) return null;//数据或解析异常 + return this.values.images; + } + + public static class Values { + /** + * int 类型, 升级模式 静默升级不需要前端通知,工控机会自动升级 + */ + @SerializedName("upgrade_mode") + private int upgradeMode = -1; + private Progress progress; + /** + * int 类型, 下载状态, 如果下载完成,下载进度会为空 + */ + @SerializedName("download_status") + private int downloadStatus = -1; + /** + * int 类型, 升级状态 + */ + @SerializedName("upgrade_status") + private int upgradeStatus = -1; + /** + * string 类型,版本号 + */ + private String images; + + public static class Progress { + /** + * total : 307405010 + * current : 1071793 + */ + /** + * int 类型 ,包总大小,字节 + */ + private int total; + /** + * int 类型 ,包已经下载大小,字节 + */ + private int current; + + public int getTotal() { + return total; + } + + public int getCurrent() { + return current; + } + + @Override + public String toString() { + return "{" + + "total=" + total + + ", current=" + current + + '}'; + } + } + } +} + +/** + * upgrade_mode: + * 0-静默升级 + * 1-提示升级 + * download_status: + * 30:开始下载 + * 31:下载完成 + * 32:下载失败 + * upgrade_status: + * 60:是否升级 + * 61:升级成功 + * 62:升级失败 + * 63:用户确认 + * 64:用户取消 + * *{ + * * "action": "ipc_upgrade_status", + * * "values": { + * * "progress": { + * * "total": 307405010, //int 类型 ,包总大小,字节 + * * "current": 1071793 //int 类型 ,包已经下载大小,字节 + * * }, + * * "download_status": 31, //int 类型, 下载状态, 如果下载完成,下载进度会为空 + * * "upgrade_status": 61, //int 类型, 升级状态 + * * "upgrade_mode": 1, //int 类型, 升级模式 + * * "images": "mogohub.tencentcloudcr.com/autocar/df:RoboTaxi_MAP-taxi_2.1.3.1_20211214_huzhengming"* } //string 类型,版本号 + * * + * * } + */ diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/LightStatueInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/LightStatueInfo.java new file mode 100644 index 0000000000..4d8df164d3 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/LightStatueInfo.java @@ -0,0 +1,143 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @des 红绿灯状态 + * @date 2020/3/12 + */ +public class LightStatueInfo implements Serializable { + + /** + * action : light + * values : {"left":1,"right ":0,"straight":3,"u_turn":0,"left_time_remains":3,"right_time_remains":3,"straight_time_remains":3,"u_turn_time_remains":3} + */ + + private String action; + private ValuesBean values; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ValuesBean getValues() { + return values; + } + + public void setValues(ValuesBean values) { + this.values = values; + } + + @Override + public String toString() { + return "LightStatueInfo{" + + "action='" + action + '\'' + + ", values=" + values + + '}'; + } + + public static class ValuesBean { + /** + * left : 1 + * right : 0 + * straight : 3 + * u_turn : 0 + * left_time_remains : 3 + * right_time_remains : 3 + * straight_time_remains : 3 + * u_turn_time_remains : 3 + */ + + private int left; + private int right; + private int straight; + private int u_turn; + private int left_time_remains; + private int right_time_remains; + private int straight_time_remains; + private int u_turn_time_remains; + + public int getLeft() { + return left; + } + + public void setLeft(int left) { + this.left = left; + } + + public int getRight() { + return right; + } + + public void setRight(int right) { + this.right = right; + } + + public int getStraight() { + return straight; + } + + public void setStraight(int straight) { + this.straight = straight; + } + + public int getU_turn() { + return u_turn; + } + + public void setU_turn(int u_turn) { + this.u_turn = u_turn; + } + + public int getLeft_time_remains() { + return left_time_remains; + } + + public void setLeft_time_remains(int left_time_remains) { + this.left_time_remains = left_time_remains; + } + + public int getRight_time_remains() { + return right_time_remains; + } + + public void setRight_time_remains(int right_time_remains) { + this.right_time_remains = right_time_remains; + } + + public int getStraight_time_remains() { + return straight_time_remains; + } + + public void setStraight_time_remains(int straight_time_remains) { + this.straight_time_remains = straight_time_remains; + } + + public int getU_turn_time_remains() { + return u_turn_time_remains; + } + + public void setU_turn_time_remains(int u_turn_time_remains) { + this.u_turn_time_remains = u_turn_time_remains; + } + + @Override + public String toString() { + return "ValuesBean{" + + "left=" + left + + ", right=" + right + + ", straight=" + straight + + ", u_turn=" + u_turn + + ", left_time_remains=" + left_time_remains + + ", right_time_remains=" + right_time_remains + + ", straight_time_remains=" + straight_time_remains + + ", u_turn_time_remains=" + u_turn_time_remains + + '}'; + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/MapLocationInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/MapLocationInfo.java new file mode 100644 index 0000000000..18ca402b11 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/MapLocationInfo.java @@ -0,0 +1,110 @@ +package com.zhidao.support.adas.high.bean; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high.bean + * @ClassName: MapLocationInfo + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/9 14:32 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/9 14:32 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public class MapLocationInfo implements Parcelable { + //纬度 + private double latitude; + //经度 + private double longitude; + private float speed; + private float bearing; + + public MapLocationInfo() { + } + + public MapLocationInfo(double latitude, double longitude, float speed, float bearing) { + this.latitude = latitude; + this.longitude = longitude; + this.speed = speed; + this.bearing = bearing; + } + + public double getLatitude() { + return latitude; + } + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + public double getLongitude() { + return longitude; + } + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + public float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + public float getBearing() { + return bearing; + } + + public void setBearing(float bearing) { + this.bearing = bearing; + } + + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeDouble(this.latitude); + dest.writeDouble(this.longitude); + dest.writeFloat(this.speed); + dest.writeFloat(this.bearing); + } + + protected MapLocationInfo(Parcel in) { + this.latitude = in.readDouble(); + this.longitude = in.readDouble(); + this.speed = in.readFloat(); + this.bearing = in.readFloat(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public MapLocationInfo createFromParcel(Parcel source) { + return new MapLocationInfo(source); + } + + @Override + public MapLocationInfo[] newArray(int size) { + return new MapLocationInfo[size]; + } + }; + + @Override + public String toString() { + return "MapLocationInfo{" + + "latitude=" + latitude + + ", longitude=" + longitude + + ", speed=" + speed + + ", bearing=" + bearing + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/ObstaclesInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/ObstaclesInfo.java new file mode 100644 index 0000000000..2af375c32b --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/ObstaclesInfo.java @@ -0,0 +1,82 @@ +package com.zhidao.support.adas.high.bean; + +import java.util.List; + +/** + * @author nie yunlong + * @des 周边物体渲染 + * @date 2020/4/24 + */ +public class ObstaclesInfo { + + private String action; + + private List models; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getModels() { + return models; + } + + public void setModels(List models) { + this.models = models; + } + + public static class ObstaclesModelInfo { + + private String id; //50~55, 50左黄,51左红,(52左白),53右黄,54右红,(55右白) + private String type; + private double distance; //距离/米 + private double direction; //正前为0,左为90,后为180,右为270 + private double heading; //物体的朝向角,90~270属于逆向车辆 + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public double getDistance() { + return distance; + } + + public void setDistance(double distance) { + this.distance = distance; + } + + public double getDirection() { + return direction; + } + + public void setDirection(double direction) { + this.direction = direction; + } + + public double getHeading() { + return heading; + } + + public void setHeading(double heading) { + this.heading = heading; + } + } + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RectInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RectInfo.java new file mode 100644 index 0000000000..ab710e82a6 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RectInfo.java @@ -0,0 +1,344 @@ +package com.zhidao.support.adas.high.bean; + +import java.util.List; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high.bean + * @ClassName: RectInfo + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/9 20:22 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/9 20:22 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public class RectInfo { + private String type; + private String action; + private List models; + private float fps; + + public float getFps() { + return fps; + } + + public void setFps(float fps) { + this.fps = fps; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getModels() { + return models; + } + + public void setModels(List models) { + this.models = models; + } + + public static class RectBean { + private int id; + private double xl; + private double xr; + private double yb; + private double yt; + //距离x轴值 + private double distance_x; + //距离y轴值 + private double distance_y; + //type="car" 是车辆 + private String type; + //纬度 + private double lat; + //经度 + private double lon; + //朝向 + private double heading; + //系统时间 + private String systemTime; + //gps 时间 + private String satelliteTime; + //海拔高度 + private double alt; + //车牌id + private String carId; + //uuid + private String uuid; + //color + private String color; + //speed + private double speed; + //危险等级 1 绿,2 黄,3 红 + private int drawlevel; + //长 + private float length; + //宽 + private float width; + //高 + private float height; + //驱动时间 + private String driverTime; + /** + * 数据来源精度 0 - 普通定位、1 - 高精定位 + */ + public int dataAccuracy = 1; + + /** + * 实际距离,使用 distanceX 和 distanceY 计算 + */ + public double distance; + + public int getDataAccuracy() { + return dataAccuracy; + } + + public void setDataAccuracy(int dataAccuracy) { + this.dataAccuracy = dataAccuracy; + } + + public double getDistance() { + return distance; + } + + public void setDistance(double distance) { + this.distance = distance; + } + + public String getSystemTime() { + return systemTime; + } + + public void setSystemTime(String systemTime) { + this.systemTime = systemTime; + } + + public String getSatelliteTime() { + return satelliteTime; + } + + public void setSatelliteTime(String satelliteTime) { + this.satelliteTime = satelliteTime; + } + + public double getAlt() { + return alt; + } + + public void setAlt(double alt) { + this.alt = alt; + } + + public String getCarId() { + return carId; + } + + public void setCarId(String carId) { + this.carId = carId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public float getLength() { + return length; + } + + public void setLength(float length) { + this.length = length; + } + + public float getWidth() { + return width; + } + + public void setWidth(float width) { + this.width = width; + } + + public float getHeight() { + return height; + } + + public void setHeight(float height) { + this.height = height; + } + + public int getDrawlevel() { + return drawlevel; + } + + public void setDrawlevel(int drawlevel) { + this.drawlevel = drawlevel; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getLat() { + return lat; + } + + public void setLat(double lat) { + this.lat = lat; + } + + public double getLon() { + return lon; + } + + public void setLon(double lon) { + this.lon = lon; + } + + public double getDistance_x() { + return distance_x; + } + + public void setDistance_x(double distance_x) { + this.distance_x = distance_x; + } + + public double getDistance_y() { + return distance_y; + } + + public void setDistance_y(double distance_y) { + this.distance_y = distance_y; + } + + public double getHeading() { + return heading; + } + + public void setHeading(double heading) { + this.heading = heading; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public double getXl() { + return xl; + } + + public void setXl(double xl) { + this.xl = xl; + } + + public double getXr() { + return xr; + } + + public void setXr(double xr) { + this.xr = xr; + } + + public double getYb() { + return yb; + } + + public void setYb(double yb) { + this.yb = yb; + } + + public double getYt() { + return yt; + } + + public void setYt(double yt) { + this.yt = yt; + } + + public String getDriverTime() { + return driverTime; + } + + public void setDriverTime(String driverTime) { + this.driverTime = driverTime; + } + + @Override + public String toString() { + return "RectBean{" + + "id=" + id + + ", xl=" + xl + + ", xr=" + xr + + ", yb=" + yb + + ", yt=" + yt + + ", distance_x=" + distance_x + + ", distance_y=" + distance_y + + ", type='" + type + '\'' + + ", lat=" + lat + + ", lon=" + lon + + ", heading=" + heading + + ", systemTime='" + systemTime + '\'' + + ", satelliteTime='" + satelliteTime + '\'' + + ", alt=" + alt + + ", carId='" + carId + '\'' + + ", uuid='" + uuid + '\'' + + ", color='" + color + '\'' + + ", speed=" + speed + + ", drawlevel=" + drawlevel + + ", length=" + length + + ", width=" + width + + ", height=" + height + + ", driverTime=" + driverTime + + '}'; + } + } + + @Override + public String toString() { + return "RectInfo{" + + ", action='" + action + '\'' + + ", models=" + models + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RemoteControlAutoPilotParameters.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RemoteControlAutoPilotParameters.java new file mode 100644 index 0000000000..4208c9d617 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RemoteControlAutoPilotParameters.java @@ -0,0 +1,139 @@ +package com.zhidao.support.adas.high.bean; + +import java.util.List; + +public +/** + * @author congtaowang + * @since 2020/10/16 + * + * 自动驾驶参数 + */ +class RemoteControlAutoPilotParameters { + + private String action; + + private RemoteControlAutoPilotParameters.ValuesBean result; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ValuesBean getResult() { + return result; + } + + public void setResult(ValuesBean result) { + this.result = result; + } + + @Override + public String toString() { + return "RemoteControlAutoPilotParameters{" + + "action='" + action + '\'' + + ", result=" + result + + '}'; + } + + public static class ValuesBean { + public AutoPilotLonLat startLatLon; + public List< AutoPilotLonLat > wayLatLons; + public AutoPilotLonLat endLatLon; + public float speedLimit; + public int vehicleType;// 运营类型 + + public static class AutoPilotLonLat { + public double lat; + public double lon; + + public AutoPilotLonLat() { + } + + public AutoPilotLonLat( double lat, double lon ) { + this.lat = lat; + this.lon = lon; + } + + public double getLat() { + return lat; + } + + public void setLat(double lat) { + this.lat = lat; + } + + public double getLon() { + return lon; + } + + public void setLon(double lon) { + this.lon = lon; + } + + @Override + public String toString() { + return "AutoPilotLonLat{" + + "lat=" + lat + + ", lon=" + lon + + '}'; + } + } + + + public AutoPilotLonLat getStartLatLon() { + return startLatLon; + } + + public void setStartLatLon(AutoPilotLonLat startLatLon) { + this.startLatLon = startLatLon; + } + + public List getWayLatLons() { + return wayLatLons; + } + + public void setWayLatLons(List wayLatLons) { + this.wayLatLons = wayLatLons; + } + + public AutoPilotLonLat getEndLatLon() { + return endLatLon; + } + + public void setEndLatLon(AutoPilotLonLat endLatLon) { + this.endLatLon = endLatLon; + } + + public float getSpeedLimit() { + return speedLimit; + } + + public void setSpeedLimit(float speedLimit) { + this.speedLimit = speedLimit; + } + + public int getVehicleType() { + return vehicleType; + } + + public void setVehicleType(int vehicleType) { + this.vehicleType = vehicleType; + } + + @Override + public String toString() { + return "RemoteControlAutoPilotParameters{" + + "startLatLon=" + startLatLon + + ", wayLatLons=" + wayLatLons + + ", endLatLon=" + endLatLon + + ", speedLimit=" + speedLimit + + ", vehicleType=" + vehicleType + + '}'; + } + } + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RouteInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RouteInfo.java new file mode 100644 index 0000000000..5229eca2f5 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/RouteInfo.java @@ -0,0 +1,23 @@ +package com.zhidao.support.adas.high.bean; + +/** + * @author song kenan + * @des + * @date 2021/12/7 + */ +public class RouteInfo { + + private String id; + + private double startLat; + + private double startLon; + + private double endLat; + + private double endLon; + + private String path; + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/SSHResult.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/SSHResult.java new file mode 100644 index 0000000000..d9f16e9219 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/SSHResult.java @@ -0,0 +1,46 @@ +package com.zhidao.support.adas.high.bean; + +/** + * SSH返回结果 + */ +public class SSHResult { + + public interface RESULT_CODE { + /** + * 工控机IP未知 + */ + int IP_UNKNOWN = -10001; + /** + * 网络异常或连接异常或IO异常 + */ + int ERROR = -10000; + /** + * 命令下发成功 可能存在-1的情况 + * 在虚拟机的ubuntu系统发送reboot或shutdown或ls 命令返回的是0,在工控机发送reboot或shutdown返回-1 ls返回0 + */ + int SEND_SUCCEED = 0; + /** + * 其他值根据Shell返回结果而定 >0 + */ + + } + + public final int code; + public final String cmd; + public final String msg; + + public SSHResult(int code, String cmd, String msg) { + this.code = code; + this.cmd = cmd; + this.msg = msg; + } + + @Override + public String toString() { + return "SSHResult{" + + "code=" + code + + ", cmd='" + cmd + '\'' + + ", msg='" + msg + '\'' + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/TrajectoryInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/TrajectoryInfo.java new file mode 100644 index 0000000000..027a1e2cb0 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/TrajectoryInfo.java @@ -0,0 +1,125 @@ +package com.zhidao.support.adas.high.bean; + +import com.google.gson.annotations.SerializedName; + +/** + * @author song kenan + * @des + * @date 2021/10/21 + */ +public class TrajectoryInfo { + //经度 + @SerializedName("lon") + private Double lon; + //纬度 + @SerializedName("lat") + private Double lat; + //高度 + @SerializedName("alt") + private Double alt; + //时间 秒s + @SerializedName("time") + private Double time; + //速度 m/s + @SerializedName("velocity") + private Double velocity; + //加速度 + @SerializedName("acceleration") + private Double acceleration; + //速度方向 + @SerializedName("theta") + private Double theta; + //曲率 + @SerializedName("kappa") + private Double kappa; + //从起点到目前的总距离 + @SerializedName("accumulated_dis") + private Double accumulatedDis; + + public void setLon(Double lon) { + this.lon = lon; + } + + public void setLat(Double lat) { + this.lat = lat; + } + + public void setAlt(Double alt) { + this.alt = alt; + } + + public void setTime(Double time) { + this.time = time; + } + + public void setVelocity(Double velocity) { + this.velocity = velocity; + } + + public void setAcceleration(Double acceleration) { + this.acceleration = acceleration; + } + + public void setTheta(Double theta) { + this.theta = theta; + } + + public void setKappa(Double kappa) { + this.kappa = kappa; + } + + public void setAccumulatedDis(Double accumulatedDis) { + this.accumulatedDis = accumulatedDis; + } + + public Double getLon() { + return lon; + } + + public Double getLat() { + return lat; + } + + public Double getAlt() { + return alt; + } + + public Double getTime() { + return time; + } + + public Double getVelocity() { + return velocity; + } + + public Double getAcceleration() { + return acceleration; + } + + public Double getTheta() { + return theta; + } + + public Double getKappa() { + return kappa; + } + + public Double getAccumulatedDis() { + return accumulatedDis; + } + + @Override + public String toString() { + return "TrajectoryModels{" + + "lon=" + lon + + ", lat=" + lat + + ", alt=" + alt + + ", time='" + time + '\'' + + ", velocity=" + velocity + + ", acceleration=" + acceleration + + ", theta=" + theta + + ", kappa=" + kappa + + ", accumulatedDis=" + accumulatedDis + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/UserInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/UserInfo.java new file mode 100644 index 0000000000..a039058cbf --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/UserInfo.java @@ -0,0 +1,28 @@ +package com.zhidao.support.adas.high.bean; + +import java.io.Serializable; + +/** + * @author nie yunlong + * @description + * @date 2018/9/6 + */ +public class UserInfo implements Serializable { + + private String userId; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + @Override + public String toString() { + return "UserInfo{" + + "userId='" + userId + '\'' + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/WarnMessageInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/WarnMessageInfo.java new file mode 100644 index 0000000000..d79071f189 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/WarnMessageInfo.java @@ -0,0 +1,80 @@ +package com.zhidao.support.adas.high.bean; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high.bean + * @ClassName: WarnMessageInfo + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/9 20:40 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/9 20:40 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public class WarnMessageInfo { + /** + * content : 小心前车 + * level : 2 + * type : 20 + * value : + */ + + private String content; + private String level; + private String type; + private String value; + + public WarnMessageInfo() { + } + + public WarnMessageInfo(String type, String content, String value, String level) { + this.type = type; + this.content = content; + this.value = value; + this.level = level; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + + @Override + public String toString() { + return "WarnMessageInfo{" + + "content='" + content + '\'' + + ", level='" + level + '\'' + + ", type='" + type + '\'' + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/AutopilotGuardianInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/AutopilotGuardianInfo.java new file mode 100644 index 0000000000..88a05c38dd --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/AutopilotGuardianInfo.java @@ -0,0 +1,113 @@ +package com.zhidao.support.adas.high.bean.guardian; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.List; + +/** + * @author songkenan + * @des 节点监控 + * @date 2021/7/7 + */ +public class AutopilotGuardianInfo implements Serializable { + //接口名称 + @SerializedName("action") + private String action; + //监控项名称 + @SerializedName("agentName") + private String agentName; + //车牌号 + @SerializedName("carNum") + private String carNum; + //车型 + @SerializedName("carType") + private String carType; + //monitorType + @SerializedName("monitorType") + private String monitorType; + //sn + @SerializedName("sn") + private String sn; + //时间 + @SerializedName("time") + private long time; + @SerializedName("modules") + private GuardianModule modules; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getAgentName() { + return agentName; + } + + public void setAgentName(String agentName) { + this.agentName = agentName; + } + + public String getCarNum() { + return carNum; + } + + public void setCarNum(String carNum) { + this.carNum = carNum; + } + + public String getCarType() { + return carType; + } + + public void setCarType(String carType) { + this.carType = carType; + } + + public String getMonitorType() { + return monitorType; + } + + public void setMonitorType(String monitorType) { + this.monitorType = monitorType; + } + + public String getSn() { + return sn; + } + + public void setSn(String sn) { + this.sn = sn; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public GuardianModule getModules() { + return modules; + } + + public void setModules(GuardianModule modules) { + this.modules = modules; + } + + @Override + public String toString() { + return "AutopilotGuardianInfo{" + + "action='" + action + '\'' + + ", agentName='" + agentName + '\'' + + ", carNum='" + carNum + '\'' + + ", carType='" + carType + '\'' + + ", monitorType='" + monitorType + '\'' + + ", modules=" + modules + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianItem.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianItem.java new file mode 100644 index 0000000000..4b2a04b761 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianItem.java @@ -0,0 +1,39 @@ +package com.zhidao.support.adas.high.bean.guardian; + +import com.google.gson.annotations.SerializedName; + +/** + * @author song kenan + * @des + * @date 2021/12/10 + */ +public class GuardianItem { + @SerializedName("name") + private String name; + @SerializedName("value") + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return "GuardianItem{" + + "name='" + name + '\'' + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianItemsName.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianItemsName.java new file mode 100644 index 0000000000..1dfe098a6e --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianItemsName.java @@ -0,0 +1,41 @@ +package com.zhidao.support.adas.high.bean.guardian; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * @author song kenan + * @des + * @date 2021/12/10 + */ +public class GuardianItemsName { + @SerializedName("name") + private String name; + @SerializedName("items") + private List items; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + @Override + public String toString() { + return "GuardianItemsName{" + + "name='" + name + '\'' + + ", items=" + items + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianModule.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianModule.java new file mode 100644 index 0000000000..4815e7b367 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianModule.java @@ -0,0 +1,41 @@ +package com.zhidao.support.adas.high.bean.guardian; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * @author song kenan + * @des + * @date 2021/12/10 + */ +public class GuardianModule { + @SerializedName("itemsname") + private List itemsname; + @SerializedName("submodules") + private List submodules; + + public List getItemsname() { + return itemsname; + } + + public void setItemsname(List itemsname) { + this.itemsname = itemsname; + } + + public List getSubmodules() { + return submodules; + } + + public void setSubmodules(List submodules) { + this.submodules = submodules; + } + + @Override + public String toString() { + return "GuardianModule{" + + "itemsname=" + itemsname + + ", submodules=" + submodules + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianSubmodule.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianSubmodule.java new file mode 100644 index 0000000000..79e4648acc --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/guardian/GuardianSubmodule.java @@ -0,0 +1,84 @@ +package com.zhidao.support.adas.high.bean.guardian; + + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * @author song kenan + * @des + * @date 2021/12/10 + */ +public class GuardianSubmodule { + @SerializedName("modulename") + private String modulename; + @SerializedName("subnodes") + private List subnodes; + + public String getModulename() { + return modulename; + } + + public void setModulename(String modulename) { + this.modulename = modulename; + } + + public List getSubnodes() { + return subnodes; + } + + public void setSubnodes(List subnodes) { + this.subnodes = subnodes; + } + + public static class Subnode { + @SerializedName("nodename") + private String nodename; + @SerializedName("nodeitems") + private List nodeitems; + @SerializedName("topicitems") + private List topicitems; + + public String getNodename() { + return nodename; + } + + public void setNodename(String nodename) { + this.nodename = nodename; + } + + public List getNodeitems() { + return nodeitems; + } + + public void setNodeitems(List nodeitems) { + this.nodeitems = nodeitems; + } + + public List getTopicitems() { + return topicitems; + } + + public void setTopicitems(List topicitems) { + this.topicitems = topicitems; + } + + @Override + public String toString() { + return "Subnode{" + + "nodename='" + nodename + '\'' + + ", nodeitems=" + nodeitems + + ", topicitems=" + topicitems + + '}'; + } + } + + @Override + public String toString() { + return "GuardianSubmodule{" + + "modulename='" + modulename + '\'' + + ", subnodes=" + subnodes + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/AutopilotIdentifyInfo.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/AutopilotIdentifyInfo.java new file mode 100644 index 0000000000..4091d0ceb3 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/AutopilotIdentifyInfo.java @@ -0,0 +1,75 @@ +package com.zhidao.support.adas.high.bean.record; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * @author song kenan + * @des + * @date 2021/8/26 + */ +public class AutopilotIdentifyInfo { + + @SerializedName("action") + private String action; + @SerializedName("result") + private Result result; + + public static class Result { + @SerializedName("panel") + private AutopilotRecordResult panel; + @SerializedName("passwd") + private String passwd; + @SerializedName("user") + private String user; + + public AutopilotRecordResult getPanel() { + return panel; + } + + public void setPanel(AutopilotRecordResult panel) { + this.panel = panel; + } + + public String getPasswd() { + return passwd; + } + + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public Result getResult() { + return result; + } + + public void setResult(Result result) { + this.result = result; + } + + @Override + public String toString() { + return "AutopilotIdentifyInfo{" + + "action='" + action + '\'' + + ", result=" + result + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/AutopilotRecordResult.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/AutopilotRecordResult.java new file mode 100644 index 0000000000..144b480fb5 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/AutopilotRecordResult.java @@ -0,0 +1,171 @@ +package com.zhidao.support.adas.high.bean.record; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * @author song kenan + * @ 自动驾驶数据采集结果 + * @date 2021/11/8 + */ +public class AutopilotRecordResult { + //磁盘可用空间(M) + @SerializedName("disk_free") + private Long diskFree; + //采集时长(秒) + @SerializedName("duration") + private double duration; + //保存的文件名 + @SerializedName("filename") + private String filename; + //其他信息,包含错误信息等 + @SerializedName("note") + private String note; + //域控制器定义的bag key + @SerializedName("key") + private String key; + //采集状态:100 - 采集成功,自动结束 + //101 - 采集成功,收到结束指令 + //102 -- 达到最大采集时长 + //103 --达到最大采集空间 + //200 - 采集失败 + //201 - 采集中 + //300 - 开始采集 + @SerializedName("stat") + private int stat; + //任务类型:1-badcase采集任务,2-地图数据采集任务 + @SerializedName("type") + private int type; + //任务id + @SerializedName("id") + private int id; + //时间戳,格式:YYYY-MM-DD-hh-mm-ss + @SerializedName("timestamp") + private String timestamp; + //此次数据总大小(M) + @SerializedName("total_size") + private Long totalSize; + //触发指令 + @SerializedName("triggerinfo") + private Triggerinfo triggerinfo; + //各topic数据量 + @SerializedName("records") + private List records; + + public static class Triggerinfo { + //是否为人工接管时自动采集:true - 自动采集 false - 手动触发 + @SerializedName("auto_trig") + private Boolean autoTrig; + //触发采集附带的信息,如任务ID,时间戳等。若为自动采集则此项忽略 + @SerializedName("trig_msg") + private String trigMsg; + + public Boolean getAutoTrig() { + return autoTrig; + } + + public String getTrigMsg() { + return trigMsg; + } + + @Override + public String toString() { + return "Triggerinfo{" + + "autoTrig=" + autoTrig + + ", trigMsg='" + trigMsg + '\'' + + '}'; + } + } + + public static class Records { + //数据记录数 + @SerializedName("nums") + private Integer nums; + //数据来源的topic名 + @SerializedName("topic") + private String topic; + + public Integer getNums() { + return nums; + } + + public String getTopic() { + return topic; + } + + @Override + public String toString() { + return "Records{" + + "nums=" + nums + + ", topic='" + topic + '\'' + + '}'; + } + } + + public Long getDiskFree() { + return diskFree; + } + + public double getDuration() { + return duration; + } + + public String getFilename() { + return filename; + } + + public String getNote() { + return note; + } + + public String getKey() { + return key; + } + + public List getRecords() { + return records; + } + + public int getStat() { + return stat; + } + + public int getType() { + return type; + } + + public int getId() { + return id; + } + + public String getTimestamp() { + return timestamp; + } + + public Long getTotalSize() { + return totalSize; + } + + public Triggerinfo getTriggerinfo() { + return triggerinfo; + } + + @Override + public String toString() { + return "AutopilotRecordResult{" + + "diskFree=" + diskFree + + ", duration=" + duration + + ", filename='" + filename + '\'' + + ", note='" + note + '\'' + + ", key='" + key + '\'' + + ", stat=" + stat + + ", type=" + type + + ", id=" + id + + ", timestamp='" + timestamp + '\'' + + ", totalSize=" + totalSize + + ", triggerinfo=" + triggerinfo + + ", records=" + records + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/RecordCauseParam.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/RecordCauseParam.java new file mode 100644 index 0000000000..9190a5fa01 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/RecordCauseParam.java @@ -0,0 +1,75 @@ +package com.zhidao.support.adas.high.bean.record; + +/** + * @author song kenan + * @des 采集类型 + * @date 2021/8/25 + */ + +public class RecordCauseParam { + private final String action = "record_cause"; + private Result result; + + public String getAction() { + return action; + } + + public Result getResult() { + return result; + } + + public void setResult(Result result) { + this.result = result; + } + + public static class Result{ + //bag key 唯一标识 + private String key; + //文件路径 + private String filename; + //接管原因 + private String reason; + //接管原因id + private String id; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + } + + @Override + public String toString() { + return "RecordDataParam{" + + "action='" + action + '\'' + + ", result='" + result + '\'' + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/RecordDataParam.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/RecordDataParam.java new file mode 100644 index 0000000000..f3ff1966a9 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/bean/record/RecordDataParam.java @@ -0,0 +1,113 @@ +package com.zhidao.support.adas.high.bean.record; + +/** + * @author song kenan + * @des + * @date 2021/8/25 + */ + +public class RecordDataParam { + private final String action = "record_data"; + private Result result; + + public String getAction() { + return action; + } + + public Result getResult() { + return result; + } + + public void setResult(Result result) { + this.result = result; + } + + public static class Result{ + //采集时间 + private String time; + //采集指令 true 采集 , false 停止采集 + private boolean isRecord; + //采集类型 1 badcase; 2 map; 3 rests + private int type; + //采集id + private int id; + //是否持续采集 + private boolean sustain; + //采集时间长 + private int duration; + //余留字段 + private String note; + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public boolean getIsRecord() { + return isRecord; + } + + public void setIsRecord(boolean isRecord) { + this.isRecord = isRecord; + } + + public boolean isRecord() { + return isRecord; + } + + public void setRecord(boolean record) { + isRecord = record; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean isSustain() { + return sustain; + } + + public void setSustain(boolean sustain) { + this.sustain = sustain; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + } + + @Override + public String toString() { + return "RecordDataParam{" + + "action='" + action + '\'' + + ", result='" + result + '\'' + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ActionTypeReceive.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ActionTypeReceive.java new file mode 100644 index 0000000000..469e6797d4 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ActionTypeReceive.java @@ -0,0 +1,148 @@ +package com.zhidao.support.adas.high.common; + +/** + * 接收的Action + * + * @author nie yunlong + * @description 请求值 + * @date 2018/7/3 + */ +public enum ActionTypeReceive { + + /** + * udp 消息渲染 action + */ + ACTION_WS_MSG_RENDER_TYPE("view", 0x101, "渲染流 渲染图像"), + /** + * 周边物体的状态 + */ + ACTION_WS_OBSTACLES_MESSAGE_TYPE("obstacles", -1, "周边物体的状态"), + /** + * 车道线渲染 + */ + ACTION_WS_LANES_MESSAGE_TYPE("lanes", -1, "车道线渲染"), + /** + * 车辆状态 + */ + ACTION_WS_CAR_STATE_TYPE("state", 0x102, "车辆状态"), + /** + * ws 报警消息 action + */ + ACTION_WS_MSG_WARNING_TYPE("warn", -1, "ws 报警消息"), + /** + * 红绿灯状态 + */ + ACTION_UDP_LIGHT_STATE_TYPE("light", -1, "udp 红绿灯状态"), + /** + * gps数据 + */ + ACTION_WS_GPS_TYPE("gdgps", -1, "gps 数据"), + /** + * 自动驾驶状态 + */ + ACTION_WS_AUTOPILOT_STATUE("autopilotstate", -1, "自动驾驶状态"), + /** + * 自动驾驶控制 + */ + ACTION_WS_AUTOPILOT_CONTROL("autopilotmode", -1, "自动驾驶控制"), + /** + * obu红绿灯数据 + */ + ACTION_WS_AI_CLOUD_OBU_RED_GREEN_LIGHT_TYPE("obuTrafficLight", -1, "obu红绿灯数据"), + /** + * ai云 + */ + ACTION_WS_AI_CLOUD_TYPE("aiCloudToStartAutopilot", -1, "云端控制自动驾驶"), + /** + * 图片大小 + */ + ACTION_WS_MSG_IMAGE_SIZE_TYPE("imagesize", -1, "ws 图片大小"), + /** + * ai云推送 在线车辆 + */ + ACTION_WS_AI_CLOUD_ONLINE_CAR_TYPE("aiCloudToOnLineCar", -1, "云端推送在线车辆"), + /** + * 自动驾驶站点通信 + */ + ACTION_WS_AUTOPILOT_WAY_ARRIVE("autopilotArrive", -1, "自动驾驶站点"), + /** + * 获取自动驾驶路径 + */ + ACTION_WS_AUTOPILOT_ROUTE("global_path", -1, "自动驾驶路径"), + /** + * 查询自动驾驶路径 + */ + ACTION_WS_AUTOPILOT_QUERY_ROUTE("query_global_path", -1, "查询自动驾驶路径"), + /** + * 工控机请求SN + */ + ACTION_WS_AUTOPILOT_SN_REQUEST("autopilotSN", -1, "工控机请求SN"), + /** + * 监控车辆节点 + */ + ACTION_WS_AUTOPILOT_GUARDIAN("guardian", 0x105, "监控车辆节点"), + /** + * BadCase数据采集 + */ + ACTION_WS_AUTOPILOT_IDENTIFY("identify", -1, "BadCase数据采集"), + /** + * 局部轨迹 车前引导钱 + */ + ACTION_WS_AUTOPILOT_TRAJECTORY("trajectory", 0x100, "局部轨迹 车前引导钱"), + /** + * car dock 基础信息 + */ + ACTION_WS_AUTOPILOT_CAR_CONFIG("car_config", -1, "car_config"), + /** + * 轨迹列表 routes + */ + ACTION_WS_AUTOPILOT_ROUTES("route_list", 0x104, "轨迹列表"), + /** + * 工控机升级状态 + */ + ACTION_WS_AUTOPILOT_UPGRADE_STATUS("ipc_upgrade_status", -1, "IPC升级状态"); + + /** + * 消息action 类型 + */ + String mActionType; + + /** + * 消息action code + */ + int mActionCode; + /** + * 描述 + */ + String mMsgDesc; + + ActionTypeReceive(String actionType, int actionCode, String msgDesc) { + this.mActionType = actionType; + this.mActionCode = actionCode; + this.mMsgDesc = msgDesc; + } + + public String getmActionType() { + return mActionType; + } + + public void setmActionType(String mActionType) { + this.mActionType = mActionType; + } + + public int getmActionCode() { + return mActionCode; + } + + public void setmActionCode(int mActionCode) { + this.mActionCode = mActionCode; + } + + public String getmMsgDesc() { + return mMsgDesc; + } + + public void setmMsgDesc(String mMsgDesc) { + this.mMsgDesc = mMsgDesc; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/AppPreferenceHelper.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/AppPreferenceHelper.java new file mode 100644 index 0000000000..bab5488aaf --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/AppPreferenceHelper.java @@ -0,0 +1,280 @@ +package com.zhidao.support.adas.high.common; + +import android.content.Context; +import android.content.SharedPreferences; +import android.text.TextUtils; +import android.util.Base64; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.bean.FaceLoginResponse; +import com.zhidao.support.adas.high.bean.UserInfo; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * Created by nie yunlong on 2018/4/13. + * sharePreference 操作 + * 根据 具体情况来写 + */ + +public class AppPreferenceHelper implements IPreferencesHelper { + + public static AppPreferenceHelper appPreferenceHelper; + /** + * 保存deviceId 文件名称 + */ + private final String UDP_RECEIVER_ADDRESS_FILE_NAME = "upd_receive"; + + /** + * 假的数据 share + */ + private final String FAKE_DATA_PRE_FILE_NAME = "data_fake"; + /** + * 用户信息 + */ + private final String USER_INFO_FILE_NAME = "user_info"; + + /** + * 保存raw + */ + private final String CONFIG_RAW_FILE_NAME = "raw_config"; + + private final String USER_NAME = "user_name"; + + + private final String CONFIG_PRE_FILE_NAME = "config"; + + /** + * 用户信息pre + */ + private final SharedPreferences mUserLoginInfoPre; + /** + * 假的数据share + */ + private final SharedPreferences mFakeDataPre; + + private final SharedPreferences mRawConfigPre; + /** + * 手机Id + */ + private SharedPreferences mDevicePre; + /** + * 配置标志位 + */ + private SharedPreferences mConfigPre; + /** + * 默认data + */ + private String defaultData = "{\"configInfoHistory\":[{\"kCode\":\"d_fcw_touch\",\"kName\":\"前车碰撞预警\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0},{\"kCode\":\"d_fcw_start\",\"kName\":\"前车启动提醒\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0},{\"kCode\":\"d_hdw_driver\",\"kName\":\"驾驶员疲劳/危险预警\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0},{\"kCode\":\"d_fcw_person\",\"kName\":\"行人碰撞预警\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0},{\"kCode\":\"d_hdw_sliding\",\"kName\":\"溜车碰撞预警\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0},{\"kCode\":\"d_ldw_out\",\"kName\":\"车道线偏离预警\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0},{\"kCode\":\"d_hmw_follow\",\"kName\":\"跟车距离预警\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0},{\"kCode\":\"d_volume_size\",\"kName\":\"音量大小\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"60\",\"userId\":0},{\"kCode\":\"is_use_ar_navBar\",\"kName\":\"是否使用AR导航\",\"kOrder\":1,\"kType\":\"aided_driving_dic\",\"kVal\":\"5\",\"userId\":0}]}"; + + public static AppPreferenceHelper getInstance(Context context) { + if (appPreferenceHelper == null) { + appPreferenceHelper = new AppPreferenceHelper(context.getApplicationContext()); + } + return appPreferenceHelper; + } + + private AppPreferenceHelper(Context context) { + mDevicePre = context.getSharedPreferences(UDP_RECEIVER_ADDRESS_FILE_NAME, Context.MODE_PRIVATE); + mUserLoginInfoPre = context.getSharedPreferences(USER_INFO_FILE_NAME, Context.MODE_PRIVATE); + mFakeDataPre = context.getSharedPreferences(FAKE_DATA_PRE_FILE_NAME, Context.MODE_PRIVATE); + mRawConfigPre = context.getSharedPreferences(CONFIG_RAW_FILE_NAME, Context.MODE_PRIVATE); + mConfigPre = context.getSharedPreferences(CONFIG_PRE_FILE_NAME, Context.MODE_PRIVATE); + } + + @Override + public void saveUdpClientAddress(String address) { + mDevicePre.edit().putString("upd_client_address", address).apply(); + } + + @Override + public String getUdpClientAddress() { + return mDevicePre.getString("upd_client_address", null); + } + + @Override + public void saveDockConfig(String dockConfig) { + mDevicePre.edit().putString("dock_version", dockConfig).apply(); + } + + @Override + public String getDockConfig() { + return mDevicePre.getString("dock_version", null); + } + + @Override + public void setUserInfo(FaceLoginResponse.DataBean loginResponse) { + + try { + saveUser(mUserLoginInfoPre, "userInfo", loginResponse); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + @Override + public FaceLoginResponse.DataBean getUserInfo() { + return getUser(mUserLoginInfoPre, "userInfo"); + } + + @Override + public void setConfigNaviMapVis(int selectIndex) { + mFakeDataPre.edit().putInt("selectIndex", selectIndex).apply(); + } + + @Override + public int getConfigNaviMapVis() { + return mFakeDataPre.getInt("selectIndex", 1); + } + + + private void saveUser(SharedPreferences sharedPreferences, String key, FaceLoginResponse.DataBean user) throws Exception { + if (user instanceof Serializable) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + ObjectOutputStream oos = new ObjectOutputStream(baos); + //把对象写到流里 + oos.writeObject(user); + String temp = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT)); + editor.putString(key, temp); + editor.commit(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + throw new Exception("User must implements Serializable"); + } + } + + + private FaceLoginResponse.DataBean getUser(SharedPreferences sharedPreferences, String key) { + String temp = sharedPreferences.getString(key, ""); + FaceLoginResponse.DataBean user = null; + try { + if (!TextUtils.isEmpty(temp)) { + ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT)); + ObjectInputStream ois = new ObjectInputStream(bais); + user = (FaceLoginResponse.DataBean) ois.readObject(); + } + } catch (IOException e) { + } catch (ClassNotFoundException e1) { + + } + try { + if (user == null) { + //是空的 使用默认的配置 + Gson gson = new Gson(); + FaceLoginResponse.DataBean dataConfig = gson.fromJson(defaultData, FaceLoginResponse.DataBean.class); + + saveUser(mUserLoginInfoPre, "userInfo", dataConfig); + } + } catch (Exception e) { + e.printStackTrace(); + } + return user; + } + + @Override + public void saveUserUnInfo(UserInfo userInfo) { + if (userInfo == null) { + userInfo = new UserInfo(); + } + if (userInfo instanceof Serializable) { + SharedPreferences.Editor editor = mUserLoginInfoPre.edit(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + ObjectOutputStream oos = new ObjectOutputStream(baos); + //把对象写到流里 + oos.writeObject(userInfo); + String temp = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT)); + editor.putString("userInfoId", temp); + editor.apply(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public UserInfo getUserUnInfo() { + String temp = mUserLoginInfoPre.getString("userInfoId", ""); + ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT)); + UserInfo user = null; + try { + ObjectInputStream ois = new ObjectInputStream(bais); + user = (UserInfo) ois.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } + if (user == null) { + user = new UserInfo(); + } + return user; + } + + @Override + public void setConfigInitResutl(boolean flag) { + mConfigPre.edit().putBoolean("configInit", flag).apply(); + } + + @Override + public boolean getConfigInitResutl() { + return mConfigPre.getBoolean("configInit", false); + } + + + @Override + public void setSelectCarInfo(String brand, String model, String style) { + mConfigPre.edit().putString("brand", brand).putString("model", model).putString("style", style).apply(); + } + + @Override + public String getSelectBrand() { + return mConfigPre.getString("brand", ""); + } + + @Override + public String getSelectModel() { + return mConfigPre.getString("model", ""); + } + + @Override + public String getSelectStyle() { + return mConfigPre.getString("style", ""); + } + + + + @Override + public void saveRawPath(int rawName, String rawPath) { + + mRawConfigPre.edit().putString("" + rawName, rawPath).apply(); + } + + @Override + public String getRawPath(int rawName) { + return mRawConfigPre.getString("" + rawName, ""); + } + + @Override + public void clearRawConfig(int rawName) { + mRawConfigPre.edit().putString("" + rawName, "").apply(); + } + + @Override + public void setAppAttachTime(long time) { + mRawConfigPre.edit().putLong("appAttachTime", time).commit(); + } + + @Override + public long getAppAttachTime() { + return mRawConfigPre.getLong("appAttachTime", 3000); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Base64.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Base64.java new file mode 100644 index 0000000000..16d63dfef1 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Base64.java @@ -0,0 +1,1033 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.zhidao.support.adas.high.common; + + +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; + + +/** + * Provides Base64 encoding and decoding as defined by RFC 2045. + * + *

+ * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. + *

+ *

+ * The class can be parameterized in the following manner with various constructors: + *

    + *
  • URL-safe mode: Default off.
  • + *
  • Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of + * 4 in the encoded data. + *
  • Line separator: Default is CRLF ("\r\n")
  • + *
+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode + * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). + *

+ * + * @see RFC 2045 + * @since 2.2 + */ +public class Base64 { + private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2; + + private static final int DEFAULT_BUFFER_SIZE = 8192; + /** + * An empty immutable {@code byte} array. + */ + private static final byte[] EMPTY_BTYE_ARRAY = new byte[0]; + /** + * Chunk size per RFC 2045 section 6.8. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 2045 section 6.8 + */ + static final int CHUNK_SIZE = 76; + + /** + * Chunk separator per RFC 2045 section 2.1. + * + * @see RFC 2045 section 2.1 + */ + private static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; + + /** + * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet" + * equivalents as specified in Table 1 of RFC 2045. + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] STANDARD_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + /** + * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / + * changed to - and _ to make the encoded Base64 results more URL-SAFE. + * This table is only used when the Base64's mode is set to URL-SAFE. + */ + private static final byte[] URL_SAFE_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' + }; + + /** + * Byte used to pad output. + */ + private static final byte PAD = '='; + + /** + * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in + * Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 + * alphabet but fall within the bounds of the array are translated to -1. + * + * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both + * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit). + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] DECODE_TABLE = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + }; + + /** Mask used to extract 6 bits, used when encoding */ + private static final int MASK_6BITS = 0x3f; + + /** Mask used to extract 8 bits, used in decoding base64 bytes */ + private static final int MASK_8BITS = 0xff; + + // The static final fields above are used for the original static byte[] methods on Base64. + // The private member fields below are used with the new streaming approach, which requires + // some state be preserved between calls of encode() and decode(). + + /** + * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able + * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch + * between the two modes. + */ + private final byte[] encodeTable; + + /** + * Line length for encoding. Not used when decoding. A value of zero or less implies no chunking of the base64 + * encoded data. + */ + private final int lineLength; + + /** + * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. + */ + private final byte[] lineSeparator; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * decodeSize = 3 + lineSeparator.length; + */ + private final int decodeSize; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * encodeSize = 4 + lineSeparator.length; + */ + private final int encodeSize; + + /** + * Buffer for streaming. + */ + private byte[] buffer; + + /** + * Position where next character should be written in the buffer. + */ + private int pos; + + /** + * Position where next character should be read from the buffer. + */ + private int readPos; + + /** + * Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to + * make sure each encoded line never goes beyond lineLength (if lineLength > 0). + */ + private int currentLinePos; + + /** + * Writes to the buffer only occur after every 3 reads when encoding, an every 4 reads when decoding. This variable + * helps track that. + */ + private int modulus; + + /** + * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this Base64 object becomes useless, + * and must be thrown away. + */ + private boolean eof; + + /** + * Place holder for the 3 bytes we're dealing with for our base64 logic. Bitwise operations store and extract the + * base64 encoding or decoding from this variable. + */ + private int x; + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ */ + public Base64() { + this(false); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode. + *

+ * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ * + * @param urlSafe + * if true, URL-safe encoding is used. In most cases this should be set to + * false. + * @since 1.4 + */ + public Base64(final boolean urlSafe) { + this(CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). + * If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored when decoding. + * @since 1.4 + */ + public Base64(final int lineLength) { + this(lineLength, CHUNK_SEPARATOR); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). + * If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored when decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @throws IllegalArgumentException + * Thrown when the provided lineSeparator included some base64 characters. + * @since 1.4 + */ + public Base64(final int lineLength, final byte[] lineSeparator) { + this(lineLength, lineSeparator, false); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). + * If {@code lineLength <= 0}, then the output will not be divided into lines (chunks). Ignored when decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @param urlSafe + * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode + * operations. Decoding seamlessly handles both modes. + * @throws IllegalArgumentException + * The provided lineSeparator included some base64 characters. That's not going to work! + * @since 1.4 + */ + public Base64(int lineLength, byte[] lineSeparator, final boolean urlSafe) { + if (lineSeparator == null) { + lineLength = 0; // disable chunk-separating + lineSeparator = EMPTY_BTYE_ARRAY; // this just gets ignored + } + this.lineLength = lineLength > 0 ? (lineLength / 4) * 4 : 0; + this.lineSeparator = new byte[lineSeparator.length]; + System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); + if (lineLength > 0) { + this.encodeSize = 4 + lineSeparator.length; + } else { + this.encodeSize = 4; + } + this.decodeSize = this.encodeSize - 1; + if (containsBase64Byte(lineSeparator)) { + final String sep = newStringUtf8(lineSeparator); + throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]"); + } + this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE; + } + + /** + * Returns our current encode mode. True if we're URL-SAFE, false otherwise. + * + * @return true if we're in URL-SAFE mode, false otherwise. + * @since 1.4 + */ + public boolean isUrlSafe() { + return this.encodeTable == URL_SAFE_ENCODE_TABLE; + } + + /** + * Returns true if this Base64 object has buffered data for reading. + * + * @return true if there is Base64 object still available for reading. + */ + boolean hasData() { + return this.buffer != null; + } + + /** + * Returns the amount of buffered data available for reading. + * + * @return The amount of buffered data available for reading. + */ + int avail() { + return buffer != null ? pos - readPos : 0; + } + + /** Doubles our buffer. */ + private void resizeBuffer() { + if (buffer == null) { + buffer = new byte[DEFAULT_BUFFER_SIZE]; + pos = 0; + readPos = 0; + } else { + final byte[] b = new byte[buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR]; + System.arraycopy(buffer, 0, b, 0, buffer.length); + buffer = b; + } + } + + /** + * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail + * bytes. Returns how many bytes were actually extracted. + * + * @param b + * byte[] array to extract the buffered data into. + * @param bPos + * position in byte[] array to start extraction at. + * @param bAvail + * amount of bytes we're allowed to extract. We may extract fewer (if fewer are available). + * @return The number of bytes successfully extracted into the provided byte[] array. + */ + int readResults(final byte[] b, final int bPos, final int bAvail) { + if (buffer != null) { + final int len = Math.min(avail(), bAvail); + if (buffer != b) { + System.arraycopy(buffer, readPos, b, bPos, len); + readPos += len; + if (readPos >= pos) { + buffer = null; + } + } else { + // Re-using the original consumer's output array is only + // allowed for one round. + buffer = null; + } + return len; + } + return eof ? -1 : 0; + } + + /** + * Sets the streaming buffer. This is a small optimization where we try to buffer directly to the consumer's output + * array for one round (if the consumer calls this method first) instead of starting our own buffer. + * + * @param out + * byte[] array to buffer directly to. + * @param outPos + * Position to start buffering into. + * @param outAvail + * Amount of bytes available for direct buffering. + */ + void setInitialBuffer(final byte[] out, final int outPos, final int outAvail) { + // We can re-use consumer's original output array under + // special circumstances, saving on some System.arraycopy(). + if (out != null && out.length == outAvail) { + buffer = out; + pos = outPos; + readPos = outPos; + } + } + + /** + *

+ * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with + * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last + * remaining bytes (if not multiple of 3). + *

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of binary data to base64 encode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + */ + void encode(final byte[] in, int inPos, final int inAvail) { + if (eof) { + return; + } + // inAvail < 0 is how we're informed of EOF in the underlying data we're + // encoding. + if (inAvail < 0) { + eof = true; + if (buffer == null || buffer.length - pos < encodeSize) { + resizeBuffer(); + } + switch (modulus) { + case 1 : + buffer[pos++] = encodeTable[(x >> 2) & MASK_6BITS]; + buffer[pos++] = encodeTable[(x << 4) & MASK_6BITS]; + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[pos++] = PAD; + buffer[pos++] = PAD; + } + break; + + case 2 : + buffer[pos++] = encodeTable[(x >> 10) & MASK_6BITS]; + buffer[pos++] = encodeTable[(x >> 4) & MASK_6BITS]; + buffer[pos++] = encodeTable[(x << 2) & MASK_6BITS]; + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[pos++] = PAD; + } + break; + default: + break; // other values ignored + } + if (lineLength > 0 && pos > 0) { + System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); + pos += lineSeparator.length; + } + } else { + for (int i = 0; i < inAvail; i++) { + if (buffer == null || buffer.length - pos < encodeSize) { + resizeBuffer(); + } + modulus = (++modulus) % 3; + int b = in[inPos++]; + if (b < 0) { + b += 256; + } + x = (x << 8) + b; + if (0 == modulus) { + buffer[pos++] = encodeTable[(x >> 18) & MASK_6BITS]; + buffer[pos++] = encodeTable[(x >> 12) & MASK_6BITS]; + buffer[pos++] = encodeTable[(x >> 6) & MASK_6BITS]; + buffer[pos++] = encodeTable[x & MASK_6BITS]; + currentLinePos += 4; + if (lineLength > 0 && lineLength <= currentLinePos) { + System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); + pos += lineSeparator.length; + currentLinePos = 0; + } + } + } + } + } + + /** + *

+ * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once + * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" + * call is not necessary when decoding, but it doesn't hurt, either. + *

+ *

+ * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are + * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, + * garbage-out philosophy: it will not check the provided data for validity. + *

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of ascii data to base64 decode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + */ + void decode(final byte[] in, int inPos, final int inAvail) { + if (eof) { + return; + } + if (inAvail < 0) { + eof = true; + } + for (int i = 0; i < inAvail; i++) { + if (buffer == null || buffer.length - pos < decodeSize) { + resizeBuffer(); + } + final byte b = in[inPos++]; + if (b == PAD) { + // We're done. + eof = true; + break; + } + if (b >= 0 && b < DECODE_TABLE.length) { + final int result = DECODE_TABLE[b]; + if (result >= 0) { + modulus = (++modulus) % 4; + x = (x << 6) + result; + if (modulus == 0) { + buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS); + buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS); + buffer[pos++] = (byte) (x & MASK_8BITS); + } + } + } + } + + // Two forms of EOF as far as base64 decoder is concerned: actual + // EOF (-1) and first time '=' character is encountered in stream. + // This approach makes the '=' padding characters completely optional. + if (eof && modulus != 0) { + x = x << 6; + switch (modulus) { + case 2 : + x = x << 6; + buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS); + break; + case 3 : + buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS); + buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS); + break; + default: + break; // other values ignored + } + } + } + + /** + * Returns whether or not the octet is in the base 64 alphabet. + * + * @param octet + * The value to test + * @return true if the value is defined in the the base 64 alphabet, false otherwise. + * @since 1.4 + */ + public static boolean isBase64(final byte octet) { + return octet == PAD || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return true if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; + * false, otherwise + */ + public static boolean isArrayByteBase64(final byte[] arrayOctet) { + for (final byte element : arrayOctet) { + if (!isBase64(element) && !isWhiteSpace(element)) { + return false; + } + } + return true; + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. + * + * @param arrayOctet + * byte array to test + * @return true if any byte is a valid character in the Base64 alphabet; false herwise + */ + private static boolean containsBase64Byte(final byte[] arrayOctet) { + for (final byte element : arrayOctet) + { + if (isBase64(element)) { + return true; + } + } + return false; + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + */ + public static byte[] encodeBase64(final byte[] binaryData) { + return encodeBase64(binaryData, false); + } + + /** + * Encodes binary data using the base64 algorithm into 76 character blocks separated by CRLF. + *

+ * For a non-chunking version, see {@link #encodeBase64StringUnChunked(byte[])}. + * + * @param binaryData + * binary data to encode + * @return String containing Base64 characters. + * @since 1.4 + */ + public static String encodeBase64String(final byte[] binaryData) { + return newStringUtf8(encodeBase64(binaryData, true)); + } + + /** + * Encodes binary data using the base64 algorithm, without using chunking. + *

+ * For a chunking version, see {@link #encodeBase64String(byte[])}. + * + * @param binaryData + * binary data to encode + * @return String containing Base64 characters. + * @since 3.2 + */ + public static String encodeBase64StringUnChunked(final byte[] binaryData) { + return newStringUtf8(encodeBase64(binaryData, false)); + } + + /** + * Encodes binary data using the base64 algorithm. + * + * @param binaryData + * binary data to encode + * @param useChunking whether to split the output into chunks + * @return String containing Base64 characters. + * @since 3.2 + */ + public static String encodeBase64String(final byte[] binaryData, final boolean useChunking) { + return newStringUtf8(encodeBase64(binaryData, useChunking)); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + * @since 1.4 + */ + public static byte[] encodeBase64URLSafe(final byte[] binaryData) { + return encodeBase64(binaryData, false, true); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * + * @param binaryData + * binary data to encode + * @return String containing Base64 characters + * @since 1.4 + */ + public static String encodeBase64URLSafeString(final byte[] binaryData) { + return newStringUtf8(encodeBase64(binaryData, false, true)); + } + + /** + * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks + * + * @param binaryData + * binary data to encode + * @return Base64 characters chunked in 76 character blocks + */ + public static byte[] encodeBase64Chunked(final byte[] binaryData) { + return encodeBase64(binaryData, true); + } + + /** + * Decodes a String containing containing characters in the Base64 alphabet. + * + * @param pArray + * A String containing Base64 character data + * @return a byte array containing binary data + * @since 1.4 + */ + public byte[] decode(final String pArray) { + return decode(getBytesUtf8(pArray)); + } + + private byte[] getBytesUtf8(final String pArray) { + return pArray.getBytes(StandardCharsets.UTF_8); + } + + /** + * Decodes a byte[] containing containing characters in the Base64 alphabet. + * + * @param pArray + * A byte array containing Base64 character data + * @return a byte array containing binary data + */ + public byte[] decode(final byte[] pArray) { + reset(); + if (pArray == null || pArray.length == 0) { + return pArray; + } + final long len = (pArray.length * 3) / 4; + final byte[] buf = new byte[(int) len]; + setInitialBuffer(buf, 0, buf.length); + decode(pArray, 0, pArray.length); + decode(pArray, 0, -1); // Notify decoder of EOF. + + // Would be nice to just return buf (like we sometimes do in the encode + // logic), but we have no idea what the line-length was (could even be + // variable). So we cannot determine ahead of time exactly how big an + // array is necessary. Hence the need to construct a 2nd byte array to + // hold the final result: + + final byte[] result = new byte[pos]; + readResults(result, 0, result.length); + return result; + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if true this encoder will chunk the base64 output into 76 character blocks + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked) { + return encodeBase64(binaryData, isChunked, false); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if true this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if true this encoder will emit - and _ instead of the usual + and / characters. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + * @since 1.4 + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe) { + return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if true this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if true this encoder will emit - and _ instead of the usual + and / characters. + * @param maxResultSize + * The maximum result size to accept. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than maxResultSize + * @since 1.4 + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe, + final int maxResultSize) { + if (binaryData == null || binaryData.length == 0) { + return binaryData; + } + + final long len = getEncodeLength(binaryData, isChunked ? CHUNK_SIZE : 0, + isChunked ? CHUNK_SEPARATOR : EMPTY_BTYE_ARRAY); + if (len > maxResultSize) { + throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + len + + ") than the specified maxium size of " + maxResultSize); + } + + final Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe); + return b64.encode(binaryData); + } + + /** + * Decodes a Base64 String into octets. + * + * @param base64String + * String containing Base64 data + * @return Array containing decoded data. + * @since 1.4 + */ + public static byte[] decodeBase64(final String base64String) { + return new Base64().decode(base64String); + } + + /** + * Decodes Base64 data into octets. + * + * @param base64Data + * Byte array containing Base64 data + * @return Array containing decoded data. + */ + public static byte[] decodeBase64(final byte[] base64Data) { + return new Base64().decode(base64Data); + } + + /** + * Checks if a byte value is whitespace or not. + * + * @param byteToCheck + * the byte to check + * @return true if byte is whitespace, false otherwise + */ + private static boolean isWhiteSpace(final byte byteToCheck) { + switch (byteToCheck) { + case ' ' : + case '\n' : + case '\r' : + case '\t' : + return true; + default : + return false; + } + } + + /** + * Encodes a byte[] containing binary data, into a String containing characters in the Base64 alphabet. + * + * @param pArray + * a byte array containing binary data + * @return A String containing only Base64 character data + * @since 1.4 + */ + public String encodeToString(final byte[] pArray) { + return newStringUtf8(encode(pArray)); + } + + private static String newStringUtf8(final byte[] encode) { + return new String(encode, StandardCharsets.UTF_8); + } + + /** + * Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet. + * + * @param pArray + * a byte array containing binary data + * @return A byte array containing only Base64 character data + */ + public byte[] encode(final byte[] pArray) { + reset(); + if (pArray == null || pArray.length == 0) { + return pArray; + } + final long len = getEncodeLength(pArray, lineLength, lineSeparator); + byte[] buf = new byte[(int) len]; + setInitialBuffer(buf, 0, buf.length); + encode(pArray, 0, pArray.length); + encode(pArray, 0, -1); // Notify encoder of EOF. + // Encoder might have resized, even though it was unnecessary. + if (buffer != buf) { + readResults(buf, 0, buf.length); + } + // In URL-SAFE mode we skip the padding characters, so sometimes our + // final length is a bit smaller. + if (isUrlSafe() && pos < buf.length) { + final byte[] smallerBuf = new byte[pos]; + System.arraycopy(buf, 0, smallerBuf, 0, pos); + buf = smallerBuf; + } + return buf; + } + + /** + * Pre-calculates the amount of space needed to base64-encode the supplied array. + * + * @param pArray byte[] array which will later be encoded + * @param chunkSize line-length of the output (<= 0 means no chunking) between each + * chunkSeparator (e.g. CRLF). + * @param chunkSeparator the sequence of bytes used to separate chunks of output (e.g. CRLF). + * + * @return amount of space needed to encoded the supplied array. Returns + * a long since a max-len array will require Integer.MAX_VALUE + 33%. + */ + private static long getEncodeLength(final byte[] pArray, int chunkSize, final byte[] chunkSeparator) { + // base64 always encodes to multiples of 4. + chunkSize = (chunkSize / 4) * 4; + + long len = (pArray.length * 4) / 3; + final long mod = len % 4; + if (mod != 0) { + len += 4 - mod; + } + if (chunkSize > 0) { + final boolean lenChunksPerfectly = len % chunkSize == 0; + len += (len / chunkSize) * chunkSeparator.length; + if (!lenChunksPerfectly) { + len += chunkSeparator.length; + } + } + return len; + } + + // Implementation of integer encoding used for crypto + /** + * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature + * + * @param pArray + * a byte array containing base64 character data + * @return A BigInteger + * @since 1.4 + */ + public static BigInteger decodeInteger(final byte[] pArray) { + return new BigInteger(1, decodeBase64(pArray)); + } + + /** + * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature + * + * @param bigInt + * a BigInteger + * @return A byte array containing base64 character data + * @throws NullPointerException + * if null is passed in + * @since 1.4 + */ + public static byte[] encodeInteger(final BigInteger bigInt) { + if (bigInt == null) { + throw new NullPointerException("encodeInteger called with null parameter"); + } + return encodeBase64(toIntegerBytes(bigInt), false); + } + + /** + * Returns a byte-array representation of a BigInteger without sign bit. + * + * @param bigInt + * BigInteger to be converted + * @return a byte array representation of the BigInteger parameter + */ + static byte[] toIntegerBytes(final BigInteger bigInt) { + int bitlen = bigInt.bitLength(); + // round bitlen + bitlen = ((bitlen + 7) >> 3) << 3; + final byte[] bigBytes = bigInt.toByteArray(); + + if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { + return bigBytes; + } + // set up params for copying everything but sign bit + int startSrc = 0; + int len = bigBytes.length; + + // if bigInt is exactly byte-aligned, just skip signbit in copy + if ((bigInt.bitLength() % 8) == 0) { + startSrc = 1; + len--; + } + final int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec + final byte[] resizedBytes = new byte[bitlen / 8]; + System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); + return resizedBytes; + } + + /** + * Resets this Base64 object to its initial newly constructed state. + */ + private void reset() { + buffer = null; + pos = 0; + readPos = 0; + currentLinePos = 0; + modulus = 0; + eof = false; + } + + // Getters for use in testing + + int getLineLength() { + return lineLength; + } + + byte[] getLineSeparator() { + return lineSeparator.clone(); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseIoUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseIoUtils.java new file mode 100644 index 0000000000..c5cbd962b6 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseIoUtils.java @@ -0,0 +1,84 @@ +package com.zhidao.support.adas.high.common; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Created by nie yunlong on 2018/4/9. + * IO 操作 + */ + +public class BaseIoUtils { + + public static final int DEFAULT_IMAGE_TOTAL_SIZE = 500 * 1024; // 500 Kb + + /** + * 从输入流中获取数据 + * + * @param inStream 输入流 + * @return + * @throws Exception + */ + public static byte[] readInputStreamToByte(InputStream inStream) throws Exception { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len = 0; + while ((len = inStream.read(buffer)) != -1) { + outStream.write(buffer, 0, len); + } + inStream.close(); + return outStream.toByteArray(); + } + + /** + * 从输入流中获取数据 + * + * @param inStream 输入流 + * @return + * @throws Exception + */ + public static String readInputStreamToString(InputStream inStream) throws Exception { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len = 0; + while ((len = inStream.read(buffer)) != -1) { + outStream.write(buffer, 0, len); + } + inStream.close(); + return outStream.toString("utf-8"); + } + + public static void closeSilently(Closeable closeable) { + + try { + if (closeable != null) { + closeable.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public static boolean copyStream(InputStream is, OutputStream os, int bufferSize) + throws IOException { + int current = 0; + int total = is.available(); + if (total <= 0) { + total = DEFAULT_IMAGE_TOTAL_SIZE; + } + + final byte[] bytes = new byte[bufferSize]; + int count; + while ((count = is.read(bytes, 0, bufferSize)) != -1) { + os.write(bytes, 0, count); + current += count; + } + os.flush(); + return true; + } + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseSDCardHelper.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseSDCardHelper.java new file mode 100644 index 0000000000..1fdceec991 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseSDCardHelper.java @@ -0,0 +1,276 @@ +package com.zhidao.support.adas.high.common; + +import android.content.Context; +import android.os.Environment; +import android.os.StatFs; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public class BaseSDCardHelper { + + // 判断SD卡是否被挂载 + public static boolean isSDCardMounted() { + // return Environment.getExternalStorageState().equals("mounted"); + return Environment.getExternalStorageState().equals( + Environment.MEDIA_MOUNTED); + } + + // 获取SD卡的根目录 + public static String getSDCardBaseDir() { + if (isSDCardMounted()) { + return Environment.getExternalStorageDirectory().getAbsolutePath(); + } + return null; + } + + + // 获取SD卡的完整空间大小,返回MB + public static long getSDCardSize() { + if (isSDCardMounted()) { + StatFs fs = new StatFs(getSDCardBaseDir()); + int count = fs.getBlockCount(); + int size = fs.getBlockSize(); + return count * size / 1024 / 1024; + } + return 0; + } + + // 获取SD卡的剩余空间大小 + public static long getSDCardFreeSize() { + if (isSDCardMounted()) { + StatFs fs = new StatFs(getSDCardBaseDir()); + int count = fs.getFreeBlocks(); + int size = fs.getBlockSize(); + return count * size / 1024 / 1024; + } + return 0; + } + + // 获取SD卡的可用空间大小 + public static long getSDCardAvailableSize() { + if (isSDCardMounted()) { + StatFs fs = new StatFs(getSDCardBaseDir()); + int count = fs.getAvailableBlocks(); + int size = fs.getBlockSize(); + return count * size / 1024 / 1024; + } + return 0; + } + + // 往SD卡的公有目录下保存文件 + public static boolean saveFileToSDCardPublicDir(byte[] data, String type, + String fileName) { + BufferedOutputStream bos = null; + if (isSDCardMounted()) { + File file = Environment.getExternalStoragePublicDirectory(type); + try { + bos = new BufferedOutputStream(new FileOutputStream(new File( + file, fileName))); + bos.write(data); + bos.flush(); + return true; + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + bos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return false; + } + + // 往SD卡的自定义目录下保存文件 + public static boolean saveFileToSDCardCustomDir(byte[] data, String dir, + String fileName) { + BufferedOutputStream bos = null; + if (isSDCardMounted()) { + File file = new File(getSDCardBaseDir() + File.separator + dir); + if (!file.exists()) { + file.mkdirs();// 递归创建自定义目录 + } + try { + bos = new BufferedOutputStream(new FileOutputStream(new File( + file, fileName))); + bos.write(data); + bos.flush(); + return true; + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + bos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return false; + } + + // 往SD卡的私有Files目录下保存文件 + public static boolean saveFileToSDCardPrivateFilesDir(byte[] data, + String type, String fileName, Context context) { + BufferedOutputStream bos = null; + if (isSDCardMounted()) { + File file = context.getExternalFilesDir(type); + try { + bos = new BufferedOutputStream(new FileOutputStream(new File( + file, fileName))); + bos.write(data); + bos.flush(); + return true; + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + bos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return false; + } + + // 往SD卡的私有Cache目录下保存文件 + public static boolean saveFileToSDCardPrivateCacheDir(byte[] data, + String fileName, Context context) { + BufferedOutputStream bos = null; + if (isSDCardMounted()) { + File file = context.getExternalCacheDir(); + try { + bos = new BufferedOutputStream(new FileOutputStream(new File( + file, fileName))); + bos.write(data); + bos.flush(); + return true; + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + bos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return false; + } + + // 从SD卡获取文件 + public static byte[] loadFileFromSDCard(String fileDir) { + BufferedInputStream bis = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try { + bis = new BufferedInputStream( + new FileInputStream(new File(fileDir))); + byte[] buffer = new byte[8 * 1024]; + int c = 0; + while ((c = bis.read(buffer)) != -1) { + baos.write(buffer, 0, c); + baos.flush(); + } + return baos.toByteArray(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + baos.close(); + if (bis != null) { + bis.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + // 获取SD卡公有目录的路径 + public static String getSDCardPublicDir(String type) { + return Environment.getExternalStoragePublicDirectory(type).toString(); + } + + // 获取SD卡私有Cache目录的路径 + public static String getSDCardPrivateCacheDir(Context context) { + return context.getExternalCacheDir().getAbsolutePath(); + } + + // 获取SD卡私有Files目录的路径 + public static String getSDCardPrivateFilesDir(Context context, String type) { + return context.getExternalFilesDir(type).getAbsolutePath(); + } + + // 获取SD卡文件目录的路径 + public static String getSDCardPrivateFilesDirOne(Context context, + String type) { + return Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + type; + } + + /* + * 获取sdcard绝对物理路径 + */ + public static String getSDCardPath() { + if (isSDCardMounted()) { + return Environment.getExternalStorageDirectory().getAbsolutePath(); + } else { + return null; + } + } + + /** + * 删除文件夹 + * @param path + */ + public static boolean deleteAllFilesOfDir(File path) { + if (!path.exists()){ + return false; + } + if (path.isFile()) { + path.delete(); + return true; + } + File[] files = path.listFiles(); + for (int i = 0; i < files.length; i++) { + deleteAllFilesOfDir(files[i]); + } + path.delete(); + System.out.println("删除文件夹成功"); + return true; + } + /** + * 删除文件夹2 + * @param path + */ + public static void deleteAllFilesOfDir2(File path) { + if (!path.exists()){ + return ; + } + if (path.isFile()) { + path.delete(); + return ; + } + File[] files = path.listFiles(); + for (int i = 0; i < files.length; i++) { + deleteAllFilesOfDir(files[i]); + } + path.delete(); + System.out.println("删除文件夹成功"); + } + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseTimeUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseTimeUtils.java new file mode 100644 index 0000000000..19d015f249 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/BaseTimeUtils.java @@ -0,0 +1,139 @@ +package com.zhidao.support.adas.high.common; + +import android.text.TextUtils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +/** + * @author nie yunlong + * @description + * @date 2018/7/25 + */ +public class BaseTimeUtils { + + + /** + * 格式化日期 + * + * @return + */ + public static String[] formatTimeDate() { + Date d = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd-HH:mm"); + String time = sdf.format(d); + if (!TextUtils.isEmpty(time) && time.contains("-")) { + String[] timeSplit = time.split("-"); + return timeSplit; + } + return null; + } + + /** + * 格式化时间 + * + * @param time + * @return + */ + public static String formatTimeDate1(long time) { + Date date = new Date(); + date.setTime(time); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + return sdf.format(date); + } + + /** + * 格式化时间 + * + * @param time + * @return + */ + public static String formatTimeDate(long time, String format) { + Date date = new Date(); + date.setTime(time); + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } + + /** + * 格式化时间 + * + * @return + */ + public static String formatTimeDate2() { + Date date = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.format(date); + } + + public static String formatTimeDate3() { + Date date = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss"); + return sdf.format(date); + } + + + /** + * + *

Description: 本地时间转化为UTC时间

+ * @param localTime + * @return + * @author wgs + * @date 2018年10月19日 下午2:23:43 + * + */ + public static Date localToUTC(String localTime) { +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// Date localDate= null; +// try { +// localDate = sdf.parse(localTime); +// } catch (ParseException e) { +// e.printStackTrace(); +// } + long localTimeInMillis=Long.parseLong(localTime); + /** long时间转换成Calendar */ + Calendar calendar= Calendar.getInstance(); + calendar.setTimeInMillis(localTimeInMillis); + /** 取得时间偏移量 */ + int zoneOffset = calendar.get(java.util.Calendar.ZONE_OFFSET); + /** 取得夏令时差 */ + int dstOffset = calendar.get(java.util.Calendar.DST_OFFSET); + /** 从本地时间里扣除这些差量,即可以取得UTC时间*/ + calendar.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset)); + /** 取得的时间就是UTC标准时间 */ + Date utcDate=new Date(calendar.getTimeInMillis()); + return utcDate; + } + + /** + * + *

Description:UTC时间转化为本地时间

+ * @param utcTime + * @return + * @author wgs + * @date 2018年10月19日 下午2:23:24 + * + */ + public static Date utcToLocal(String utcTime){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + Date utcDate = null; + try { + utcDate = sdf.parse(utcTime); + } catch (ParseException e) { + e.printStackTrace(); + } + sdf.setTimeZone(TimeZone.getDefault()); + Date locatlDate = null; + String localTime = sdf.format(utcDate.getTime()); + try { + locatlDate = sdf.parse(localTime); + } catch (ParseException e) { + e.printStackTrace(); + } + return locatlDate; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Constants.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Constants.java new file mode 100644 index 0000000000..8c24926f9f --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Constants.java @@ -0,0 +1,52 @@ +package com.zhidao.support.adas.high.common; + +/** + * @ProjectName: lib-adas-fpga + * @Package: PACKAGE_NAME + * @ClassName: com.zhidao.lib.adas.high.common.Constants + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/7 15:53 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/7 15:53 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public class Constants { + /** + * ws 主机地址 需要从udp里面获取 + */ + public static final String WS_IP_HOST_HEAD = "ws:"; + /** + * ws 端口以及资源名称 + */ + public static final String WS_PORT = ":4110/xvideo-detector"; + /** + * 端口 + */ + public static final String WS_PORT_=":4110"; + + /** + * 发送位置信息 action + */ + public static final int WS_SEND_LOCATION = 2; + + /** + * 查询自动驾驶轨迹 + */ + public static final String QUERY_GLOBAL_PATH = "{\"action\":\"query_global_path\",\"result\":null}"; + /** + * 查询节点信息 + */ + public static final String QUERY_GUARDIAN = "{\"action\":\"query_guardian\",\"result\":null}"; + + /** + * 查询docker版本 + */ + public static final String QUERY_CAR_CONFIG = "{\"action\":\"car_config\",\"result\":null}"; + + /** + * 查询轨迹 + */ + public static final String QUERY_ROUTES = "{\"action\":\"query_routes\",\"result\":null}"; +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/CupidLogUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/CupidLogUtils.java new file mode 100644 index 0000000000..1b3c9d2217 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/CupidLogUtils.java @@ -0,0 +1,85 @@ +package com.zhidao.support.adas.high.common; + +import android.util.Log; + +import com.zhidao.support.adas.high.BuildConfig; + +/** + * @author nie yunlong + * @description video-lib + * @date 2018/6/15 + */ +public class CupidLogUtils { + /** + * 默认是打开日志 + */ +// private static boolean mIsEnableLog = BuildConfig.DEBUG; + private static boolean mIsEnableLog = true; + /** + * 是否写日志 + */ + private static boolean isWriteLog = true; + + /** + * @param isEnableLog true开启 false关闭 + */ + public static void setEnableLog(boolean isEnableLog) { + mIsEnableLog = isEnableLog; + } + + + public static boolean isIsWriteLog() { + return isWriteLog; + } + + public static void setIsWriteLog(boolean isWriteLog) { + CupidLogUtils.isWriteLog = isWriteLog; + } + + public static void i(String tag, String msg) { + if (!mIsEnableLog) { + return; + } + Log.i(tag, msg); + } + + public static void w(String tag, String msg) { + if (!mIsEnableLog) { + return; + } + Log.w(tag, msg); + } + + public static void e(String tag, String msg) { + if (!mIsEnableLog) { + return; + } + Log.e(tag, msg); + } + + public static void e(String msg) { + if (!mIsEnableLog) { + return; + } + Log.e("elita_lib", msg); + } + + public static void w(String msg) { + if (!mIsEnableLog) { + return; + } + Log.e("elita_lib", msg); + } + + /** + * 写文件 + * + * @param msg + */ + public static void writeOwnerCarStateLog(String msg) { + if (!isWriteLog) { + return; + } + LogSaveManage.getInstance().saveWrite(msg); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/DigitalTrans.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/DigitalTrans.java new file mode 100644 index 0000000000..fe344bee47 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/DigitalTrans.java @@ -0,0 +1,516 @@ +package com.zhidao.support.adas.high.common; + +public class DigitalTrans { + + /** + * 数字字符串转ASCII码字符串 + * + * @param content 字符串 + * @return ASCII字符串 + */ + public static String StringToAsciiString(String content) { + String result = ""; + int max = content.length(); + for (int i = 0; i < max; i++) { + char c = content.charAt(i); + String b = Integer.toHexString(c); + result = result + b; + } + return result; + } + + /** + * 十六进制转字符串 + * + * @param hexString 十六进制字符串 + * @param encodeType 编码类型4:Unicode,2:普通编码 + * @return 字符串 + */ + public static String hexStringToString(String hexString, int encodeType) { + String result = ""; + int max = hexString.length() / encodeType; + for (int i = 0; i < max; i++) { + char c = (char) DigitalTrans.hexStringToAlgorism(hexString + .substring(i * encodeType, (i + 1) * encodeType)); + result += c; + } + return result; + } + + /** + * 十六进制字符串装十进制 + * + * @param hex 十六进制字符串 + * @return 十进制数值 + */ + public static int hexStringToAlgorism(String hex) { + hex = hex.toUpperCase(); + int max = hex.length(); + int result = 0; + for (int i = max; i > 0; i--) { + char c = hex.charAt(i - 1); + int algorism = 0; + if (c >= '0' && c <= '9') { + algorism = c - '0'; + } else { + algorism = c - 55; + } + result += Math.pow(16, max - i) * algorism; + } + return result; + } + + /** + * 十六转二进制 + * + * @param hex 十六进制字符串 + * @return 二进制字符串 + */ + public static String hexStringToBinary(String hex) { + hex = hex.toUpperCase(); + String result = ""; + int max = hex.length(); + for (int i = 0; i < max; i++) { + char c = hex.charAt(i); + switch (c) { + case '0': + result += "0000"; + break; + case '1': + result += "0001"; + break; + case '2': + result += "0010"; + break; + case '3': + result += "0011"; + break; + case '4': + result += "0100"; + break; + case '5': + result += "0101"; + break; + case '6': + result += "0110"; + break; + case '7': + result += "0111"; + break; + case '8': + result += "1000"; + break; + case '9': + result += "1001"; + break; + case 'A': + result += "1010"; + break; + case 'B': + result += "1011"; + break; + case 'C': + result += "1100"; + break; + case 'D': + result += "1101"; + break; + case 'E': + result += "1110"; + break; + case 'F': + result += "1111"; + break; + } + } + return result; + } + + /** + * ASCII码字符串转数字字符串 + * + * @param content ASCII字符串 + * @return 字符串 + */ + public static String AsciiStringToString(String content) { + String result = ""; + int length = content.length() / 2; + for (int i = 0; i < length; i++) { + String c = content.substring(i * 2, i * 2 + 2); + int a = hexStringToAlgorism(c); + char b = (char) a; + String d = String.valueOf(b); + result += d; + } + return result; + } + + /** + * 将十进制转换为指定长度的十六进制字符串 + * + * @param algorism int 十进制数字 + * @param maxLength int 转换后的十六进制字符串长度 + * @return String 转换后的十六进制字符串 + */ + public static String algorismToHEXString(int algorism, int maxLength) { + String result = ""; + result = Integer.toHexString(algorism); + + if (result.length() % 2 == 1) { + result = "0" + result; + } + return patchHexString(result.toUpperCase(), maxLength); + } + + /** + * 字节数组转为普通字符串(ASCII对应的字符) + * + * @param bytearray byte[] + * @return String + */ + public static String bytetoString(byte[] bytearray) { + String result = ""; + char temp; + + int length = bytearray.length; + for (int i = 0; i < length; i++) { + temp = (char) bytearray[i]; + result += temp; + } + return result; + } + + /** + * 二进制字符串转十进制 + * + * @param binary 二进制字符串 + * @return 十进制数值 + */ + public static int binaryToAlgorism(String binary) { + int max = binary.length(); + int result = 0; + for (int i = max; i > 0; i--) { + char c = binary.charAt(i - 1); + int algorism = c - '0'; + result += Math.pow(2, max - i) * algorism; + } + return result; + } + + /** + * 十进制转换为十六进制字符串 + * + * @param algorism int 十进制的数字 + * @return String 对应的十六进制字符串 + */ + public static String algorismToHEXString(int algorism) { + String result = ""; + result = Integer.toHexString(algorism); + + if (result.length() % 2 == 1) { + result = "0" + result; + + } + result = result.toUpperCase(); + + return result; + } + + /** + * HEX字符串前补0,主要用于长度位数不足。 + * + * @param str String 需要补充长度的十六进制字符串 + * @param maxLength int 补充后十六进制字符串的长度 + * @return 补充结果 + */ + static public String patchHexString(String str, int maxLength) { + String temp = ""; + for (int i = 0; i < maxLength - str.length(); i++) { + temp = "0" + temp; + } + str = (temp + str).substring(0, maxLength); + return str; + } + + /** + * 将一个字符串转换为int + * + * @param s String 要转换的字符串 + * @param defaultInt int 如果出现异常,默认返回的数字 + * @param radix int 要转换的字符串是什么进制的,如16 8 10. + * @return int 转换后的数字 + */ + public static int parseToInt(String s, int defaultInt, int radix) { + int i = 0; + try { + i = Integer.parseInt(s, radix); + } catch (NumberFormatException ex) { + i = defaultInt; + } + return i; + } + + /** + * 将一个十进制形式的数字字符串转换为int + * + * @param s String 要转换的字符串 + * @param defaultInt int 如果出现异常,默认返回的数字 + * @return int 转换后的数字 + */ + public static int parseToInt(String s, int defaultInt) { + int i = 0; + try { + i = Integer.parseInt(s); + } catch (NumberFormatException ex) { + i = defaultInt; + } + return i; + } + + /** + * 十六进制字符串转为Byte数组,每两个十六进制字符转为一个Byte + * + * @param hex 十六进制字符串 + * @return byte 转换结果 + */ + public static byte[] hexStringToByte(String hex) { + int max = hex.length() / 2; + byte[] bytes = new byte[max]; + String binarys = DigitalTrans.hexStringToBinary(hex); + for (int i = 0; i < max; i++) { + bytes[i] = (byte) DigitalTrans.binaryToAlgorism(binarys.substring( + i * 8 + 1, (i + 1) * 8)); + if (binarys.charAt(8 * i) == '1') { + bytes[i] = (byte) (0 - bytes[i]); + } + } + return bytes; + } + + /** + * 十六进制串转化为byte数组 + * + * @return the array of byte + */ + public static final byte[] hex2byte(String hex) + throws IllegalArgumentException { + if (hex.length() % 2 != 0) { + throw new IllegalArgumentException(); + } + char[] arr = hex.toCharArray(); + byte[] b = new byte[hex.length() / 2]; + for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) { + String swap = "" + arr[i++] + arr[i]; + int byteint = Integer.parseInt(swap, 16) & 0xFF; + b[j] = new Integer(byteint).byteValue(); + } + return b; + } + + /** + * 字节数组转换为十六进制字符串 + * + * @param b byte[] 需要转换的字节数组 + * @return String 十六进制字符串 + */ + public static final String byte2hex(byte b[]) { + if (b == null) { + throw new IllegalArgumentException( + "Argument b ( byte array ) is null! "); + } + String hs = ""; + String stmp = ""; + for (int n = 0; n < b.length; n++) { + stmp = Integer.toHexString(b[n] & 0xff); + if (stmp.length() == 1) { + hs = hs + "0" + stmp; + } else { + hs = hs + stmp; + } + } + return hs.toUpperCase(); + } + + /** + * 字符串转换成十六进制字符串 + * + * @param String str 待转换的ASCII字符串 + * @return String 每个Byte之间空格分隔,如: [61 6C 6B] + */ + public static String str2HexStr(String str) { + + char[] chars = "0123456789ABCDEF".toCharArray(); + StringBuilder sb = new StringBuilder(""); + byte[] bs = str.getBytes(); + int bit; + + for (int i = 0; i < bs.length; i++) { + bit = (bs[i] & 0x0f0) >> 4; + sb.append(chars[bit]); + bit = bs[i] & 0x0f; + sb.append(chars[bit]); + sb.append(' '); + } + return sb.toString().trim(); + } + + /** + * 十六进制转换字符串 + * + * @param String str Byte字符串(Byte之间无分隔符 如:[616C6B]) + * @return String 对应的字符串 + */ + public static String hexStr2Str(String hexStr) { + String str = "0123456789ABCDEF"; + char[] hexs = hexStr.toCharArray(); + byte[] bytes = new byte[hexStr.length() / 2]; + int n; + + for (int i = 0; i < bytes.length; i++) { + n = str.indexOf(hexs[2 * i]) * 16; + n += str.indexOf(hexs[2 * i + 1]); + bytes[i] = (byte) (n & 0xff); + } + return new String(bytes); + } + + /** + * bytes转换成十六进制字符串 + * + * @param byte[] b byte数组 + * @return String 每个Byte值之间空格分隔 + */ + public static String byte2HexStr(byte[] b) { + String stmp = ""; + StringBuilder sb = new StringBuilder(""); + for (int n = 0; n < b.length; n++) { + stmp = Integer.toHexString(b[n] & 0xFF); + sb.append((stmp.length() == 1) ? "0" + stmp : stmp); + sb.append(" "); + } + return sb.toString().toUpperCase().trim(); + } + + /** + * bytes字符串转换为Byte值 + * + * @param String src Byte字符串,每个Byte之间没有分隔符 + * @return byte[] + */ + public static byte[] hexStr2Bytes(String src) { + int m = 0, n = 0; + int l = src.length() / 2; + System.out.println(l); + byte[] ret = new byte[l]; + for (int i = 0; i < l; i++) { + m = i * 2 + 1; + n = m + 1; + ret[i] = Byte.decode("0x" + src.substring(i * 2, m) + src.substring(m, n)); + } + return ret; + } + + /** + * String的字符串转换成unicode的String + * + * @param String strText 全角字符串 + * @return String 每个unicode之间无分隔符 + * @throws Exception + */ + public static String strToUnicode(String strText) + throws Exception { + char c; + StringBuilder str = new StringBuilder(); + int intAsc; + String strHex; + for (int i = 0; i < strText.length(); i++) { + c = strText.charAt(i); + intAsc = (int) c; + strHex = Integer.toHexString(intAsc); + if (intAsc > 128) + str.append("\\u" + strHex); + else // 低位在前面补00 + str.append("\\u00" + strHex); + } + return str.toString(); + } + + /** + * unicode的String转换成String的字符串 + * + * @param String hex 16进制值字符串 (一个unicode为2byte) + * @return String 全角字符串 + */ + public static String unicodeToString(String hex) { + int t = hex.length() / 6; + StringBuilder str = new StringBuilder(); + for (int i = 0; i < t; i++) { + String s = hex.substring(i * 6, (i + 1) * 6); + // 高位需要补上00再转 + String s1 = s.substring(2, 4) + "00"; + // 低位直接转 + String s2 = s.substring(4); + // 将16进制的string转为int + int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16); + // 将int转换为字符 + char[] chars = Character.toChars(n); + str.append(new String(chars)); + } + return str.toString(); + } + + /** + * 整型数据拆分为长度为2的字节数组,低8位存放在序号小的元素,高8位存放在序号大的元素中(大端存储) + * + * @param data + * @return + */ + public static byte[] intTo2Byte(int data) { + byte[] byteArray = new byte[2]; + byteArray[0] = (byte) (data >> 8); + byteArray[1] = (byte) data; + return byteArray; + } + + /** + * 将两个字节拼接还原成无符号的整型数据 + * 数据域中的数据都按小端存储,示例:数据0x1234,则Byte0为0x34,Byte1为0x12 + * + * @param byte1 + * @param byte2 + * @return + */ + public static int joint2ByteToInt(byte byte1, byte byte2) { + int result = byte1 & 0xFF; + result = (result << 8) | (0x00FF & byte2); + return result; + } + + /** + * 拼接两个byte[] + * + * @param + * @param + * @return + */ + public static byte[] concatBytes(byte[] bt1, byte[] bt2) { + if (bt1 == null) { + return bt2; + } + if (bt2 == null) { + return bt1; + } + byte[] bt3 = new byte[bt1.length + bt2.length]; + System.arraycopy(bt1, 0, bt3, 0, bt1.length); + System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length); + return bt3; + } + + //获得本机cpu大小端 + public static boolean isBigendian() { + short i = 0x1; + boolean bRet = ((i >> 8) == 0x1); + return bRet; + } + +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/FileUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/FileUtils.java new file mode 100644 index 0000000000..4376c74e9a --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/FileUtils.java @@ -0,0 +1,1543 @@ +package com.zhidao.support.adas.high.common; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.net.URL; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import javax.net.ssl.HttpsURLConnection; + +/** + *
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2016/05/03
+ *     desc  : utils about file
+ * 
+ */ +public final class FileUtils { + + private static final String LINE_SEP = System.getProperty("line.separator"); + + private FileUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * Return the file by path. + * + * @param filePath The path of file. + * @return the file + */ + public static File getFileByPath(final String filePath) { + return isSpace(filePath) ? null : new File(filePath); + } + + /** + * Return whether the file exists. + * + * @param filePath The path of file. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isFileExists(final String filePath) { + return isFileExists(getFileByPath(filePath)); + } + + /** + * Return whether the file exists. + * + * @param file The file. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isFileExists(final File file) { + return file != null && file.exists(); + } + + /** + * Rename the file. + * + * @param filePath The path of file. + * @param newName The new name of file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean rename(final String filePath, final String newName) { + return rename(getFileByPath(filePath), newName); + } + + /** + * Rename the file. + * + * @param file The file. + * @param newName The new name of file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean rename(final File file, final String newName) { + // file is null then return false + if (file == null) return false; + // file doesn't exist then return false + if (!file.exists()) return false; + // the new name is space then return false + if (isSpace(newName)) return false; + // the new name equals old name then return true + if (newName.equals(file.getName())) return true; + File newFile = new File(file.getParent() + File.separator + newName); + // the new name of file exists then return false + return !newFile.exists() + && file.renameTo(newFile); + } + + /** + * Return whether it is a directory. + * + * @param dirPath The path of directory. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isDir(final String dirPath) { + return isDir(getFileByPath(dirPath)); + } + + /** + * Return whether it is a directory. + * + * @param file The file. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isDir(final File file) { + return file != null && file.exists() && file.isDirectory(); + } + + /** + * Return whether it is a file. + * + * @param filePath The path of file. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isFile(final String filePath) { + return isFile(getFileByPath(filePath)); + } + + /** + * Return whether it is a file. + * + * @param file The file. + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isFile(final File file) { + return file != null && file.exists() && file.isFile(); + } + + /** + * Create a directory if it doesn't exist, otherwise do nothing. + * + * @param dirPath The path of directory. + * @return {@code true}: exists or creates successfully
{@code false}: otherwise + */ + public static boolean createOrExistsDir(final String dirPath) { + return createOrExistsDir(getFileByPath(dirPath)); + } + + /** + * Create a directory if it doesn't exist, otherwise do nothing. + * + * @param file The file. + * @return {@code true}: exists or creates successfully
{@code false}: otherwise + */ + public static boolean createOrExistsDir(final File file) { + return file != null && (file.exists() ? file.isDirectory() : file.mkdirs()); + } + + /** + * Create a file if it doesn't exist, otherwise do nothing. + * + * @param filePath The path of file. + * @return {@code true}: exists or creates successfully
{@code false}: otherwise + */ + public static boolean createOrExistsFile(final String filePath) { + return createOrExistsFile(getFileByPath(filePath)); + } + + /** + * Create a file if it doesn't exist, otherwise do nothing. + * + * @param file The file. + * @return {@code true}: exists or creates successfully
{@code false}: otherwise + */ + public static boolean createOrExistsFile(final File file) { + if (file == null) return false; + if (file.exists()) return file.isFile(); + if (!createOrExistsDir(file.getParentFile())) return false; + try { + return file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Create a file if it doesn't exist, otherwise delete old file before creating. + * + * @param filePath The path of file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean createFileByDeleteOldFile(final String filePath) { + return createFileByDeleteOldFile(getFileByPath(filePath)); + } + + /** + * Create a file if it doesn't exist, otherwise delete old file before creating. + * + * @param file The file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean createFileByDeleteOldFile(final File file) { + if (file == null) return false; + // file exists and unsuccessfully delete then return false + if (file.exists() && !file.delete()) return false; + if (!createOrExistsDir(file.getParentFile())) return false; + try { + return file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Copy the directory. + * + * @param srcDirPath The path of source directory. + * @param destDirPath The path of destination directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyDir(final String srcDirPath, + final String destDirPath) { + return copyDir(getFileByPath(srcDirPath), getFileByPath(destDirPath)); + } + + /** + * Copy the directory. + * + * @param srcDirPath The path of source directory. + * @param destDirPath The path of destination directory. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyDir(final String srcDirPath, + final String destDirPath, + final OnReplaceListener listener) { + return copyDir(getFileByPath(srcDirPath), getFileByPath(destDirPath), listener); + } + + /** + * Copy the directory. + * + * @param srcDir The source directory. + * @param destDir The destination directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyDir(final File srcDir, + final File destDir) { + return copyOrMoveDir(srcDir, destDir, false); + } + + /** + * Copy the directory. + * + * @param srcDir The source directory. + * @param destDir The destination directory. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyDir(final File srcDir, + final File destDir, + final OnReplaceListener listener) { + return copyOrMoveDir(srcDir, destDir, listener, false); + } + + /** + * Copy the file. + * + * @param srcFilePath The path of source file. + * @param destFilePath The path of destination file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyFile(final String srcFilePath, + final String destFilePath) { + return copyFile(getFileByPath(srcFilePath), getFileByPath(destFilePath)); + } + + /** + * Copy the file. + * + * @param srcFilePath The path of source file. + * @param destFilePath The path of destination file. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyFile(final String srcFilePath, + final String destFilePath, + final OnReplaceListener listener) { + return copyFile(getFileByPath(srcFilePath), getFileByPath(destFilePath), listener); + } + + /** + * Copy the file. + * + * @param srcFile The source file. + * @param destFile The destination file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyFile(final File srcFile, + final File destFile) { + return copyOrMoveFile(srcFile, destFile, false); + } + + /** + * Copy the file. + * + * @param srcFile The source file. + * @param destFile The destination file. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean copyFile(final File srcFile, + final File destFile, + final OnReplaceListener listener) { + return copyOrMoveFile(srcFile, destFile, listener, false); + } + + /** + * Move the directory. + * + * @param srcDirPath The path of source directory. + * @param destDirPath The path of destination directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveDir(final String srcDirPath, + final String destDirPath) { + return moveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath)); + } + + /** + * Move the directory. + * + * @param srcDirPath The path of source directory. + * @param destDirPath The path of destination directory. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveDir(final String srcDirPath, + final String destDirPath, + final OnReplaceListener listener) { + return moveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath), listener); + } + + /** + * Move the directory. + * + * @param srcDir The source directory. + * @param destDir The destination directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveDir(final File srcDir, + final File destDir) { + return copyOrMoveDir(srcDir, destDir, true); + } + + /** + * Move the directory. + * + * @param srcDir The source directory. + * @param destDir The destination directory. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveDir(final File srcDir, + final File destDir, + final OnReplaceListener listener) { + return copyOrMoveDir(srcDir, destDir, listener, true); + } + + /** + * Move the file. + * + * @param srcFilePath The path of source file. + * @param destFilePath The path of destination file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveFile(final String srcFilePath, + final String destFilePath) { + return moveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath)); + } + + /** + * Move the file. + * + * @param srcFilePath The path of source file. + * @param destFilePath The path of destination file. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveFile(final String srcFilePath, + final String destFilePath, + final OnReplaceListener listener) { + return moveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath), listener); + } + + /** + * Move the file. + * + * @param srcFile The source file. + * @param destFile The destination file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveFile(final File srcFile, + final File destFile) { + return copyOrMoveFile(srcFile, destFile, true); + } + + /** + * Move the file. + * + * @param srcFile The source file. + * @param destFile The destination file. + * @param listener The replace listener. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean moveFile(final File srcFile, + final File destFile, + final OnReplaceListener listener) { + return copyOrMoveFile(srcFile, destFile, listener, true); + } + + private static boolean copyOrMoveDir(final File srcDir, + final File destDir, + final boolean isMove) { + return copyOrMoveDir(srcDir, destDir, new OnReplaceListener() { + @Override + public boolean onReplace() { + return true; + } + }, isMove); + } + + private static boolean copyOrMoveDir(final File srcDir, + final File destDir, + final OnReplaceListener listener, + final boolean isMove) { + if (srcDir == null || destDir == null) return false; + // destDir's path locate in srcDir's path then return false + String srcPath = srcDir.getPath() + File.separator; + String destPath = destDir.getPath() + File.separator; + if (destPath.contains(srcPath)) return false; + if (!srcDir.exists() || !srcDir.isDirectory()) return false; + if (destDir.exists()) { + if (listener == null || listener.onReplace()) {// require delete the old directory + if (!deleteAllInDir(destDir)) {// unsuccessfully delete then return false + return false; + } + } else { + return true; + } + } + if (!createOrExistsDir(destDir)) return false; + File[] files = srcDir.listFiles(); + for (File file : files) { + File oneDestFile = new File(destPath + file.getName()); + if (file.isFile()) { + if (!copyOrMoveFile(file, oneDestFile, listener, isMove)) return false; + } else if (file.isDirectory()) { + if (!copyOrMoveDir(file, oneDestFile, listener, isMove)) return false; + } + } + return !isMove || deleteDir(srcDir); + } + + private static boolean copyOrMoveFile(final File srcFile, + final File destFile, + final boolean isMove) { + return copyOrMoveFile(srcFile, destFile, new OnReplaceListener() { + @Override + public boolean onReplace() { + return true; + } + }, isMove); + } + + private static boolean copyOrMoveFile(final File srcFile, + final File destFile, + final OnReplaceListener listener, + final boolean isMove) { + if (srcFile == null || destFile == null) return false; + // srcFile equals destFile then return false + if (srcFile.equals(destFile)) return false; + // srcFile doesn't exist or isn't a file then return false + if (!srcFile.exists() || !srcFile.isFile()) return false; + if (destFile.exists()) { + if (listener == null || listener.onReplace()) {// require delete the old file + if (!destFile.delete()) {// unsuccessfully delete then return false + return false; + } + } else { + return true; + } + } + if (!createOrExistsDir(destFile.getParentFile())) return false; + try { + return writeFileFromIS(destFile, new FileInputStream(srcFile)) + && !(isMove && !deleteFile(srcFile)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return false; + } + } + + /** + * Delete the directory. + * + * @param filePath The path of file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean delete(final String filePath) { + return delete(getFileByPath(filePath)); + } + + /** + * Delete the directory. + * + * @param file The file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean delete(final File file) { + if (file == null) return false; + if (file.isDirectory()) { + return deleteDir(file); + } + return deleteFile(file); + } + + /** + * Delete the directory. + * + * @param dirPath The path of directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteDir(final String dirPath) { + return deleteDir(getFileByPath(dirPath)); + } + + /** + * Delete the directory. + * + * @param dir The directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteDir(final File dir) { + if (dir == null) return false; + // dir doesn't exist then return true + if (!dir.exists()) return true; + // dir isn't a directory then return false + if (!dir.isDirectory()) return false; + File[] files = dir.listFiles(); + if (files != null && files.length != 0) { + for (File file : files) { + if (file.isFile()) { + if (!file.delete()) return false; + } else if (file.isDirectory()) { + if (!deleteDir(file)) return false; + } + } + } + return dir.delete(); + } + + /** + * Delete the file. + * + * @param srcFilePath The path of source file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteFile(final String srcFilePath) { + return deleteFile(getFileByPath(srcFilePath)); + } + + /** + * Delete the file. + * + * @param file The file. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteFile(final File file) { + return file != null && (!file.exists() || file.isFile() && file.delete()); + } + + /** + * Delete the all in directory. + * + * @param dirPath The path of directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteAllInDir(final String dirPath) { + return deleteAllInDir(getFileByPath(dirPath)); + } + + /** + * Delete the all in directory. + * + * @param dir The directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteAllInDir(final File dir) { + return deleteFilesInDirWithFilter(dir, new FileFilter() { + @Override + public boolean accept(File pathname) { + return true; + } + }); + } + + /** + * Delete all files in directory. + * + * @param dirPath The path of directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteFilesInDir(final String dirPath) { + return deleteFilesInDir(getFileByPath(dirPath)); + } + + /** + * Delete all files in directory. + * + * @param dir The directory. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteFilesInDir(final File dir) { + return deleteFilesInDirWithFilter(dir, new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.isFile(); + } + }); + } + + /** + * Delete all files that satisfy the filter in directory. + * + * @param dirPath The path of directory. + * @param filter The filter. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteFilesInDirWithFilter(final String dirPath, + final FileFilter filter) { + return deleteFilesInDirWithFilter(getFileByPath(dirPath), filter); + } + + /** + * Delete all files that satisfy the filter in directory. + * + * @param dir The directory. + * @param filter The filter. + * @return {@code true}: success
{@code false}: fail + */ + public static boolean deleteFilesInDirWithFilter(final File dir, final FileFilter filter) { + if (dir == null) return false; + // dir doesn't exist then return true + if (!dir.exists()) return true; + // dir isn't a directory then return false + if (!dir.isDirectory()) return false; + File[] files = dir.listFiles(); + if (files != null && files.length != 0) { + for (File file : files) { + if (filter.accept(file)) { + if (file.isFile()) { + if (!file.delete()) return false; + } else if (file.isDirectory()) { + if (!deleteDir(file)) return false; + } + } + } + } + return true; + } + + /** + * Return the files in directory. + *

Doesn't traverse subdirectories

+ * + * @param dirPath The path of directory. + * @return the files in directory + */ + public static List listFilesInDir(final String dirPath) { + return listFilesInDir(dirPath, false); + } + + /** + * Return the files in directory. + *

Doesn't traverse subdirectories

+ * + * @param dir The directory. + * @return the files in directory + */ + public static List listFilesInDir(final File dir) { + return listFilesInDir(dir, false); + } + + /** + * Return the files in directory. + * + * @param dirPath The path of directory. + * @param isRecursive True to traverse subdirectories, false otherwise. + * @return the files in directory + */ + public static List listFilesInDir(final String dirPath, final boolean isRecursive) { + return listFilesInDir(getFileByPath(dirPath), isRecursive); + } + + /** + * Return the files in directory. + * + * @param dir The directory. + * @param isRecursive True to traverse subdirectories, false otherwise. + * @return the files in directory + */ + public static List listFilesInDir(final File dir, final boolean isRecursive) { + return listFilesInDirWithFilter(dir, new FileFilter() { + @Override + public boolean accept(File pathname) { + return true; + } + }, isRecursive); + } + + /** + * Return the files that satisfy the filter in directory. + *

Doesn't traverse subdirectories

+ * + * @param dirPath The path of directory. + * @param filter The filter. + * @return the files that satisfy the filter in directory + */ + public static List listFilesInDirWithFilter(final String dirPath, + final FileFilter filter) { + return listFilesInDirWithFilter(getFileByPath(dirPath), filter, false); + } + + /** + * Return the files that satisfy the filter in directory. + *

Doesn't traverse subdirectories

+ * + * @param dir The directory. + * @param filter The filter. + * @return the files that satisfy the filter in directory + */ + public static List listFilesInDirWithFilter(final File dir, + final FileFilter filter) { + return listFilesInDirWithFilter(dir, filter, false); + } + + /** + * Return the files that satisfy the filter in directory. + * + * @param dirPath The path of directory. + * @param filter The filter. + * @param isRecursive True to traverse subdirectories, false otherwise. + * @return the files that satisfy the filter in directory + */ + public static List listFilesInDirWithFilter(final String dirPath, + final FileFilter filter, + final boolean isRecursive) { + return listFilesInDirWithFilter(getFileByPath(dirPath), filter, isRecursive); + } + + /** + * Return the files that satisfy the filter in directory. + * + * @param dir The directory. + * @param filter The filter. + * @param isRecursive True to traverse subdirectories, false otherwise. + * @return the files that satisfy the filter in directory + */ + public static List listFilesInDirWithFilter(final File dir, + final FileFilter filter, + final boolean isRecursive) { + if (!isDir(dir)) return null; + List list = new ArrayList<>(); + File[] files = dir.listFiles(); + if (files != null && files.length != 0) { + for (File file : files) { + if (filter.accept(file)) { + list.add(file); + } + if (isRecursive && file.isDirectory()) { + //noinspection ConstantConditions + list.addAll(listFilesInDirWithFilter(file, filter, true)); + } + } + } + return list; + } + + /** + * Return the time that the file was last modified. + * + * @param filePath The path of file. + * @return the time that the file was last modified + */ + + public static long getFileLastModified(final String filePath) { + return getFileLastModified(getFileByPath(filePath)); + } + + /** + * Return the time that the file was last modified. + * + * @param file The file. + * @return the time that the file was last modified + */ + public static long getFileLastModified(final File file) { + if (file == null) return -1; + return file.lastModified(); + } + + /** + * Return the charset of file simply. + * + * @param filePath The path of file. + * @return the charset of file simply + */ + public static String getFileCharsetSimple(final String filePath) { + return getFileCharsetSimple(getFileByPath(filePath)); + } + + /** + * Return the charset of file simply. + * + * @param file The file. + * @return the charset of file simply + */ + public static String getFileCharsetSimple(final File file) { + int p = 0; + InputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(file)); + p = (is.read() << 8) + is.read(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + switch (p) { + case 0xefbb: + return "UTF-8"; + case 0xfffe: + return "Unicode"; + case 0xfeff: + return "UTF-16BE"; + default: + return "GBK"; + } + } + + /** + * Return the number of lines of file. + * + * @param filePath The path of file. + * @return the number of lines of file + */ + public static int getFileLines(final String filePath) { + return getFileLines(getFileByPath(filePath)); + } + + /** + * Return the number of lines of file. + * + * @param file The file. + * @return the number of lines of file + */ + public static int getFileLines(final File file) { + int count = 1; + InputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(file)); + byte[] buffer = new byte[1024]; + int readChars; + if (LINE_SEP.endsWith("\n")) { + while ((readChars = is.read(buffer, 0, 1024)) != -1) { + for (int i = 0; i < readChars; ++i) { + if (buffer[i] == '\n') ++count; + } + } + } else { + while ((readChars = is.read(buffer, 0, 1024)) != -1) { + for (int i = 0; i < readChars; ++i) { + if (buffer[i] == '\r') ++count; + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return count; + } + + /** + * Return the size of directory. + * + * @param dirPath The path of directory. + * @return the size of directory + */ + public static String getDirSize(final String dirPath) { + return getDirSize(getFileByPath(dirPath)); + } + + /** + * Return the size of directory. + * + * @param dir The directory. + * @return the size of directory + */ + public static String getDirSize(final File dir) { + long len = getDirLength(dir); + return len == -1 ? "" : byte2FitMemorySize(len); + } + + /** + * Return the length of file. + * + * @param filePath The path of file. + * @return the length of file + */ + public static String getFileSize(final String filePath) { + long len = getFileLength(filePath); + return len == -1 ? "" : byte2FitMemorySize(len); + } + + /** + * Return the length of file. + * + * @param file The file. + * @return the length of file + */ + public static String getFileSize(final File file) { + long len = getFileLength(file); + return len == -1 ? "" : byte2FitMemorySize(len); + } + + /** + * Return the length of directory. + * + * @param dirPath The path of directory. + * @return the length of directory + */ + public static long getDirLength(final String dirPath) { + return getDirLength(getFileByPath(dirPath)); + } + + /** + * Return the length of directory. + * + * @param dir The directory. + * @return the length of directory + */ + public static long getDirLength(final File dir) { + if (!isDir(dir)) return -1; + long len = 0; + File[] files = dir.listFiles(); + if (files != null && files.length != 0) { + for (File file : files) { + if (file.isDirectory()) { + len += getDirLength(file); + } else { + len += file.length(); + } + } + } + return len; + } + + /** + * Return the length of file. + * + * @param filePath The path of file. + * @return the length of file + */ + public static long getFileLength(final String filePath) { + boolean isURL = filePath.matches("[a-zA-z]+://[^\\s]*"); + if (isURL) { + try { + HttpsURLConnection conn = (HttpsURLConnection) new URL(filePath).openConnection(); + conn.setRequestProperty("Accept-Encoding", "identity"); + conn.connect(); + if (conn.getResponseCode() == 200) { + return conn.getContentLength(); + } + return -1; + } catch (IOException e) { + e.printStackTrace(); + } + } + return getFileLength(getFileByPath(filePath)); + } + + /** + * Return the length of file. + * + * @param file The file. + * @return the length of file + */ + public static long getFileLength(final File file) { + if (!isFile(file)) return -1; + return file.length(); + } + + /** + * 获取指定文件大小 + * @return + * @throws Exception + */ + public static long getFileSizeLong(File file) throws Exception + { + long size = 0; + if (file.exists()){ + FileInputStream fis = null; + fis = new FileInputStream(file); + size = fis.available(); + } + else{ + CupidLogUtils.e("获取文件大小","文件不存在!"); + } + return size; + } + + /** + * Return the MD5 of file. + * + * @param filePath The path of file. + * @return the md5 of file + */ + public static String getFileMD5ToString(final String filePath) { + File file = isSpace(filePath) ? null : new File(filePath); + return getFileMD5ToString(file); + } + + /** + * Return the MD5 of file. + * + * @param file The file. + * @return the md5 of file + */ + public static String getFileMD5ToString(final File file) { + return bytes2HexString(getFileMD5(file)); + } + + /** + * Return the MD5 of file. + * + * @param filePath The path of file. + * @return the md5 of file + */ + public static byte[] getFileMD5(final String filePath) { + return getFileMD5(getFileByPath(filePath)); + } + + /** + * Return the MD5 of file. + * + * @param file The file. + * @return the md5 of file + */ + public static byte[] getFileMD5(final File file) { + if (file == null) return null; + DigestInputStream dis = null; + try { + FileInputStream fis = new FileInputStream(file); + MessageDigest md = MessageDigest.getInstance("MD5"); + dis = new DigestInputStream(fis, md); + byte[] buffer = new byte[1024 * 256]; + while (true) { + if (!(dis.read(buffer) > 0)) break; + } + md = dis.getMessageDigest(); + return md.digest(); + } catch (NoSuchAlgorithmException | IOException e) { + e.printStackTrace(); + } finally { + try { + if (dis != null) { + dis.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + /** + * Return the file's path of directory. + * + * @param file The file. + * @return the file's path of directory + */ + public static String getDirName(final File file) { + if (file == null) return ""; + return getDirName(file.getAbsolutePath()); + } + + /** + * Return the file's path of directory. + * + * @param filePath The path of file. + * @return the file's path of directory + */ + public static String getDirName(final String filePath) { + if (isSpace(filePath)) return ""; + int lastSep = filePath.lastIndexOf(File.separator); + return lastSep == -1 ? "" : filePath.substring(0, lastSep + 1); + } + + /** + * Return the name of file. + * + * @param file The file. + * @return the name of file + */ + public static String getFileName(final File file) { + if (file == null) return ""; + return getFileName(file.getAbsolutePath()); + } + + /** + * Return the name of file. + * + * @param filePath The path of file. + * @return the name of file + */ + public static String getFileName(final String filePath) { + if (isSpace(filePath)) return ""; + int lastSep = filePath.lastIndexOf(File.separator); + return lastSep == -1 ? filePath : filePath.substring(lastSep + 1); + } + + /** + * Return the name of file without extension. + * + * @param file The file. + * @return the name of file without extension + */ + public static String getFileNameNoExtension(final File file) { + if (file == null) return ""; + return getFileNameNoExtension(file.getPath()); + } + + /** + * Return the name of file without extension. + * + * @param filePath The path of file. + * @return the name of file without extension + */ + public static String getFileNameNoExtension(final String filePath) { + if (isSpace(filePath)) return ""; + int lastPoi = filePath.lastIndexOf('.'); + int lastSep = filePath.lastIndexOf(File.separator); + if (lastSep == -1) { + return (lastPoi == -1 ? filePath : filePath.substring(0, lastPoi)); + } + if (lastPoi == -1 || lastSep > lastPoi) { + return filePath.substring(lastSep + 1); + } + return filePath.substring(lastSep + 1, lastPoi); + } + + /** + * Return the extension of file. + * + * @param file The file. + * @return the extension of file + */ + public static String getFileExtension(final File file) { + if (file == null) return ""; + return getFileExtension(file.getPath()); + } + + /** + * Return the extension of file. + * + * @param filePath The path of file. + * @return the extension of file + */ + public static String getFileExtension(final String filePath) { + if (isSpace(filePath)) return ""; + int lastPoi = filePath.lastIndexOf('.'); + int lastSep = filePath.lastIndexOf(File.separator); + if (lastPoi == -1 || lastSep >= lastPoi) return ""; + return filePath.substring(lastPoi + 1); + } + + /** + * Notify system to scan the file. + * + * @param file The file. + */ + public static void notifySystemToScan(Context context, final File file) { + if (file == null || !file.exists()) return; + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + Uri uri = Uri.fromFile(file); + intent.setData(uri); + context.sendBroadcast(intent); + } + + /** + * Notify system to scan the file. + * + * @param filePath The path of file. + */ + public static void notifySystemToScan(final Context context, final String filePath) { + notifySystemToScan(context, getFileByPath(filePath)); + } + + /////////////////////////////////////////////////////////////////////////// + // interface + /////////////////////////////////////////////////////////////////////////// + + public interface OnReplaceListener { + boolean onReplace(); + } + + /////////////////////////////////////////////////////////////////////////// + // other utils methods + /////////////////////////////////////////////////////////////////////////// + + private static final char[] HEX_DIGITS = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + private static String bytes2HexString(final byte[] bytes) { + if (bytes == null) return ""; + int len = bytes.length; + if (len <= 0) return ""; + char[] ret = new char[len << 1]; + for (int i = 0, j = 0; i < len; i++) { + ret[j++] = HEX_DIGITS[bytes[i] >> 4 & 0x0f]; + ret[j++] = HEX_DIGITS[bytes[i] & 0x0f]; + } + return new String(ret); + } + + private static String byte2FitMemorySize(final long byteNum) { + if (byteNum < 0) { + return "shouldn't be less than zero!"; + } else if (byteNum < 1024) { + return String.format(Locale.getDefault(), "%.3fB", (double) byteNum); + } else if (byteNum < 1048576) { + return String.format(Locale.getDefault(), "%.3fKB", (double) byteNum / 1024); + } else if (byteNum < 1073741824) { + return String.format(Locale.getDefault(), "%.3fMB", (double) byteNum / 1048576); + } else { + return String.format(Locale.getDefault(), "%.3fGB", (double) byteNum / 1073741824); + } + } + + private static boolean isSpace(final String s) { + if (s == null) return true; + for (int i = 0, len = s.length(); i < len; ++i) { + if (!Character.isWhitespace(s.charAt(i))) { + return false; + } + } + return true; + } + + private static boolean writeFileFromIS(final File file, + final InputStream is) { + OutputStream os = null; + try { + os = new BufferedOutputStream(new FileOutputStream(file)); + byte data[] = new byte[8192]; + int len; + while ((len = is.read(data, 0, 8192)) != -1) { + os.write(data, 0, len); + } + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (os != null) { + os.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 写文件 string + * + * @param fullFileName + * @param logContent + * @param isAppend + */ + public static void writeFile(String fullFileName, String logContent, boolean isAppend) { + FileWriter fileWriter = null; + try { + fileWriter = new FileWriter(new File(fullFileName), isAppend); + fileWriter.write(logContent); + fileWriter.write("\n"); + fileWriter.flush(); + fileWriter.close(); + } catch (Exception e) { + } finally { + BaseIoUtils.closeSilently(fileWriter); + } + } + + /** + * 获取文件路径 + * + * @param baseDir + * @param fileName + * @return + */ + public static String getFilePath(Context context, String baseDir, String fileName) { + String basePath = saveVideoBasePathDir(context, baseDir); + File file = new File(basePath + File.separator + fileName); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + + if (!file.exists()) { + try { + file.createNewFile(); + return file.getAbsolutePath(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return file.getAbsolutePath(); + } + + /** + * 保存图片的路径 + * + * @return + */ + public static String saveVideoBasePathDir(Context context, String dirName) { + String basePath = null; + //有SD卡 + if (BaseSDCardHelper.isSDCardMounted()) { + basePath = BaseSDCardHelper.getSDCardBaseDir(); + } else { + basePath = context.getCacheDir().getAbsolutePath(); + } + + return basePath + File.separator + dirName; + + } + + /** + * 删除文件夹 + * + * @param context + * @param baseDir + */ + public static void removeAllFileDir(Context context, String baseDir) { + String basePath = saveVideoBasePathDir(context, baseDir); + File file = new File(basePath); + if (file.exists()) { + delAllFile(file.getAbsolutePath()); + } + } + + + public static boolean delAllFile(String path) { + boolean flag = false; + try { + File file = new File(path); + if (!file.exists()) { + return flag; + } + if (!file.isDirectory()) { + return flag; + } + String[] tempList = file.list(); + File temp = null; + for (int i = 0; i < tempList.length; i++) { + if (path.endsWith(File.separator)) { + temp = new File(path + tempList[i]); + } else { + temp = new File(path + File.separator + tempList[i]); + } + if (temp.isFile()) { + temp.delete(); + } + if (temp.isDirectory()) { + delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件 + delFolder(path + "/" + tempList[i]);// 再删除空文件夹 + flag = true; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return flag; + } + + private static void delFolder(String folderPath) { + try { + delAllFile(folderPath); // 删除完里面所有内容 + String filePath = folderPath; + filePath = filePath.toString(); + File myFilePath = new File(filePath); + myFilePath.delete(); // 删除空文件夹 + } catch (Exception e) { + e.printStackTrace(); + } + } + + + /** + * 根据byte数组生成文件 + * + * @param bytes 生成文件用到的byte数组 + */ + public static void createFileWithByte(byte[] bytes, String filePath) { + /** + * 创建File对象,其中包含文件所在的目录以及文件的命名 + */ + File file = new File(filePath); + // 创建FileOutputStream对象 + FileOutputStream outputStream = null; + // 创建BufferedOutputStream对象 + BufferedOutputStream bufferedOutputStream = null; + try { + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + if (!file.exists()) { + // 在文件系统中根据路径创建一个新的空文件 + file.createNewFile(); + } + // 获取FileOutputStream对象 + outputStream = new FileOutputStream(file); + // 获取BufferedOutputStream对象 + bufferedOutputStream = new BufferedOutputStream(outputStream); + // 往文件所在的缓冲输出流中写byte数据 + bufferedOutputStream.write(bytes); + // 刷出缓冲输出流,该步很关键,要是不执行flush()方法,那么文件的内容是空的。 + bufferedOutputStream.flush(); + } catch (Exception e) { + // 打印异常信息 + e.printStackTrace(); + } finally { + // 关闭创建的流对象 + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (bufferedOutputStream != null) { + try { + bufferedOutputStream.close(); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + } + } + + /** + * Mapped File way MappedByteBuffer 可以在处理大文件时,提升性能 + * + * @param filename + * @return + * @throws IOException + */ + public static byte[] file2ByteArray(String filename) throws IOException { + + FileChannel fc = null; + try { + fc = new RandomAccessFile(filename, "r").getChannel(); + MappedByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, + fc.size()).load(); + System.out.println(byteBuffer.isLoaded()); + byte[] result = new byte[(int) fc.size()]; + if (byteBuffer.remaining() > 0) { + // System.out.println("remain"); + byteBuffer.get(result, 0, byteBuffer.remaining()); + } + return result; + } catch (IOException e) { + e.printStackTrace(); + throw e; + } finally { + try { + fc.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static String getNowString(final java.text.DateFormat format) { + return millis2String(System.currentTimeMillis(), format); + } + + /** + * Milliseconds to the formatted time string. + * + * @param millis The milliseconds. + * @param format The format. + * @return the formatted time string + */ + public static String millis2String(final long millis, final java.text.DateFormat format) { + return format.format(new Date(millis)); + } + +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/HandlerThreadManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/HandlerThreadManager.java new file mode 100644 index 0000000000..94cfee8328 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/HandlerThreadManager.java @@ -0,0 +1,63 @@ +package com.zhidao.support.adas.high.common; + +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +public class HandlerThreadManager { + private volatile static HandlerThread sBackgroundHandlerThread; + private volatile static HandlerThread sIOHandlerThread; + private volatile static Handler sBackgroundHandler; + private volatile static Handler sMainHandler; + + public static Handler getBackgroundHandler() { + if (sBackgroundHandler == null) { + sBackgroundHandler = new Handler(getBackgroundHandlerThread().getLooper()); + } + return sBackgroundHandler; + } + + public static HandlerThread getBackgroundHandlerThread() { + synchronized (HandlerThreadManager.class) { + if (sBackgroundHandlerThread == null) { + sBackgroundHandlerThread = new HandlerThread("autopilot_bgd_thread"); + sBackgroundHandlerThread.start(); + } + } + return sBackgroundHandlerThread; + } + + private static HandlerThread getVideoHandlerThread() { + synchronized (HandlerThreadManager.class) { + if (sIOHandlerThread == null) { + sIOHandlerThread = new HandlerThread("autopilot_video_thread"); + sIOHandlerThread.start(); + } + } + return sIOHandlerThread; + } + + + public static Handler getMainHandler() { + if (sMainHandler == null) { + sMainHandler = new Handler(Looper.getMainLooper()); + } + return sMainHandler; + } + + public static final Executor EXECUTOR = new ThreadPoolExecutor(2, 5, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue(30), + new ThreadFactory() { + private final AtomicInteger mCount = new AtomicInteger(1); + + public Thread newThread(Runnable r) { + return new Thread(r, "autopilot-thread-pool" + mCount.getAndIncrement()); + } + }); +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/IPreferencesHelper.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/IPreferencesHelper.java new file mode 100644 index 0000000000..1c843a1066 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/IPreferencesHelper.java @@ -0,0 +1,135 @@ +package com.zhidao.support.adas.high.common; + + +import com.zhidao.support.adas.high.bean.FaceLoginResponse; +import com.zhidao.support.adas.high.bean.UserInfo; + +/** + * Created by nie yunlong on 2018/4/13. + */ + +public interface IPreferencesHelper { + /** + * 保存udp client address + * + * @param address + */ + void saveUdpClientAddress(String address); + + /** + * 获取client address + * + * @return + */ + String getUdpClientAddress(); + + /** + * 保存dock config + * + * @param dockConfig + */ + void saveDockConfig(String dockConfig); + + /** + * 获取dock config + * + * @return + */ + String getDockConfig(); + + /** + * 设置用户信息 + * + * @param loginResponse + */ + void setUserInfo(FaceLoginResponse.DataBean loginResponse); + + /** + * 获取用户信息 + * + * @return + */ + FaceLoginResponse.DataBean getUserInfo(); + + /** + * 假的 以后干掉 + * + * @param selectIndex + */ + void setConfigNaviMapVis(int selectIndex); + + /** + * @return + */ + int getConfigNaviMapVis(); + + /** + * @param userInfo + */ + void saveUserUnInfo(UserInfo userInfo); + + /** + * 用户ID userInfo 用于扩展 + * + * @return + */ + UserInfo getUserUnInfo(); + + + /** + * 初始化标志位 + * + * @param flag + */ + void setConfigInitResutl(boolean flag); + + /** + * 初始化标志位 + * + * @return + */ + boolean getConfigInitResutl(); + + + + void setSelectCarInfo(String brand, String model, String style); + + String getSelectBrand(); + + String getSelectModel(); + + String getSelectStyle(); + + + /** + * raw + * + * @param rawPath + */ + void saveRawPath(int rawName, String rawPath); + + /** + * @param rawName + * @return + */ + String getRawPath(int rawName); + + /** + * + */ + void clearRawConfig(int rawName); + + /** + * app 启动开始时间 + * + * @param time + */ + void setAppAttachTime(long time); + + /** + * 获取 + * @return + */ + long getAppAttachTime(); + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/LogSaveManage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/LogSaveManage.java new file mode 100644 index 0000000000..48e2df1031 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/LogSaveManage.java @@ -0,0 +1,70 @@ +package com.zhidao.support.adas.high.common; + +import android.text.TextUtils; + +import com.zhidao.support.adas.high.thread.QueuedWork; + +import java.io.File; + +public +/** + * @author nie yunlong + * @des + * @date 2021/3/4 + */ +class LogSaveManage { + private static final LogSaveManage ourInstance = new LogSaveManage(); + //当前保存的文件路径 + private String currentSaveFilePath; + //6M + private final long FILE_LIMIT_SIZE = 6 * 1024 * 1024; + + static LogSaveManage getInstance() { + return ourInstance; + } + + private LogSaveManage() { + } + + /** + * 保存文件 + * + * @param msg + */ + public synchronized void saveWrite(final String msg) { + QueuedWork.runInBack(new Runnable() { + @Override + public void run() { + try { + String logFilePath = createFileReturnPath(); + FileUtils.writeFile(logFilePath, msg, true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + } + + /** + * 创建文件 + * + * @return + */ + private synchronized String createFileReturnPath() throws Exception { + if (!TextUtils.isEmpty(currentSaveFilePath)) { + long fileSize = FileUtils.getFileSizeLong(new File(currentSaveFilePath)); + if (fileSize <= FILE_LIMIT_SIZE) { + return currentSaveFilePath; + } + } + //大于6M + String filePath = BaseSDCardHelper.getSDCardPrivateFilesDir(MgContextUtils.getContext(), "adas-log") + File.separator + BaseTimeUtils.formatTimeDate3() + "-log.txt"; + //把日志保存到文件 + boolean isCreateFileSuccess = FileUtils.createOrExistsFile(filePath); + if (isCreateFileSuccess) { + currentSaveFilePath = filePath; + } + return currentSaveFilePath; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MgContextUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MgContextUtils.java new file mode 100644 index 0000000000..fcc310a381 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MgContextUtils.java @@ -0,0 +1,33 @@ +package com.zhidao.support.adas.high.common; + +import android.content.Context; + +/** + * @author nie yunlong + * @des 上下文管理 + * @date 2019/5/13 + */ +public class MgContextUtils { + /** + * 上下文 + */ + private static Context mContext; + + /** + * 设置上下文 + * + * @param context + */ + public static void setContext(Context context) { + mContext = context.getApplicationContext(); + } + + /** + * 获取上下文 + * + * @return + */ + public static Context getContext() { + return mContext; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/RSATool.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/RSATool.java new file mode 100644 index 0000000000..7f112faf19 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/RSATool.java @@ -0,0 +1,107 @@ +package com.zhidao.support.adas.high.common; + +import android.util.Log; + + +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +import javax.crypto.Cipher; + +public class RSATool { + private static final String KEY_ALGORITHM = "RSA"; + private static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding"; + + public static Map initKey() throws Exception { + //实例化密钥生成器 + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); //加密方式 + //初始化密钥生成器 + keyPairGenerator.initialize(512, new SecureRandom()); //长度 + //生成密钥对 + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + //甲方公钥 + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + //甲方私钥 + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + //将密钥存储在map中 + Map keyMap = new HashMap(); + keyMap.put("PUBLIC_KEY", publicKey); + keyMap.put("PRIVATE_KEY", privateKey); + return keyMap; + } + + public static void getBase64() { + try { + Map map = initKey(); + byte[] privateKey = ((Key) map.get("PRIVATE_KEY")).getEncoded(); + byte[] publicKey = ((Key) map.get("PUBLIC_KEY")).getEncoded(); + // 将公私钥转为base64-法1 +// String privateBase64 = new String(Base64.encodeBase64(privateKey)); +// String publicBase64 = new String(Base64.encodeBase64(publicKey)); + // 将公私钥转为base64-法2 + String privateBase64 = Base64.encodeBase64String(privateKey); + String publicBase64 = Base64.encodeBase64String(publicKey); + Log.i("RSATool", "privateBase64=" + privateBase64); + Log.i("RSATool", "publicBase64=" + publicBase64); + String data = "mogo@ZHIDAO10"; + String encryptData = encryptByPublicKey(data, publicKey); + Log.i("RSATool", "encryptData=" + encryptData); + String decodeData = decodeByPrivateKey(encryptData, Base64.decodeBase64(privateBase64)); + Log.i("RSATool", "decodeData=" + decodeData); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 公钥加密 + * + * @param data 待加密数据 + * @param key 密钥 + * @return String 加密数据 Base64类型 + */ + public static String encryptByPublicKey(String data, byte[] key) throws Exception { + //实例化密钥工厂 + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //初始化公钥 + //密钥材料转换 + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); + //产生公钥 + PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); + //数据加密 + Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); + cipher.init(Cipher.ENCRYPT_MODE, pubKey); + return Base64.encodeBase64String(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8))); + } + + /** + * 私钥解密 + * + * @param data 待解密数据 Base64类型 + * @param key 密钥 + * @return String 解密数据 + */ + public static String decodeByPrivateKey(String data, byte[] key) throws Exception { + //取得私钥 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + //生成私钥 + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); + //数据解密 + Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + return new String(cipher.doFinal(Base64.decodeBase64(data))); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/RequestWsMsgType.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/RequestWsMsgType.java new file mode 100644 index 0000000000..6eb1ffa5b2 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/RequestWsMsgType.java @@ -0,0 +1,52 @@ +package com.zhidao.support.adas.high.common; + +/** + * @author nie yunlong + * @description 请求值 + * @date 2018/7/3 + */ +public enum RequestWsMsgType { + + /** + * 获取视频信息 + */ + MSG_GET_VIDEO_INFO(1, "get video info"), + /** + * 视频分辨率 + */ + MSG_SEND_LOCATION(2, "视频分辨率"), + /** + * 上传配置 + */ + MSG_SEND_UPLOAD_CONFIG(3, "上传配置"), + + MSG_SEND_CLOSE(5, "关闭socket"); + int mMsgType; + /** + * 描述 + */ + String mMsgDesc; + + RequestWsMsgType(int msgType, String msgDesc) { + this.mMsgType = msgType; + this.mMsgDesc = msgDesc; + } + + /** + * 获取msgType + * + * @return + */ + public int getMsgType() { + return mMsgType; + } + + /** + * 获取描述 + * + * @return + */ + public String getmMsgDesc() { + return mMsgDesc; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/SSH.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/SSH.java new file mode 100644 index 0000000000..561a360952 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/SSH.java @@ -0,0 +1,150 @@ +package com.zhidao.support.adas.high.common; + +import android.text.TextUtils; +import android.util.Log; + +import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import com.zhidao.support.adas.high.bean.SSHResult; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Properties; + +public class SSH { + private static final String TAG = SSH.class.getSimpleName(); + + private Session session = null; + private ChannelExec channelExec = null; + ByteArrayOutputStream err = null; + StringBuffer outBuf = null; + + public ByteArrayOutputStream getErr() { + return err; + } + + public StringBuffer getOutBuf() { + return outBuf; + } + + public Session getSession() { + return session; + } + + public ChannelExec getChannelExec() { + return channelExec; + } + + /** + * 使用用户名、密码连接 + * + * @param host 主机ip + * @param port 主机端口 + * @param username 主机用户名 + * @param password 主机密码 + * @throws JSchException + */ + public void connect(String host, int port, String username, String password) throws JSchException { + JSch jsch = new JSch(); + session = jsch.getSession(username, host, port); + session.setPassword(password); + Properties config = new Properties(); + config.put("StrictHostKeyChecking", "no"); + session.setConfig(config); + session.setTimeout(30000); + session.connect(); + Log.i(TAG, "Connected to " + host + "."); + } + + /** + * 使用授信连接 + * + * @param host 主机ip + * @param username 主机用户名 + * @param privateKey 私钥路径 + * @throws JSchException + */ + public void connect(String host, String username, String privateKey) throws JSchException { + JSch jsch = new JSch(); + jsch.addIdentity(privateKey); + session = jsch.getSession(username, host); + + Properties config = new Properties(); + config.put("StrictHostKeyChecking", "no"); + session.setConfig(config); + session.setTimeout(30000); + session.connect(); + Log.i(TAG, "Connected to " + host + "."); + } + + /** + * 执行 + * + * @param cmd 命令 + * @return 状态 + * @throws JSchException + * @throws IOException + */ + public SSHResult exec(String cmd) throws JSchException, IOException { + return exec(cmd, null); + } + + public SSHResult exec(String cmd, String suPwd) throws JSchException, IOException { + int exitStatus = 0; + channelExec = (ChannelExec) session.openChannel("exec"); + channelExec.setInputStream(null); + err = new ByteArrayOutputStream(); + channelExec.setErrStream(err); + channelExec.setCommand(cmd); + InputStream in = channelExec.getInputStream(); + OutputStream out = channelExec.getOutputStream(); + channelExec.connect(); + if (!TextUtils.isEmpty(suPwd) && (cmd.contains("sudo") || cmd.contains("su"))) { + out.write((suPwd + "\n").getBytes()); //这里是密码后跟了一个换行符 + out.flush(); + } + outBuf = new StringBuffer(); + byte[] tmp = new byte[1024]; + while (true) { + while (in.available() > 0) { + int i = in.read(tmp, 0, 1024); + if (i < 0) break; + outBuf.append(new String(tmp, 0, i)); + } + if (channelExec.isClosed()) { + if (in.available() > 0) continue; + exitStatus = channelExec.getExitStatus(); + break; + } + try { + Thread.sleep(1000L); + } catch (Exception e) { + } + } + channelExec.disconnect(); + if (exitStatus == 0) { + String outInfo = this.getOutBuf().toString(); + return new SSHResult(exitStatus, cmd, outInfo); + } else { + String errInfo = this.getErr().toString(); + return new SSHResult(exitStatus, cmd, errInfo); + } + } + + /** + * 断开连接 + */ + public void disConnect() { + if (channelExec != null) { + channelExec.disconnect(); + } + if (session != null) { + session.disconnect(); + } + } + +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ThreadPoolManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ThreadPoolManager.java new file mode 100644 index 0000000000..4ae835c3ef --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ThreadPoolManager.java @@ -0,0 +1,127 @@ +package com.zhidao.support.adas.high.common; + + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 线程池 + * Created by xfk on 2018/9/30. + */ + +public class ThreadPoolManager { + + /** + * 根据cpu的数量动态的配置核心线程数和最大线程数 + */ + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); + /** + * 核心线程数 = CPU核心数 + 1 + */ + private static final int CORE_POOL_SIZE = CPU_COUNT + 1; + /** + * 线程池最大线程数 = CPU核心数 * 2 + 1 + */ + private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; + /** + * 非核心线程闲置时超时1s + */ + private static final int KEEP_ALIVE = 1; + /** + * 线程池的对象 + */ + private ThreadPoolExecutor executor; + + /** + * 要确保该类只有一个实例对象,避免产生过多对象消费资源,所以采用单例模式 + */ + private ThreadPoolManager() { + } + + private volatile static ThreadPoolManager INSTANCE; + + public static ThreadPoolManager getsInstance() { + if (INSTANCE == null) { + synchronized (ThreadPoolManager.class) { + if (INSTANCE == null) { + INSTANCE = new ThreadPoolManager(); + } + } + + } + return INSTANCE; + } + + /** + * 开启一个无返回结果的线程 + * + * @param r + */ + public void execute(Runnable r) { + if (executor == null) { + /** + * corePoolSize:核心线程数 + * maximumPoolSize:线程池所容纳最大线程数(workQueue队列满了之后才开启) + * keepAliveTime:非核心线程闲置时间超时时长 + * unit:keepAliveTime的单位 + * workQueue:等待队列,存储还未执行的任务 + * threadFactory:线程创建的工厂 + * handler:异常处理机制 + * + */ + executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, + KEEP_ALIVE, TimeUnit.SECONDS, new ArrayBlockingQueue(200), + Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); + } + // 把一个任务丢到了线程池中 + try { + executor.execute(r); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + /** + * 开启一个有返回结果的线程 + * + * @param r + * @return + */ + public Future submit(Callable r) { + if (executor == null) { + /** + * corePoolSize:核心线程数 + * maximumPoolSize:线程池所容纳最大线程数(workQueue队列满了之后才开启) + * keepAliveTime:非核心线程闲置时间超时时长 + * unit:keepAliveTime的单位 + * workQueue:等待队列,存储还未执行的任务 + * threadFactory:线程创建的工厂 + * handler:异常处理机制 + * + */ + executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, + KEEP_ALIVE, TimeUnit.SECONDS, new ArrayBlockingQueue(20), + Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); + } + // 把一个任务丢到了线程池中 + return executor.submit(r); + } + + /** + * 把任务移除等待队列 + * + * @param r + */ + public void cancel(Runnable r) { + if (r != null) { + executor.getQueue().remove(r); + } + } + +} + diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/IMsg.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/IMsg.java new file mode 100644 index 0000000000..acdc45de7d --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/IMsg.java @@ -0,0 +1,22 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +/** + * @author nie yunlong + * @des + * @date 2020/3/12 + */ +public interface IMsg { + /** + * 处理消息 + * + * @param msg + */ + void handlerMsg(Gson gson, OnAdasListener adasListener, String msg); + + void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg); + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/IMyMessageFactory.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/IMyMessageFactory.java new file mode 100644 index 0000000000..d85aeee531 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/IMyMessageFactory.java @@ -0,0 +1,20 @@ +package com.zhidao.support.adas.high.msg; + +/** + * 生产产品的工厂 + */ +public interface IMyMessageFactory { + /** + * + * @param messageType 消息类型 + * @return + */ + public IMsg createMessage(String messageType); + + /** + * + * @param messageCode 消息类型 + * @return + */ + public IMsg createMessage(int messageCode); +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyAbstractMessageHandler.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyAbstractMessageHandler.java new file mode 100644 index 0000000000..59dcf3d8c3 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyAbstractMessageHandler.java @@ -0,0 +1,11 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.protobuf.util.JsonFormat; + +/** + * @author nie yunlong + * @des 消息处理中心 + * @date 2020/3/12 + */ +public abstract class MyAbstractMessageHandler implements IMsg { +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java new file mode 100644 index 0000000000..055d002223 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java @@ -0,0 +1,233 @@ +package com.zhidao.support.adas.high.msg; + +import android.text.TextUtils; + +import com.zhidao.support.adas.high.common.ActionTypeReceive; + +/** + * @author nie yunlong + * @des 简易工厂 + * @date 2020/3/12 + */ +public class MyMessageFactory implements IMyMessageFactory { + /** + * udp 渲染 image + */ + private IMsg udpRenderImageMsg; + /** + * ws 报警 消息 + */ + private IMsg wsWarnMessage; + /** + * ws 图像size + */ + private IMsg wsImageSizeMessage; + /** + * 空实现 + */ + private IMsg nuImplMessage; + /** + * udp 车辆状态消息 + */ + private IMsg udpCarStateMessage; + /** + * 红绿灯状态 + */ + private IMsg udpLightStateMessage; + /** + * 周边物体的状态 + */ + private IMsg udpObstaclesMessage; + + /** + * 局部轨迹消息 + */ + private IMsg trajectoryMessage; + + /** + * 监控信息 + */ + private IMsg guardianMessage; + /** + * 车道线渲染 + */ + private IMsg lanesMessage; + /** + * 自动驾驶状态 + */ + private IMsg autopilotStatusMessage; + /** + * 自动驾驶到站 + */ + private IMsg autopilotArriveMessage; + /** + * 自动驾驶路径 + */ + private IMsg autopilotRouteMessage; + /** + * 工控机获取SN + */ + private IMsg autopilotSNMessage; + /** + * 数据采集信息 + */ + private IMsg autopilotIdentify; + /** + * 工控机升级状态 + */ + private IMsg autopilotUpgradeStatusMessage; + /** + * car dock 基础信息 + */ + private IMsg autopilotConfig; + + + + @Override + public IMsg createMessage(String messageType) { + if (TextUtils.isEmpty(messageType)) { + if (nuImplMessage == null) { + nuImplMessage = new NuImplMessage(); + } + return nuImplMessage; + } + if (messageType.equals(ActionTypeReceive.ACTION_WS_MSG_RENDER_TYPE.getmActionType())) { + //udp render + if (udpRenderImageMsg == null) { + udpRenderImageMsg = new UdpRenderImageMessage(); + } + return udpRenderImageMsg; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_MSG_WARNING_TYPE.getmActionType())) { + //ws 报警消息 + if (wsWarnMessage == null) { + wsWarnMessage = new WsWarnMessage(); + } + return wsWarnMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_MSG_IMAGE_SIZE_TYPE.getmActionType())) { + //ws 报警消息 + if (wsImageSizeMessage == null) { + wsImageSizeMessage = new WsImageSizeMessage(); + } + return wsImageSizeMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_CAR_STATE_TYPE.getmActionType())) { + //udp 车辆消息 + if (udpCarStateMessage == null) { + udpCarStateMessage = new UdpCarStateMessage(); + } + return udpCarStateMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_UDP_LIGHT_STATE_TYPE.getmActionType())) { + //udp 红绿灯状态 + if (udpLightStateMessage == null) { + udpLightStateMessage = new UdpLightStateMessage(); + } + return udpLightStateMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_OBSTACLES_MESSAGE_TYPE.getmActionType())) { + //udp 周边物体的状态 + if (udpObstaclesMessage == null) { + udpObstaclesMessage = new UdpObstaclesMessage(); + } + return udpObstaclesMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_LANES_MESSAGE_TYPE.getmActionType())) { + // 车道线渲染 + if (lanesMessage == null) { + lanesMessage = new UdpLanesMessage(); + } + return lanesMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_STATUE.getmActionType())) { + //ws 自动驾驶状态 + if (autopilotStatusMessage == null) { + autopilotStatusMessage = new WsAutopilotStatusMessage(); + } + return autopilotStatusMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_WAY_ARRIVE.getmActionType())) { + //自送驾驶到站 + if (autopilotArriveMessage == null) { + autopilotArriveMessage = new WsAutopilotArriveMessage(); + } + return autopilotArriveMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_ROUTE.getmActionType())) { + //自动驾驶路径 + if (autopilotRouteMessage == null) { + autopilotRouteMessage = new WsAutopilotRouteMessage(); + } + return autopilotRouteMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_SN_REQUEST.getmActionType())) { + //工控机获取sn + if (autopilotSNMessage == null) { + autopilotSNMessage = new WsAutopilotSNMessage(); + } + return autopilotSNMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_IDENTIFY.getmActionType())) { + //数据采集信息 + if (autopilotIdentify == null) { + autopilotIdentify = new WsAutopilotIdentify(); + } + return autopilotIdentify; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_TRAJECTORY.getmActionType())) { + //局部轨迹 + if (trajectoryMessage == null) { + trajectoryMessage = new WsAutopilotTrajectoryMessage(); + } + return trajectoryMessage; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_CAR_CONFIG.getmActionType())) { + //dock config + if (autopilotConfig == null) { + autopilotConfig = new WsAutopilotConfig(); + } + return autopilotConfig; + } else if (messageType.equals(ActionTypeReceive.ACTION_WS_AUTOPILOT_UPGRADE_STATUS.getmActionType())) { + //ws 工控机升级状态 + if (autopilotUpgradeStatusMessage == null) { + autopilotUpgradeStatusMessage = new WsAutopilotUpgradeStatusMessage(); + } + return autopilotUpgradeStatusMessage; + } + + if (nuImplMessage == null) { + nuImplMessage = new NuImplMessage(); + } + return nuImplMessage; + } + + @Override + public IMsg createMessage(int messageCode) { + if (messageCode == 0) { + if (nuImplMessage == null) { + nuImplMessage = new NuImplMessage(); + } + return nuImplMessage; + } + if (messageCode == ActionTypeReceive.ACTION_WS_MSG_RENDER_TYPE.getmActionCode()) { + //感知数据 + if (udpRenderImageMsg == null) { + udpRenderImageMsg = new UdpRenderImageMessage(); + } + return udpRenderImageMsg; + } else if (messageCode == ActionTypeReceive.ACTION_WS_CAR_STATE_TYPE.getmActionCode()) { + //定位数据 + if (udpCarStateMessage == null) { + udpCarStateMessage = new UdpCarStateMessage(); + } + return udpCarStateMessage; + } else if (messageCode == (ActionTypeReceive.ACTION_WS_AUTOPILOT_TRAJECTORY.getmActionCode())) { + //局部轨迹 + if (trajectoryMessage == null) { + trajectoryMessage = new WsAutopilotTrajectoryMessage(); + } + return trajectoryMessage; + } else if (messageCode == (ActionTypeReceive.ACTION_WS_AUTOPILOT_ROUTES.getmActionCode())) { + //轨迹列表 + + } else if (messageCode == (ActionTypeReceive.ACTION_WS_AUTOPILOT_GUARDIAN.getmActionCode())) { + //监控信息 + if (guardianMessage == null) { + guardianMessage = new WsAutopilotGuardian(); + } + return guardianMessage; + } + if (nuImplMessage == null) { + nuImplMessage = new NuImplMessage(); + } + return nuImplMessage; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/NuImplMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/NuImplMessage.java new file mode 100644 index 0000000000..31e816b59c --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/NuImplMessage.java @@ -0,0 +1,23 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +/** + * @author nie yunlong + * @des 空实现防止空指针 + * @date 2020/3/12 + */ +public class NuImplMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpCarStateMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpCarStateMessage.java new file mode 100644 index 0000000000..10a8cb7efe --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpCarStateMessage.java @@ -0,0 +1,100 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.google.protobuf.InvalidProtocolBufferException; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.CarStateInfo; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +import mogo.status.CarStatus; + +/** + * @author nie yunlong + * @des udp 车辆状态 + * @date 2020/3/12 + */ +public class UdpCarStateMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + CupidLogUtils.w("CarStateData", "===>carStateInfo" + adasListener); + CarStateInfo carStateInfo = gson.fromJson(msg, CarStateInfo.class); +// String satelliteTime = carStateInfo.getValues().getSatelliteTime(); +// long systemTime = System.currentTimeMillis(); +// Date date = BaseTimeUtils.localToUTC(String.valueOf(System.currentTimeMillis())); +// long time = date.getTime(); +// long l = Long.parseLong(satelliteTime)-time; +// CupidLogUtils.w("CarStateData", "carStateInfo2 pad system time="+systemTime); +// CupidLogUtils.w("CarStateData", "carStateInfo2 pad utc time=" + time); +// CupidLogUtils.w("CarStateData", "carStateInfo2 gkj utc time=" + satelliteTime); +// CupidLogUtils.w("CarStateData", "carStateInfo2 time difference=" + l); + if (adasListener != null) { + adasListener.onCarStateData(carStateInfo); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + try { + long time = System.currentTimeMillis(); + CarStatus.Status status = CarStatus.Status.parseFrom(msg); + if (status != null) { + CarStateInfo carStateInfo = new CarStateInfo(); + carStateInfo.setAction("state"); + CarStateInfo.ValuesBean values = new CarStateInfo.ValuesBean(); + values.setLon(status.getLon()); + values.setLat(status.getLat()); + values.setAlt(status.getAlt()); + values.setHeading(status.getHeading()); + values.setAcceleration(status.getAcceleration()); + values.setYaw_rate(status.getYawRate()); + values.setGnss_speed(status.getGnssSpeed()); + values.setVehicle_speed(status.getVehicleSpeed()); + values.setSatelliteTime(status.getSatelliteTime()); + values.setSystemTime(status.getSystemTime()); + values.setTurn_light(status.getTurnLight()); + values.setFlash_light(status.getFlashLight()); + values.setBrake_light(status.getBrakeLight()); + values.setFrame_num(status.getFrameNum()); + values.setReceiverDataTime(time); + carStateInfo.setValues(values); + setTurnLightState(values); + if (adasListener != null) { + adasListener.onCarStateData(carStateInfo); + CupidLogUtils.w("UdpCarStateMessage", "" + carStateInfo.toString()); + } + } + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } + + /** + * 解析转向灯 + */ + private int turnLightTimes = 0; + private boolean isOnTurnLight = false; + private int turnLight = 0; + + public void setTurnLightState(CarStateInfo.ValuesBean values) { + int turn_light = values.getTurn_light(); + if (turn_light == 0) { + if (isOnTurnLight) { + if (turnLightTimes >= 10) { + isOnTurnLight = false; + turnLight = 0; + } + turnLightTimes++; + } + } else if (turn_light == 1) { + turnLightTimes = 0; + isOnTurnLight = true; + turnLight = 1; + } else if (turn_light == 2) { + turnLightTimes = 0; + isOnTurnLight = true; + turnLight = 2; + } + values.setTurnLightOften(turnLight); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpLanesMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpLanesMessage.java new file mode 100644 index 0000000000..16cea5dc1d --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpLanesMessage.java @@ -0,0 +1,28 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.CarLaneInfo; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +/** + * @author nie yunlong + * @des udp 车道线渲染 + * @date 2020/3/12 + */ +public class UdpLanesMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + //udp 车道线渲染 + CarLaneInfo carLaneInfo = gson.fromJson(msg, CarLaneInfo.class); + if (adasListener != null) { + adasListener.onCarLaneInfo(carLaneInfo); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpLightStateMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpLightStateMessage.java new file mode 100644 index 0000000000..d77597908e --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpLightStateMessage.java @@ -0,0 +1,29 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.CarStateInfo; +import com.zhidao.support.adas.high.bean.LightStatueInfo; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +/** + * @author nie yunlong + * @des udp 红绿灯状态 + * @date 2020/3/12 + */ +public class UdpLightStateMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + //udp 红绿灯状态 + LightStatueInfo lightStatueInfo = gson.fromJson(msg, LightStatueInfo.class); + if (adasListener != null) { + adasListener.onLightStateData(lightStatueInfo); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpObstaclesMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpObstaclesMessage.java new file mode 100644 index 0000000000..5bf41edbcc --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpObstaclesMessage.java @@ -0,0 +1,29 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.LightStatueInfo; +import com.zhidao.support.adas.high.bean.ObstaclesInfo; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +/** + * @author nie yunlong + * @des udp 周边物体渲染 + * @date 2020/3/12 + */ +public class UdpObstaclesMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + //udp 周边物体渲染 + ObstaclesInfo obstaclesInfo = gson.fromJson(msg, ObstaclesInfo.class); + if (adasListener != null) { + adasListener.onObstaclesInfo(obstaclesInfo); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpRenderImageMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpRenderImageMessage.java new file mode 100644 index 0000000000..84be2140d4 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/UdpRenderImageMessage.java @@ -0,0 +1,101 @@ +package com.zhidao.support.adas.high.msg; + +import android.text.TextUtils; + +import com.google.gson.Gson; +import com.google.protobuf.InvalidProtocolBufferException; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.RectInfo; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +import java.util.ArrayList; + +import adas.Adas; + +/** + * @author nie yunlong + * @des udp渲染 + * @date 2020/3/12 + */ +public class UdpRenderImageMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + //渲染图像流 + RectInfo rectInfo = gson.fromJson(msg, RectInfo.class); + CupidLogUtils.e("UdpRenderImageMessage--->json:num = " + rectInfo.getModels().size()); + if (adasListener != null) { + adasListener.onRectData(rectInfo); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + Adas.ViwesMsg viewMsg = null; + try { + viewMsg = Adas.ViwesMsg.parseFrom(msg); + } catch (InvalidProtocolBufferException e) { + CupidLogUtils.e("UdpRenderImageMessage--->protoBuf Exception:" + e.toString()); + e.printStackTrace(); + } + if (viewMsg != null) { + if (TextUtils.equals(viewMsg.getAction(), "view")) { + RectInfo rectInfo = new RectInfo(); + rectInfo.setAction(viewMsg.getAction()); + ArrayList rectBeans = new ArrayList<>(); + for (int i = 0; i < viewMsg.getModelsList().size(); i++) { + RectInfo.RectBean rectBean = new RectInfo.RectBean(); + rectBean.setYt(viewMsg.getModels(i).getYt()); + rectBean.setYb(viewMsg.getModels(i).getYb()); + rectBean.setXr(viewMsg.getModels(i).getXr()); + rectBean.setXl(viewMsg.getModels(i).getXl()); + rectBean.setDistance_x(viewMsg.getModels(i).getDistanceX()); + rectBean.setDistance_y(viewMsg.getModels(i).getDistanceY()); + rectBean.setType(viewMsg.getModels(i).getType()); + rectBean.setLat(viewMsg.getModels(i).getLat()); + rectBean.setLon(viewMsg.getModels(i).getLon()); + rectBean.setHeading(viewMsg.getModels(i).getHeading()); + rectBean.setSystemTime(viewMsg.getModels(i).getSystemTime()); + rectBean.setSatelliteTime(viewMsg.getModels(i).getSatelliteTime()); + rectBean.setAlt(viewMsg.getModels(i).getAlt()); + rectBean.setCarId(viewMsg.getModels(i).getCarId()); + rectBean.setUuid(viewMsg.getModels(i).getUuid()); + rectBean.setColor(viewMsg.getModels(i).getColor()); + rectBean.setSpeed(viewMsg.getModels(i).getSpeed()); + rectBean.setDrawlevel(viewMsg.getModels(i).getDrawlevel()); + rectBean.setLength(viewMsg.getModels(i).getLength()); + rectBean.setWidth(viewMsg.getModels(i).getWidth()); + rectBean.setHeight(viewMsg.getModels(i).getHeight()); + rectBean.setDriverTime(viewMsg.getModels(i).getDriverTime()); +// if (viewMsg.getModels(i).getDriverTime()!=null){ +// String s16 = conversionTime(viewMsg.getModels(i).getDriverTime()); +// if (s16!=null){ +// CupidLogUtils.e("UdpRenderImageMessage--->time===>s16=" + s16); +// String s13 = s16.substring(0, 13); +// CupidLogUtils.e("UdpRenderImageMessage--->time===>s13=" + s13); +// rectBean.setDriverTime(s13); +// }else { +// rectBean.setDriverTime(viewMsg.getModels(i).getDriverTime()); +// } +// } + rectBeans.add(rectBean); + } + rectInfo.setModels(rectBeans); + if (adasListener != null) { + adasListener.onRectData(rectInfo); + CupidLogUtils.e("UdpRenderImageMessage--->protoBuf===>:rectInfo = " + rectInfo.toString()); + } + } + } + } + + public String conversionTime(String str) { + StringBuffer stringBuffer = new StringBuffer(""); + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) != '.') { + stringBuffer.append(str.charAt(i)); + } + } + return stringBuffer.toString(); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotArriveMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotArriveMessage.java new file mode 100644 index 0000000000..bb45a115a6 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotArriveMessage.java @@ -0,0 +1,29 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.AutopilotStatus; +import com.zhidao.support.adas.high.bean.AutopilotWayArrive; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +/** + * @author nie yunlong + * @des ws自动驾驶到站 + * @date 2020/3/12 + */ +public class WsAutopilotArriveMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + //ws 自动驾驶状态 + AutopilotWayArrive autopilotWayArrive = gson.fromJson(msg, AutopilotWayArrive.class); + if (adasListener != null) { + adasListener.autopilotArrive(autopilotWayArrive); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotConfig.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotConfig.java new file mode 100644 index 0000000000..1046cebaf1 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotConfig.java @@ -0,0 +1,34 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.AdasConfig; +import com.zhidao.support.adas.high.bean.AutopilotConfig; +import com.zhidao.support.adas.high.bean.guardian.AutopilotGuardianInfo; +import com.zhidao.support.adas.high.common.AppPreferenceHelper; +import com.zhidao.support.adas.high.common.Constants; +import com.zhidao.support.adas.high.common.MgContextUtils; + +/** + * @author song kenan + * @des + * @date 2021/11/17 + */ +public class WsAutopilotConfig extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + AutopilotConfig autopilotConfig = gson.fromJson(msg, AutopilotConfig.class); + AutopilotConfig.ResultBean result = autopilotConfig.getResult(); + if (result!=null){ + String dockVersion = result.getDock_version(); + AppPreferenceHelper.getInstance(MgContextUtils.getContext()).saveDockConfig(dockVersion); + } + + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotGuardian.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotGuardian.java new file mode 100644 index 0000000000..2dc502c8bc --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotGuardian.java @@ -0,0 +1,51 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.util.JsonFormat; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.guardian.AutopilotGuardianInfo; +import com.zhidao.support.adas.high.bean.guardian.GuardianItemsName; +import com.zhidao.support.adas.high.bean.guardian.GuardianModule; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +import java.util.ArrayList; + +import mogo.guardian.MogoGuardian; + +/** + * @author song kenan + * @des + * @date 2021/7/7 + */ +public class WsAutopilotGuardian extends MyAbstractMessageHandler{ + private final JsonFormat.Printer printer = JsonFormat.printer(); + private AutopilotGuardianInfo info; + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { +// CupidLogUtils.w("WsAutopilotGuardian===>"+msg); + AutopilotGuardianInfo autopilotGuardian = gson.fromJson(msg, AutopilotGuardianInfo.class); + if (adasListener != null) { + adasListener.onAutopilotGuardian(autopilotGuardian); + } + + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + try { + MogoGuardian.GuardianProto proto = MogoGuardian.GuardianProto.parseFrom(msg); + String print = printer.print(proto); + info = gson.fromJson(print, AutopilotGuardianInfo.class); + if (adasListener != null) { + adasListener.onAutopilotGuardian(info); + CupidLogUtils.w("WsAutopilotGuardian===>"+ info.toString()); + + } + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotIdentify.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotIdentify.java new file mode 100644 index 0000000000..82187a79a3 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotIdentify.java @@ -0,0 +1,71 @@ +package com.zhidao.support.adas.high.msg; + +import android.content.Intent; +import android.os.Handler; +import android.os.Message; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.record.AutopilotIdentifyInfo; +import com.zhidao.support.adas.high.bean.record.AutopilotRecordResult; +import com.zhidao.support.adas.high.common.HandlerThreadManager; +import com.zhidao.support.adas.high.common.MgContextUtils; +import com.zhidao.support.recorder.RecordDataManager; +import com.zhidao.support.recorder.activity.LoginSftpActivity; + +/** + * @author song kenan + * @des + * @date 2021/7/7 + */ +public class WsAutopilotIdentify extends MyAbstractMessageHandler { + private static final int SHOW_RECORDER = 0x01; + private boolean isConnect = false; + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + AutopilotIdentifyInfo info = gson.fromJson(msg, AutopilotIdentifyInfo.class); + AutopilotIdentifyInfo.Result result = info.getResult(); + AutopilotRecordResult panel = result.getPanel(); + if (adasListener != null) { + adasListener.onAutopilotRecord(panel); + } +// if (panel!=null){ +// int stat = panel.getStat(); +// if (stat==1){ +// final String user = result.getUser(); +// final String passwd = result.getPasswd(); +// String timestamp = panel.getTimestamp(); +// final String udpClientAddress = AppPreferenceHelper.getInstance(MgContextUtils.getContext()).getUdpClientAddress(); +// if (TextUtils.isEmpty(user) || TextUtils.isEmpty(passwd) || TextUtils.isEmpty(udpClientAddress)) { +// CupidLogUtils.w("ftp message error"); +// return; +// } +// RecordDataManager.getInstance().init(MgContextUtils.getContext(),timestamp , udpClientAddress, 22, user, passwd); +// isConnect = RecordDataManager.getInstance().connectSftp(); +// handler.removeMessages(SHOW_RECORDER); +// handler.sendEmptyMessage(SHOW_RECORDER); +// } +// } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } + + private Handler handler = new Handler(HandlerThreadManager.getMainHandler().getLooper()) { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + if (isConnect) { + RecordDataManager.getInstance().record(); + } else { + Intent intent = new Intent(MgContextUtils.getContext(), LoginSftpActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MgContextUtils.getContext().startActivity(intent); + } + } + }; + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotRouteMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotRouteMessage.java new file mode 100644 index 0000000000..fa6398c9a0 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotRouteMessage.java @@ -0,0 +1,26 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.AutopilotRoute; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +/** + * 自动驾驶路径 + */ +public class WsAutopilotRouteMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { +// CupidLogUtils.w("WsAutopilotRouteMessage===>"+msg); + AutopilotRoute autopilotRoute = gson.fromJson(msg, AutopilotRoute.class); + if (adasListener != null) { + adasListener.onAutopilotRoute(autopilotRoute); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotRoutesMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotRoutesMessage.java new file mode 100644 index 0000000000..c816039bb7 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotRoutesMessage.java @@ -0,0 +1,29 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.google.protobuf.InvalidProtocolBufferException; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.AutopilotTrajectory; +import com.zhidao.support.adas.high.bean.TrajectoryInfo; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +import java.util.ArrayList; +import java.util.List; + +import mogo.trajectory.TrajectoryOuterClass; + +/** + * 自动驾驶路径 + */ +public class WsAutopilotRoutesMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotSNMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotSNMessage.java new file mode 100644 index 0000000000..dbb4e7b0fa --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotSNMessage.java @@ -0,0 +1,27 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.AutopilotRoute; +import com.zhidao.support.adas.high.bean.AutopilotSnRequest; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +/** + * 自动驾驶路径 + */ +public class WsAutopilotSNMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { +// CupidLogUtils.w("WsAutopilotSNMessage===>"+msg); + AutopilotSnRequest autopilotSn = gson.fromJson(msg, AutopilotSnRequest.class); + if (adasListener != null) { + adasListener.onAutopilotSNRequest(); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotStatusMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotStatusMessage.java new file mode 100644 index 0000000000..5f384202d6 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotStatusMessage.java @@ -0,0 +1,28 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.AutopilotStatus; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +/** + * @author nie yunlong + * @des ws自动驾驶状态 + * @date 2020/3/12 + */ +public class WsAutopilotStatusMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + //ws 自动驾驶状态 + AutopilotStatus autopilotStatus = gson.fromJson(msg, AutopilotStatus.class); + if (adasListener != null) { + adasListener.autopilotStatus(autopilotStatus); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotTrajectoryMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotTrajectoryMessage.java new file mode 100644 index 0000000000..cc20edd9eb --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotTrajectoryMessage.java @@ -0,0 +1,60 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.google.protobuf.InvalidProtocolBufferException; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.AutopilotRoute; +import com.zhidao.support.adas.high.bean.AutopilotTrajectory; +import com.zhidao.support.adas.high.bean.RectInfo; +import com.zhidao.support.adas.high.bean.TrajectoryInfo; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +import java.util.ArrayList; +import java.util.List; + +import mogo.trajectory.TrajectoryOuterClass; + +/** + * 自动驾驶路径 + */ +public class WsAutopilotTrajectoryMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + CupidLogUtils.w("WsAutopilotTrajectoryMessage===>"+msg); + AutopilotTrajectory trajectory = gson.fromJson(msg, AutopilotTrajectory.class); + if (adasListener != null) { + adasListener.onAutopilotTrajectory(trajectory.getModels()); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + try { + TrajectoryOuterClass.Trajectory trajectory = TrajectoryOuterClass.Trajectory.parseFrom(msg); + List pointsList = trajectory.getPointsList(); + ArrayList trajectoryInfos = new ArrayList<>(); + for (int i = 0;i" + trajectoryInfos.toString()); + } + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotUpgradeStatusMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotUpgradeStatusMessage.java new file mode 100644 index 0000000000..501077e959 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsAutopilotUpgradeStatusMessage.java @@ -0,0 +1,27 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.IPCUpgradeStateInfo; +import com.zhidao.support.adas.high.common.CupidLogUtils; + +/** + * @des 工控机升级状态 + * @date 2020/3/12 + */ +public class WsAutopilotUpgradeStatusMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + CupidLogUtils.i("工控机升级", "msg=" + msg); + IPCUpgradeStateInfo autopilotStatus = gson.fromJson(msg, IPCUpgradeStateInfo.class); + if (adasListener != null) { + adasListener.onUpgradeStateInfo(autopilotStatus); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsImageSizeMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsImageSizeMessage.java new file mode 100644 index 0000000000..994c4384fe --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsImageSizeMessage.java @@ -0,0 +1,40 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * @author nie yunlong + * @des 图像大小 + * @date 2020/3/12 + */ +public class WsImageSizeMessage extends MyAbstractMessageHandler { + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + JSONObject jsonObject = null; + try { + jsonObject = new JSONObject(msg); + JSONObject videoInfo = jsonObject.optJSONObject("values"); + if (videoInfo != null) { + int width = videoInfo.optInt("width"); + int height = videoInfo.optInt("height"); + CupidLogUtils.e("--->width" + width + ",height" + height); + if (adasListener != null) { + adasListener.onVideoSize(width, height); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsWarnMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsWarnMessage.java new file mode 100644 index 0000000000..373c5b9ac1 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/WsWarnMessage.java @@ -0,0 +1,43 @@ +package com.zhidao.support.adas.high.msg; + +import com.google.gson.Gson; +import com.zhidao.support.adas.high.OnAdasListener; +import com.zhidao.support.adas.high.bean.WarnMessageInfo; +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.queue.UdpMsgModel; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * @author nie yunlong + * @des 报警消息 + * @date 2020/3/12 + */ +public class WsWarnMessage extends MyAbstractMessageHandler { + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, String msg) { + try { + JSONObject jsonObject = new JSONObject(msg); + JSONObject warning = jsonObject.optJSONObject("values"); + if (warning != null) { + String type = warning.optString("type"); + String content = warning.optString("content"); + String value = warning.optString("value"); + String level = warning.optString("level"); + CupidLogUtils.e(String.format("--->type:%s, content:%s, value:%s, level:%s", type, content, value, level)); + if (adasListener != null) { + adasListener.onWarnMessage(new WarnMessageInfo(type, content, value, level)); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void handlerMsg(Gson gson, OnAdasListener adasListener, byte[] msg) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/PublicQueue.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/PublicQueue.java new file mode 100644 index 0000000000..60476a7d42 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/PublicQueue.java @@ -0,0 +1,96 @@ +package com.zhidao.support.adas.high.queue; + +import java.util.Iterator; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.LinkedBlockingDeque; + +/** + * 公共缓存队列 + * 只做两件事:(1)生产;(2)消费 + */ +public class PublicQueue { + + private BlockingDeque blockingDeque = new LinkedBlockingDeque<>();//缓冲区 + + public static PublicQueue publicQueue; + + public static synchronized PublicQueue getInstance() { + if (publicQueue == null) { + publicQueue = new PublicQueue(); + } + return publicQueue; + } + + public void add(T msg) { + + try { + blockingDeque.put(msg); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * 先移除最新的然后添加最新的 + * + * @param msg + */ + public void removeLastPutLast(T msg) { + + try { + //移除最新的 然后把最新的添加到队尾 + blockingDeque.takeFirst(); + blockingDeque.put(msg); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + + public T remove() { + + T t = null; + try { + t = blockingDeque.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return t; + } + + /** + * 清空所有数据 + */ + public void clear(){ + if (blockingDeque!=null){ + blockingDeque.clear(); + } + } + /** + * 获取个数 + * + * @return + */ + public int getSize() { + return blockingDeque.size(); + } + + /** + * 移除最后一个 + */ + public void removeLast() { + blockingDeque.removeLast(); + } + + + public String iteratorData(){ + StringBuilder stringBuilder=new StringBuilder(); + Iterator iterater = blockingDeque.iterator(); + while (iterater.hasNext()){ + T data = iterater.next(); + stringBuilder.append(","+data); + } + return stringBuilder.toString(); + } +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/UdpMsgModel.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/UdpMsgModel.java new file mode 100644 index 0000000000..9763e0dbb6 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/UdpMsgModel.java @@ -0,0 +1,62 @@ +package com.zhidao.support.adas.high.queue; + +import okio.ByteString; + +/** + * author nieyunlong + * + * @des + * @date 2021/3/10 + */ +public class UdpMsgModel { + + /** + * 发送数据类型 + * 1 json,2 pb + */ + private int type; + + /** + * 当前接收到的时间 + */ + private long receiverDataTimeUdp; + + /** + * udp 数据 + */ + private String content; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public long getReceiverDataTimeUdp() { + return receiverDataTimeUdp; + } + + public void setReceiverDataTimeUdp(long receiverDataTimeUdp) { + this.receiverDataTimeUdp = receiverDataTimeUdp; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + + @Override + public String toString() { + return "UdpMsgModel{" + + "receiverDataTimeUdp=" + receiverDataTimeUdp + + ", content='" + content + '\'' + + ", type='" + type + '\'' + + '}'; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/UdpQueueManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/UdpQueueManager.java new file mode 100644 index 0000000000..c4ca870879 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/UdpQueueManager.java @@ -0,0 +1,101 @@ +package com.zhidao.support.adas.high.queue; + +import com.zhidao.support.adas.high.AdasChannel; +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.thread.QueuedWork; +import com.zhidao.support.adas.high.thread.callback.NormalCallback; + +import java.util.concurrent.Future; + +/** + * author : peng hongqiu + * e-mail : penghongqiu@163.com + * date : 2020/12/22 11:46 + * desc : + * version: + */ +public class UdpQueueManager { + + private static UdpQueueManager sInstance = new UdpQueueManager(); + //存储dup发送的数据 + PublicQueue publicQueue = new PublicQueue<>(); + //实时消费 + private boolean runConsumerFlag = true; + private AdasChannel adasChannel; + private RealTimeConsumerFrameMission realTimeConsumerFrameMission; + private Future mFutureTask; + + public static UdpQueueManager getInstance() { + return sInstance; + } + + private UdpQueueManager() { + + } + + + public void addQueueData(String data) { + publicQueue.add(data); + } + + public void registerAdasChannel(AdasChannel adasChannel) { + this.adasChannel = adasChannel; + } + + + /** + * 实时消费帧 消费完一帧 立马取最新一帧 + */ + private class RealTimeConsumerFrameMission extends NormalCallback { + //消费者 + private PublicQueue mPublicQueue; + + public RealTimeConsumerFrameMission(PublicQueue publicQueue) { + mPublicQueue = publicQueue; + } + + @Override + public String doInBackground() { + try { + while (runConsumerFlag) { + String data = mPublicQueue.remove(); + if (adasChannel != null) { + adasChannel.udpDataManage(data); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return super.doInBackground(); + } + + public void stop() { + runConsumerFlag = false; + } + } + + public synchronized void initDector() { + CupidLogUtils.w("===>UdpQueueManager initDector"); + release(); + runConsumerFlag = true; + if (realTimeConsumerFrameMission == null){ + realTimeConsumerFrameMission = new RealTimeConsumerFrameMission(publicQueue); + } + mFutureTask = QueuedWork.submit(null, realTimeConsumerFrameMission); + } + + public void release() { + publicQueue.clear(); + stopCallBack(); + } + + private void stopCallBack() { + if (realTimeConsumerFrameMission != null) { + realTimeConsumerFrameMission.stop(); + realTimeConsumerFrameMission = null; + } + if (mFutureTask != null) { + mFutureTask.cancel(true); + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/WSByteQueueManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/WSByteQueueManager.java new file mode 100644 index 0000000000..b218efb98b --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/WSByteQueueManager.java @@ -0,0 +1,107 @@ +package com.zhidao.support.adas.high.queue; + + +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.socket.FpgaSocket; +import com.zhidao.support.adas.high.thread.QueuedWork; +import com.zhidao.support.adas.high.thread.callback.NormalCallback; + +import java.util.concurrent.Future; + +import okio.ByteString; + +/** + * author : peng hongqiu + * e-mail : penghongqiu@163.com + * date : 2020/12/22 11:46 + * desc : + * version: + */ +public class WSByteQueueManager { + + private static WSByteQueueManager sInstance = new WSByteQueueManager(); + //存储dup/websocket发送的数据 + PublicQueue publicQueue = new PublicQueue<>(); + private RealTimeConsumerFrameMission realTimeConsumerFrameMission; + + private Future mFutureTask; + + private FpgaSocket.IWebSocketConnectListener webSocketConnectListener; + + public static WSByteQueueManager getInstance() { + return sInstance; + } + + private WSByteQueueManager() { + + } + + + public void addQueueData(ByteString data) { +// CupidLogUtils.w("====>生产者几个数据" + publicQueue.getSize() + ",list" + publicQueue.iteratorData()); + publicQueue.add(data); + } + + public void registerWebSocketListener(FpgaSocket.IWebSocketConnectListener webSocketConnectListener) { + this.webSocketConnectListener = webSocketConnectListener; + } + + + /** + * 实时消费帧 消费完一帧 立马取最新一帧 + */ + private class RealTimeConsumerFrameMission extends NormalCallback{ + //消费者 + private PublicQueue mPublicQueue; + //实时消费 + private boolean runConsumerFlag = true; + public RealTimeConsumerFrameMission(PublicQueue publicQueue) { + mPublicQueue = publicQueue; + } + public ByteString doInBackground() { + try { + while (runConsumerFlag) { +// CupidLogUtils.w("===>消费者==>ConsumerDataMission"); + ByteString data = mPublicQueue.remove(); +// CupidLogUtils.w("===>socket消费者" + data + ",内容个数" + mPublicQueue.getSize() + "\n所有数据" + mPublicQueue.iteratorData()); + if (webSocketConnectListener != null) { + webSocketConnectListener.onMessage(data); + } + + } + } catch (Exception e) { + e.printStackTrace(); + } + return super.doInBackground(); + } + + public void stop() { + runConsumerFlag = false; + } + + } + + + public synchronized void initDector() { + release(); + realTimeConsumerFrameMission = new RealTimeConsumerFrameMission(publicQueue); + mFutureTask = QueuedWork.submit(null,realTimeConsumerFrameMission); + + } + + public void release() { + publicQueue.clear(); + stopCallBack(); + } + + private void stopCallBack() { + if (realTimeConsumerFrameMission != null) { + realTimeConsumerFrameMission.stop(); + realTimeConsumerFrameMission = null; + } + if (mFutureTask != null) { + mFutureTask.cancel(true); + } + } + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/WebSocketQueueManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/WebSocketQueueManager.java new file mode 100644 index 0000000000..b7d8c864f4 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/queue/WebSocketQueueManager.java @@ -0,0 +1,105 @@ +package com.zhidao.support.adas.high.queue; + + +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.socket.FpgaSocket; +import com.zhidao.support.adas.high.thread.QueuedWork; +import com.zhidao.support.adas.high.thread.callback.NormalCallback; + +import java.util.concurrent.Future; + +/** + * author : peng hongqiu + * e-mail : penghongqiu@163.com + * date : 2020/12/22 11:46 + * desc : + * version: + */ +public class WebSocketQueueManager { + + private static WebSocketQueueManager sInstance = new WebSocketQueueManager(); + //存储dup/websocket发送的数据 + PublicQueue publicQueue = new PublicQueue<>(); + private RealTimeConsumerFrameMission realTimeConsumerFrameMission; + + private Future mFutureTask; + + private FpgaSocket.IWebSocketConnectListener webSocketConnectListener; + + public static WebSocketQueueManager getInstance() { + return sInstance; + } + + private WebSocketQueueManager() { + + } + + + public void addQueueData(String data) { +// CupidLogUtils.w("====>生产者几个数据" + publicQueue.getSize() + ",list" + publicQueue.iteratorData()); + publicQueue.add(data); + } + + public void registerWebSocketListener(FpgaSocket.IWebSocketConnectListener webSocketConnectListener) { + this.webSocketConnectListener = webSocketConnectListener; + } + + + /** + * 实时消费帧 消费完一帧 立马取最新一帧 + */ + private class RealTimeConsumerFrameMission extends NormalCallback{ + //消费者 + private PublicQueue mPublicQueue; + //实时消费 + private boolean runConsumerFlag = true; + public RealTimeConsumerFrameMission(PublicQueue publicQueue) { + mPublicQueue = publicQueue; + } + public String doInBackground() { + try { + while (runConsumerFlag) { +// CupidLogUtils.w("===>消费者==>ConsumerDataMission"); + String data = mPublicQueue.remove(); +// CupidLogUtils.w("===>socket消费者" + data + ",内容个数" + mPublicQueue.getSize() + "\n所有数据" + mPublicQueue.iteratorData()); + if (webSocketConnectListener != null) { + webSocketConnectListener.onMessage(data); + } + + } + } catch (Exception e) { + e.printStackTrace(); + } + return super.doInBackground(); + } + + public void stop() { + runConsumerFlag = false; + } + + } + + + public synchronized void initDector() { + release(); + realTimeConsumerFrameMission = new RealTimeConsumerFrameMission(publicQueue); + mFutureTask = QueuedWork.submit(null,realTimeConsumerFrameMission); + + } + + public void release() { + publicQueue.clear(); + stopCallBack(); + } + + private void stopCallBack() { + if (realTimeConsumerFrameMission != null) { + realTimeConsumerFrameMission.stop(); + realTimeConsumerFrameMission = null; + } + if (mFutureTask != null) { + mFutureTask.cancel(true); + } + } + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/FpgaSocket.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/FpgaSocket.java new file mode 100644 index 0000000000..a84da89669 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/FpgaSocket.java @@ -0,0 +1,350 @@ +package com.zhidao.support.adas.high.socket; + +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_WEB_SOCKET_MESSAGE_BYTE; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_WEB_SOCKET_MESSAGE_JSON; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_WEB_SOCKET_OPEN; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_ADAS; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_DATA; +import static com.zhidao.support.adas.high.common.Constants.WS_IP_HOST_HEAD; +import static com.zhidao.support.adas.high.common.Constants.WS_PORT; + +import android.graphics.Bitmap; +import android.text.TextUtils; + +import com.google.gson.Gson; +import com.google.protobuf.InvalidProtocolBufferException; +import com.zhidao.support.adas.high.AdasChannel; +import com.zhidao.support.adas.high.bean.FaceLoginResponse; +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.common.RequestWsMsgType; +import com.zhidao.support.adas.high.queue.WSByteQueueManager; +import com.zhidao.support.adas.high.queue.WebSocketQueueManager; +import com.zhjt.service.chain.ChainLog; +import com.zhjt.service.chain.TracingConstants; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high + * @ClassName: FpgaSocket + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/7 13:36 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/7 13:36 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public class FpgaSocket implements IWebSocket { + private static final String TAG = FpgaSocket.class.getSimpleName(); + private OkHttpClient client; + + private WebSocket mWebSocket; + + private EchoWebSocketListener listener; + + private Request request; + + private OkHttpClient.Builder okBuilder; + + private JSONObject jsonObject; + /** + * 是否是用户主动关闭socket + */ + private boolean isUserCloseWebSocket = false; + + public FpgaSocket() { + init(); + } + + private void init() { + if (listener == null) { + listener = new EchoWebSocketListener(); + } + if (okBuilder == null) { + okBuilder = new OkHttpClient.Builder(); + okBuilder.readTimeout(20, TimeUnit.SECONDS); + okBuilder.connectTimeout(20, TimeUnit.SECONDS); + } + if (client == null) { + client = okBuilder.build(); + } + } + + @Override + public void connectWebSocket(String address) { + String wsHost = WS_IP_HOST_HEAD + address + WS_PORT; + CupidLogUtils.i(TAG, "--->connectWebSocket" + wsHost); + init(); + if (client != null) { + request = new Request.Builder() + .url(wsHost) + .build(); + client.newWebSocket(request, listener); + } + } + + @Override + public void closeWebSocket() { + CupidLogUtils.i(TAG, "===>closeWebSocket"); + if (AdasChannel.isUseQueue) { + WebSocketQueueManager.getInstance().release(); + WSByteQueueManager.getInstance().release(); + } + isUserCloseWebSocket = true; + listener = null; + jsonObject = null; + if (mWebSocket != null) { + boolean isClose = mWebSocket.close(1000, null); + CupidLogUtils.i(TAG, "===>webSocket关闭了吗" + isClose); + + mWebSocket.cancel(); + mWebSocket = null; + } + client = null; + request = null; + listener = null; + } + + @Override + public boolean sendDataWebSocket(String data) { + if (mWebSocket != null) { + boolean result = mWebSocket.send(data); + CupidLogUtils.i(TAG, "sendDataWebSocket--->String: " + data + ", result= " + result); + return result; + } + return false; + } + + @Override + public boolean sendDataWebSocket(ByteString data) { + if (mWebSocket != null) { + boolean result = mWebSocket.send(data); + CupidLogUtils.i(TAG, "sendDataWebSocket--->ByteString: " + data + ", result= " + result); + return result; + } + return false; + } + + @Override + public void getConfigData(String appId, String userId) { + CupidLogUtils.i(TAG, "getConfigData appId: " + appId + ", userId:" + userId); + } + + @Override + public void doConfigChanged(int type, String ip, List configInfos) { + CupidLogUtils.i(TAG, "doConfigChanged, type: " + type + " ip: " + ip + " configInfos:" + configInfos); + } + + @Override + public void doConfigChanged(List configInfos) { + CupidLogUtils.i(TAG, "doConfigChanged, configInfos:" + configInfos); + JSONObject jsonObject = new JSONObject(); + //上传配置信息 + //位置信息 action是3 + try { + jsonObject.put("action", RequestWsMsgType.MSG_SEND_UPLOAD_CONFIG.getMsgType()); + jsonObject.put("config", new JSONArray(new Gson().toJson(configInfos))); + sendDataWebSocket(jsonObject.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void saveShotPic(Bitmap bitmap) { + CupidLogUtils.i(TAG, "saveShotPic"); + } + + @Override + public void getTouchImage(String url, double x, double y) { + CupidLogUtils.i(TAG, "getTouchImage, url: " + url + " ,x: " + x + " ,y: " + y); + } + + @Override + public void doRecognizeImage(File file, String deviceId, String tag) { + CupidLogUtils.i(TAG, "doRecognizeImage"); + } + + @Override + public void getUserAchieveInfo(String userId) { + CupidLogUtils.i(TAG, "getUserAchieveInfo, userId:" + userId); + } + + @Override + public void getNaviInfo(int type) { + CupidLogUtils.i(TAG, "getNaviInfo, type:" + type); + } + + @Override + public void syncMedalDetailInfo(String userId, int action, String medalType) { + CupidLogUtils.i(TAG, "syncMedalDetailInfo"); + } + + @Override + public void getCarModelInfo(String s, int id) { + CupidLogUtils.i(TAG, "getCarModelInfo"); + } + + @Override + public void doUpdateCarInfo(String userId, String brandId, String brandName, String modelId, String modelName, String styleId, String styleName) { + CupidLogUtils.i(TAG, "doUpdateCarInfo"); + } + + @Override + public void getApkAndFireWareInfo(String deviceId, String userId, int apkVersionCode, int xvideoCppVersionCode, int appId) { + CupidLogUtils.i(TAG, "getApkAndFireWareInfo"); + } + + @Override + public void getFireWareBaseInfo(String baseUrl) { + CupidLogUtils.i(TAG, "getFireWareBaseInfo"); + } + + @Override + public void sendFirmWareUpdateInfo(String baseUrl, String json) { + CupidLogUtils.i(TAG, "sendFirmWareUpdateInfo"); + } + + @Override + public void startNavigate(String userId, String naviStartName, String naviEndName) { + CupidLogUtils.i(TAG, "startNavigate"); + } + + @Override + public void syncUserNavigateInfo(String navigateId, String longtitude, String latitude, String poId, String currentSpeed) { + CupidLogUtils.i(TAG, "syncUserNavigateInfo"); + } + + @Override + public void doVerticalLineConfigCompleted() { + CupidLogUtils.i(TAG, "doVerticalLineConfigCompleted"); + } + + @Override + public void doSyncCarSpaceInfo(String carLength, String carWidth, String carHeight) { + CupidLogUtils.i(TAG, "doSyncCarSpaceInfo"); + } + + private IWebSocketConnectListener mWebSocketConnectListener; + + public interface IWebSocketConnectListener { + void onWebSocketConnectSuccess(WebSocket webSocket); + + void onWebSocketConnectFailed(WebSocket webSocket, String t); + + void onMessage(String message); + + void onMessage(ByteString bytes) throws InvalidProtocolBufferException; + } + + public void setWebSocketListener(IWebSocketConnectListener listener) { + mWebSocketConnectListener = listener; + } + + public class EchoWebSocketListener extends WebSocketListener { + +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_CONNECT_STATUS, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_WEB_SOCKET_OPEN, +// paramIndexes = {1}, +// clientPkFileName = "sn") + @Override + public void onOpen(WebSocket webSocket, Response response) { + super.onOpen(webSocket, response); + mWebSocket = webSocket; + CupidLogUtils.i(TAG, "websocket response connect success"); + mWebSocketConnectListener.onWebSocketConnectSuccess(webSocket); + } + +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_WEB_SOCKET_MESSAGE_JSON, +// paramIndexes = {1}, +// clientPkFileName = "sn") + @Override + public void onMessage(WebSocket webSocket, String text) { + super.onMessage(webSocket, text); + CupidLogUtils.i(TAG, "websocket response connect text" + text); + if (TextUtils.isEmpty(text)) { + return; + } + if (AdasChannel.isUseQueue) { + WebSocketQueueManager.getInstance().addQueueData(text); + } else { + mWebSocketConnectListener.onMessage(text); + } + } +// +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_WEB_SOCKET_MESSAGE_BYTE, +// paramIndexes = {-1}, +// clientPkFileName = "sn") + @Override + public void onMessage(WebSocket webSocket, ByteString bytes) { + super.onMessage(webSocket, bytes); + CupidLogUtils.i(TAG, "websocket response connect byte" + bytes.hex()); + if (bytes == null) { + return; + } + if (AdasChannel.isUseQueue) { + WSByteQueueManager.getInstance().addQueueData(bytes); + } else { + try { + mWebSocketConnectListener.onMessage(bytes); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } + + } + + @Override + public void onClosing(WebSocket webSocket, int code, String reason) { + super.onClosing(webSocket, code, reason); + mWebSocket = null; + CupidLogUtils.i(TAG, "websocket onClosing==> onClosing" + reason); + } + + @Override + public void onClosed(WebSocket webSocket, int code, String reason) { + super.onClosed(webSocket, code, reason); + mWebSocket = null; + CupidLogUtils.i(TAG, "websocket onClosed ==> " + reason); + mWebSocketConnectListener.onWebSocketConnectFailed(webSocket, reason); + } + + @Override + public void onFailure(WebSocket webSocket, Throwable t, Response response) { + super.onFailure(webSocket, t, response); + mWebSocket = null; + CupidLogUtils.i(TAG, "websocket onFailure ===>" + t.getMessage()); + mWebSocketConnectListener.onWebSocketConnectFailed(webSocket, t.toString()); + + } + } + + public WebSocket getWebSocket() { + return mWebSocket; + } + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/IWebSocket.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/IWebSocket.java new file mode 100644 index 0000000000..4c38b96e6a --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/IWebSocket.java @@ -0,0 +1,154 @@ +package com.zhidao.support.adas.high.socket; + +import android.graphics.Bitmap; + +import com.zhidao.support.adas.high.bean.FaceLoginResponse; + +import java.io.File; +import java.util.List; + +import okio.ByteString; + +/** + * @ProjectName: lib-adas-fpga + * @Package: com.zhidao.lib.adas.high + * @ClassName: IWebSocket + * @Description: java类作用描述 + * @Author: fenghl + * @CreateDate: 2020/2/7 13:28 + * @UpdateUser: 更新者: + * @UpdateDate: 2020/2/7 13:28 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ +public interface IWebSocket { + /** + * 连接socket + */ + void connectWebSocket(String address); + + /** + * 关闭webSocket + */ + void closeWebSocket(); + + /** + * websocket send data + * + * @param data + */ + boolean sendDataWebSocket(String data); + boolean sendDataWebSocket(ByteString data); + + /** + * 云端拉取配置信息 + * + * @param + */ + void getConfigData(String appId, String userId); + + /** + * 更改云端配置信息 + * + * @param configInfos + */ + void doConfigChanged(int type, String ip, List configInfos); + + /** + * 上传配置 + * @param configInfos + */ + void doConfigChanged( List configInfos); + + /** + * 保存图片 + */ + void saveShotPic(Bitmap bitmap); + + + /** + * @param x + * @param y + */ + void getTouchImage(String url, double x, double y); + + /** + * @param file + * @param deviceId + * @param tag + */ + void doRecognizeImage(File file, String deviceId, String tag); + + /** + * @param userId + */ + void getUserAchieveInfo(String userId); + + + /** + * 从板子上获取导航信息 + * + * @param type 10/角度 11/位置 + */ + void getNaviInfo(int type); + + + /** + * 同步成就信息 + * + * @param userId + * @param action + * @param medalType + */ + void syncMedalDetailInfo(String userId, int action, String medalType); + + + /** + * 获取品牌车型车款信息 + * + * @param s + */ + void getCarModelInfo(String s, int id); + + void doUpdateCarInfo(String userId, String brandId, String brandName, String modelId, String modelName, String styleId, String styleName); + + /** + * 获取apk 以及 固件升级信息 + * + * @param deviceId + * @param userId + * @param apkVersionCode + * @param xvideoCppVersionCode + * @param appId 2是专业版 + */ + void getApkAndFireWareInfo(String deviceId, String userId, int apkVersionCode, int xvideoCppVersionCode,int appId); + + /** + * 获取固件基础信息 + */ + void getFireWareBaseInfo(String baseUrl); + + /** + * 发送板子 更新升级信息 + * @param baseUrl + * @param json + */ + void sendFirmWareUpdateInfo(String baseUrl,String json); + + void startNavigate(String userId, String naviStartName, String naviEndName); + + void syncUserNavigateInfo(String navigateId, String longtitude, String latitude, String poId, String currentSpeed); + + + void doVerticalLineConfigCompleted(); + + + /** + * 给板子同步长宽高信息 + * @param carLength + * @param carWidth + * @param carHeight + */ + void doSyncCarSpaceInfo(String carLength, String carWidth, String carHeight); +} + diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/SocketMsgType.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/SocketMsgType.java new file mode 100644 index 0000000000..aa4d402a78 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/SocketMsgType.java @@ -0,0 +1,62 @@ +package com.zhidao.support.adas.high.socket; + +/** + * @author nie yunlong + * @description 接收消息type + * @date 2018/7/3 + */ +public enum SocketMsgType { + + /** + * 警告 + */ + MSG_WARNING_TYPE(1, "警告"), + /** + * 视频分辨率 + */ + MSG_VIDEO_INFO_TYPE(2, "视频分辨率"), + + /** + * 控制台开 + */ + MSG_CONSOLE_OPEN_TYPE(3, "控制台开"), + /** + * 控制台关 + */ + MSG_CONSOLE_CLOSE_TYPE(4, "控制台关"), + /** + * 车道线曲率 + */ + MSG_CONSOLE_ROAD_TYPE(11, "车道线曲率"), + /** + * 是否是最左侧车道 + */ + MSG_IS_ROAD_LEFT(10, "获取位置"), + + /** + * 获取通知进度 + */ + MSG_UPGRADE_NOTIFY(12,"通知进度"); + + + int mMsgType; + String mMsgContent; + + SocketMsgType(int msgType, String msgContent) { + this.mMsgType = msgType; + this.mMsgContent = msgContent; + } + + /** + * 获取msgType + * + * @return + */ + public int getMsgType() { + return mMsgType; + } + + public String getmMsgContent() { + return mMsgContent; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/DefaultMessageProtocol.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/DefaultMessageProtocol.java new file mode 100644 index 0000000000..2095861dbc --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/DefaultMessageProtocol.java @@ -0,0 +1,50 @@ +package com.zhidao.support.adas.high.socket.read; + +import com.zhidao.support.adas.high.common.DigitalTrans; + +/** + * @author song kenan + * @des + * @date 2021/10/20 + */ +public class DefaultMessageProtocol implements IMessageProtocol{ + @Override + public int getMagicCodeLength() { + return 2; + } + + @Override + public int getPackageLength() { + return 4; + } + + @Override + public int getOffsetLength() { + return 2; + } + + public int getOutHeader(){ + return getMagicCodeLength()+getPackageLength()+getOffsetLength(); + } + + @Override + public int getHeaderLength(byte[] offset) { + if (offset == null) { + return 0; + } + String lengthStr = DigitalTrans.byte2hex(offset); + int length = DigitalTrans.hexStringToAlgorism(lengthStr); + return length - 8; + } + + @Override + public int getPayloadLength(byte[] readData,byte[] offset) { + if (readData == null){ + return 0; + } + if (offset == null){ + return DigitalTrans.hexStringToAlgorism(DigitalTrans.byte2hex(readData)); + } + return 0; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/IMessageProtocol.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/IMessageProtocol.java new file mode 100644 index 0000000000..e68846c9f9 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/IMessageProtocol.java @@ -0,0 +1,35 @@ +package com.zhidao.support.adas.high.socket.read; + +import java.nio.ByteOrder; + +/** + * @author song kenan + * @des + * @date 2021/10/20 + */ +public interface IMessageProtocol { + /** + * 获取magicCode的长度 + */ + int getMagicCodeLength(); + + /** + * 包长度 + */ + int getPackageLength(); + + /** + * 数据偏移量的长度 + */ + int getOffsetLength(); + + /** + * 获取header数据长度 + */ + int getHeaderLength(byte[] offset); + + /** + * 消息体长度 + */ + int getPayloadLength(byte[] readData,byte[] offset); +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/OriginReadData.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/OriginReadData.java new file mode 100644 index 0000000000..b078e4e7c7 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/OriginReadData.java @@ -0,0 +1,103 @@ +package com.zhidao.support.adas.high.socket.read; + +import com.zhidao.support.adas.high.common.DigitalTrans; + +import java.io.Serializable; + +/** + * @author song kenan + * @des + * @date 2021/10/20 + */ +public class OriginReadData implements Serializable { + /** + * 用于检查数据是否为正确数据 + * mg=0x6d67 + */ + private byte[] magicCode; + + /** + * 包长度 + */ + private byte[] packageLength; + + /** + * 偏移量,用于计算header长度 + */ + private byte[] offset; + + /** + * 头部消息,装载消息类型等 + * 长度=offset-out_header.length + */ + private byte[] header; + + /** + * 负载数据:真实上报的数据 + */ + private byte[] payload; + + + /** + * 获取out_header 由魔数、包大小、payload偏移量组成; + * 用于识别连接数据和数据报解码使用。 + * 固定8个字节,否则出错。 + */ + public byte[] getOutHeaderBytes() { + byte[] bytes = DigitalTrans.concatBytes(getMagicCode(), getPackageLength()); + byte[] outHeader = DigitalTrans.concatBytes(bytes, getOffset()); + return outHeader; + } + + /** + * 获取完整的数据 + * + * @return + */ + public byte[] getOriginDataBytes() { + byte[] bytes = DigitalTrans.concatBytes(getOutHeaderBytes(), getHeader()); + byte[] originData = DigitalTrans.concatBytes(bytes, getPayload()); + return originData; + } + + + public byte[] getMagicCode() { + return magicCode; + } + + public void setMagicCode(byte[] magicCode) { + this.magicCode = magicCode; + } + + public byte[] getPackageLength() { + return packageLength; + } + + public void setPackageLength(byte[] packageLength) { + this.packageLength = packageLength; + } + + public byte[] getOffset() { + return offset; + } + + public void setOffset(byte[] offset) { + this.offset = offset; + } + + public byte[] getHeader() { + return header; + } + + public void setHeader(byte[] header) { + this.header = header; + } + + public byte[] getPayload() { + return payload; + } + + public void setPayload(byte[] payload) { + this.payload = payload; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/SocketReader.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/SocketReader.java new file mode 100644 index 0000000000..007a41f4d2 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/read/SocketReader.java @@ -0,0 +1,69 @@ +package com.zhidao.support.adas.high.socket.read; + +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.common.DigitalTrans; +import com.zhidao.support.adas.high.udp.CupidUdpConstract; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.util.Arrays; + +import okio.ByteString; + +/** + * @author song kenan + * @des + * @date 2021/10/20 + */ +public class SocketReader { + private DefaultMessageProtocol messageProtocol; + private static final byte[] mg = new byte[]{(byte) 0x6d, 0x67}; + + public SocketReader() { + messageProtocol = new DefaultMessageProtocol(); + } + + public OriginReadData read(ByteString bytes) { + OriginReadData originalData = new OriginReadData(); + OriginReadData originReadData = readData(bytes, originalData); + //分发 + return originReadData; + + } + + private synchronized OriginReadData readData(ByteString bytes, OriginReadData originalData) { +// CupidLogUtils.w("--->websocket byte read bytes :"+bytes.hex()); + //读取magicCode + ByteString magicCode = bytes.substring(0, messageProtocol.getMagicCodeLength()); + originalData.setMagicCode(magicCode.toByteArray()); +// CupidLogUtils.w("--->websocket byte read magic :"+magicCode.hex()); + if (Arrays.equals(magicCode.toByteArray(), mg)) { + //读取offset + ByteString offset = bytes.substring(messageProtocol.getMagicCodeLength(), messageProtocol.getMagicCodeLength() + messageProtocol.getOffsetLength()); + originalData.setOffset(offset.toByteArray()); +// CupidLogUtils.w("--->websocket byte read offset :"+offset.hex()+";offset length="+ DigitalTrans.hexStringToAlgorism(offset.hex())); + //读取packageLength + ByteString packageLength = bytes.substring(messageProtocol.getMagicCodeLength() + messageProtocol.getOffsetLength(), messageProtocol.getOutHeader()); + originalData.setPackageLength(packageLength.toByteArray()); +// CupidLogUtils.w("--->websocket byte read packageLength :"+packageLength.hex()+";pl="+ DigitalTrans.hexStringToAlgorism(packageLength.hex())); + //读取header + ByteString header = bytes.substring(messageProtocol.getOutHeader(), messageProtocol.getOutHeader() + messageProtocol.getHeaderLength(offset.toByteArray())); + originalData.setHeader(header.toByteArray()); +// CupidLogUtils.w("--->websocket byte read header :"+header.hex()); + //读取payload + ByteString payload = bytes.substring(messageProtocol.getOutHeader() + messageProtocol.getHeaderLength(offset.toByteArray())); + originalData.setPayload(payload.toByteArray()); +// CupidLogUtils.w("--->websocket byte read payload :"+payload.hex()); + return originalData; + } else { + CupidLogUtils.w("--->websocket byte read magicCode error 丢弃"); + return null; + } + + + } + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/CallableWrapper.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/CallableWrapper.java new file mode 100644 index 0000000000..1d0508a537 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/CallableWrapper.java @@ -0,0 +1,84 @@ +/* +Copyright 2017 yangchong211(github.com/yangchong211) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package com.zhidao.support.adas.high.thread; + + + +import com.zhidao.support.adas.high.thread.callback.NormalCallback; +import com.zhidao.support.adas.high.thread.callback.ThreadCallback; + +import java.util.concurrent.Callable; + +/** + * @param + */ +public final class CallableWrapper implements Callable { + + private ThreadCallback callback; + + private Callable proxy; + + /** + * 构造方法 + * + * @param proxy 线程优先级 + */ + public CallableWrapper(Callable proxy, NormalCallback normalCallback) { + this.proxy = proxy; + this.callback = normalCallback; + } + + /** + * 详细可以看我的GitHub:https://github.com/yangchong211 + * 自定义Callable继承Callable类,Callable 是在 JDK1.5 增加的。 + * Callable 的 call() 方法可以返回值和抛出异常 + * + * @return 泛型 + * @throws Exception 异常 + */ + @Override + public T call() { + if (callback != null) { + //开始 + callback.onStart(); + } + T t = null; + try { + t = proxy == null ? null : proxy.call(); + if (callback != null) { + T callInBackground = callback.doInBackground(); + if (callInBackground != null) { + t = callInBackground; + } + } + } catch (Exception e) { + e.printStackTrace(); + //异常错误 + if (callback != null) { + callback.onError(e); + } + } finally { + //完成 + if (callback != null) { + callback.onCompleted(); + } + } + return t; + } + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/QueuedWork.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/QueuedWork.java new file mode 100644 index 0000000000..595736858d --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/QueuedWork.java @@ -0,0 +1,141 @@ +package com.zhidao.support.adas.high.thread; + +import android.os.Handler; +import android.os.Looper; + + +import com.zhidao.support.adas.high.thread.callback.NormalCallback; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by nieyunlong on 17/8/8. + * 队列 + */ + +public class QueuedWork { + + private static Handler uiHandler; + + /*sdk请求量不是很大*/ + private static final int MAX_MISSION_COUNT = 1; //设置线程池最大线程个数 + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); + // We want at least 2 threads and at most 4 threads in the core pool, + // preferring to have 1 less than the CPU count to avoid saturating + // the CPU with background work +// private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); + private static final int CORE_POOL_SIZE = 3; + private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; + + public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR; + + static { + ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, 30, TimeUnit.SECONDS, + new LinkedBlockingDeque(128)); + threadPoolExecutor.allowCoreThreadTimeOut(true); + THREAD_POOL_EXECUTOR = threadPoolExecutor; + } + + + public static void runInMain(Runnable paramRunnable) { + if (uiHandler == null) + uiHandler = new Handler(Looper.getMainLooper()); + uiHandler.post(paramRunnable); + } + + public static void runInBack(Runnable task) { + THREAD_POOL_EXECUTOR.execute(task); + } + + /** + * 建议停止正在执行的任务 + */ + public static void shutDownNow() { + THREAD_POOL_EXECUTOR.shutdownNow(); + } + + /** + * 建议停止正在执行的任务 + */ + public static void shutDown() { + THREAD_POOL_EXECUTOR.shutdown(); + } + + /** + * 发射任务 + * 提交任务有返回值 + * 当我们使用submit来提交任务时,它会返回一个future,我们就可以通过这个future来判断任务是否执行成功, + * 还可以通过future的get方法来获取返回值。如果子线程任务没有完成,get方法会阻塞住直到任务完成, + * 而使用get(long timeout, TimeUnit unit)方法则会阻塞一段时间后立即返回,这时候有可能任务并没有执行完。 + * + * @param callable callable + * @param type + * @return {@link Future} + */ + public static Future submit(Callable callable, NormalCallback normalCallback) { + callable = new CallableWrapper<>(callable, normalCallback); + Future result = THREAD_POOL_EXECUTOR.submit(callable); + return result; + } + + /** + * 移除队列里面的任务 + */ + public static int getQueueSize() { + if (null != THREAD_POOL_EXECUTOR) { + BlockingQueue queue = THREAD_POOL_EXECUTOR.getQueue(); + return queue.size(); + } + return 0; + } + + + public static abstract class ZSAsyncTask { + + protected Runnable thread; + + protected void onPreExecute() { + } + + protected abstract Result doInBackground(); + + protected void onPostExecute(Result paramResult) { + } + + public final ZSAsyncTask execute() { + this.thread = new Runnable() { + public void run() { + final Result var1 = ZSAsyncTask.this.doInBackground(); + QueuedWork.runInMain(new Runnable() { + public void run() { + ZSAsyncTask.this.onPostExecute(var1); + } + }); + } + }; + QueuedWork.runInMain(new Runnable() { + public void run() { + //pre execute + ZSAsyncTask.this.onPreExecute(); + runInBack(ZSAsyncTask.this.thread); + } + }); + return this; + } + } + + private static final ThreadFactory sThreadFactory = new ThreadFactory() { + private final AtomicInteger mCount = new AtomicInteger(1); + + public Thread newThread(Runnable r) { + return new Thread(r, "ZSAsyncTask #" + mCount.getAndIncrement()); + } + }; +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/callback/NormalCallback.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/callback/NormalCallback.java new file mode 100644 index 0000000000..15ba267b0a --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/callback/NormalCallback.java @@ -0,0 +1,44 @@ +/* +Copyright 2017 yangchong211(github.com/yangchong211) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package com.zhidao.support.adas.high.thread.callback; + +/** + * + * @param + */ +public class NormalCallback implements ThreadCallback { + + + @Override + public void onError(Throwable t) { + + } + + @Override + public Result doInBackground() { + return null; + } + + @Override + public void onCompleted() { + + } + + @Override + public void onStart() { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/callback/ThreadCallback.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/callback/ThreadCallback.java new file mode 100644 index 0000000000..9e9d0965b9 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/thread/callback/ThreadCallback.java @@ -0,0 +1,47 @@ +/* +Copyright 2017 yangchong211(github.com/yangchong211) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package com.zhidao.support.adas.high.thread.callback; + +/** + * + * @param + */ +public interface ThreadCallback { + + /** + * 当线程发生错误时,将调用此方法。 + * @param t 异常 + */ + void onError(Throwable t); + + /** + * 做后台操作 + * 如果没有Callable 代理 直接走这个后台操作 如果有代理会直接走代理 + */ + Result doInBackground(); + + /** + * 通知用户知道它已经完成 + */ + void onCompleted(); + + /** + * 通知用户任务开始运行 + */ + void onStart(); + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidBufStreamImpl.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidBufStreamImpl.java new file mode 100644 index 0000000000..b9e0497aec --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidBufStreamImpl.java @@ -0,0 +1,88 @@ +package com.zhidao.support.adas.high.udp; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +/** + * Created by wangyaofu on 2018/6/14. + */ +public class CupidBufStreamImpl implements IBuffStream { + + // 5M +// public static final int BUF_SIZE = 5242880; + public static final int BUF_SIZE = 2097152; + //3M + public static final int BUF_SIZE_LIMIT = 3145728; + + ByteArrayOutputStream ostream0_; + ByteArrayOutputStream ostream1_; + + volatile Boolean isSwitch; + + @Override + public void init() { + ostream0_ = new ByteArrayOutputStream(BUF_SIZE); + ostream1_ = new ByteArrayOutputStream(BUF_SIZE); + isSwitch = false; + } + + @Override + public OutputStream getOutputStream() { + synchronized (isSwitch) { + if (isSwitch) { + return ostream1_; + } else { + return ostream0_; + } + } + + } + + @Override + public byte[] getData() { + byte[] b = null; + synchronized (isSwitch) { + if (isSwitch) { + b = ostream0_.toByteArray(); + } else { + b = ostream1_.toByteArray(); + } + } + return b; + } + + @Override + public int getLength() { + int size; + synchronized (isSwitch) { + if (isSwitch) { + size = ostream0_.size(); + } else { + size = ostream1_.size(); + } + } + return size; + } + + @Override + public void close() { + if (ostream0_ != null) { + ostream0_.reset(); + } + if (ostream1_ != null) { + ostream1_.reset(); + } + } + + @Override + public void doSwitch() { + synchronized (isSwitch) { + if (isSwitch) { + ostream0_.reset(); + } else { + ostream1_.reset(); + } + isSwitch = !isSwitch; + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidBufStreamImpl2.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidBufStreamImpl2.java new file mode 100644 index 0000000000..df33ac8ade --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidBufStreamImpl2.java @@ -0,0 +1,54 @@ +package com.zhidao.support.adas.high.udp; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +/** + * Created by wangyaofu on 2018/6/14. + */ +public class CupidBufStreamImpl2 implements IBuffStream { + + // 5M +// public static final int BUF_SIZE = 5242880; + public static final int BUF_SIZE = 2097152; + //3M + public static final int BUF_SIZE_LIMIT = 3145728; + + ByteArrayOutputStream ostream0_; + + @Override + public void init() { + if (ostream0_ != null) { + ostream0_.reset(); + ostream0_ = null; + } + ostream0_ = new ByteArrayOutputStream(BUF_SIZE); + } + + @Override + public OutputStream getOutputStream() { + return ostream0_; + } + + @Override + public byte[] getData() { + byte[] b = ostream0_.toByteArray(); + return b; + } + + @Override + public int getLength() { + int size = ostream0_.size(); + return size; + } + + @Override + public void close() { + init(); + } + + @Override + public void doSwitch() { + ostream0_.reset(); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidUdpConstract.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidUdpConstract.java new file mode 100644 index 0000000000..8a0aabf976 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidUdpConstract.java @@ -0,0 +1,145 @@ +package com.zhidao.support.adas.high.udp; + + +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_ALIAS_CODE_UDP_INIT; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_ADAS; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS; + +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.udp.factory.AbstractUdpImpl; +import com.zhidao.support.adas.high.udp.factory.CupidUdpFactory; +import com.zhjt.service.chain.ChainLog; +import com.zhjt.service.chain.TracingConstants; + +/** + * @author nie yunlong + * @description udp 与 stream + * @date 2018/6/15 + */ +public class CupidUdpConstract { + + + private CupidBufStreamImpl2 buffStreamImpl; + /** + * udp 接收数据线程 + */ + private Thread udpReceiverDataThread; + /** + * 默认的udp端口 + */ + private int defaultVideoUdpPort = 6665; + + /** + * 默认的udp端口 + */ + private int defaultRenderImageUdpPort = 6661; + + private AbstractUdpImpl udpImpl; + /** + * 默认是0 创建h264解析流 + */ + public static final int VIDEO_STREAM_UDP = 0; + /** + * 上层绘制 待开发 + */ + public static final int VIDEO_RENDER_IMAGE_UDP = 1; + + public CupidUdpConstract(int udpType) { + init(udpType); + } + + /** + * 初始化UDPserver 接收数据 + */ + + private void init(int udpType) { + if (udpType == VIDEO_STREAM_UDP) { + udpImpl = CupidUdpFactory.createVideoStreamUdp(); + udpImpl.setUdpPort(defaultVideoUdpPort); + // buffStreamImpl = new CupidBufStreamImpl(); + buffStreamImpl = new CupidBufStreamImpl2(); + buffStreamImpl.init(); + udpImpl.setBuffStream(buffStreamImpl); + } else if (udpType == VIDEO_RENDER_IMAGE_UDP) { + udpImpl = CupidUdpFactory.createRenderImageUdp(); + udpImpl.setUdpPort(defaultRenderImageUdpPort); + } + udpImpl.setStop(false); + startReceiverDataThread(); + } + + /** + * 开启线程 在surface准备好之后再进行接收数据 + */ +// @ChainLog(linkCode = CHAIN_LINK_ADAS, +// linkChainLog = CHAIN_LINK_LOG_CONNECT_STATUS, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = CHAIN_ALIAS_CODE_UDP_INIT, +// paramIndexes = {0}, +// clientPkFileName = "sn") + public void startReceiverDataThread() { + if (udpReceiverDataThread != null) { + udpReceiverDataThread.interrupt(); + udpReceiverDataThread = null; + } + udpReceiverDataThread = new Thread(udpImpl); + udpReceiverDataThread.start(); + } + + public void setOnReceiverH264Data(IGetH264Data getH264Data) { + udpImpl.getVideoInputStreamData(getH264Data); + } + + /** + * 连接listener + * + * @param connectListener + */ + public void setOnConnectListener(IConnectRtpListener connectListener) { + udpImpl.setOnConnectListener(connectListener); + } + + public void onPause() { + udpImpl.onPause(); + } + + public void onResume() { + udpImpl.onResume(); + } + + /** + * 初始化webSocket + */ + public void setUdpIsFirstInit() { + if (udpImpl != null) { + udpImpl.setFirstReceiverAddress(false); + } + } + + /** + * 服务端关闭 初始化buffer + */ + public void resetBuffer() { + if (udpImpl != null) { + udpImpl.initBuffer(); + } + } + + + public void release() { + try { + CupidLogUtils.e("---->关闭socket"); + if (udpImpl != null) { + udpImpl.close(); + udpImpl = null; + } + if (udpReceiverDataThread != null && !udpReceiverDataThread.isInterrupted()) { + udpReceiverDataThread.interrupt(); + udpReceiverDataThread = null; + } + + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidUdpServer.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidUdpServer.java new file mode 100644 index 0000000000..bc4f6c1a0f --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/CupidUdpServer.java @@ -0,0 +1,275 @@ +package com.zhidao.support.adas.high.udp; + + + +import com.zhidao.support.adas.high.common.CupidLogUtils; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; + +/** + * Created by wangyaofu on 18/6/14. + */ +public class CupidUdpServer implements Runnable { + + static final String TAG = CupidUdpServer.class.getSimpleName(); + + private int udpPort; + private boolean isMultiCast; + private String multiCastIp; + private volatile boolean isStop; + + private IBuffStream buffStream; + /** + * 接口 回调一帧 + */ + private IGetH264Data mGetH264Data; + + private IConnectRtpListener mConnectRtpListener; + /** + * 接收的ip地址 + */ + private volatile String mReceiveAddress; + + + public int getUdpPort() { + return udpPort; + } + + public void setUdpPort(int udpPort) { + this.udpPort = udpPort; + } + + public boolean isMultiCast() { + return isMultiCast; + } + + public void setMultiCast(boolean multiCast) { + isMultiCast = multiCast; + } + + public String getMultiCastIp() { + return multiCastIp; + } + + public void setMultiCastIp(String multiCastIp) { + this.multiCastIp = multiCastIp; + } + + public boolean isStop() { + return isStop; + } + + public synchronized void setStop(boolean stop) { + isStop = stop; + } + + public IBuffStream getBuffStream() { + return buffStream; + } + + public void setBuffStream(IBuffStream buffStream) { + this.buffStream = buffStream; + } + + + /** + * + * @param connectRtpListener + */ + public void setOnConnectListener(IConnectRtpListener connectRtpListener) { + this.mConnectRtpListener = connectRtpListener; + } + + /** + * + * @param getH264Data + */ + public void setOnReceiverListener(IGetH264Data getH264Data) { + this.mGetH264Data = getH264Data; + } + + private static final int DATA_LEN = 4096; + byte[] inBuff = new byte[DATA_LEN]; + /** + * 接收的包 + */ + private DatagramPacket inPacket = new DatagramPacket(inBuff, inBuff.length); + /** + * udp + */ + private DatagramSocket socket = null; + /** + * 带广播的udp + */ + private MulticastSocket mMulticastSocket = null; + /** + * 第一次获取到接收端的ip + */ + private volatile boolean isFirstReceiverAddress; + + boolean parseRTP() { + int naluType = 0; + int nalunri = 0; + int naluf = 0; + + boolean isEnd = false; + if ((int) (inBuff[1] >> 7 & 0x01) == 1) { + isEnd = true; + } + + byte naluHeader = inBuff[12]; + naluType = naluHeader & 0x1f; + nalunri = naluHeader >> 5 & 0x03; + naluf = naluHeader >> 7 & 0x01; + int len = inPacket.getLength(); + CupidLogUtils.i(TAG, "packet-len:" + len); + + byte[] fu_h_byte = new byte[5]; + fu_h_byte[0] = 0; + fu_h_byte[1] = 0; + fu_h_byte[2] = 0; + fu_h_byte[3] = 1; + + if (28 == naluType) { + // H264 Begin + int fu_type = 0; + int fu_r = 0; + int fu_e = 0; + int fu_s = 0; + + byte fu_header = inBuff[13]; + fu_type = fu_header & 0x1f; + fu_r = fu_header >> 5 & 0x01; + fu_e = fu_header >> 6 & 0x01; + fu_s = fu_header >> 7 & 0x01; + + if (fu_s == 1) { + //buffStream.doSwitch(); + // start of fu-a + fu_h_byte[4] = (byte) ((fu_type & 0x1f) | (nalunri << 5 & 0x60) | (naluf << 7 & 0x80)); + try { + //buffStream.getOutputStream().write(fu_h_byte, 0, 5); + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } else { + // end of fu-a + try { + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + } else { + fu_h_byte[4] = (byte) ((naluType & 0x1f) | (nalunri << 5 & 0x60) | (naluf << 7 & 0x80)); + try { + //buffStream.getOutputStream().write(fu_h_byte, 0, 5); + buffStream.getOutputStream().write(inBuff, 13, len - 13); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + if (isEnd) { + buffStream.doSwitch(); + if (mGetH264Data != null) { + mGetH264Data.getH264Data(buffStream.getData(),System.currentTimeMillis()); + } + } + return true; + } + + @Override + public void run() { + CupidLogUtils.e(TAG, "---->开始接收数据"); + try { + if (isMultiCast) { + mMulticastSocket = new MulticastSocket(udpPort); + InetAddress bcAddr = InetAddress.getByName(multiCastIp); + mMulticastSocket.setReuseAddress(true); + mMulticastSocket.joinGroup(bcAddr); + mMulticastSocket.setLoopbackMode(false); + } else { + CupidLogUtils.e(TAG, "---->开始连接端口" + udpPort); + socket = new DatagramSocket(udpPort); + socket.setReuseAddress(true); + CupidLogUtils.e(TAG, "---->连接成功" + udpPort); + } + } catch (Exception e) { + e.printStackTrace(); + if (mConnectRtpListener != null) { + mConnectRtpListener.onConnectionFailedRtp(e.getMessage()); + } + return; + } + + while (!isStop) { + try { + if (isMultiCast && mMulticastSocket != null) { + mMulticastSocket.receive(inPacket); + } else { + if (socket != null) { + socket.receive(inPacket); + } + } + if (!isFirstReceiverAddress) { + mReceiveAddress = inPacket.getAddress().getHostAddress(); + CupidLogUtils.e("mReceiveAddress--->mReceiveAddress" + mReceiveAddress); + isFirstReceiverAddress = true; + if (mConnectRtpListener != null) { + mConnectRtpListener.getOnConnectionAddress(mReceiveAddress); + } + } + + + if (inPacket.getLength() > 12) { + parseRTP(); + } + } catch (Exception e) { + e.printStackTrace(); + if (mConnectRtpListener != null) { + mConnectRtpListener.onConnectionFailedRtp(e.getMessage()); + } + } + } + } + + /** + * 获取到连接ip地址 + * + * @return + */ + public String getmReceiveAddress() { + return mReceiveAddress; + } + + + /** + * 关闭流 + */ + public synchronized void close() { + setStop(true); + if (mMulticastSocket != null) { + mMulticastSocket.close(); + } + if (socket != null) { + socket.close(); + } + } + + public boolean isFirstReceiverAddress() { + return isFirstReceiverAddress; + } + + public void setFirstReceiverAddress(boolean firstReceiverAddress) { + isFirstReceiverAddress = firstReceiverAddress; + } +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IBuffStream.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IBuffStream.java new file mode 100644 index 0000000000..07b065ab5b --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IBuffStream.java @@ -0,0 +1,20 @@ +package com.zhidao.support.adas.high.udp; + +import java.io.OutputStream; + +/** + * Created by wangyaofu on 2018/6/14. + */ +public interface IBuffStream { + void init(); + + OutputStream getOutputStream(); + + void doSwitch(); + + byte[] getData(); + + int getLength(); + + void close(); +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IConnectRtpListener.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IConnectRtpListener.java new file mode 100644 index 0000000000..ecccba0bb9 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IConnectRtpListener.java @@ -0,0 +1,25 @@ +package com.zhidao.support.adas.high.udp; + +/** + * @author nie yunlong + * @description + * @date 2018/6/15 + */ +public interface IConnectRtpListener { + + /** + * 连接成功 指的是 client发送数据包 + */ + void onConnectionSuccessRtp(); + + void onConnectionFailedRtp(String reason); + + /** + * 获取到client的ip地址 + * @param address + */ + void getOnConnectionAddress(String address); + + void onDisconnectRtp(); + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IGetH264Data.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IGetH264Data.java new file mode 100644 index 0000000000..d32a9f0351 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IGetH264Data.java @@ -0,0 +1,16 @@ +package com.zhidao.support.adas.high.udp; + +/** + * @author nie yunlong + * @description h264数据 + * @date 2018/6/15 + */ +public interface IGetH264Data { + + /** + * 获取h264数据 + * @param data h264 + */ + void getH264Data(byte[] data,long receiverDataUdpTime); + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IRenderImageListener.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IRenderImageListener.java new file mode 100644 index 0000000000..88b4495452 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/IRenderImageListener.java @@ -0,0 +1,81 @@ +package com.zhidao.support.adas.high.udp; + +import android.view.SurfaceHolder; + +/** + * @author nie yunlong + * @description 回调获取数据时候 ui变化 + * @date 2018/6/26 + */ +public interface IRenderImageListener { + /** + * 获取udp包的数据 用来告知展示什么ui + * + * @param data + */ + void getUdpData(String data); + + /** + * surface create + * + * @param holder + */ + void surfaceCreated(SurfaceHolder holder); + + /** + * 改变尺寸 + * + * @param holder + * @param format + * @param width + * @param height + */ + void surfaceChanged(SurfaceHolder holder, int format, int width, int height); + + /** + * 销毁 + * + * @param holder + */ + void surfaceDestroyed(SurfaceHolder holder); + + /** + * udp 连接失败 + */ + void onConnectionFailedRtp(String reason); + + /** + * 连接udpok + * @param address + */ + void getOnConnectionAddress(String address); + + + /** + * 所有的都是模拟 贴图模式 + * + * @param canvas + * @param width + * @param height + * @param scaleWidth + * @param scaleHeight + * @param isChange 是否改变元数据坐标 + */ + //boolean draw(Canvas canvas, int width, int height, float scaleWidth, float scaleHeight, List drawUiInfoList, boolean isChange); + + /** + * 绘制 与帧绑定 + * + * @param canvas + * @param width 展示UI层 宽度 + */ + // void draw(Canvas canvas, int width, int height, float scaleWidth, float scaleHeight, DrawUiInfo drawUiInfo); + + /** + * @param canvas + * @param picWidth 图片的宽度 + * @param picHeight 图片的高度 + * @param drawAlarmAnimationList 报警位置的集合 + */ +// void drawAlarm(Canvas canvas, float picWidth, float picHeight, List drawAlarmAnimationList); +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/RTPUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/RTPUtils.java new file mode 100644 index 0000000000..34bfaf260d --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/RTPUtils.java @@ -0,0 +1,392 @@ +package com.zhidao.support.adas.high.udp; + +import java.util.Comparator; + +/** + * RTP-related static utility methods. + * + * @deprecated + * + * @author Boris Grozev + */ +public class RTPUtils +{ + /** + * Hex characters for converting bytes to readable hex strings + */ + private final static char[] HEXES = new char[] + { + '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + /** + * Returns the delta between two RTP sequence numbers, taking into account + * rollover. This will return the 'shortest' delta between the two + * sequence numbers in the form of the number you'd add to b to get a. e.g.: + * getSequenceNumberDelta(1, 10) -> -9 (10 + -9 = 1) + * getSequenceNumberDelta(1, 65530) -> 7 (65530 + 7 = 1) + * @return the delta between two RTP sequence numbers (modulo 2^16). + */ + public static int getSequenceNumberDelta(int a, int b) + { + int diff = a - b; + + if (diff < -(1<<15)) + { + diff += 1 << 16; + } + else if (diff > 1<<15) + { + diff -= 1 << 16; + } + + return diff; + } + + /** + * Returns whether or not seqNumOne is 'older' than seqNumTwo, taking + * rollover into account + * @param seqNumOne + * @param seqNumTwo + * @return true if seqNumOne is 'older' than seqNumTwo + */ + public static boolean isOlderSequenceNumberThan(int seqNumOne, int seqNumTwo) + { + return getSequenceNumberDelta(seqNumOne, seqNumTwo) < 0; + } + + /** + * Returns result of the subtraction of one RTP sequence number from another + * (modulo 2^16). + * @return result of the subtraction of one RTP sequence number from another + * (modulo 2^16). + */ + public static int subtractNumber(int a, int b) + { + return as16Bits(a - b); + } + + + /** + * Apply a delta to a given sequence number and return the result (taking + * rollover into account) + * @param startingSequenceNumber the starting sequence number + * @param delta the delta to be applied + * @return the sequence number result from doing + * startingSequenceNumber + delta + */ + public static int applySequenceNumberDelta( + int startingSequenceNumber, int delta) + { + return (startingSequenceNumber + delta) & 0xFFFF; + } + + /** + * Set an integer at specified offset in network order. + * + * @param off Offset into the buffer + * @param data The integer to store in the packet + */ + public static int writeInt(byte[] buf, int off, int data) + { + if (buf == null || buf.length < off + 4) + { + return -1; + } + + buf[off++] = (byte)(data>>24); + buf[off++] = (byte)(data>>16); + buf[off++] = (byte)(data>>8); + buf[off] = (byte)data; + return 4; + } + + /** + * Writes the least significant 24 bits from the given integer into the + * given byte array at the given offset. + * @param buf the buffer into which to write. + * @param off the offset at which to write. + * @param data the integer to write. + * @return 3 + */ + public static int writeUint24(byte[] buf, int off, int data) + { + if (buf == null || buf.length < off + 3) + { + return -1; + } + + buf[off++] = (byte)(data>>16); + buf[off++] = (byte)(data>>8); + buf[off] = (byte)data; + return 3; + } + + /** + * Set an integer at specified offset in network order. + * + * @param off Offset into the buffer + * @param data The integer to store in the packet + */ + public static int writeShort(byte[] buf, int off, short data) + { + buf[off++] = (byte)(data>>8); + buf[off] = (byte)data; + return 2; + } + + /** + * Read an integer from a buffer at a specified offset. + * + * @param buf the buffer. + * @param off start offset of the integer to be read. + */ + public static int readInt(byte[] buf, int off) + { + return + ((buf[off++] & 0xFF) << 24) + | ((buf[off++] & 0xFF) << 16) + | ((buf[off++] & 0xFF) << 8) + | (buf[off] & 0xFF); + } + + /** + * Reads a 32-bit unsigned integer from the given buffer at the given + * offset and returns its {@link long} representation. + * @param buf the buffer. + * @param off start offset of the integer to be read. + */ + public static long readUint32AsLong(byte[] buf, int off) + { + return readInt(buf, off) & 0xFFFF_FFFFL; + } + + /** + * Read an unsigned short at a specified offset as an int. + * + * @param buf the buffer from which to read. + * @param off start offset of the unsigned short + * @return the int value of the unsigned short at offset + */ + public static int readUint16AsInt(byte[] buf, int off) + { + int b1 = (0xFF & (buf[off + 0])); + int b2 = (0xFF & (buf[off + 1])); + int val = b1 << 8 | b2; + return val; + } + + /** + * Read a signed short at a specified offset as an int. + * + * @param buf the buffer from which to read. + * @param off start offset of the unsigned short + * @return the int value of the unsigned short at offset + */ + public static int readInt16AsInt(byte[] buf, int off) + { + int ret = ((0xFF & (buf[off])) << 8) + | (0xFF & (buf[off + 1])); + if ((ret & 0x8000) != 0) + { + ret = ret | 0xFFFF_0000; + } + + return ret; + } + + /** + * Read an unsigned short at specified offset as a int + * + * @param buf + * @param off start offset of the unsigned short + * @return the int value of the unsigned short at offset + */ + public static int readUint24AsInt(byte[] buf, int off) + { + int b1 = (0xFF & (buf[off + 0])); + int b2 = (0xFF & (buf[off + 1])); + int b3 = (0xFF & (buf[off + 2])); + return b1 << 16 | b2 << 8 | b3; + } + + /** + * Returns the given integer masked to 16 bits + * @param value the integer to mask + * @return the value, masked to only keep the lower + * 16 bits + */ + public static int as16Bits(int value) + { + return value & 0xFFFF; + } + + /** + * Returns the given integer masked to 32 bits + * @param value the integer to mask + * @return the value, masked to only keep the lower + * 32 bits + */ + public static long as32Bits(long value) + { + return value & 0xFFFF_FFFFL; + } + + /** + * A {@link Comparator} implementation for unsigned 16-bit {@link Integer}s. + * Compares {@code a} and {@code b} inside the [0, 2^16] ring; + * {@code a} is considered smaller than {@code b} if it takes a smaller + * number to reach from {@code a} to {@code b} than the other way round. + * + * IMPORTANT: This is a valid {@link Comparator} implementation only when + * used for subsets of [0, 2^16) which don't span more than 2^15 elements. + * + * E.g. it works for: [0, 2^15-1] and ([50000, 2^16) u [0, 10000]) + * Doesn't work for: [0, 2^15] and ([0, 2^15-1] u {2^16-1}) and [0, 2^16) + */ + public static final Comparator sequenceNumberComparator + = new Comparator() { + @Override + public int compare(Integer a, Integer b) + { + if (a.equals(b)) + { + return 0; + } + else if (a > b) + { + if (a - b < 0x10000) + { + return 1; + } + else + { + return -1; + } + } + else //a < b + { + if (b - a < 0x10000) + { + return -1; + } + else + { + return 1; + } + } + } + }; + + /** + * Returns the difference between two RTP timestamps. + * @return the difference between two RTP timestamps. + */ + public static long rtpTimestampDiff(long a, long b) + { + long diff = a - b; + if (diff < -(1L<<31)) + { + diff += 1L << 32; + } + else if (diff > 1L<<31) + { + diff -= 1L << 32; + } + + return diff; + } + + /** + * Returns whether or not the first given timestamp is newer than the second + * @param a + * @param b + * @return true if a is newer than b, false otherwise + */ + public static boolean isNewerTimestampThan(long a, long b) + { + return rtpTimestampDiff(a, b) > 0; + } + + /** + * Return a string containing the hex string version of the given byte + * @param b + * @return + */ + private static String toHexString(byte b) + { + + StringBuilder hexStringBuilder = new StringBuilder(2); + + hexStringBuilder.append(HEXES[(b & 0xF0) >> 4]); + hexStringBuilder.append(HEXES[b & 0x0F]); + + return hexStringBuilder.toString(); + } + + /** + * Return a string containing the hex string version of the given bytes + * @param buf + * @return + */ + public static String toHexString(byte[] buf) + { + return toHexString(buf, 0, buf.length, true); + } + + /** + * Return a string containing the hex string version of the given byte + * @param buf + * @param off + * @param len + * @return + */ + public static String toHexString(byte[] buf, int off, int len) + { + return toHexString(buf, off, len, true); + } + + /** + * Return a string containing the hex string version of the given byte + * @param buf + * @param off + * @param len + * @param format a boolean that indicates whether or not to format the hex + * string. + * @return + */ + public static String toHexString(byte[] buf, int off, int len, boolean format) + { + if (buf == null) + { + return null; + } + else + { + StringBuilder hexStringBuilder + = new StringBuilder(2 * buf.length); + + for (int i = 0; i < len; i++) + { + if (format) + { + if (i % 16 == 0) + { + hexStringBuilder.append("\n") + .append(toHexString((byte) i)) + .append(" "); + } + else if (i % 8 == 0) + { + hexStringBuilder.append(" "); + } + } + byte b = buf[off + i]; + + hexStringBuilder.append(toHexString(b)); + hexStringBuilder.append(" "); + } + return hexStringBuilder.toString(); + } + } +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/AbstractUdpImpl.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/AbstractUdpImpl.java new file mode 100644 index 0000000000..69401db025 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/AbstractUdpImpl.java @@ -0,0 +1,217 @@ +package com.zhidao.support.adas.high.udp.factory; + + +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.udp.IConnectRtpListener; +import com.zhidao.support.adas.high.udp.IGetH264Data; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; + +/** + * @author nie yunlong + * @description + * @date 2018/7/11 + */ +public abstract class AbstractUdpImpl implements IUdpAction, Runnable { + + + static final String TAG = AbstractUdpImpl.class.getSimpleName(); + /** + * udp端口 + */ + private int udpPort; + /** + * 是否组播 + */ + private boolean isMultiCast; + /** + * 组播IP + */ + private String multiCastIp; + + public static final int DATA_LEN = 8 * 1024; + byte[] inBuff; + /** + * 接收的包 + */ + private DatagramPacket inPacket; + /** + * udp + */ + private DatagramSocket socket = null; + /** + * 带广播的udp + */ + private MulticastSocket mMulticastSocket = null; + /** + * 第一次获取到接收端的ip + */ + private volatile boolean isFirstReceiverAddress; + + /** + * 接口 回调一帧 + */ + protected IGetH264Data mGetH264Data; + + private IConnectRtpListener mConnectRtpListener; + /** + * stop + */ + private volatile boolean isStop; + + /** + * 接收的ip地址 + */ + private volatile String mReceiveAddress; + /** + * 暂停状态 + */ + protected volatile boolean isPause = false; + + public AbstractUdpImpl(int byteSize) { + inBuff = new byte[byteSize]; + inPacket = new DatagramPacket(inBuff, inBuff.length); + + + } + + @Override + public void onPause() { + isPause = true; + } + + @Override + public void onResume() { + isPause = false; + } + + @Override + public void close() { + try { + setStop(true); + if (mMulticastSocket != null) { + mMulticastSocket.close(); + mMulticastSocket = null; + } + if (socket != null) { + socket.close(); + socket = null; + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (mConnectRtpListener != null) { + mConnectRtpListener = null; + } + if (mGetH264Data != null) { + mGetH264Data = null; + } + inPacket = null; + inBuff = null; + } + } + + @Override + public void setUdpPort(int udpPort) { + this.udpPort = udpPort; + } + + @Override + public void setMultiCast(boolean multiCast) { + isMultiCast = multiCast; + } + + @Override + public synchronized void setStop(boolean stop) { + isStop = stop; + } + + @Override + public void setOnConnectListener(IConnectRtpListener connectRtpListener) { + this.mConnectRtpListener = connectRtpListener; + } + + @Override + public void getVideoInputStreamData(IGetH264Data getH264Data) { + this.mGetH264Data = getH264Data; + } + + public void setFirstReceiverAddress(boolean firstReceiverAddress) { + isFirstReceiverAddress = firstReceiverAddress; + } + + @Override + public void initBuffer() { + + } + + @Override + public void run() { + // CupidLogUtils.e(TAG, "---->开始接收数据"); + try { + if (isMultiCast) { + mMulticastSocket = new MulticastSocket(udpPort); + InetAddress bcAddr = InetAddress.getByName(multiCastIp); + mMulticastSocket.setReuseAddress(true); + mMulticastSocket.joinGroup(bcAddr); + mMulticastSocket.setLoopbackMode(false); + } else { + CupidLogUtils.e(TAG, "---->开始连接端口" + udpPort + ",stop" + isStop); + if (socket == null) { + socket = new DatagramSocket(udpPort); + socket.setReuseAddress(true); + socket.setReceiveBufferSize(32 * 1024); + CupidLogUtils.e("--->setReceiveBufferSize:" + socket.getReceiveBufferSize()); + CupidLogUtils.e(TAG, "---->连接成功" + udpPort); + } + } + } catch (Exception e) { + e.printStackTrace(); + CupidLogUtils.e(TAG, "---->udp" + e.getMessage()); + if (mConnectRtpListener != null) { + mConnectRtpListener.onConnectionFailedRtp(e.getMessage()); + } + } + + while (!isStop) { + try { + if (isMultiCast && mMulticastSocket != null) { + mMulticastSocket.receive(inPacket); + } else { + if (socket != null) { + //inPacket.setLength(0); + socket.receive(inPacket); + } + } + long receiverDataTimeUdp = System.currentTimeMillis(); + if (!isFirstReceiverAddress) { + if (inPacket.getAddress() != null) { + mReceiveAddress = inPacket.getAddress().getHostAddress(); + CupidLogUtils.e("mReceiveAddress--->mReceiveAddress" + mReceiveAddress); + isFirstReceiverAddress = true; + if (mConnectRtpListener != null) { + mConnectRtpListener.getOnConnectionAddress(mReceiveAddress); + } + } + + } + if (inPacket.getAddress() != null) { + parseData(inPacket, receiverDataTimeUdp); + } + } catch (Exception e) { + e.printStackTrace(); + CupidLogUtils.e("UdpException" + e.getMessage()); + if (mConnectRtpListener != null) { + mConnectRtpListener.onConnectionFailedRtp(e.getMessage()); + } + } + } + + } + + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidRenderImageServer.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidRenderImageServer.java new file mode 100644 index 0000000000..f35b10635c --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidRenderImageServer.java @@ -0,0 +1,55 @@ +package com.zhidao.support.adas.high.udp.factory; + +import com.zhidao.support.adas.high.udp.IBuffStream; + +import java.net.DatagramPacket; + +/** + * @author nie yunlong + * @description 绘制上层数据 + * @date 2018/7/11 + */ +public class CupidRenderImageServer extends AbstractUdpImpl { + + +// StringBuilder stringBuilder = new StringBuilder(); +// +// StringBuilder normalDataBuilder = new StringBuilder(); + /** + * 内容 + */ + private String content; + + public CupidRenderImageServer() { + super(8*1024); + } + + + /** + * 回调真实数据 + * + * @param realData + */ + public void callBackRealData(String realData) { + if (realData.contains("<")) { + realData.replace("<", ""); + } + if (realData.contains(">")) { + realData.replace(">", ""); + } + mGetH264Data.getH264Data(realData.getBytes(),System.currentTimeMillis()); + } + + @Override + public void parseData(DatagramPacket inPacket, long receiverDataTimeUdp) { + if (mGetH264Data != null && !isPause) { + content = new String(inPacket.getData(), 0, inPacket.getLength()); + mGetH264Data.getH264Data(content.getBytes(),receiverDataTimeUdp); + } + } + + @Override + public void setBuffStream(IBuffStream buffStream) { + + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidUdpFactory.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidUdpFactory.java new file mode 100644 index 0000000000..a5c8c22ca8 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidUdpFactory.java @@ -0,0 +1,37 @@ +package com.zhidao.support.adas.high.udp.factory; + +/** + * @author nie yunlong + * @description 生产udp对象 + * @date 2018/7/11 + */ +public class CupidUdpFactory { + + /** + * 创建视频流解析对象 + * + * @return + */ + public static AbstractUdpImpl createVideoStreamUdp() { + return new CupidVideoUdpServer(); + } + + /** + * 优化后的接收udp buffer + * + * @return + */ + public static AbstractUdpImpl createVideoStreamUdp2() { + return new CupidVideoUdpServer2(); + } + + /** + * 上层绘制 接收udp 给的数据 解析展示数据 + * + * @return + */ + public static AbstractUdpImpl createRenderImageUdp() { + return new CupidRenderImageServer(); + } + +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidVideoUdpServer.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidVideoUdpServer.java new file mode 100644 index 0000000000..a579e76b5f --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidVideoUdpServer.java @@ -0,0 +1,243 @@ +package com.zhidao.support.adas.high.udp.factory; + + + +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.udp.IBuffStream; + +import java.io.IOException; +import java.net.DatagramPacket; + +import static com.zhidao.support.adas.high.udp.CupidBufStreamImpl.BUF_SIZE_LIMIT; + + +/** + * @author nie yunlong + * @description 视频流 + * @date 2018/7/11 + */ +public class CupidVideoUdpServer extends AbstractUdpImpl { + + private IBuffStream buffStream; + + private byte[] fu_h_byte; + + /** + * 是否是开始第一帧 + */ + boolean isBegin = false; + /** + * 对照h264帧 + */ + private int mIndexSeqNo = 0; + + /** + * 容错次数 + */ + private int mConcernedNumber = 0; + /** + * 容错常量 2次 + */ + private final int CONCERNED_NUMBER_RTP = 5; + + public CupidVideoUdpServer() { + super(DATA_LEN); + } + + + @Override + public void setBuffStream(IBuffStream buffStream) { + this.buffStream = buffStream; + } + + /** + * 替换rtp头 暴露h264 + * + * @param inPacket + * @return + */ + boolean parseRTP(DatagramPacket inPacket) { + int naluType = 0; + int nalunri = 0; + int naluf = 0; + + boolean isEnd = false; + //最高位是否是F 1111 **** + if ((int) (inBuff[1] >> 7 & 0x01) == 1) { + isEnd = true; + } + //inBuff[3] 是啥数据 就是啥 0xFF 都是1 1111 1111 + int seq_no = inBuff[3] & 0xFF; + //左移 补0 结果是把inBuffer[3]inBuffer[2] 得到数据 获取到的长度 + seq_no |= (((int) inBuff[2] << 8) & 0xFF00); + +// CupidLogUtils.e("seq_no" + seq_no + ",begin=>" + isBegin + ",isEnd=>" + isEnd); + + if (seq_no == 1) { //0001 开始位置 + isBegin = true; + mIndexSeqNo = 1; + } else if (seq_no == 65530) { //FFFF 结束一帧 + isEnd = true; + isBegin = false; + mIndexSeqNo = 0; + } + +// boolean isSkip = isCheckConcernedNumer(isEnd); +//// if (isSkip) { +//// return false; +//// } + + if (buffStream.getLength() > BUF_SIZE_LIMIT) { + buffStream.close(); + return false; + } + byte naluHeader = inBuff[12]; + naluType = naluHeader & 0x1f; // + nalunri = naluHeader >> 5 & 0x03; + naluf = naluHeader >> 7 & 0x01; + int len = inPacket.getLength(); +// CupidLogUtils.i(TAG, "packet-len:" + len); + + fu_h_byte = new byte[5]; + fu_h_byte[0] = 0; + fu_h_byte[1] = 0; + fu_h_byte[2] = 0; + fu_h_byte[3] = 1; + + if (28 == naluType) { //0x1C ‭0001 1100‬ + // H264 Begin + int fu_type = 0; + int fu_r = 0; + int fu_e = 0; + int fu_s = 0; + + byte fu_header = inBuff[13]; + fu_type = fu_header & 0x1f; + fu_r = fu_header >> 5 & 0x01; + fu_e = fu_header >> 6 & 0x01; + fu_s = fu_header >> 7 & 0x01; + + if (fu_s == 1) { + //buffStream.doSwitch(); + // start of fu-a + fu_h_byte[4] = (byte) ((fu_type & 0x1f) | (nalunri << 5 & 0x60) | (naluf << 7 & 0x80)); + try { + //buffStream.getOutputStream().write(fu_h_byte, 0, 5); + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + } else if (1 == fu_e) { + // end of fu-a + try { + if (isBegin || isEnd) { + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + } else { + // middle of fu-a + try { + if (isBegin) { + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + } + + } else { + //TODO 没用上 + fu_h_byte[4] = (byte) ((naluType & 0x1f) | (nalunri << 5 & 0x60) | (naluf << 7 & 0x80)); + try { + //buffStream.getOutputStream().write(fu_h_byte, 0, 5); + buffStream.getOutputStream().write(inBuff, 13, len - 13); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + if (isEnd) { + if (mGetH264Data != null) { + try { + mGetH264Data.getH264Data(buffStream.getData(),System.currentTimeMillis()); + } catch (OutOfMemoryError outOfMemoryError) { + CupidLogUtils.e("===>内存溢出"); + buffStream.close(); + System.gc(); + } + } + buffStream.doSwitch(); + } + return true; + } + + /** + * 是否跳过 后边代码 + * + * @param isEnd + * @return + */ + private boolean isCheckConcernedNumer(boolean isEnd) { + int seq_no = inBuff[3] & 0xFF; + seq_no |= (((int) inBuff[2] << 8) & 0xFF00); + + CupidLogUtils.e("seq_no" + seq_no + ",begin=>" + isBegin + ",isEnd=>" + isEnd); + + if (seq_no == 1) { + isBegin = true; + mIndexSeqNo = 1; + } else if (seq_no == 65530) { + isEnd = true; + isBegin = false; + mIndexSeqNo = 0; + } else { + mIndexSeqNo++; + if (mIndexSeqNo != seq_no && mConcernedNumber <= CONCERNED_NUMBER_RTP) { + mConcernedNumber++; + } + if (mConcernedNumber > CONCERNED_NUMBER_RTP) { + CupidLogUtils.e("===>超过次数==>mConcernedNumber" + mConcernedNumber); + mConcernedNumber = 0; + buffStream.doSwitch(); + return true; + } + } + return false; + } + + @Override + public void close() { + super.close(); + if (buffStream != null) { + buffStream.close(); + buffStream = null; + } + } + + @Override + public void parseData(DatagramPacket inPacket, long receiverDataTimeUdp) { + if (isPause) { + buffStream.close(); + } + if (inPacket.getLength() > 0 && !isPause) { + CupidLogUtils.w("===》数据包" + inPacket.getLength() + ",string" + new String(inPacket.getData())); + parseRTP(inPacket); + } + } + + @Override + public void initBuffer() { + super.initBuffer(); + if (buffStream != null) { + buffStream.close(); + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidVideoUdpServer2.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidVideoUdpServer2.java new file mode 100644 index 0000000000..9d2c434049 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/CupidVideoUdpServer2.java @@ -0,0 +1,247 @@ +package com.zhidao.support.adas.high.udp.factory; + + + +import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.udp.IBuffStream; + +import java.io.IOException; +import java.net.DatagramPacket; + +import static com.zhidao.support.adas.high.udp.CupidBufStreamImpl2.BUF_SIZE_LIMIT; + + +/** + * @author nie yunlong + * @description 视频流 + * @date 2018/7/11 + */ +public class CupidVideoUdpServer2 extends AbstractUdpImpl { + + private IBuffStream buffStream; + + private byte[] fu_h_byte; + + /** + * 是否是开始第一帧 + */ + boolean isBegin = false; + /** + * 对照h264帧 + */ + private int mIndexSeqNo = 0; + + /** + * 容错次数 + */ + private int mConcernedNumber = 0; + /** + * 容错常量 2次 + */ + private final int CONCERNED_NUMBER_RTP = 5; + + public CupidVideoUdpServer2() { + super(DATA_LEN); + } + + + @Override + public void setBuffStream(IBuffStream buffStream) { + this.buffStream = buffStream; + } + + /** + * 替换rtp头 暴露h264 + * + * @param inPacket + * @return + */ + boolean parseRTP(DatagramPacket inPacket) { + int naluType = 0; + int nalunri = 0; + int naluf = 0; + + boolean isEnd = false; + //最高位是否是F 1111 **** + if ((int) (inBuff[1] >> 7 & 0x01) == 1) { + isEnd = true; + } + //inBuff[3] 是啥数据 就是啥 0xFF 都是1 1111 1111 + int seq_no = inBuff[3] & 0xFF; + //左移 补0 结果是把inBuffer[3]inBuffer[2] 得到数据 获取到的长度 + seq_no |= (((int) inBuff[2] << 8) & 0xFF00); + +// CupidLogUtils.e("seq_no" + seq_no + ",begin=>" + isBegin + ",isEnd=>" + isEnd); + + if (seq_no == 1) { //0001 开始位置 + //如果在开始有问题 reset + if (buffStream.getLength() > 0) { + buffStream.doSwitch(); + } + isBegin = true; + mIndexSeqNo = 1; + } else if (seq_no == 65530) { //FFFF 结束一帧 + isEnd = true; + isBegin = false; + mIndexSeqNo = 0; + } + +// boolean isSkip = isCheckConcernedNumer(isEnd); +//// if (isSkip) { +//// return false; +//// } + + if (buffStream.getLength() > BUF_SIZE_LIMIT) { + buffStream.close(); + return false; + } + byte naluHeader = inBuff[12]; + naluType = naluHeader & 0x1f; // + nalunri = naluHeader >> 5 & 0x03; + naluf = naluHeader >> 7 & 0x01; + int len = inPacket.getLength(); +// CupidLogUtils.i(TAG, "packet-len:" + len); + + fu_h_byte = new byte[5]; + fu_h_byte[0] = 0; + fu_h_byte[1] = 0; + fu_h_byte[2] = 0; + fu_h_byte[3] = 1; + + if (28 == naluType) { //0x1C ‭0001 1100‬ + // H264 Begin + int fu_type = 0; + int fu_r = 0; + int fu_e = 0; + int fu_s = 0; + + byte fu_header = inBuff[13]; + fu_type = fu_header & 0x1f; + fu_r = fu_header >> 5 & 0x01; + fu_e = fu_header >> 6 & 0x01; + fu_s = fu_header >> 7 & 0x01; + + if (fu_s == 1) { + //buffStream.doSwitch(); + // start of fu-a + fu_h_byte[4] = (byte) ((fu_type & 0x1f) | (nalunri << 5 & 0x60) | (naluf << 7 & 0x80)); + try { + //buffStream.getOutputStream().write(fu_h_byte, 0, 5); + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + } else if (1 == fu_e) { + // end of fu-a + try { + if (isBegin || isEnd) { + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + } else { + // middle of fu-a + try { + if (isBegin) { + buffStream.getOutputStream().write(inBuff, 14, len - 14); + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + } + + } else { + //TODO 没用上 + fu_h_byte[4] = (byte) ((naluType & 0x1f) | (nalunri << 5 & 0x60) | (naluf << 7 & 0x80)); + try { + //buffStream.getOutputStream().write(fu_h_byte, 0, 5); + buffStream.getOutputStream().write(inBuff, 13, len - 13); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + if (isEnd) { + if (mGetH264Data != null) { + try { + mGetH264Data.getH264Data(buffStream.getData(),System.currentTimeMillis()); + } catch (OutOfMemoryError outOfMemoryError) { + CupidLogUtils.e("===>内存溢出"); + buffStream.close(); + System.gc(); + } + } + buffStream.doSwitch(); + } + return true; + } + + /** + * 是否跳过 后边代码 + * + * @param isEnd + * @return + */ + private boolean isCheckConcernedNumer(boolean isEnd) { + int seq_no = inBuff[3] & 0xFF; + seq_no |= (((int) inBuff[2] << 8) & 0xFF00); + + CupidLogUtils.e("seq_no" + seq_no + ",begin=>" + isBegin + ",isEnd=>" + isEnd); + + if (seq_no == 1) { + isBegin = true; + mIndexSeqNo = 1; + } else if (seq_no == 65530) { + isEnd = true; + isBegin = false; + mIndexSeqNo = 0; + } else { + mIndexSeqNo++; + if (mIndexSeqNo != seq_no && mConcernedNumber <= CONCERNED_NUMBER_RTP) { + mConcernedNumber++; + } + if (mConcernedNumber > CONCERNED_NUMBER_RTP) { + CupidLogUtils.e("===>超过次数==>mConcernedNumber" + mConcernedNumber); + mConcernedNumber = 0; + buffStream.doSwitch(); + return true; + } + } + return false; + } + + @Override + public void close() { + super.close(); + if (buffStream != null) { + buffStream.close(); + buffStream = null; + } + } + + @Override + public void parseData(DatagramPacket inPacket, long receiverDataTimeUdp) { + if (isPause) { + buffStream.close(); + } + if (inPacket.getLength() > 12 && !isPause) { + CupidLogUtils.w("===》数据包" + inPacket.getLength() + ",string" + new String(inPacket.getData())); + parseRTP(inPacket); + } + } + + @Override + public void initBuffer() { + super.initBuffer(); + if (buffStream != null) { + buffStream.close(); + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/IUdpAction.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/IUdpAction.java new file mode 100644 index 0000000000..bfff270c14 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/udp/factory/IUdpAction.java @@ -0,0 +1,88 @@ +package com.zhidao.support.adas.high.udp.factory; + + + +import com.zhidao.support.adas.high.udp.IBuffStream; +import com.zhidao.support.adas.high.udp.IConnectRtpListener; +import com.zhidao.support.adas.high.udp.IGetH264Data; + +import java.net.DatagramPacket; + +/** + * @author nie yunlong + * @description udp 抽象方法 + * @date 2018/7/11 + */ +public interface IUdpAction { + + /** + * udp 关闭释放资源 + */ + void close(); + + /** + * set udp port + * + * @param udpPort + */ + void setUdpPort(int udpPort); + + /** + * 设置广播模式 + * + * @param multiCast + */ + void setMultiCast(boolean multiCast); + + /** + * 停止udp 线程 + * + * @param stop + */ + void setStop(boolean stop); + + /** + * 设置socket 连接状态监听 + * + * @param connectRtpListener + */ + void setOnConnectListener(IConnectRtpListener connectRtpListener); + + /** + * 获取udp数据 + * + * @param getH264Data + */ + void getVideoInputStreamData(IGetH264Data getH264Data); + + /** + * 解析接收到数据包 + * + * @param inPacket + */ + void parseData(DatagramPacket inPacket,long receiverDataTimeUdp); + + + /** + * 设置buffer + * + * @param buffStream + */ + void setBuffStream(IBuffStream buffStream); + + /** + * onPause + */ + void onPause(); + + /** + * onResume + */ + void onResume(); + + /** + * init buffer 服务器关闭 初始化数据 + */ + void initBuffer(); + +} diff --git a/libraries/mogo-adas/src/main/proto/adas.proto b/libraries/mogo-adas/src/main/proto/adas.proto new file mode 100644 index 0000000000..f8b5478853 --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/adas.proto @@ -0,0 +1,87 @@ +syntax = "proto2"; +package adas; + +enum CarLocation +{ + Same_LINE = 0; + Left_LINE = 1; + Right_LINE = 2; + left2_LINE = 3; + Right2_LINE = 4; +} + +enum ActionType +{ + action_type_view = 1; + action_type_obstacles = 2; + action_type_lanes = 3; + action_type_state = 4; + action_type_warn = 5; + action_type_light = 6; + action_type_config = 7; + action_type_gdgps = 8; + action_type_auto_pilot_state = 9; + action_type_auto_pilot_mode = 10; + action_type_obu_traffic_light = 11; + action_type_ai_cloud_to_start_autopilot = 12; +} + +message View +{ + optional int32 xl = 1; + optional int32 yt = 2; + optional int32 xr = 3; + optional int32 yb = 4; + //物体类型 + optional string type = 5; + optional CarLocation showImageLocation = 6; + //距离x轴值 + optional double distance_x = 7; + //距离y轴值 + optional double distance_y = 8; + //经度 + optional double lon = 9; + //纬度 + optional double lat = 10; + //海拔 + optional double alt = 11; + //系统时间 + optional string systemTime = 12; + //gps时间 + optional string satelliteTime = 13; + //车辆id + optional string uuid = 14; + //车牌id + optional string carId = 15; + //车辆颜色 + optional string color = 16; + //车辆朝向 + optional double heading = 17; + //车辆速度 + optional double speed = 18; + //长 + optional float length = 19; + //宽 + optional float width = 20; + //高 + optional float height = 21; + //危险等级 1 绿,2 黄,3 红 + optional int32 drawlevel = 22; + //驱动感知时间 + optional string driverTime = 23; +} + + +// 渲染流消息 +message ViwesMsg +{ + optional string action = 1; + repeated View models = 2; +} + + + + + + + diff --git a/libraries/mogo-adas/src/main/proto/car_status.proto b/libraries/mogo-adas/src/main/proto/car_status.proto new file mode 100644 index 0000000000..6f4f477051 --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/car_status.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package mogo.status; + + +message Status +{ + //经度 + double lon = 1; + //纬度 + double lat = 2; + //海拔 + double alt = 3; + //航向角 + double heading = 4; + //加速度 + double acceleration = 5; + //曲率 + double yaw_rate = 6; + //惯导车速 m/s + float gnss_speed = 7; + //车辆车速 m/s + float vehicle_speed = 8; + //gps时间 + string satelliteTime = 9; + //系统时间 + string systemTime = 10; + //转向灯状态 + int32 turn_light = 11; + //双闪灯状态 + int32 flash_light = 12; + //刹车灯状态 + int32 brake_light = 13; + //统计包个数 + int32 frame_num = 14; +} + + + + + + + diff --git a/libraries/mogo-adas/src/main/proto/geometry.proto b/libraries/mogo-adas/src/main/proto/geometry.proto new file mode 100644 index 0000000000..9910b32a10 --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/geometry.proto @@ -0,0 +1,84 @@ +syntax = "proto2"; +package geometry; + +message Vector3 { + optional double x = 1; + optional double y = 2; + optional double z = 3; +} + +message Vector3f { + optional float x = 1; + optional float y = 2; + optional float z = 3; +} + +message Point2D { + optional double x = 1 [default = nan]; + optional double y = 2 [default = nan]; +} + +message Point3D { + optional double x = 1 [default = nan]; + optional double y = 2 [default = nan]; + optional double z = 3 [default = nan]; +} + +message Trace { + optional double timestamp = 1; + optional Point3D position = 2; + optional Point3D velocity = 3; + optional Point3D acceleration = 4; + optional Point3D heading = 5; +} + +message PointLLH { + // Longitude in degrees, ranging from -180 to 180. + optional double lon = 1 [default = nan]; + // Latitude in degrees, ranging from -90 to 90. + optional double lat = 2 [default = nan]; + // WGS-84 ellipsoid height in meters. + optional double height = 3 [default = 0.0]; +} + +message Point { + optional double x = 1; + optional double y = 2; + optional double z = 3; +} + +message Quaternion { + optional double x = 1 [default = nan]; + optional double y = 2 [default = nan]; + optional double z = 3 [default = nan];; + optional double w = 4 [default = nan]; +} + +message Polygon { + repeated Point points = 1; +} + +message Transform { + optional Vector3 translation = 1; + optional Quaternion rotation = 2; +} + +//pose in free space, composed of position and orientation +message Pose { + optional Point position = 1; + optional Quaternion orientation = 2; +} + +//acceleration in free space broken into its linear and angular parts +message Accel { + optional Vector3 linear = 1; + optional Vector3 angular = 2; +} + +//velocity in free space broken into its linear and angular parts +message Twist { + optional Vector3 linear = 1; + optional Vector3 angular = 2; +} + + diff --git a/libraries/mogo-adas/src/main/proto/header.proto b/libraries/mogo-adas/src/main/proto/header.proto new file mode 100644 index 0000000000..2a50a1702d --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/header.proto @@ -0,0 +1,23 @@ +syntax = "proto2"; + +package common; + +message Time { + optional uint32 sec = 1; + optional uint32 nsec = 2; +} + +message Header { + // Sequence number for each message. Each module maintains its own counter for + // sequence_num, always starting from 1 on boot. + optional uint32 seq = 1; + + // Message publishing time in seconds. + optional Time stamp = 2; + + // frame id + optional string frame_id = 3; + + // Module name. + optional string module_name = 4; +} diff --git a/libraries/mogo-adas/src/main/proto/mogo_guardian.proto b/libraries/mogo-adas/src/main/proto/mogo_guardian.proto new file mode 100644 index 0000000000..27e5946a47 --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/mogo_guardian.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; +package mogo.guardian; +/* +message xxx { + // 字段规则:required -> 字段只能也必须出现 1 次. proto3中移除了required + // 字段规则:optional -> 字段可出现 0 次或1次 + // 字段规则:repeated -> 字段可出现任意多次(包括 0) + // 类型:int32、int64、sint32、sint64、string、32-bit .... + // 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字) + 字段规则 类型 名称 = 字段编号; +} +*/ +/* 监控实体 */ +message GuardianProto { +/* i接口名成*/ + string action = 1; +/* 监控项名称*/ + string agentName = 2; +/* 车牌号*/ + string carNum = 3; +/* 工控机mac地址*/ + string macAddr = 4; +/* 车型*/ + string carType = 5; +/* 监控类型*/ + string monitorType = 6; +/* sn*/ + string sn = 7; +/* 时间*/ + uint64 time = 8; +/* 模块*/ + Modules modules = 9; +} + +/* 模块*/ +message Modules { +/* 子项*/ + repeated ItemsName itemsname = 1; +/* 子模块*/ + repeated SubModules submodules = 2; +} + +/* 子项*/ +message ItemsName { +/* 子项名称*/ + string name = 1; +/* 子项键值属性*/ + repeated Items items = 2; +} +/* 键值对*/ +message Items { +/* key*/ + string name = 1; +/* value*/ + string value = 2; + +} +/* 子模块*/ +message SubModules { +/* 子模块名称*/ + string modulename = 1; +/* 子节点*/ + repeated SubNode subnodes = 2; + +} + +/* 模块中的节点*/ +message SubNode{ +/* 节点名称*/ + string nodename = 1; +/* 节点项*/ + repeated Items nodeitems = 2; +/* *topic项*/ + repeated ItemsName topicitems = 3; +} + diff --git a/libraries/mogo-adas/src/main/proto/route_list.proto b/libraries/mogo-adas/src/main/proto/route_list.proto new file mode 100644 index 0000000000..407ca0563c --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/route_list.proto @@ -0,0 +1,27 @@ +syntax = "proto2"; + +package hadmap; + +import "geometry.proto"; +import "header.proto"; + +message RouteInfo { + optional string id = 1; + optional geometry.Point start = 2;//经纬度坐标 + optional string start_eng = 3; //起点拼音大写 + optional string start_chn = 4; //起点中文名 + optional geometry.Point end = 5;//经纬度坐标 + optional string end_eng = 6; //终点拼音大写 + optional string end_chn = 7; //终点中文名 + optional string traj_file_path = 8; // file path+file name + optional int32 vehicle_type = 9; + optional string time = 10; + optional string comment = 11; +} + +message RouteList { + optional common.Header header = 1; + optional uint32 routes_count = 2; + repeated RouteInfo routes_info = 3; +} + diff --git a/libraries/mogo-adas/src/main/proto/trajectory.proto b/libraries/mogo-adas/src/main/proto/trajectory.proto new file mode 100644 index 0000000000..afd61c757c --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/trajectory.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package mogo.trajectory; + +message TrajectoryPoint { + double x = 1; + double y = 2; + double z = 3; + double t = 4; //time in seconds + double v = 5; //velocity in m/s + double a = 6; //acceleration in m/s^26766 + double theta = 7; //direction of v + double kappa = 8; //curvature + double s = 9; //accumulated distance in meters from beginning +} + +message Trajectory { + repeated TrajectoryPoint points = 1; +} diff --git a/libraries/mogo-adas/src/main/proto/websocket_header.proto b/libraries/mogo-adas/src/main/proto/websocket_header.proto new file mode 100644 index 0000000000..909787d1d3 --- /dev/null +++ b/libraries/mogo-adas/src/main/proto/websocket_header.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package mogo.webproto; + +enum Constants { + DEFAULT = 0x0000; //0 + Magic = 0x6d67; //"mg" +} + +/************************Head Def***********************/ +/*******************************************************/ + +message Header_websock { + uint32 msgType = 1; //payload type, enum @PacketType +} + + +enum MsgType_websock { + mogo_DEFAULT = 0x000; // 0 + mogoTrajectory = 0x100; // 轨迹规划 + mogoAdas = 0x101; //adas数据 + mogoCar = 0x102; //自车数据 + mogoDataCollect = 0x103; //数据采集文件 + mogoRoutList = 0x104; //maplist + mogoGuardian = 0x105; //监控 +} diff --git a/libraries/mogo-adas/src/main/res/values/strings.xml b/libraries/mogo-adas/src/main/res/values/strings.xml new file mode 100644 index 0000000000..9e8787cc20 --- /dev/null +++ b/libraries/mogo-adas/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + adas-high + diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/VisualAngleMode.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/VisualAngleMode.java index 3d6462fab2..2d76d530f1 100644 --- a/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/VisualAngleMode.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/VisualAngleMode.java @@ -15,9 +15,25 @@ public enum VisualAngleMode implements IMogoMapVisualAngle { /** * 视距远景 */ - MODE_LONG_SIGHT(2); + MODE_LONG_SIGHT(2), - private int code; + /** + * 后方来车300视角 + */ + MAP_STYLE_VR_ANGLE_300(3), + + /** + * 顶视角 + */ + MAP_STYLE_VR_ANGLE_TOP(4), + + /** + * 十字路口视角 + */ + MAP_STYLE_VR_ANGLE_CROSS(5); + + + private final int code; VisualAngleMode(int code) { this.code = code; diff --git a/modules.txt b/modules.txt index a969ffe1d8..ac24aa7e14 100644 --- a/modules.txt +++ b/modules.txt @@ -4,21 +4,21 @@ :core:mogo-core-network :core:mogo-core-function-api :core:mogo-core-function-call -:foudations:mogo-utils :tts:tts-base :tts:tts-pad :libraries:mogo-map-api :services:mogo-service-api :foudations:mogo-aicloud-services-sdk :foudations:mogo-commons +:libraries:map-usbcamera :libraries:map-custom :libraries:mogo-map +:libraries:mogo-adas :modules:mogo-module-carchattingprovider :modules:mogo-module-common :modules:mogo-module-chat :modules:mogo-module-carchatting :test:crashreport -:test:crashreport-bugly :test:crashreport-apm :test:crashreport-noop :test:crashreport-upgrade diff --git a/modules/mogo-module-common/build.gradle b/modules/mogo-module-common/build.gradle index 47db9c2ec2..49b6b6cbf6 100644 --- a/modules/mogo-module-common/build.gradle +++ b/modules/mogo-module-common/build.gradle @@ -73,23 +73,21 @@ dependencies { if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { api rootProject.ext.dependencies.mogomap api rootProject.ext.dependencies.mogomapapi - api rootProject.ext.dependencies.mogo_core_utils api rootProject.ext.dependencies.mogocommons api rootProject.ext.dependencies.mogoserviceapi implementation rootProject.ext.dependencies.callchatprovider - - implementation rootProject.ext.dependencies.mogo_core_utils + + api rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_function_call } else { api project(":libraries:mogo-map") api project(":libraries:mogo-map-api") - api project(':core:mogo-core-utils') api project(":foudations:mogo-commons") api project(':services:mogo-service-api') implementation project(':modules:mogo-module-carchattingprovider') - implementation project(':core:mogo-core-utils') + api project(':core:mogo-core-utils') implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-function-call') } diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/AdasRecognizedResultDrawer.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/AdasRecognizedResultDrawer.java index f02e748b39..57d5e2d4ab 100644 --- a/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/AdasRecognizedResultDrawer.java +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/AdasRecognizedResultDrawer.java @@ -211,7 +211,6 @@ public class AdasRecognizedResultDrawer extends BaseDrawer { return; } Iterator iterator = mLastPositions.values().iterator(); - Log.d("EmArrow", "removeUselessLastRecord size : " + mLastPositions.size()); while (iterator.hasNext()) { TrafficData result = iterator.next(); long internal = result.getSatelliteTime() - getCurSatelliteTime(); diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/SnapshotSetDataDrawer.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/SnapshotSetDataDrawer.java index c6fa8939fc..d5e3a69162 100644 --- a/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/SnapshotSetDataDrawer.java +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/SnapshotSetDataDrawer.java @@ -1,5 +1,6 @@ package com.mogo.module.common.drawer; +import static com.mogo.eagle.core.data.chain.ChainConstant.CHAIN_LINK_CLOUD_SHOW; import static com.mogo.module.common.constants.DataTypes.TYPE_MARKER_CLOUD_DATA; import android.os.Build; @@ -140,11 +141,11 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic * * @param data 自车周边数据 */ - @ChainLog(linkCode = 0, - endpoint = TracingConstants.Endpoint.PAD, - nodeAliasCode = "PAD_YINGYAN_SHOW", - paramIndexes = {0}, - clientPkFileName = "sn") +// @ChainLog(linkCode = CHAIN_LINK_CLOUD_SHOW, +// endpoint = TracingConstants.Endpoint.PAD, +// nodeAliasCode = "PAD_YINGYAN_SHOW", +// paramIndexes = {0}, +// clientPkFileName = "sn") public void renderSnapshotData(SocketDownData.LauncherSnapshotProto data) { final long start = System.nanoTime(); if (clear(data)) { @@ -252,7 +253,6 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic return; } Iterator iterator = mLastPositions.values().iterator(); - Log.d("EmArrow", "removeUselessLastRecord size : " + mLastPositions.size()); while (iterator.hasNext()) { SocketDownData.CloudRoadDataProto result = iterator.next(); long internal = Long.parseLong(adasControllerApi.getSatelliteTime()) - result.getSatelliteTime(); diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/kt/ScopeManager.kt b/modules/mogo-module-common/src/main/java/com/mogo/module/common/kt/ScopeManager.kt deleted file mode 100644 index 8909e4213b..0000000000 --- a/modules/mogo-module-common/src/main/java/com/mogo/module/common/kt/ScopeManager.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.mogo.module.common.kt - -import androidx.annotation.RestrictTo -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.launch - -/** - * @author congtaowang - * @since 2021/3/3 - * - * 描述 - */ -object ScopeManager { - - private var mScope = MainScope() - private var mAdasScope = MainScope() - private var mThreadScope: RestrictTo.Scope? = null - - fun mainScope(runnable: Runnable?) { - mScope.launch(Dispatchers.Default) { - runnable?.apply { - run() - } - } - } - - fun adasScope(runnable: Runnable?) { - mAdasScope.launch(Dispatchers.Default) { - runnable?.apply { - run() - } - } - } -} \ No newline at end of file diff --git a/modules/mogo-module-extensions/build.gradle b/modules/mogo-module-extensions/build.gradle index 3380212888..4b63e7ffee 100644 --- a/modules/mogo-module-extensions/build.gradle +++ b/modules/mogo-module-extensions/build.gradle @@ -64,25 +64,23 @@ dependencies { if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { api rootProject.ext.dependencies.mogomapapi - api rootProject.ext.dependencies.mogo_core_utils api rootProject.ext.dependencies.mogocommons api rootProject.ext.dependencies.mogoserviceapi implementation rootProject.ext.dependencies.modulecommon implementation rootProject.ext.dependencies.moduleservice - implementation rootProject.ext.dependencies.mogo_core_utils + api rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_res implementation rootProject.ext.dependencies.mogo_core_function_call } else { api project(":libraries:mogo-map-api") - api project(':core:mogo-core-utils') api project(":foudations:mogo-commons") api project(':services:mogo-service-api') implementation project(':modules:mogo-module-common') implementation project(':modules:mogo-module-service') - implementation project(':core:mogo-core-utils') + api project(':core:mogo-core-utils') implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-res') implementation project(':core:mogo-core-function-call') diff --git a/modules/mogo-module-main/build.gradle b/modules/mogo-module-main/build.gradle index c4e3370763..b209b14507 100644 --- a/modules/mogo-module-main/build.gradle +++ b/modules/mogo-module-main/build.gradle @@ -53,7 +53,6 @@ dependencies { compileOnly rootProject.ext.dependencies.adasapi compileOnly rootProject.ext.dependencies.adasconfigapi if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { - api rootProject.ext.dependencies.mogo_core_utils api rootProject.ext.dependencies.mogocommons api rootProject.ext.dependencies.modulecommon api rootProject.ext.dependencies.mogoserviceapi @@ -63,8 +62,8 @@ dependencies { implementation rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogo_core_data implementation rootProject.ext.dependencies.mogo_core_function_call + implementation rootProject.ext.dependencies.mogo_core_function_carcorder } else { - api project(':core:mogo-core-utils') api project(":foudations:mogo-commons") api project(':modules:mogo-module-common') api project(':services:mogo-service-api') @@ -74,6 +73,8 @@ dependencies { implementation project(':core:mogo-core-utils') implementation project(':core:mogo-core-data') implementation project(':core:mogo-core-function-call') + implementation project(':core:function-impl:mogo-core-function-carcorder') + } } diff --git a/modules/mogo-module-main/src/main/java/com/mogo/module/main/MainActivity.java b/modules/mogo-module-main/src/main/java/com/mogo/module/main/MainActivity.java index 670e5f7676..b423200a68 100644 --- a/modules/mogo-module-main/src/main/java/com/mogo/module/main/MainActivity.java +++ b/modules/mogo-module-main/src/main/java/com/mogo/module/main/MainActivity.java @@ -1,5 +1,7 @@ package com.mogo.module.main; +import static com.mogo.module.main.MainPresenter.MOGO_PERMISSION_REQUEST_CODE; + import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; @@ -22,6 +24,7 @@ import com.mogo.commons.mvp.MvpActivity; import com.mogo.commons.mvp.MvpFragment; import com.mogo.eagle.core.data.constants.MoGoFragmentPaths; import com.mogo.eagle.core.data.map.MogoLocation; +import com.mogo.eagle.core.function.carcorder.service.CarcorderService; import com.mogo.eagle.core.utilcode.mogo.AppLaunchTimeUtils; import com.mogo.eagle.core.utilcode.mogo.logger.Logger; import com.mogo.eagle.core.utilcode.mogo.permissions.PermissionsDialogUtils; @@ -50,8 +53,6 @@ import com.zhidao.autopilot.support.api.AutopilotServiceManage; import java.util.HashMap; import java.util.Map; -import static com.mogo.module.main.MainPresenter.MOGO_PERMISSION_REQUEST_CODE; - /** * @author congtaowang * @since 2019-12-23 @@ -255,8 +256,12 @@ public class MainActivity extends MvpActivity implement } private void startBaseService() { - Intent intent = new Intent(this, MogoMainService.class); - startService(intent); + Intent intentMainServicee = new Intent(this, MogoMainService.class); + startService(intentMainServicee); + + // USB 摄像头行车记录仪进程 +// Intent intentCarcorderService = new Intent(this, CarcorderService.class); +// startService(intentCarcorderService); } protected void loadContainerModules() { @@ -272,7 +277,7 @@ public class MainActivity extends MvpActivity implement @Override public void loadFunctionFragment() { - Logger.d(TAG,"loadFunctionFragment……"); + Logger.d(TAG, "loadFunctionFragment……"); // 加载 HMI 图层 BaseFragment fragmentHdMap = (BaseFragment) ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_HMI).navigation(); addFragment(fragmentHdMap, fragmentHdMap.getTagName(), R.id.module_main_id_waring_fragment); diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java index e453747ba7..192a6f7345 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/marker/MapMarkerManager.java @@ -142,11 +142,6 @@ public class MapMarkerManager implements IMogoMarkerClickListener, @Override public void onMsgReceived(SocketDownData.LauncherSnapshotProto mogoSnapshotSetData) { DebugConfig.setStatus(DebugConfig.sDownloadSnapshot, true); -// SnapshotSetDataDrawer.getInstance().renderSnapshotData(mogoSnapshotSetData); - // Message msg = mSnapshotHandler.obtainMessage(); - // msg.obj = mogoSnapshotSetData; - // msg.what = MSG_SNAPSHOT; - // msg.sendToTarget(); } }); } @@ -528,10 +523,6 @@ public class MapMarkerManager implements IMogoMarkerClickListener, int radius, boolean fitBounds) { - // if ( DebugConfig.isNeedUploadCoordinatesDurationInTime() ) {//todo 实时在线车辆需要注释,否则在2D模式下不能展示 - // return; - // } - if (DebugConfig.isDebug()) { if (!DebugConfig.isRequestOnlineCarData()) { return; diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java index 11fa9763e0..d580ac9aa1 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/MogoRouteOverlayManager.java @@ -83,17 +83,20 @@ public class MogoRouteOverlayManager implements // Log.d(TAG, "trajectoryInfos:" + adasTrajectoryInfo.getLat()+":"+adasTrajectoryInfo.getLon()); // Log.d(TAG, "temp:"+temp+" location:" + lat+":"+lon); List mogoLatLngs = new ArrayList<>(); - for (ADASTrajectoryInfo a : trajectoryInfos) { -// Log.d(TAG, "temp:"+temp+" trajectoryInfos:" + a.getLat()+":"+a.getLon()); - builder.append(a.getLon()).append(","); - builder.append(a.getLat()).append(","); - mogoLatLngs.add(new MogoLatLng(a.getLat(), a.getLon())); + for (int i = 0; i < trajectoryInfos.size(); i++) { + // 临时解决车尾拖线问题,丢弃距离车最近的几个经纬度,原因是惯性导航的中心靠近车尾,会导致经纬度靠近尾部,且两个数据不同频 + if (i > 5) { + ADASTrajectoryInfo a = trajectoryInfos.get(i); + builder.append(a.getLon()).append(","); + builder.append(a.getLat()).append(","); + mogoLatLngs.add(new MogoLatLng(a.getLat(), a.getLon())); + } } if (FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData || STATUS_AUTOPILOT == 1){ RouteOverlayDrawer.getInstance(mContext).drawTrajectoryList(mogoLatLngs); } builder.append("}"); - Log.d(TAG,builder.toString()); + //Log.d(TAG,builder.toString()); } @Override diff --git a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java index 0419d5d39a..c7a023eebb 100644 --- a/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java +++ b/modules/mogo-module-service/src/main/java/com/mogo/module/service/routeoverlay/RouteOverlayDrawer.java @@ -124,7 +124,7 @@ public class RouteOverlayDrawer { long start = System.currentTimeMillis(); List list = new ArrayList<>(); // list = ColorUtils.gradientAlpha("#FF2AAFFD", "#002965ED", mPolylinePointList.size()); - int[] startColor = ColorUtils.hexToArgb("#FF64C3EA"); + int[] startColor = ColorUtils.hexToArgb("#CC64C3EA"); int[] endColor = ColorUtils.hexToArgb("#0064C3EA"); list.add(Color.argb(startColor[0],startColor[1],startColor[2],startColor[3])); list.add(Color.argb(endColor[0],endColor[1],endColor[2],endColor[3])); diff --git a/services/mogo-service/build.gradle b/services/mogo-service/build.gradle index 76d36c3203..f6c6e92e28 100644 --- a/services/mogo-service/build.gradle +++ b/services/mogo-service/build.gradle @@ -51,7 +51,6 @@ dependencies { implementation rootProject.ext.dependencies.adasapi implementation rootProject.ext.dependencies.adasconfigapi if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { - implementation rootProject.ext.dependencies.moduleADAS api rootProject.ext.dependencies.mogomap implementation rootProject.ext.dependencies.mogomapapi implementation rootProject.ext.dependencies.mogo_core_utils diff --git a/settings.gradle b/settings.gradle index 725732a98f..0e8e0f5ad8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -40,6 +40,8 @@ include ':core:function-impl:mogo-core-function-notice' include ':core:function-impl:mogo-core-function-autopilot' // 行车超视距服务,路测摄像头、前车摄像头 include ':core:function-impl:mogo-core-function-monitoring' +// USB 行车记录仪 +include ':core:function-impl:mogo-core-function-carcorder' // 服务 @@ -55,6 +57,7 @@ include ':libraries:map-usbcamera' include ':libraries:map-custom' include ':libraries:mogo-map-api' include ':libraries:mogo-map' +include ':libraries:mogo-adas' // OLD业务模块 include ':modules:mogo-module-common' diff --git a/test/crashreport-apmbyte/build.gradle b/test/crashreport-apmbyte/build.gradle index 825f58a947..d3c9f93c1e 100644 --- a/test/crashreport-apmbyte/build.gradle +++ b/test/crashreport-apmbyte/build.gradle @@ -52,7 +52,7 @@ dependencies { if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { api rootProject.ext.dependencies.crashreport - implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogocommons } else { api project(":test:crashreport") diff --git a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java index 8446c6d2e7..86e15da72e 100644 --- a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java +++ b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java @@ -8,11 +8,13 @@ import com.apm.insight.CrashType; import com.apm.insight.MonitorCrash; import com.apm.insight.log.VLog; import com.bytedance.apm.insight.ApmInsight; +import com.bytedance.apm.insight.ApmInsightAgent; import com.bytedance.apm.insight.ApmInsightInitConfig; import com.mogo.cloud.passport.MoGoAiCloudClientConfig; import com.mogo.eagle.core.utilcode.mogo.logger.Logger; import com.mogo.eagle.core.utilcode.util.AppUtils; import com.mogo.eagle.core.utilcode.util.CommonUtils; +import com.mogo.eagle.core.utilcode.util.DeviceIdUtils; import com.mogo.test.crashreport.CrashReportConstants; import com.mogo.test.crashreport.ITestCrashReportProvider; @@ -23,7 +25,7 @@ import java.util.Map; /** * @author congtaowang * @since 2020/9/9 - * + *

* 描述 */ @Route(path = CrashReportConstants.PATH) @@ -31,6 +33,7 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { private static final String BYTEAMP_APPID = "302368"; private static final String TAG = "ApmCrashReportProvider"; + private static final String MAP_SDK_VERSION = "MAP_SDK_VERSION"; @Override public void init(Context context) { @@ -38,7 +41,8 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { initCrash(context); initApmInsight(context); } - private void initCrash(final Context context) { + + private void initCrash(final Context context) { MonitorCrash crash = MonitorCrash.init(context, BYTEAMP_APPID, CommonUtils.getVersionCode(context), CommonUtils.getVersionName(context)) .setCustomDataCallback(new AttachUserData() { @@ -53,8 +57,18 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { }); crash.config().setChannel("eagle"); crash.config().setDeviceId(MoGoAiCloudClientConfig.getInstance().getSn());//可选,可以设置自定义did,不设置会使用内部默认的 + String mapSDKVersion = AppUtils.getCustomMapSDKVersion(context); + crash.addTags(MAP_SDK_VERSION, mapSDKVersion); // crash.setReportUrl("www.xxx.com"); // 私有化部署:私有化部署才配置上报地址 // crash.addTags("key", "value"); // 自定义筛选tag, 按需添加、可多次覆盖 + + HashMap dimension = new HashMap<>(); + //维度值 + dimension.put("Devices_ID", DeviceIdUtils.getWidevineID(context)); + HashMap metric = new HashMap<>(); + //指标值 + metric.put("Devices_ID_metric", (double) 100); + ApmInsightAgent.monitorEvent("Devices_ID_EVENT", dimension, metric); } /** @@ -66,17 +80,17 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { //设置分配的appid builder.aid(BYTEAMP_APPID); //是否开启卡顿功能 - builder.blockDetect(true); + builder.blockDetect(false); //是否开启严重卡顿功能 - builder.seriousBlockDetect(true); + builder.seriousBlockDetect(false); //是否开启流畅性和丢帧 - builder.fpsMonitor(true); + builder.fpsMonitor(false); //控制是否打开WebVeiw监控 - builder.enableWebViewMonitor(true); + builder.enableWebViewMonitor(false); //控制是否打开内存监控 - builder.memoryMonitor(true); + builder.memoryMonitor(false); //控制是否打开电量监控 - builder.batteryMonitor(true); + builder.batteryMonitor(false); //是否打印日志,注:线上release版本要配置为false builder.debugMode(true); //支持用户自定义user_id把平台数据和自己用户关联起来,可以不配置