Merge remote-tracking branch 'origin/dev_robotaxi-d_241112_6.8.0' into dev_robotaxi-d_241112_6.8.0
# Conflicts: # OCH/common/common/src/main/java/com/mogo/och/common/module/manager/scnner/ScannerManager.kt
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.data.enums.EventTypeEnumNew
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxType
|
||||
@@ -22,11 +21,11 @@ import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
|
||||
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
|
||||
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.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
|
||||
|
||||
@@ -35,7 +34,6 @@ object ScannerManager : IOchLanPassengerStatusListener {
|
||||
|
||||
private val TAG = "ScannerManager"
|
||||
|
||||
private var serialPortManager = SerialPortManager()
|
||||
|
||||
private val stateChanageListeners: ConcurrentHashMap<String, StateChangeListener> =
|
||||
ConcurrentHashMap()
|
||||
@@ -43,8 +41,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) {
|
||||
@@ -72,40 +73,57 @@ 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()) {
|
||||
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}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,38 +131,39 @@ 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<out String>?) {
|
||||
CallerLogger.d(M_BUS_P + TAG, "$paths")
|
||||
OchChainLogManager.writeChainLogScanner(TAG +"onFindSerialPort","查询串口:${paths}")
|
||||
if(paths==null) {
|
||||
bindStatus = BindStatus.BIND_FAILURE_NO_PERMISSION_NOT_FOUND
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -186,10 +205,11 @@ object ScannerManager : IOchLanPassengerStatusListener {
|
||||
|
||||
init {
|
||||
//监听司机端消息
|
||||
LoginLanPassengerSocket.addListener(TAG,this)
|
||||
LoginLanPassengerSocket.addListener(TAG, this)
|
||||
// 核销设备信息
|
||||
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_WRITEOFF_DEVICES_INFO.type,writeOfDevicefMsg)
|
||||
serialPortManager.bindService(AbsMogoApplication.getApp(), onSerialPortListener)//绑定服务
|
||||
DevicesManager.addBindStateChangeListener(TAG, onSerialPortListener)
|
||||
DevicesManager.addVerificationListener(TAG, onDeviceVerificationListener)
|
||||
}
|
||||
|
||||
fun addStateChangeListener(tag: String, listener: StateChangeListener) {
|
||||
@@ -205,7 +225,7 @@ object ScannerManager : IOchLanPassengerStatusListener {
|
||||
|
||||
override fun onDriverConnectChangeListener(isConnect: Boolean) {
|
||||
super.onDriverConnectChangeListener(isConnect)
|
||||
if(isConnect) {
|
||||
if (isConnect) {
|
||||
sendScannerState()
|
||||
}
|
||||
}
|
||||
@@ -216,17 +236,17 @@ object ScannerManager : IOchLanPassengerStatusListener {
|
||||
val mutableMapOf = mutableMapOf<String, String>()
|
||||
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}")
|
||||
}
|
||||
|
||||
@@ -235,7 +255,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)
|
||||
@@ -254,12 +274,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)
|
||||
}
|
||||
}
|
||||
@@ -269,16 +289,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 -> {}
|
||||
}
|
||||
@@ -288,7 +311,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 {
|
||||
|
||||
@@ -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",
|
||||
|
||||
|
||||
@@ -276,9 +276,9 @@ internal object V2NIdentifyDrawer: IEventDismissListener {
|
||||
AiRoadMarker.aiMakers.getOrPut(id) {
|
||||
AiRoadMarker().apply {
|
||||
try {
|
||||
val current = abs(location.gnssSpeed) * 3.6f.toInt()
|
||||
val min = abs(data.speedStraightMin * 3.6f).toInt()
|
||||
val max = abs(data.speedStraightMax * 3.6f).toInt()
|
||||
val current = abs(location.gnssSpeed).toInt()
|
||||
val min = abs(data.speedStraightMin).toInt()
|
||||
val max = abs(data.speedStraightMax).toInt()
|
||||
marker(Marker(id, EventTypeEnumNew.TYPE_SOCKET_ROAD_GREE_WAVE.poiType, destX, destY, 0.0, null, null, null), drawMarker = false, false)
|
||||
var alertTts = ""
|
||||
var alertContent = ""
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager
|
||||
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.function.call.telematic.CallerTelematicListenerManager
|
||||
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
|
||||
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
@@ -155,6 +156,42 @@ class TeleMsgHandler : IMsgHandler {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (it.protocolType == TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_REQ) {
|
||||
try {
|
||||
Log.d(TAG, "乘客屏收到司机屏转发的驾驶位视频流开关 --- 1 ---")
|
||||
val content = String(it.body, Charset.defaultCharset())
|
||||
Log.d(TAG, "乘客屏收到司机屏转发的驾驶位视频流开关 --- 2 ---:$content")
|
||||
val data = GsonUtils.fromJson(content, Map::class.java)
|
||||
val open = data["open"].toString().toInt() == 1
|
||||
val playUrl = data["playUrl"]?.toString()
|
||||
//TODO yangyakun
|
||||
if (open) {
|
||||
if (playUrl != null) {
|
||||
// 1. 获取视频播放控件
|
||||
val target = CallerDevaToolsManager.driveSeatVideoProvider()?.getDriveVideoView(playUrl) { event ->
|
||||
|
||||
}
|
||||
|
||||
if (target != null) {
|
||||
// 2. 添加到一个ViewGroup上
|
||||
// 11: 第1个1代表运营面板开关打开,第2个1代表打开成功,告之司机端
|
||||
// 10: 第1个1代表运营面板开关打开,第2个0代表打开成功,告之司机端
|
||||
CallerTelematicManager.sendMsgToServer(TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_RSP, "11".toByteArray())
|
||||
}
|
||||
|
||||
} else {
|
||||
CallerTelematicManager.sendMsgToServer(TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_RSP, "10".toByteArray())
|
||||
}
|
||||
} else {
|
||||
//第1个0代表运营面板开关关闭,第2个1代表关闭成功,告之司机端; 相应的还有状态:00表示关闭失败
|
||||
CallerTelematicManager.sendMsgToServer(TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_RSP, "01".toByteArray())
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
Log.e(TAG, "乘客屏收到司机屏转发的驾驶位视频流开关--- 3 ---", t)
|
||||
}
|
||||
return
|
||||
}
|
||||
when (it.protocolType) {
|
||||
MogoProtocolMsg.NORMAL_DATA -> {
|
||||
try {
|
||||
@@ -349,6 +386,11 @@ class TeleMsgHandler : IMsgHandler {
|
||||
)
|
||||
}
|
||||
|
||||
TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_RSP -> {
|
||||
// 来自客户端的响应
|
||||
CallerTelematicListenerManager.invokeReceivedMsg(TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_RSP, it.body)
|
||||
}
|
||||
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,8 @@ import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
|
||||
import com.zhjt.mogo_core_function_devatools.binding.BindingCarManager
|
||||
import com.zhjt.mogo_core_function_devatools.block.MoGoBlockProviderImpl
|
||||
import com.zhjt.mogo_core_function_devatools.coldstart.ColdStartManager
|
||||
import com.zhjt.mogo_core_function_devatools.driver.video.DriveSeatVideoProviderImpl
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider
|
||||
import com.zhjt.mogo_core_function_devatools.env.EnvChangeManager
|
||||
import com.zhjt.mogo_core_function_devatools.exam.ExamControlManager
|
||||
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigCenter.Companion.bizConfigCenter
|
||||
@@ -125,6 +127,8 @@ class DevaToolsProvider : IDevaToolsProvider, IAppStateListener {
|
||||
ARouter.getInstance().build(MogoServicePaths.PATH_MAP_ROUTE_GUIDE).navigation() as? IMapRouteProvider
|
||||
}
|
||||
|
||||
private val driveSeatVideoProvider by lazy { DriveSeatVideoProviderImpl() }
|
||||
|
||||
@Volatile
|
||||
private var lastCanAutopilotStatus: Int? = null
|
||||
|
||||
@@ -682,4 +686,8 @@ class DevaToolsProvider : IDevaToolsProvider, IAppStateListener {
|
||||
override fun takeOver(@TakeOverAnnotation takeOverAnnotation: Int) {
|
||||
TakeOverManager.takeOverManager.takeOver(takeOverAnnotation)
|
||||
}
|
||||
|
||||
override fun driveSeatVideoProvider(): IDriveSeatVideoProvider {
|
||||
return driveSeatVideoProvider
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.zhjt.mogo_core_function_devatools.driver.video
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.core.view.doOnAttach
|
||||
import androidx.core.view.doOnDetach
|
||||
import com.mogo.commons.constants.HostConst
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.data.app.AppConfigInfo
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Event
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Event.Failed
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Event.Loading
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Event.Playing
|
||||
import com.mogo.eagle.core.network.MoGoRetrofitFactory
|
||||
import com.mogo.eagle.core.utilcode.util.AppStateManager
|
||||
import com.tencent.liteav.basic.log.TXCLog
|
||||
import com.tencent.rtmp.ITXLivePlayListener
|
||||
import com.tencent.rtmp.TXLiveConstants
|
||||
import com.tencent.rtmp.TXLivePlayConfig
|
||||
import com.tencent.rtmp.TXLivePlayer
|
||||
import com.tencent.rtmp.ui.TXCloudVideoView
|
||||
import com.zhjt.mogo_core_function_devatools.driver.video.vo.VideoUrlData
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Headers
|
||||
import retrofit2.http.Query
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "DriveSeatVideoProvider"
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var target: WeakReference<TXCloudVideoView>? = null
|
||||
|
||||
@Volatile
|
||||
private var timer: Job? = null
|
||||
|
||||
private val scope by lazy { CoroutineScope(Dispatchers.IO + SupervisorJob()) }
|
||||
|
||||
private var data: VideoUrlData? = null
|
||||
|
||||
internal interface IVideoLiveUrlApi {
|
||||
@Headers("Content-Type:application/json;charset=UTF-8")
|
||||
@GET("/eagleEye-mis/camera/monitor/watch/status")
|
||||
suspend fun requestVideoLiveUrl(@Query(value = "numberPlate") numberPlate: String, @Query("cameraType") cameraType: Int, @Query("protocolType") protocolType: Int): BaseResponse<VideoUrlData>
|
||||
}
|
||||
|
||||
|
||||
override suspend fun requestVideoInfo(): VideoUrlData? {
|
||||
val plateNumber = AppConfigInfo.plateNumber
|
||||
if (TextUtils.isEmpty(plateNumber)) {
|
||||
Log.e(TAG, "-- isVideoLiveUsable -- plate number is empty.")
|
||||
return null
|
||||
}
|
||||
val resp = getApi()?.requestVideoLiveUrl(plateNumber, 2, 2) ?: return null
|
||||
Log.e(TAG, "-- isVideoLiveUsable -- receive response: {code: ${resp.code}, msg: ${resp.msg}, result: ${resp.result}}")
|
||||
data = resp.result
|
||||
return resp.result
|
||||
}
|
||||
|
||||
override fun getDriveVideoView(playUrl: String, playCallback: ((Event) -> Unit)?): View? {
|
||||
val activity = AppStateManager.currentActivity() ?: return null
|
||||
val t = target?.get()
|
||||
if (t != null) {
|
||||
return t
|
||||
}
|
||||
val x = TXCloudVideoView(activity)
|
||||
Log.d(TAG, "getDriveVideoView --> $playUrl")
|
||||
x.doOnAttach {
|
||||
Log.d(TAG, "onAttachToWindow --> $playUrl")
|
||||
val player = TXLivePlayer(activity)
|
||||
player.setPlayerView(x)
|
||||
player.setMute(true)
|
||||
TXCLog.setLevel(4)
|
||||
val config = TXLivePlayConfig()
|
||||
config.setConnectRetryCount(30)
|
||||
player.setConfig(config)
|
||||
player.enableHardwareDecode(true)
|
||||
player.startPlay(playUrl, TXLivePlayer.PLAY_TYPE_LIVE_RTMP)
|
||||
player.setPlayListener(object : ITXLivePlayListener {
|
||||
|
||||
override fun onPlayEvent(event: Int, bundle: Bundle?) {
|
||||
Log.d(TAG, "直播信息 => event: $event, playUrl: $playUrl, bundle: $bundle")
|
||||
if (event == TXLiveConstants.PLAY_EVT_PLAY_LOADING) {
|
||||
Log.d(TAG, "play loading...")
|
||||
playCallback?.invoke(Loading)
|
||||
} else if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {
|
||||
Log.d(TAG, "play begin...")
|
||||
start()
|
||||
playCallback?.invoke(Playing)
|
||||
} else {
|
||||
if (event < 0) {
|
||||
Log.d(TAG, "play failed...$event, bundle: $bundle")
|
||||
stop()
|
||||
playCallback?.invoke(Failed(bundle?.toString() ?: "播放失败"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNetStatus(bundle: Bundle?) {
|
||||
Log.d(TAG, "直播信息 => onNetStatus -> $bundle")
|
||||
}
|
||||
})
|
||||
|
||||
x.doOnDetach {
|
||||
Log.d(TAG, "-- onDetachedFromWindow ---: $playUrl")
|
||||
try {
|
||||
player.stopPlay(true)
|
||||
stop()
|
||||
} finally {
|
||||
target?.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
target = WeakReference(x)
|
||||
return x
|
||||
}
|
||||
|
||||
|
||||
override fun getLastData(): VideoUrlData? {
|
||||
return data
|
||||
}
|
||||
|
||||
private fun start() {
|
||||
timer?.cancel()
|
||||
scope.launch {
|
||||
val result = requestVideoInfo()
|
||||
if (result != null) {
|
||||
data = result
|
||||
}
|
||||
delay(5000)
|
||||
}.also {
|
||||
timer = it
|
||||
}
|
||||
}
|
||||
|
||||
private fun stop() {
|
||||
timer?.cancel()
|
||||
}
|
||||
|
||||
private fun getApi(): IVideoLiveUrlApi? {
|
||||
return MoGoRetrofitFactory.getInstanceNoCallAdapter(HostConst.getHost()).create(IVideoLiveUrlApi::class.java)
|
||||
}
|
||||
}
|
||||
@@ -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')
|
||||
|
||||
@@ -216,7 +216,12 @@ class StartAutoPilotStatusView @JvmOverloads constructor(
|
||||
if (isAnyOneError) R.drawable.icon_no_fsm_status_bg_error
|
||||
else R.drawable.icon_no_fsm_status_bg_normal
|
||||
)
|
||||
notifyStatus(isAnyOneError)
|
||||
if (!hasFSM.get()) {
|
||||
notifyStatus(isAnyOneError)
|
||||
Logger.d(TAG, "--- handleWithoutFSM --- do update")
|
||||
} else {
|
||||
Logger.d(TAG, "--- handleWithoutFSM --- do not update")
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyStatus(isError: Boolean) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.iflytek.cloud.RecognizerListener
|
||||
import com.iflytek.cloud.RecognizerResult
|
||||
import com.iflytek.cloud.SpeechError
|
||||
import com.iflytek.cloud.SpeechRecognizer
|
||||
import com.mogo.commons.env.ProjectUtils
|
||||
import com.mogo.commons.storage.SharedPrefsMgr
|
||||
import com.mogo.eagle.core.data.app.AppConfigInfo
|
||||
import com.mogo.eagle.core.data.deva.report.CategoryInfo
|
||||
@@ -173,7 +174,9 @@ class FaultReasonView @JvmOverloads constructor(
|
||||
iconDown?.setBounds(0, 0, iconDown.minimumWidth, iconDown.minimumHeight)
|
||||
iconUp?.setBounds(0, 0, iconUp.minimumWidth, iconUp.minimumHeight)
|
||||
//获取一级分类
|
||||
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId, 1, 0, type, 0)
|
||||
if(ProjectUtils.isSaas()){
|
||||
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId, 1, 0, type, 0)
|
||||
}
|
||||
//弹窗展示时间
|
||||
tvFaultTime.text =
|
||||
millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
|
||||
@@ -538,7 +541,9 @@ class FaultReasonView @JvmOverloads constructor(
|
||||
|
||||
override fun getCategoriesError(msg: String) {
|
||||
super.getCategoriesError(msg)
|
||||
ToastUtils.showShort("故障列表获取失败:$msg")
|
||||
if(ProjectUtils.isSaas()){
|
||||
ToastUtils.showShort("故障列表获取失败:$msg")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
@@ -546,7 +551,9 @@ class FaultReasonView @JvmOverloads constructor(
|
||||
if(visibility == View.VISIBLE){
|
||||
CallerDevaToolsListenerManager.addListener(TAG, this)
|
||||
//获取一级分类
|
||||
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId, 1, 0, type, 0)
|
||||
if(ProjectUtils.isSaas()){
|
||||
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId, 1, 0, type, 0)
|
||||
}
|
||||
//弹窗展示时间
|
||||
tvFaultTime.text =
|
||||
millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
|
||||
|
||||
@@ -191,6 +191,8 @@ class ReportTypeView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
oneClickTimer?.start()
|
||||
//请求一键上报故障码
|
||||
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,level,0,4,1)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,9 +298,11 @@ class ReportTypeView @JvmOverloads constructor(
|
||||
Log.i(TAG,"onAutopilotStatistics status = "+ it.status)
|
||||
if(it.status == AutopilotStatistics.AUTOPILOT_START_STATUS.FAILED){
|
||||
//触发一键上报
|
||||
ThreadUtils.runOnUiThread {
|
||||
if(!typeSelectStatus){
|
||||
showOneCLickReportView()
|
||||
if(ProjectUtils.isSaas()){
|
||||
ThreadUtils.runOnUiThread {
|
||||
if(!typeSelectStatus){
|
||||
showOneCLickReportView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener
|
||||
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.FUNC_MODE_DEMO
|
||||
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.FUNC_MODE_RAIN
|
||||
import com.mogo.eagle.core.function.api.setting.ISopSettingListener
|
||||
import com.mogo.eagle.core.function.api.telematic.IReceivedMsgListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager
|
||||
@@ -41,6 +42,7 @@ import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.function.call.obu.CallerObuApiManager
|
||||
import com.mogo.eagle.core.function.call.setting.CallerSopSettingManager
|
||||
import com.mogo.eagle.core.function.call.telematic.CallerTelematicListenerManager
|
||||
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
|
||||
import com.mogo.eagle.core.function.call.unmanned.CallerUnmannedListenerManager
|
||||
import com.mogo.eagle.core.function.call.vehicle.CallerSweeperModeListenerManager
|
||||
@@ -59,11 +61,13 @@ import com.mogo.eagle.core.utilcode.mogo.logger.Logger
|
||||
import com.mogo.eagle.core.utilcode.mogo.vehicle.SweeperVehicleConfigUtils
|
||||
import com.mogo.eagle.core.utilcode.rv.divider.CommonDividerItemDecoration
|
||||
import com.mogo.eagle.core.utilcode.util.AppStateManager
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils.*
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.zhjt.mogo.adas.data.AdasConstants
|
||||
import com.zhjt.mogo.adas.data.bean.AdasParam
|
||||
import kotlinx.android.synthetic.main.layout_operate_panel.view.iv_operate_panel_close
|
||||
import kotlinx.android.synthetic.main.layout_operate_panel_preference_widget_switch_compat.switchWidget
|
||||
import kotlinx.coroutines.launch
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
import mogo.telematics.pad.MessagePad
|
||||
@@ -669,9 +673,10 @@ class OperatePanelLayout : LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
class BusinessPreferenceFragmentCompat : OperatePanelDetailBase() {
|
||||
class BusinessPreferenceFragmentCompat : OperatePanelDetailBase(), IReceivedMsgListener {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "BusinessPreferenceFragmentCompat"
|
||||
private const val KEY_FAULT_REPORT_TIP = "fault_report_tip"
|
||||
private const val KEY_LIMIT_SPEED_MARKER = "limit_speed_marker"
|
||||
private const val KEY_WEATHER_EFFECT_SWITCH = "weather_effect_switch"
|
||||
@@ -680,6 +685,22 @@ class OperatePanelLayout : LinearLayout {
|
||||
private const val KEY_UNMANNED_DEMO_PULL_INTERVAL = "unmanned_demo_pull_interval"
|
||||
private const val KEY_SWEEPER_CLOUD_CONTROL = "sweeper_cloud_control"
|
||||
private const val KEY_LOOK_AROUND_360 = "look_around_360"
|
||||
private const val KEY_DRIVE_SEAT_VIDEO_STREAM = "drive_seat_video_stream"
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
CallerTelematicListenerManager.addListener(TAG, this)
|
||||
lifecycleScope.launchWhenResumed {
|
||||
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_DRIVE_SEAT_VIDEO_STREAM)?.also {
|
||||
it.isEnabled = CallerDevaToolsManager.driveSeatVideoProvider()?.requestVideoInfo()?.livePlayUrl?.isNotEmpty() ?: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
CallerTelematicListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
override fun getDefaultVal(pref: Preference): Any? {
|
||||
@@ -758,6 +779,30 @@ class OperatePanelLayout : LinearLayout {
|
||||
return super.onPreferenceClick(preference)
|
||||
}
|
||||
|
||||
override fun onReceivedMsg(type: Int, byteArray: ByteArray) {
|
||||
if (type == TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_RSP) {
|
||||
val s = String(byteArray)
|
||||
clickEventAnalytics("视频流驾驶位开头-RSP->$s", false)
|
||||
lifecycleScope.launchWhenResumed {
|
||||
when(s) {
|
||||
"01" -> {
|
||||
//关闭成功
|
||||
FunctionBuildConfig.isDriveSeatVideoStream = false
|
||||
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_DRIVE_SEAT_VIDEO_STREAM)?.also { changeValue(it, false) }
|
||||
}
|
||||
"11" -> {
|
||||
//打开成功
|
||||
FunctionBuildConfig.isDriveSeatVideoStream = true
|
||||
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_DRIVE_SEAT_VIDEO_STREAM)?.also { changeValue(it, true) }
|
||||
}
|
||||
else -> {
|
||||
//关闭失败或打开失败
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
|
||||
when (preference.key) {
|
||||
KEY_FAULT_REPORT_TIP -> {
|
||||
@@ -848,6 +893,15 @@ class OperatePanelLayout : LinearLayout {
|
||||
clickEventAnalytics("清扫云控业务", isChecked)
|
||||
return true
|
||||
}
|
||||
KEY_DRIVE_SEAT_VIDEO_STREAM -> {
|
||||
val isChecked = newValue as? Boolean ?: false
|
||||
clickEventAnalytics("视频流驾驶位开关", isChecked)
|
||||
val map = HashMap<String, String>()
|
||||
map["open"] = if (isChecked) "1" else "0"
|
||||
map["playUrl"] = CallerDevaToolsManager.driveSeatVideoProvider()?.getLastData()?.livePlayUrl ?: ""
|
||||
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.DRIVE_SEAT_VIDEO_STREAM_REQ, toJson(map).toByteArray())
|
||||
return false
|
||||
}
|
||||
}
|
||||
return super.onPreferenceChange(preference, newValue)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,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
|
||||
@@ -135,6 +136,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
|
||||
@@ -276,6 +279,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
|
||||
@@ -357,7 +361,7 @@ internal class DebugSettingView @JvmOverloads constructor(
|
||||
IMoGoChassisStatesListener,
|
||||
IMoGoSweeperFutianCleanSystemListener,
|
||||
IMoGoObuInfoListener,
|
||||
ISopSettingListener, IViewControlListener, IMoGoCloudListener {
|
||||
ISopSettingListener, IViewControlListener, IMoGoCloudListener, IBindStateChangeListener {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "DebugSettingView"
|
||||
@@ -480,6 +484,7 @@ internal class DebugSettingView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
CallerObuInfoListenerManager.addListener(TAG, this)
|
||||
DevicesManager.addBindStateChangeListener(TAG,this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
@@ -509,7 +514,7 @@ internal class DebugSettingView @JvmOverloads constructor(
|
||||
CallerSopSettingManager.removeListener(TAG)
|
||||
|
||||
CallerHmiViewControlListenerManager.removeListener(TAG)
|
||||
|
||||
DevicesManager.removeBindStateChangeListener(TAG)
|
||||
// 移除 业务配置监听
|
||||
CallerDevaToolsFuncConfigListenerManager.unRegisterDevaToolsFuncConfigListener(
|
||||
FuncBizConfig.FOUNDATION,
|
||||
@@ -1329,6 +1334,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()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2725,4 +2764,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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -681,6 +681,23 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#F0F0F0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvHardwareDeviceBindState"
|
||||
style="@style/DebugSettingText"
|
||||
android:text="硬件服务绑定状态: 未知"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#F0F0F0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvBackgroundOperation"
|
||||
style="@style/DebugSettingText"
|
||||
|
||||
@@ -51,5 +51,12 @@
|
||||
android:title="360环视"
|
||||
android:persistent="false"
|
||||
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
|
||||
<SwitchPreferenceCompat
|
||||
android:key="drive_seat_video_stream"
|
||||
android:layout="@layout/layout_operate_panel_preference_switch_compat"
|
||||
android:title="驾驶位视频流"
|
||||
android:persistent="false"
|
||||
android:enabled="false"
|
||||
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
|
||||
</PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
||||
@@ -448,4 +448,11 @@ object FunctionBuildConfig {
|
||||
@Volatile
|
||||
@JvmField
|
||||
var maxSpeedLimit: Double = 0.0
|
||||
|
||||
/**
|
||||
* 驾驶位视频流开关是否打开-运营面板使用
|
||||
*/
|
||||
@Volatile
|
||||
@JvmField
|
||||
var isDriveSeatVideoStream: Boolean = false
|
||||
}
|
||||
@@ -30,5 +30,16 @@ class TelematicConstant {
|
||||
|
||||
const val V2N_AI_ROAD_SHI_GU = 207
|
||||
// -------------------- For Android Unit Test ------ END ------------
|
||||
|
||||
/**
|
||||
* 驾驶位视频流开关-请求
|
||||
*/
|
||||
const val DRIVE_SEAT_VIDEO_STREAM_REQ = 208
|
||||
|
||||
|
||||
/**
|
||||
* 驾驶位视频流开关-响应
|
||||
*/
|
||||
const val DRIVE_SEAT_VIDEO_STREAM_RSP = 209
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.mogo.eagle.core.function.api.devatools.mofang.*
|
||||
import com.mogo.eagle.core.function.api.devatools.perf.IMoGoCpuUsageProvider
|
||||
import com.mogo.eagle.core.function.api.lookaround.*
|
||||
import com.mogo.eagle.core.function.api.upgrade.*
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider
|
||||
|
||||
/**
|
||||
* 开发套件工具接口
|
||||
@@ -367,4 +368,9 @@ interface IDevaToolsProvider : IProvider {
|
||||
* 接管
|
||||
*/
|
||||
fun takeOver(@TakeOverAnnotation takeOverAnnotation: Int)
|
||||
|
||||
/**
|
||||
* 驾驶位视频流相关业务逻辑提供者
|
||||
*/
|
||||
fun driveSeatVideoProvider(): IDriveSeatVideoProvider
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.mogo.eagle.core.function.api.driver.video
|
||||
|
||||
import android.view.View
|
||||
import com.zhjt.mogo_core_function_devatools.driver.video.vo.VideoUrlData
|
||||
|
||||
interface IDriveSeatVideoProvider {
|
||||
|
||||
/**
|
||||
* 视频直播是否可用
|
||||
* @return true: 可用; false: 不可用
|
||||
*/
|
||||
suspend fun requestVideoInfo(): VideoUrlData?
|
||||
|
||||
/**
|
||||
* 获取司机位视频展示控件
|
||||
*/
|
||||
fun getDriveVideoView(playUrl: String, playCallback: ((Event) -> Unit)? = null): View?
|
||||
|
||||
|
||||
/**
|
||||
* 获取最新的视频数据
|
||||
*/
|
||||
fun getLastData(): VideoUrlData?
|
||||
|
||||
|
||||
sealed class Event {
|
||||
|
||||
object Loading: Event()
|
||||
|
||||
object Playing: Event()
|
||||
|
||||
data class Failed(val msg: String): Event()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.zhjt.mogo_core_function_devatools.driver.video.vo
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
|
||||
@Keep data class VideoUrlData(var cameraType: Int? = null, var livePlayUrl: String? = null)
|
||||
@@ -28,6 +28,7 @@ import com.mogo.eagle.core.function.api.devatools.strict.*
|
||||
import com.mogo.eagle.core.function.api.lookaround.*
|
||||
import com.mogo.eagle.core.function.call.base.CallerBase
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider
|
||||
|
||||
object CallerDevaToolsManager {
|
||||
|
||||
@@ -470,4 +471,8 @@ object CallerDevaToolsManager {
|
||||
fun takeOver(@TakeOverAnnotation takeOverAnnotation: Int) {
|
||||
devaToolsProviderApi?.takeOver(takeOverAnnotation)
|
||||
}
|
||||
|
||||
fun driveSeatVideoProvider(): IDriveSeatVideoProvider? {
|
||||
return devaToolsProviderApi?.driveSeatVideoProvider()
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
package com.mogo.eagle.core.utilcode.mogo
|
||||
|
||||
/**
|
||||
* 取值要与mis后台配置对应上
|
||||
* https://mogogo.zhidaozhixing.com/eagleEye-mis/appInfo/query/all?keyWord=&pageNum=1&pageSize=20
|
||||
*/
|
||||
fun AppIdentityModeUtils.getMisChannelCode(appIdentityMode: String): Int {
|
||||
return when {
|
||||
isTaxi(appIdentityMode) && isPassenger(appIdentityMode) -> 1 // 出租乘客端
|
||||
isTaxi(appIdentityMode) && isDriver(appIdentityMode) -> 2 // 出租司机端
|
||||
|
||||
isBus(appIdentityMode) && isPassenger(appIdentityMode) -> 3 // 公交乘客端
|
||||
isBus(appIdentityMode) && isDriver(appIdentityMode) -> 4 // 公交司机端
|
||||
isBus(appIdentityMode) && isPassenger(appIdentityMode) && isB1(appIdentityMode) -> 3 // B1公交乘客端
|
||||
isBus(appIdentityMode) && isDriver(appIdentityMode) && isB1(appIdentityMode) -> 4 // B1公交司机端
|
||||
|
||||
isBus(appIdentityMode) && isPassenger(appIdentityMode) && isB2(appIdentityMode) -> 17 // B2公交乘客端
|
||||
isBus(appIdentityMode) && isDriver(appIdentityMode) && isB2(appIdentityMode) -> 15 // B2公交司机端
|
||||
|
||||
isCharter(appIdentityMode) && isPassenger(appIdentityMode) -> 8 // 包车乘客端
|
||||
isCharter(appIdentityMode) && isDriver(appIdentityMode) -> 9 // 包车司机端
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ext {
|
||||
gradle_version = '3.5.3'
|
||||
gradle_version = '3.5.4'
|
||||
kotlin_plugin_version = '1.5.30'
|
||||
plugin_version = '10.0.10_mogo'
|
||||
service_chain_version = '5.3.14'
|
||||
|
||||
1
libraries/mogo-hardware-devices/.gitignore
vendored
Normal file
1
libraries/mogo-hardware-devices/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
4
libraries/mogo-hardware-devices/README.md
Normal file
4
libraries/mogo-hardware-devices/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
#### 说明
|
||||
# 硬件设备管理
|
||||
## 目前包含:核销设备(SK87R和Q350)、TTS语音设备、LED屏幕
|
||||
|
||||
39
libraries/mogo-hardware-devices/build.gradle
Normal file
39
libraries/mogo-hardware-devices/build.gradle
Normal file
@@ -0,0 +1,39 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'kotlin-android'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode rootProject.versionCode as int
|
||||
versionName rootProject.versionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
api rootProject.ext.dependencies.serialport
|
||||
}
|
||||
0
libraries/mogo-hardware-devices/consumer-rules.pro
Normal file
0
libraries/mogo-hardware-devices/consumer-rules.pro
Normal file
3
libraries/mogo-hardware-devices/gradle.properties
Normal file
3
libraries/mogo-hardware-devices/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
GROUP=com.mogo.device
|
||||
POM_ARTIFACT_ID=mogo-device
|
||||
VERSION_CODE=1
|
||||
21
libraries/mogo-hardware-devices/proguard-rules.pro
vendored
Normal file
21
libraries/mogo-hardware-devices/proguard-rules.pro
vendored
Normal file
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
<manifest package="com.mogo.support.device"/>
|
||||
@@ -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<String, IBindStateChangeListener> =
|
||||
ConcurrentHashMap()
|
||||
private val verificationAutoListeners: ConcurrentHashMap<String, IVerificationAutoListener> =
|
||||
ConcurrentHashMap()
|
||||
private val speechCx830seListeners: ConcurrentHashMap<String, ISpeechCx830seListener> =
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.mogo.support.device
|
||||
|
||||
//服务绑定状态接口回调
|
||||
interface IBindStateChangeListener {
|
||||
fun onServiceState(state: Int)
|
||||
}
|
||||
@@ -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}
|
||||
* <p>
|
||||
* 当 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
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -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?)
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
// 语音
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user