From 2531d8f4f270e59ab4bd38f2167fd2bb3fb536e1 Mon Sep 17 00:00:00 2001 From: xinfengkun Date: Tue, 19 Nov 2024 10:32:56 +0800 Subject: [PATCH] =?UTF-8?q?[672][app][device]=E5=8D=87=E7=BA=A7build=20gra?= =?UTF-8?q?dle=E7=89=88=E6=9C=AC=E5=88=B03.5.4=E7=94=A8=E4=BA=8E=E5=85=BC?= =?UTF-8?q?=E5=AE=B9Android11=20manifest=20=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=EF=BC=9B=E6=B7=BB=E5=8A=A0=E7=A1=AC=E4=BB=B6=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=94=A8=E4=BA=8E=E7=AE=A1=E7=90=86=E8=BD=A6?= =?UTF-8?q?=E8=BD=BD=E5=B7=B2=E7=A1=AC=E4=BB=B6=EF=BC=9A=E6=96=B0=E8=80=81?= =?UTF-8?q?=E6=A0=B8=E9=94=80=E3=80=81=E8=AF=AD=E9=9F=B3=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=AD=89=EF=BC=9BOCH=E6=A0=B8=E9=94=80=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E4=B8=8B=E6=B2=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OCH/common/common/build.gradle | 4 +- .../module/manager/scnner/ScannerManager.kt | 157 ++++---- config.gradle | 4 +- .../build.gradle | 1 + .../eagle/core/function/DataCenterProvider.kt | 7 +- .../function/datacenter/iot/IotInItManager.kt | 28 ++ .../mogo-core-function-hmi/build.gradle | 2 + .../hmi/ui/setting/DebugSettingView.kt | 70 +++- .../main/res/layout/view_debug_setting.xml | 17 + gradle/ext.gradle | 2 +- libraries/mogo-hardware-devices/.gitignore | 1 + libraries/mogo-hardware-devices/README.md | 4 + libraries/mogo-hardware-devices/build.gradle | 39 ++ .../mogo-hardware-devices/consumer-rules.pro | 0 .../mogo-hardware-devices/gradle.properties | 3 + .../mogo-hardware-devices/proguard-rules.pro | 21 + .../src/main/AndroidManifest.xml | 1 + .../com/mogo/support/device/DevicesManager.kt | 369 ++++++++++++++++++ .../device/IBindStateChangeListener.kt | 6 + .../support/device/ISpeechCx830seListener.kt | 73 ++++ .../device/IVerificationAutoListener.kt | 16 + settings.gradle | 1 + test/crashreport-noop/build.gradle | 2 +- 23 files changed, 750 insertions(+), 78 deletions(-) create mode 100644 core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/iot/IotInItManager.kt create mode 100644 libraries/mogo-hardware-devices/.gitignore create mode 100644 libraries/mogo-hardware-devices/README.md create mode 100644 libraries/mogo-hardware-devices/build.gradle create mode 100644 libraries/mogo-hardware-devices/consumer-rules.pro create mode 100644 libraries/mogo-hardware-devices/gradle.properties create mode 100644 libraries/mogo-hardware-devices/proguard-rules.pro create mode 100644 libraries/mogo-hardware-devices/src/main/AndroidManifest.xml create mode 100644 libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/DevicesManager.kt create mode 100644 libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IBindStateChangeListener.kt create mode 100644 libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/ISpeechCx830seListener.kt create mode 100644 libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IVerificationAutoListener.kt diff --git a/OCH/common/common/build.gradle b/OCH/common/common/build.gradle index 6597437eaf..f4659eaf17 100644 --- a/OCH/common/common/build.gradle +++ b/OCH/common/common/build.gradle @@ -64,8 +64,8 @@ dependencies { implementation rootProject.ext.dependencies.amapnavi3dmap implementation rootProject.ext.dependencies.rxandroid - // 串口链接 - implementation rootProject.ext.dependencies.serialport + // 硬件管理 + implementation project(":libraries:mogo-hardware-devices") implementation rootProject.ext.dependencies.arouter kapt rootProject.ext.dependencies.aroutercompiler diff --git a/OCH/common/common/src/main/java/com/mogo/och/common/module/manager/scnner/ScannerManager.kt b/OCH/common/common/src/main/java/com/mogo/och/common/module/manager/scnner/ScannerManager.kt index 847d1eadfc..110379dae3 100644 --- a/OCH/common/common/src/main/java/com/mogo/och/common/module/manager/scnner/ScannerManager.kt +++ b/OCH/common/common/src/main/java/com/mogo/och/common/module/manager/scnner/ScannerManager.kt @@ -1,7 +1,6 @@ package com.mogo.och.common.module.manager.scnner import android.net.Uri -import com.mogo.commons.AbsMogoApplication import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS_P @@ -9,17 +8,17 @@ import com.mogo.eagle.core.utilcode.util.GsonUtils import com.mogo.eagle.core.utilcode.util.StringUtils import com.mogo.och.common.module.biz.lansocket.IOchLanPassengerStatusListener import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket -import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDevicesMsg -import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffMsg import com.mogo.och.common.module.constant.OchCommonConst import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager import com.mogo.och.common.module.manager.socket.lan.LanSocketManager -import com.mogo.support.serialport.client.SerialPortManager -import com.mogo.support.serialport.client.SerialPortManager.SERVICE_STATE -import com.mogo.support.serialport.client.listener.OnDeviceVerificationListener -import com.mogo.support.serialport.client.listener.OnSerialPortListener -import com.mogo.support.serialport.common.verification.UnpackStatus -import com.mogo.support.serialport.common.verification.data.VerificationActiveData +import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDevicesMsg +import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffMsg +import com.mogo.support.device.manager.SerialPortManager +import com.mogo.support.device.manager.bean.VerificationData +import com.mogo.support.serialport.common.core.DeviceType +import com.mogo.support.device.DevicesManager +import com.mogo.support.device.IBindStateChangeListener +import com.mogo.support.device.IVerificationAutoListener import java.util.concurrent.ConcurrentHashMap import kotlin.properties.Delegates @@ -28,7 +27,6 @@ object ScannerManager : IOchLanPassengerStatusListener { private val TAG = "ScannerManager" - private var serialPortManager = SerialPortManager() private val stateChanageListeners: ConcurrentHashMap = ConcurrentHashMap() @@ -36,8 +34,11 @@ object ScannerManager : IOchLanPassengerStatusListener { private var bindStatus: BindStatus by Delegates.observable(BindStatus.NOTHING) { _, oldV, newV -> if (oldV != newV) { try { - CallerLogger.d(SceneConstant.M_OCHCOMMON + TAG, "扫码枪状态发生变化old:${oldV}_new:${newV}") - if(newV!= BindStatus.BIND_SUCCEED) { + CallerLogger.d( + SceneConstant.M_OCHCOMMON + TAG, + "扫码枪状态发生变化old:${oldV}_new:${newV}" + ) + if (newV != BindStatus.BIND_SUCCEED) { dispatchMsg(newV) } if (stateChanageListeners.size > 0) { @@ -65,41 +66,58 @@ object ScannerManager : IOchLanPassengerStatusListener { } } - private val onDeviceVerificationListener = object :OnDeviceVerificationListener(){ - override fun onSerialPortState( + private val onDeviceVerificationListener = object : IVerificationAutoListener { + override fun onDeviceState( path: String?, + deviceType: Byte, isOpen: Boolean, - throwableMessage: String? + message: String? ) { - CallerLogger.d( - M_BUS_P + TAG, - "path ${path}---isOpen${isOpen}--throwableMessage${throwableMessage}" + super.onDeviceState(path, deviceType, isOpen, message) + var deviceTypeString = "未知" + if (deviceType == DeviceType.VERIFICATION_SK87R) { + deviceTypeString = "(SK87R)" + } else if (deviceType == DeviceType.VERIFICATION_Q350) { + deviceTypeString = "(Q350)" + } + val msg = + "地址:${path} 设备类型:${deviceTypeString} 是否打开:${isOpen} 消息:${message}" + CallerLogger.d(M_BUS_P + TAG, msg) + OchChainLogManager.writeChainLogScanner( + TAG + "onSerialPortState", + "扫码枪是否打开:${msg}" ) - OchChainLogManager.writeChainLogScanner(TAG +"onSerialPortState","扫码枪是否打开:path${path}_isOpen${isOpen}_throwableMessage${throwableMessage}") openStatus = if (isOpen) { - sendWriteOffDevicesMessage2Driver(true,"扫码枪打开成功") + sendWriteOffDevicesMessage2Driver(true, "扫码枪打开成功") OpenStatus.Open } else { - sendWriteOffDevicesMessage2Driver(false,"扫码枪打开错误:${throwableMessage}_${path}") + sendWriteOffDevicesMessage2Driver( + false, + "扫码枪打开错误:${msg}_${path}_${deviceTypeString}" + ) OpenStatus.Unopen } } - override fun onActiveDataReceive(data: VerificationActiveData?) { - OchChainLogManager.writeChainLogScanner(TAG +"onActiveDataReceive","扫码结果:data:${data}") + + override fun onReceive(data: VerificationData?) { + OchChainLogManager.writeChainLogScanner( + TAG + "onActiveDataReceive", + "扫码结果:data:${data}" + ) data?.let { - if(data.unpackStatus==UnpackStatus.SUCCEED){ + if (data.unpackStatus.isNullOrEmpty()) { "数据类型${it.dataType.name}" CallerLogger.d(M_BUS_P + TAG, "data $it") - if(!StringUtils.isEmpty(it.payload)){ + if (!StringUtils.isEmpty(it.payload)) { parseParams(it.payload) - }else{ + } else { CallerLogger.d(M_BUS_P + TAG, "数据错误") sendWriteOffMessage2Driver("扫码数据为空") } - }else{ - sendWriteOffMessage2Driver("解包失败") - CallerLogger.d(M_BUS_P + TAG, "解包失败") + } else { + sendWriteOffMessage2Driver("解包失败:${data.unpackStatus}") + CallerLogger.d(M_BUS_P + TAG, "解包失败:${data.unpackStatus}") } } } @@ -107,45 +125,47 @@ object ScannerManager : IOchLanPassengerStatusListener { } - private val onSerialPortListener = object :OnSerialPortListener{ - override fun onServiceState(serviceState: Int) { - OchChainLogManager.writeChainLogScanner(TAG +"bindStatus","绑定服务结果:serviceState:${serviceState}") - when (serviceState) { - SERVICE_STATE.BIND_SUCCEED -> { + private val onSerialPortListener = object : IBindStateChangeListener { + override fun onServiceState(state: Int) { + OchChainLogManager.writeChainLogScanner( + TAG + "bindStatus", + "绑定服务结果:serviceState:${state}" + ) + when (state) { + SerialPortManager.SERVICE_STATE.BIND_SUCCEED -> { CallerLogger.d(M_BUS_P + TAG, "服务绑定成功") bindStatus = BindStatus.BIND_SUCCEED - serialPortManager.openVerificationDevice(onDeviceVerificationListener) } - SERVICE_STATE.BIND_FAILURE_UNINSTALLED -> { + + SerialPortManager.SERVICE_STATE.BIND_FAILURE_UNINSTALLED -> { CallerLogger.d(M_BUS_P + TAG, "服务绑定失败:未安装串口服务端APP") bindStatus = BindStatus.BIND_FAILURE_UNINSTALLED } - SERVICE_STATE.BIND_FAILURE_NO_PERMISSION_NOT_FOUND -> { - CallerLogger.d(M_BUS_P + TAG, "服务绑定失败:没有绑定权限或找不到服务(如果是此状态,基本上安装后就可以找到,主要就是权限问题)") + + SerialPortManager.SERVICE_STATE.BIND_FAILURE_NO_PERMISSION_NOT_FOUND -> { + CallerLogger.d( + M_BUS_P + TAG, + "服务绑定失败:没有绑定权限或找不到服务(如果是此状态,基本上安装后就可以找到,主要就是权限问题)" + ) bindStatus = BindStatus.BIND_FAILURE_NO_PERMISSION_NOT_FOUND } - SERVICE_STATE.EXCEPTION -> { + + SerialPortManager.SERVICE_STATE.EXCEPTION -> { CallerLogger.d(M_BUS_P + TAG, "服务被异常销毁") bindStatus = BindStatus.EXCEPTION } + else -> {} } } - // 查询串口 - override fun onFindSerialPort(paths: Array?) { - CallerLogger.d(M_BUS_P + TAG, "$paths") - OchChainLogManager.writeChainLogScanner(TAG +"onFindSerialPort","查询串口:${paths}") - if(paths==null) { - bindStatus = BindStatus.BIND_FAILURE_NO_PERMISSION_NOT_FOUND - } - } } init { //监听司机端消息 - LoginLanPassengerSocket.addListener(TAG,this) - serialPortManager.bindService(AbsMogoApplication.getApp(), onSerialPortListener)//绑定服务 + LoginLanPassengerSocket.addListener(TAG, this) + DevicesManager.addBindStateChangeListener(TAG, onSerialPortListener) + DevicesManager.addVerificationListener(TAG, onDeviceVerificationListener) } fun addStateChangeListener(tag: String, listener: StateChangeListener) { @@ -157,7 +177,7 @@ object ScannerManager : IOchLanPassengerStatusListener { override fun onDriverConnectChangeListener(isConnect: Boolean) { super.onDriverConnectChangeListener(isConnect) - if(isConnect) { + if (isConnect) { sendScannerState() } } @@ -168,17 +188,17 @@ object ScannerManager : IOchLanPassengerStatusListener { val mutableMapOf = mutableMapOf() queryParameterNames.forEach { val queryParameter = parse.getQueryParameter(it) - if(it!=null&&queryParameter!=null){ + if (it != null && queryParameter != null) { mutableMapOf[it] = queryParameter } } - if(mutableMapOf.isNotEmpty()){ + if (mutableMapOf.isNotEmpty()) { if (stateChanageListeners.size > 0) { stateChanageListeners.forEach { - it.value.parseData(mutableMapOf,payload) + it.value.parseData(mutableMapOf, payload) } } - }else{ + } else { sendWriteOffMessage2Driver("扫码参数数据为空:${payload}") } @@ -187,7 +207,7 @@ object ScannerManager : IOchLanPassengerStatusListener { /** * @param isConnectScanner 是否打开设备 */ - private fun sendWriteOffDevicesMessage2Driver(isConnectScanner:Boolean, message:String){ + private fun sendWriteOffDevicesMessage2Driver(isConnectScanner: Boolean, message: String) { val msg = WriteOffDevicesMsg(isConnectScanner, message) CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg)) LanSocketManager.sendMsgToServer(msg) @@ -196,8 +216,8 @@ object ScannerManager : IOchLanPassengerStatusListener { /** * 打开设备后数据异常 */ - private fun sendWriteOffMessage2Driver(message:String){ - val msg = WriteOffMsg(false, "", 0, "", message,"") + private fun sendWriteOffMessage2Driver(message: String) { + val msg = WriteOffMsg(false, "", 0, "", message, "") CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg)) LanSocketManager.sendMsgToServer(msg) } @@ -206,12 +226,12 @@ object ScannerManager : IOchLanPassengerStatusListener { * 链接司机屏后向司机屏同步扫码枪状态 */ private fun sendScannerState() { - if(bindStatus == BindStatus.BIND_SUCCEED && openStatus == OpenStatus.Open){ - sendWriteOffDevicesMessage2Driver(true,"扫码枪打开状态") - }else{ - if(bindStatus == BindStatus.BIND_SUCCEED && openStatus == OpenStatus.Unopen){ - sendWriteOffDevicesMessage2Driver(false,"绑定成功、打开失败") - }else{ + if (bindStatus == BindStatus.BIND_SUCCEED && openStatus == OpenStatus.Open) { + sendWriteOffDevicesMessage2Driver(true, "扫码枪打开状态") + } else { + if (bindStatus == BindStatus.BIND_SUCCEED && openStatus == OpenStatus.Unopen) { + sendWriteOffDevicesMessage2Driver(false, "绑定成功、打开失败") + } else { dispatchMsg(bindStatus) } } @@ -221,16 +241,19 @@ object ScannerManager : IOchLanPassengerStatusListener { when (newV) { BindStatus.BIND_FAILURE_UNINSTALLED -> { // 服务绑定失败:未安装串口服务端APP - sendWriteOffDevicesMessage2Driver(false,"服务绑定失败:未安装串口服务端APP") + sendWriteOffDevicesMessage2Driver(false, "服务绑定失败:未安装串口服务端APP") } + BindStatus.BIND_FAILURE_NO_PERMISSION_NOT_FOUND -> { // 服务绑定失败:没有绑定权限或找不到服务(如果是此状态,基本上安装后就可以找到,主要就是权限问题) - sendWriteOffDevicesMessage2Driver(false,"服务绑定失败:没有绑定权限或找不到服务") + sendWriteOffDevicesMessage2Driver(false, "服务绑定失败:没有绑定权限或找不到服务") } + BindStatus.EXCEPTION -> { // 扫码枪open错误 - sendWriteOffDevicesMessage2Driver(false,"扫码枪打开错误") + sendWriteOffDevicesMessage2Driver(false, "扫码枪打开错误") } + BindStatus.NOTHING -> {} else -> {} } @@ -240,7 +263,7 @@ object ScannerManager : IOchLanPassengerStatusListener { } enum class BindStatus { - BIND_SUCCEED, BIND_FAILURE_UNINSTALLED ,BIND_FAILURE_NO_PERMISSION_NOT_FOUND,EXCEPTION,NOTHING + BIND_SUCCEED, BIND_FAILURE_UNINSTALLED, BIND_FAILURE_NO_PERMISSION_NOT_FOUND, EXCEPTION, NOTHING } enum class OpenStatus { diff --git a/config.gradle b/config.gradle index 5ce7f621f8..e1ceac5ec3 100644 --- a/config.gradle +++ b/config.gradle @@ -216,8 +216,8 @@ ext { //========================= autosize ====================== androidautoSize : 'com.github.JessYanCoding:AndroidAutoSize:v1.2.1', - //========================= 扫码机 ====================== - serialport : 'com.mogo.support.serialport:client:1.0.0-alpha5', + //========================= 串口设备 ====================== + serialport : 'com.mogo.support.device.manager:serial_port:2.2.3', thread_opt : "com.mogo.thread.opt:lib:10.10.3", diff --git a/core/function-impl/mogo-core-function-datacenter/build.gradle b/core/function-impl/mogo-core-function-datacenter/build.gradle index 1039f768ea..0926586b53 100644 --- a/core/function-impl/mogo-core-function-datacenter/build.gradle +++ b/core/function-impl/mogo-core-function-datacenter/build.gradle @@ -61,6 +61,7 @@ dependencies { implementation project(':libraries:mogo-obu') implementation project(':libraries:mogo-adas') + implementation project(':libraries:mogo-hardware-devices') implementation rootProject.ext.dependencies.mogoaicloudtelematic compileOnly project(':core:function-impl:mogo-core-function-map') implementation project(':core:mogo-core-function-call') diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/DataCenterProvider.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/DataCenterProvider.kt index 97f447c434..df37673e6f 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/DataCenterProvider.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/DataCenterProvider.kt @@ -4,20 +4,20 @@ import android.content.Context import com.alibaba.android.arouter.facade.annotation.Route import com.mogo.eagle.core.data.constants.MogoServicePaths import com.mogo.eagle.core.function.api.datacenter.IDataCenterProvider -import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizListener import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizManager import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager import com.mogo.eagle.core.function.datacenter.location.MoGoLocationDispatcher import com.mogo.eagle.core.function.datacenter.v2x.SpeedLimitDispatcher import com.mogo.eagle.core.function.datacenter.v2x.TrafficLightDispatcher +import com.mogo.eagle.core.function.datacenter.iot.IotInItManager @Route(path = MogoServicePaths.PATH_DATA_CENTER_MODULE) -class DataCenterProvider: IDataCenterProvider { +class DataCenterProvider : IDataCenterProvider { override val functionName: String get() = "DataCenterProvider" - private var mContext:Context? = null + private var mContext: Context? = null override fun init(context: Context?) { MoGoLocationDispatcher.initListener() @@ -27,6 +27,7 @@ class DataCenterProvider: IDataCenterProvider { CallerMsgBoxManager.queryAllMessages(it) TrafficLightDispatcher.INSTANCE.initServer(it) SpeedLimitDispatcher.INSTANCE.initLimit(it) + IotInItManager.init() } } diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/iot/IotInItManager.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/iot/IotInItManager.kt new file mode 100644 index 0000000000..33e5b3ff09 --- /dev/null +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/iot/IotInItManager.kt @@ -0,0 +1,28 @@ +package com.mogo.eagle.core.function.datacenter.iot + +import com.mogo.commons.AbsMogoApplication +import com.mogo.commons.storage.SharedPrefsMgr +import com.mogo.eagle.core.function.api.cloud.IMoGoCloudListener +import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager +import com.mogo.support.device.DevicesManager + +object IotInItManager : IMoGoCloudListener { + private const val TAG = "IotInIt" + + + fun init() { + CallerCloudListenerManager.addListener(TAG, this) + hardwareDeviceBind(SharedPrefsMgr.getInstance().sn) + } + + override fun tokenGot(token: String, sn: String) { + super.tokenGot(token, sn) + hardwareDeviceBind(sn) + } + + private fun hardwareDeviceBind(sn: String) { + if (sn.isNotEmpty()) { + DevicesManager.init(AbsMogoApplication.getApp(), sn) + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/build.gradle b/core/function-impl/mogo-core-function-hmi/build.gradle index 8cd10480ce..8b9835a8e5 100644 --- a/core/function-impl/mogo-core-function-hmi/build.gradle +++ b/core/function-impl/mogo-core-function-hmi/build.gradle @@ -81,6 +81,8 @@ dependencies { implementation rootProject.ext.dependencies.preference_ktx implementation rootProject.ext.dependencies.amapsearch + // 硬件管理 + compileOnly project(":libraries:mogo-hardware-devices") implementation rootProject.ext.dependencies.thread_opt api project(':test:crashreport-apmbyte') compileOnly project(':core:function-impl:mogo-core-function-datacenter') 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 e4c3bc988c..7b0887f6e5 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 @@ -19,6 +19,7 @@ import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.TextView import androidx.annotation.RequiresApi +import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.ListPopupWindow import androidx.appcompat.widget.PopupMenu import androidx.constraintlayout.widget.ConstraintLayout @@ -132,6 +133,8 @@ 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_LONG_SIGHT import com.mogo.tts.base.IMogoTTSCallback +import com.mogo.support.device.DevicesManager +import com.mogo.support.device.IBindStateChangeListener import com.zhjt.mogo.adas.data.AdasConstants import com.zhjt.service.chain.ChainLog import kotlinx.android.synthetic.main.view_debug_setting.view.appVersionInfoLayout @@ -272,6 +275,7 @@ import kotlinx.android.synthetic.main.view_debug_setting.view.tvDriverServerStar import kotlinx.android.synthetic.main.view_debug_setting.view.tvGearInfo import kotlinx.android.synthetic.main.view_debug_setting.view.tvGitBranchInfo import kotlinx.android.synthetic.main.view_debug_setting.view.tvHDCityCode +import kotlinx.android.synthetic.main.view_debug_setting.view.tvHardwareDeviceBindState import kotlinx.android.synthetic.main.view_debug_setting.view.tvIPCMac import kotlinx.android.synthetic.main.view_debug_setting.view.tvIdentifyInfo import kotlinx.android.synthetic.main.view_debug_setting.view.tvIdentifyInfoCopy @@ -351,7 +355,7 @@ internal class DebugSettingView @JvmOverloads constructor( IMoGoChassisStatesListener, IMoGoSweeperFutianCleanSystemListener, IMoGoObuInfoListener, - ISopSettingListener, IViewControlListener, IMoGoCloudListener { + ISopSettingListener, IViewControlListener, IMoGoCloudListener, IBindStateChangeListener { companion object { private const val TAG = "DebugSettingView" @@ -474,6 +478,7 @@ internal class DebugSettingView @JvmOverloads constructor( } CallerObuInfoListenerManager.addListener(TAG, this) + DevicesManager.addBindStateChangeListener(TAG,this) } override fun onDetachedFromWindow() { @@ -503,7 +508,7 @@ internal class DebugSettingView @JvmOverloads constructor( CallerSopSettingManager.removeListener(TAG) CallerHmiViewControlListenerManager.removeListener(TAG) - + DevicesManager.removeBindStateChangeListener(TAG) // 移除 业务配置监听 CallerDevaToolsFuncConfigListenerManager.unRegisterDevaToolsFuncConfigListener( FuncBizConfig.FOUNDATION, @@ -1323,6 +1328,40 @@ internal class DebugSettingView @JvmOverloads constructor( } CallerHmiManager.toggleHdMapVisualAngleAdjust(isChecked) } + + //硬件服务绑定状态以及版本 + tvHardwareDeviceBindState.setOnClickListener { + val state = when (DevicesManager.getServiceBindState()) { + 0 -> { + "绑定成功" + } + + 1 -> { + "绑定失败:未安装“硬件服务”APP" + } + + 2 -> { + "绑定失败:没有绑定权限或找不到服务" + } + + 3 -> { + "服务被异常销毁" + } + + else -> { + "未知" + } + } + var msg = "客户端SDK版本:${DevicesManager.getSDKVersion() ?: "未知"}\n" + msg += "客户端SDK AIDL版本:${DevicesManager.getSDKAIDLVersion() ?: "未知"}\n" + msg += "硬件服务端APP版本:${DevicesManager.getServerVersion() ?: "未知"}\n" + msg += "硬件服务端APP AIDL版本:${DevicesManager.getServerAIDLVersion() ?: ""}" + AlertDialog.Builder(context) + .setTitle("硬件服务绑定状态: $state") + .setMessage(msg) + .setPositiveButton("确定", null) + .create().show() + } } /** @@ -2707,4 +2746,31 @@ internal class DebugSettingView @JvmOverloads constructor( private fun invokeCronetResult(json: String) { CallerLogger.d(SceneConstant.M_HMI + "CronetNetwork", json) } + + override fun onServiceState(state: Int) { + val stateMsg = when (state) { + 0 -> { + "绑定成功" + } + + 1 -> { + "绑定失败:未安装“硬件服务”APP" + } + + 2 -> { + "绑定失败:没有绑定权限或找不到服务" + } + + 3 -> { + "服务被异常销毁" + } + + else -> { + "未知" + } + } + UiThreadHandler.post { + tvHardwareDeviceBindState.text = "硬件服务绑定状态: $stateMsg" + } + } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml index e7453824c8..7f647fddaa 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml @@ -681,6 +681,23 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + + + + + + \ No newline at end of file diff --git a/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/DevicesManager.kt b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/DevicesManager.kt new file mode 100644 index 0000000000..bd2ec77ccf --- /dev/null +++ b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/DevicesManager.kt @@ -0,0 +1,369 @@ +package com.mogo.support.device + +import android.content.Context +import android.util.Log +import com.mogo.support.device.manager.DefaultDevices +import com.mogo.support.device.manager.SerialPortManager +import com.mogo.support.device.manager.SerialPortManager.SERVICE_STATE +import com.mogo.support.device.manager.bean.VerificationData +import com.mogo.support.device.manager.listener.OnBindServerListener +import com.mogo.support.device.manager.listener.OnDeviceSpeechCx830seListener +import com.mogo.support.device.manager.listener.OnDeviceVerificationListener +import com.mogo.support.serialport.common.core.Code +import com.mogo.support.serialport.common.core.Define +import com.mogo.support.serialport.common.core.Device +import com.mogo.support.serialport.common.devices.speech.cx830se.data.SwitchingValueData +import java.util.concurrent.ConcurrentHashMap + +object DevicesManager { + private const val TAG = "DevicesManager" + private var serviceBindState = -1//-1:未知 + private val serialPortManager: SerialPortManager by lazy { + SerialPortManager() // 初始化 SerialPortManager + } + + private val bindStateChangeListeners: ConcurrentHashMap = + ConcurrentHashMap() + private val verificationAutoListeners: ConcurrentHashMap = + ConcurrentHashMap() + private val speechCx830seListeners: ConcurrentHashMap = + ConcurrentHashMap() + + fun init(context: Context, sn: String) { + serialPortManager.bindService(context, sn, bindStateChangeListener) + } + + /** + * 注册服务端APP绑定状态 + */ + fun addBindStateChangeListener(tag: String, listener: IBindStateChangeListener) { + if (bindStateChangeListeners.containsKey(tag)) { + return + } + bindStateChangeListeners[tag] = listener + } + + /** + * 取消注册服务端APP绑定状态 + */ + fun removeBindStateChangeListener(tag: String) { + if (bindStateChangeListeners.containsKey(tag)) { + bindStateChangeListeners.remove(tag) + } + } + + /** + * 注册核销设备回调接口 注册时自动连接核销设备 + */ + fun addVerificationListener(tag: String, listener: IVerificationAutoListener) { + if (verificationAutoListeners.containsKey(tag)) { + return + } + verificationAutoListeners[tag] = listener + if (verificationAutoListeners.isNotEmpty()) { + if (serviceBindState == SERVICE_STATE.BIND_SUCCEED) { + serialPortManager.open(DefaultDevices.VERIFICATION, verificationListener) + } + } + } + + /** + * 取消注册核销设备回调接口 + */ + fun removeVerificationListener(tag: String) { + if (verificationAutoListeners.containsKey(tag)) { + verificationAutoListeners.remove(tag) + } + if (verificationAutoListeners.isEmpty()) { + + } + } + + /** + * 注册语音设备回调接口 注册时自动连接语音设备 + */ + fun addSpeechCx830seListener(tag: String, listener: ISpeechCx830seListener) { + if (speechCx830seListeners.containsKey(tag)) { + return + } + speechCx830seListeners[tag] = listener + if (speechCx830seListeners.isNotEmpty()) { + if (serviceBindState == SERVICE_STATE.BIND_SUCCEED) { + serialPortManager.open(DefaultDevices.SPEECH_CX830SE, speechCx830seListener) + } + } + } + + /** + * 取消注册语音设备回调接口 + */ + fun removeSpeechCx830seListener(tag: String) { + if (speechCx830seListeners.containsKey(tag)) { + speechCx830seListeners.remove(tag) + } + } + + + private val bindStateChangeListener = object : OnBindServerListener() { + + override fun onServiceState(serviceState: Int) { + serviceBindState = serviceState + if (bindStateChangeListeners.isNotEmpty()) { + bindStateChangeListeners.forEach { + it.value.onServiceState(serviceState) + } + } + //TODO 链路日志和埋点 +// OchChainLogManager.writeChainLogScanner( +// TAG + "bindStatus", +// "绑定服务结果:serviceState:${serviceState}" +// ) + when (serviceState) { + SERVICE_STATE.BIND_SUCCEED -> { + Log.d(TAG, "服务绑定成功") + if (verificationAutoListeners.isNotEmpty()) { + serialPortManager.open(DefaultDevices.VERIFICATION, verificationListener) + } + if (speechCx830seListeners.isNotEmpty()) { + serialPortManager.open(DefaultDevices.SPEECH_CX830SE, speechCx830seListener) + } + } + + SERVICE_STATE.BIND_FAILURE_UNINSTALLED -> { + Log.d(TAG, "服务绑定失败:未安装串口服务端APP") + } + + SERVICE_STATE.BIND_FAILURE_NO_PERMISSION_NOT_FOUND -> { + Log.d( + TAG, + "服务绑定失败:没有绑定权限或找不到服务(如果是此状态,基本上安装后就可以找到,主要就是权限问题)" + ) + } + + SERVICE_STATE.EXCEPTION -> { + Log.d(TAG, "服务被异常销毁") + } + + else -> {} + } + } + } + + private val verificationListener: OnDeviceVerificationListener = + object : OnDeviceVerificationListener() { + override fun onDeviceState( + path: String?, + deviceType: Byte, + isOpen: Boolean, + message: String? + ) { + if (verificationAutoListeners.isNotEmpty()) { + verificationAutoListeners.forEach { + it.value.onDeviceState(path, deviceType, isOpen, message) + } + } + } + + override fun onReceive(data: VerificationData) { + if (verificationAutoListeners.isNotEmpty()) { + verificationAutoListeners.forEach { + it.value.onReceive(data) + } + } + } + } + + + private val speechCx830seListener: OnDeviceSpeechCx830seListener = + object : OnDeviceSpeechCx830seListener() { + override fun onSerialPortState( + path: String, + isOpen: Boolean, + throwableMessage: String? + ) { + if (speechCx830seListeners.isNotEmpty()) { + speechCx830seListeners.forEach { + it.value.onOpenState(path, isOpen, throwableMessage) + } + } + +// if (isOpen) { +// openBtnEnable(!serialPortManager.isOpen(selectDevice.path)) +// updateUi(path, true) +// if (serialPortManager.getDeviceType(path) == DeviceType.SPEECH_CX830SE) { +// val device = serialPortManager.getOpenedSerialPort(path) +// serialPortManager.speechCx830seSendCommand( +// device, +// SpeechCommand.READ_DEVICE_ADDRESS +// ) +// serialPortManager.speechCx830seSendCommand( +// device, +// SpeechCommand.READ_SWITCHING_VALUE_STATE +// ) +// } +// } else { +// showOpenFailed(path) +// } + } + + override fun onSpeechState(path: String, state: Int) { + if (speechCx830seListeners.isNotEmpty()) { + speechCx830seListeners.forEach { + it.value.onSpeechState(path, state) + } + } + val msg = when (state) { + Code.SUCCESS -> { + "播报内容下发成功" + } + + Code.FAILED -> { + "播报内容下发失败" + } + + + Code.TIMEOUT -> { + "播报内容下发超时" + } + + Code.SPEECH_CX830SE_SPEECH_BROADCAST_COMPLETE -> { + "播报完成" + } + + else -> "" + } + Log.d(TAG, msg) + } + + override fun onSwitchingValue(path: String, state: Int, data: SwitchingValueData?) { + super.onSwitchingValue(path, state, data) + if (speechCx830seListeners.isNotEmpty()) { + speechCx830seListeners.forEach { + it.value.onSwitchingValue(path, state, data) + } + } + + val msg = when (state) { + Code.SUCCESS -> { + "开关量读取成功" + } + + Code.TIMEOUT -> { + "开关量读取超时" + } + + Code.PASSIVITY_RECEIVE -> { + "设备主动触发" + } + + else -> null + } + if (!msg.isNullOrEmpty()) { + Log.d(TAG, msg) + } + } + + override fun onDeviceAddress(path: String, state: Int, address: Int) { + super.onDeviceAddress(path, state, address) + if (speechCx830seListeners.isNotEmpty()) { + speechCx830seListeners.forEach { + it.value.onDeviceAddress(path, state, address) + } + } + + val msg = when (state) { + Code.SUCCESS -> { + "设备地址读取成功" + } + + Code.TIMEOUT -> { + "设备地址读取超时" + } + + else -> null + } + if (!msg.isNullOrEmpty()) { + Log.d(TAG, msg) + } + } + + + override fun onCommandResponse( + path: String, + mainCommand: Int, + subcommand: Int, + state: Int + ) { + super.onCommandResponse(path, mainCommand, subcommand, state) + if (speechCx830seListeners.isNotEmpty()) { + speechCx830seListeners.forEach { + it.value.onCommandResponse(path, mainCommand, subcommand, state) + } + } +// val command = SpeechCommand.getCommandBySign(mainCommand) +// var msg = "" +// if (state == Code.SUCCESS) { +// msg = "执行成功" +// } else if (state == Code.TIMEOUT) { +// msg = "执行超时" +// } + Log.i(TAG, "主命令=${mainCommand} 子命令=${subcommand} 命令结果=$state") + + } + } + + + /** + * 语音设备(科星互联 CX-830S-E)语音播报 + * AIDL调用 + * @param content 播报内容 打断模式下,输入 null或""可以停止语音播报 + * @return 是否调用成功 调用成功(不代表命令执行成功):[Code.SUCCESS];命令未识别:[Code.COMMAND_ERROR]; + */ + @Define.Code + fun speechCx830seBroadcast(content: String?): Int { + return serialPortManager.speechCx830seBroadcastSpeech( + DefaultDevices.SPEECH_CX830SE, + content + ) + } + + /** + * 设备是否打开 + * @param device {@link DefaultDevices#SPEECH_CX830SE} + * {@link DefaultDevices#VERIFICATION} + * {@link DefaultDevices#VERIFICATION_SK87R} + * {@link DefaultDevices#VERIFICATION_Q350} + */ + fun isDeviceOpen(device: Device): Boolean { + if (DefaultDevices.VERIFICATION.equals(device)) { + return serialPortManager.isOpen(DefaultDevices.VERIFICATION_SK87R.path) || serialPortManager.isOpen( + DefaultDevices.VERIFICATION_Q350.path + ) + } + return serialPortManager.isOpen(device.path) + } + + /** + * 绑定状态 + * -1:未知 其他的状态 [SerialPortManager.SERVICE_STATE] + */ + fun getServiceBindState(): Int { + return serviceBindState + } + + fun getSDKVersion(): String { + return serialPortManager.version + } + + fun getSDKAIDLVersion(): String { + return serialPortManager.aidlVersion + } + + fun getServerVersion(): String? { + return serialPortManager.serverVersionName + } + + fun getServerAIDLVersion(): String? { + return serialPortManager.serverAidlVersion + } +} \ No newline at end of file diff --git a/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IBindStateChangeListener.kt b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IBindStateChangeListener.kt new file mode 100644 index 0000000000..00e53a2d59 --- /dev/null +++ b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IBindStateChangeListener.kt @@ -0,0 +1,6 @@ +package com.mogo.support.device + +//服务绑定状态接口回调 +interface IBindStateChangeListener { + fun onServiceState(state: Int) +} \ No newline at end of file diff --git a/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/ISpeechCx830seListener.kt b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/ISpeechCx830seListener.kt new file mode 100644 index 0000000000..710c4040d1 --- /dev/null +++ b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/ISpeechCx830seListener.kt @@ -0,0 +1,73 @@ +package com.mogo.support.device; + +import com.mogo.support.serialport.common.core.Define +import com.mogo.support.serialport.common.devices.speech.cx830se.data.SwitchingValueData + +/** + * 语音设备(科星互联 CX-830S-E)监听 + */ +interface ISpeechCx830seListener { + + /** + * 设备打开状态 + * + * @param path 串口地址 + * @param isOpen 是否打开成功 + * @param throwableMessage 异常消息 + */ + fun onOpenState(path: String, isOpen: Boolean, throwableMessage: String?) {} + + /** + * 语音播报状态 + * + * @param path 串口 + * @param state 状态 语音命令下发成功:{@link Code#SUCCESS};语音命令下发失败:{@link Code#FAILED};语音命令下发超时:{@link Code#TIMEOUT};语音播报完成:{@link Code#SPEECH_CX830SE_SPEECH_BROADCAST_COMPLETE}; + */ + fun onSpeechState(path: String, @Define.Code state: Int) {} + + /** + * 开关量状态 + * 设备主动触发开关量时 state = Code.PASSIVITY_RECEIVE + * + * @param path 串口 + * @param state 状态 查询成功:{@link Code#SUCCESS};查询命令下发失败:{@link Code#FAILED};查询超时:{@link Code#TIMEOUT};设备主动触发开关量:{@link Code#PASSIVITY_RECEIVE}; + * @param data 开关量数据 + */ + fun onSwitchingValue(path: String, @Define.Code state: Int, data: SwitchingValueData?) {} + + /** + * 设备地址 + * + * @param path 串口 + * @param state 查询状态 成功:{@link Code#SUCCESS};查询命令下发失败:{@link Code#FAILED};超时:{@link Code#TIMEOUT}; + * @param address 设备地址 -1:解析失败 + */ + fun onDeviceAddress(path: String, @Define.Code state: Int, address: Int) {} + + /** + * 命令下发响应 + * + * @param path 串口 + * @param mainCommand 命令 + * @param subcommand mainCommand 中如果存在子流程则表示正在执行的子命令 目前只有存在子流程的命令有:{@link SpeechCommand#INITIALIZE}; + * @param state 状态 成功:{@link Code#SUCCESS};失败:{@link Code#FAILED};超时:{@link Code#TIMEOUT}; + * 当 mainCommand == {@link SpeechCommand#INITIALIZE} && subcommand == {@link SpeechCommand#UNKNOWN} 时 + * state表示整体流程状态 + * * 初始化开始(整体初始化流程的开始):{@link Code#SPEECH_CX830SE_INITIALIZE_START} + * * 初始化完成(整体初始化流程的完成):{@link Code#SPEECH_CX830SE_INITIALIZE_COMPLETE} + *

+ * 当 mainCommand == {@link SpeechCommand#INITIALIZE} && subcommand != {@link SpeechCommand#UNKNOWN} 时 + * state表示子命令执行状态 + * * 初始化子命令开始执行(初始化流程中的子命令开始下发):{@link Code#SPEECH_CX830SE_INITIALIZE_SUBCOMMAND_START} + * * 初始化子命令成功:{@link Code#SUCCESS} + * * 初始化子命令失败:{@link Code#FAILED} + * * 初始化子命令超时:{@link Code#TIMEOUT} + */ + fun onCommandResponse( + path: String, + @Define.CommandSign mainCommand: Int, + @Define.CommandSign subcommand: Int, + @Define.Code state: Int + ) { + } +} diff --git a/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IVerificationAutoListener.kt b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IVerificationAutoListener.kt new file mode 100644 index 0000000000..ed3aaff456 --- /dev/null +++ b/libraries/mogo-hardware-devices/src/main/java/com/mogo/support/device/IVerificationAutoListener.kt @@ -0,0 +1,16 @@ +package com.mogo.support.device + +import com.mogo.support.device.manager.bean.VerificationData + +//核销设备数据回调 +interface IVerificationAutoListener { + /** + * 设备状态 + * + * @param deviceType 设备类型 [com.mogo.support.serialport.common.core.DeviceType.VERIFICATION_Q350] [com.mogo.support.serialport.common.core.DeviceType.VERIFICATION_SK87R] + * @param isOpen 是否打开 + * @param message 消息 + */ + fun onDeviceState(path: String?, deviceType: Byte, isOpen: Boolean, message: String?) {} + fun onReceive(data: VerificationData?) +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 8705e605ac..720c3a940c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -44,6 +44,7 @@ include ':libraries:mogo-map' include ':libraries:mogo-adas' include ':libraries:mogo-adas-data' include ':libraries:mogo-obu' +include ':libraries:mogo-hardware-devices' //include ':libraries:mapmodule' // 语音 diff --git a/test/crashreport-noop/build.gradle b/test/crashreport-noop/build.gradle index a6ccdfcea6..ee7583553f 100644 --- a/test/crashreport-noop/build.gradle +++ b/test/crashreport-noop/build.gradle @@ -54,7 +54,7 @@ dependencies { implementation rootProject.ext.dependencies.androidxappcompat implementation rootProject.ext.dependencies.arouter - implementation "com.android.tools.build:gradle:3.5.3" + implementation "com.android.tools.build:gradle:3.5.4" kapt rootProject.ext.dependencies.aroutercompiler if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {