同步212 版本

This commit is contained in:
lixiaopeng
2022-11-15 19:05:33 +08:00
730 changed files with 31009 additions and 55206 deletions

View File

@@ -2,11 +2,9 @@ package com.mogo.eagle.core.function.autopilot
import android.Manifest.permission
import android.content.Context
import android.util.Log
import androidx.annotation.RequiresPermission
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.autopilot.toAutoPilotLine
import com.mogo.eagle.core.data.autopilot.toRouteInfo
@@ -27,6 +25,7 @@ import com.mogo.eagle.core.function.autopilot.adapter.MoGoAdasListenerImpl
import com.mogo.eagle.core.function.autopilot.adapter.MoGoAdasMsgConnectStatusListenerImpl
import com.mogo.eagle.core.function.autopilot.adapter.MoGoHandAdasMsgManager
import com.mogo.eagle.core.function.autopilot.server.AsyncDataToAutopilotServer
import com.mogo.eagle.core.function.autopilot.telematic.EventListener
import com.mogo.eagle.core.function.autopilot.telematic.IMsgHandler
import com.mogo.eagle.core.function.autopilot.telematic.TeleMsgHandler
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager
@@ -38,6 +37,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.telematic.MogoProtocolMsg
import com.mogo.telematic.MogoProtocolMsg.NORMAL_DATA
import com.mogo.telematic.MogoProtocolMsg.SYNC_MODE_STATUS
@@ -56,6 +56,7 @@ import com.zhjt.service.chain.ChainLog
import com.zhjt.service.chain.TracingConstants
import io.netty.channel.Channel
import mogo.telematics.pad.MessagePad
import java.util.*
import java.util.concurrent.TimeUnit
@@ -71,6 +72,10 @@ class MoGoAutopilotProvider :
private val TAG = "MoGoAutoPilotProvider"
private var mContext: Context? = null
private lateinit var msgHandler: IMsgHandler
private var timer: Timer? = null
@Volatile
private var isInit = false
override val functionName: String
get() = TAG
@@ -82,18 +87,30 @@ class MoGoAutopilotProvider :
// 初始化ADAS 域控制器
CupidLogUtils.setEnableLog(false)
msgHandler = TeleMsgHandler()
// TODO 临时方案根据不同的身份标识连接不同的工控机IP
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {// 司机
// 注册地图采集功能
CallerMapDataCollectorManager.registerOnMapCollectTaskListener(this)
// 配置默认关闭的连接topic
// val messageTypes: MutableSet<MessageType> = HashSet()
// messageTypes.add(MessageType.TYPE_RECEIVE_POINT_CLOUD)
// val subscribeInterfaceOptions = SubscribeInterfaceOptions.newBuilder()
// .setRole(Constants.TERMINAL_ROLE.DRIVER)
// .setType(Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE)
// .setMessageTypes(messageTypes).build()
// "192.168.1.102"
val options = AdasOptions.Builder()
.setIpcConnectionMode(AdasOptions.IPC_CONNECTION_MODE.FIXATION)
.setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(mContext))
.setClient(false)
// .setSubscribeInterfaceOptions(subscribeInterfaceOptions)//
.build()
AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl())
//////////////////////////////////注意先后顺序AdasManager.getInstance().create后才可以设置监听/////////////////////////////////////////////
// 监听ADAS-SDK获取到的工控机数据
AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl())
NSDNettyManager.getInstance().startNSDNettyServerWithSN(context, object :
NettyServerListener<MogoProtocolMsg> {
override fun onMessageResponseServer(msg: MogoProtocolMsg?, channel: Channel?) {
@@ -102,11 +119,25 @@ class MoGoAutopilotProvider :
override fun onStartServer() {
ToastUtils.showShort("司机端服务启动成功!")
if (timer == null) {
timer = Timer()
}
// 10s同步一次数据到乘客屏
timer!!.schedule(object : TimerTask() {
override fun run() {
// 同步是否开启美化模式
setDemoMode(FunctionBuildConfig.isDemoMode)
setIgnoreConditionDraw(FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData)
msgHandler.synMsgToAllClients()
}
}, 1000, 10000)
invokeNettyConnResult("司机端服务启动成功!")
}
override fun onStopServer() {
ToastUtils.showLong("司机端服务停止!")
timer?.cancel()
timer = null
invokeNettyConnResult("司机端服务停止!")
}
@@ -122,45 +153,85 @@ class MoGoAutopilotProvider :
}
}, MoGoAiCloudClientConfig.getInstance().sn)
} else {
// 乘客端默认接收绘制全局路径+引导线
//FunctionBuildConfig.isDemoMode = true
//FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true
// "192.168.1.103"
val options = AdasOptions
.Builder()
.setClient(true)
.build()
AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl())
NSDNettyManager.getInstance()
.searchAndConnectServer(context, MoGoAiCloudClientConfig.getInstance().sn,
AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode),
object : NettyClientListener<MogoProtocolMsg> {
override fun onMessageResponseClient(
msg: MogoProtocolMsg?,
sign: String?,
channel: Channel
) {
// 乘客端收到adas数据直接解析后续分发解析后的数据流程同司机端
msgHandler.handleMsgFromServer(msg, channel)
}
.searchAndConnectServer(context, MoGoAiCloudClientConfig.getInstance().sn,
AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode),
object : NettyClientListener<MogoProtocolMsg> {
override fun onMessageResponseClient(
msg: MogoProtocolMsg?,
sign: String?,
channel: Channel
) {
// 乘客端收到adas数据直接解析后续分发解析后的数据流程同司机端
msgHandler.handleMsgFromServer(msg, channel)
}
override fun onClientStatusConnectChanged(
statusCode: Int,
sign: String?,
channel: Channel
) {
msgHandler.handleClientConnStatus(statusCode, sign, channel)
}
})
override fun onClientStatusConnectChanged(
statusCode: Int,
sign: String?,
channel: Channel
) {
msgHandler.handleClientConnStatus(statusCode, sign, channel)
}
})
}
msgHandler.setListener(object : EventListener {
override fun connectDevice(isSupportMulti: Boolean) {
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
if (!isInit) {
isInit = true
// 转发工控机数据给乘客屏
listenDeviceData()
}
} else {
if (!isInit) {
isInit = true
UiThreadHandler.post {
if (isSupportMulti) {
// 直连工控机
directConnect()
} else {
val options = AdasOptions
.Builder()
.setClient(true)
.build()
AdasManager.getInstance()
.create(options, MoGoAdasMsgConnectStatusListenerImpl())
// 监听ADAS-SDK获取到的工控机数据
AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl())
// 接收司机屏发过来的感知、定位等数据
listenDeviceData()
}
}
}
}
}
})
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
CallerLogger.i("$M_ADAS_IMPL$TAG", "initServer……")
// 同步数据给工控机的服务
AsyncDataToAutopilotServer.INSTANCE.initServer()
// 同步是否开启雨天模式
setRainMode(FunctionBuildConfig.isRainMode)
}
private fun directConnect() {
val options = AdasOptions
.Builder()
.setIpcConnectionMode(AdasOptions.IPC_CONNECTION_MODE.FIXATION)
.setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(mContext))
.setClient(false)// 乘客端直连工控机改为false
.build()
AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl())
//////////////////////////////////注意先后顺序AdasManager.getInstance().create后才可以设置监听/////////////////////////////////////////////
// 监听ADAS-SDK获取到的工控机数据(乘客也需注册)
// 监听ADAS-SDK获取到的工控机数据
AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl())
// 乘客屏监听工控机基础信息回调
if (!AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
}
}
/**
* 司机屏转发工控机发过来的数据,乘客屏接收解析后的数据保持原流程不变
*/
private fun listenDeviceData() {
AdasManager.getInstance().setOnMultiDeviceListener(object : OnMultiDeviceListener {
override fun onForwardingDriverIPCMessage(bytes: ByteArray?) {
if (bytes == null)
@@ -183,18 +254,9 @@ class MoGoAutopilotProvider :
MogoProtocolMsg(NORMAL_DATA, bytes.size, bytes),
null
)
}
});
CallerLogger.i("$M_ADAS_IMPL$TAG", "initServer……")
// 同步数据给工控机的服务
AsyncDataToAutopilotServer.INSTANCE.initServer()
// 同步是否开启美化模式
setDemoMode(FunctionBuildConfig.isDemoMode)
// 同步是否开启雨天模式
setRainMode(FunctionBuildConfig.isRainMode)
})
}
/**
@@ -316,7 +378,17 @@ class MoGoAutopilotProvider :
}
override fun recordPackage(type: Int, id: Int, duration: Int, bduration: Int): Boolean {
return AdasManager.getInstance().startRecordPackage(id,duration, type, bduration)
return AdasManager.getInstance().startRecordPackage(id, duration, type, bduration)
}
override fun recordPackage(
type: Int,
id: Int,
duration: Int,
bduration: Int,
topics: List<String>
): Boolean {
return AdasManager.getInstance().startRecordPackage(id, duration, type, bduration, topics)
}
override fun stopRecord(type: Int, id: Int): Boolean {
@@ -358,7 +430,6 @@ class MoGoAutopilotProvider :
}
/**
* 演示模式(美化模式)设置只限定于鹰眼
* isEnable = true 开启
@@ -367,7 +438,12 @@ class MoGoAutopilotProvider :
override fun setDemoMode(isEnable: Boolean) {
// 同步给乘客端
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
var byteArray = if (isEnable) byteArrayOf(1) else byteArrayOf(0)
val byteArray = if (isEnable) {
"1;${System.currentTimeMillis()}".toByteArray()
} else {
"0;${System.currentTimeMillis()}".toByteArray()
}
// val byteArray = if (isEnable) byteArrayOf(1) else byteArrayOf(0)
if (NSDNettyManager.getInstance().isServerStart) {
NSDNettyManager.getInstance()
.sendMsgToAllClients(
@@ -383,6 +459,29 @@ class MoGoAutopilotProvider :
}
}
override fun setIgnoreConditionDraw(isIgnore: Boolean) {
// 同步给乘客端
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
val byteArray = if (isIgnore) {
"1;${System.currentTimeMillis()}".toByteArray()
} else {
"0;${System.currentTimeMillis()}".toByteArray()
}
if (NSDNettyManager.getInstance().isServerStart) {
NSDNettyManager.getInstance()
.sendMsgToAllClients(
MogoProtocolMsg(
11,
byteArray.size,
byteArray
)
)
} else {
CallerLogger.d("$M_ADAS_IMPL$TAG", "同步美化模式状态时司机端Server未启动")
}
}
}
/**
* 设置工控机演示模式(美化模式)开启、关闭
* isEnable = true 开启
@@ -410,10 +509,82 @@ class MoGoAutopilotProvider :
}
/**
* 获取数据采集录制模式配置列表
* 绕障类功能开关
* isEnable = true 开启
* isEnable = false 关闭
* @return boolean
*/
override fun getBadCaseConfig() {
AdasManager.getInstance().sendRecordDataConfigReq()
override fun sendDetouring(isEnable: Boolean): Boolean {
return if(isEnable){
AdasManager.getInstance().sendDetouring(1)
}else{
AdasManager.getInstance().sendDetouring(0)
}
}
/**
* 变道绕障的目标障碍物速度阈值
* @param speed 速度阈值 m/s
* @return boolean
*/
override fun sendDetouringSpeed(speed: Double): Boolean {
return AdasManager.getInstance().sendDetouringSpeed(speed)
}
/**
* 获取数据采集录制模式配置列表
* @param reqType 0: all, 1:获取当前所有topic列表, 2:配置需要预加载的topic组合
* @param recordType 0:不需要修改内置类型的topic组合, 1:需要修改内置类型的topic组合
* @param topicsNeedToCache
* @return boolean
*/
override fun getBadCaseConfig(reqType: Int,recordType: Int,topicsNeedToCache: List<String>): Boolean{
return AdasManager.getInstance().sendRecordDataConfigReq(reqType, recordType, topicsNeedToCache)
}
/**
* 向左变道
*/
override fun sendOperatorChangeLaneLeft() {
AdasManager.getInstance().sendOperatorCmdChangeLaneLeft()
}
/**
* 向右变道
*/
override fun sendOperatorChangeLaneRight() {
AdasManager.getInstance().sendOperatorCmdChangeLaneRight()
}
/**
* 发送设置加速度 acc>0加速 acc<0减速 acc=0复位
*/
override fun sendOperatorSetAcceleratedSpeed(cc: Double) {
AdasManager.getInstance().sendOperatorCmdSetAcceleratedSpeed(cc)
}
/**
* 鸣笛 value 1: honk 2: stop honking
*/
override fun sendOperatorSetHorn(value: Double) {
AdasManager.getInstance().sendOperatorCmdSetHorn(value)
}
/**
* 发生行程相关
* type=1或2的时 需要参数 lineName
* type=3或4的时 需要参数 lineName departureStopName arrivalStopName isLastStop
* type=5时 不需要任何参数
*
* @param type 事件类型, 1:行程开始, 2:行程结束, 3:出站, 4:进站, 5:城市占道施工预警
* @param lineName 路线名
* @param departureStopName 出站站点名
* @param arrivalStopName 下一站到达站点名
* @param isLastStop 是否最终站
* @return boolean
*/
override fun sendTripInfo(type: Int, lineName: String, departureStopName: String,arrivalStopName: String, isLastStop: Boolean) {
AdasManager.getInstance().sendTripInfoReq(type, lineName, departureStopName,arrivalStopName, isLastStop)
}
/**
@@ -433,7 +604,10 @@ class MoGoAutopilotProvider :
if (isEnable) {
AdasManager.getInstance().sendAutoPilotModeReq(1, 0, null)
} else {
AdasManager.getInstance().sendAutoPilotModeReq(0, 0, null)
// 司机屏才可关闭自动驾驶
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
AdasManager.getInstance().sendAutoPilotModeReq(0, 0, null)
}
}
}
@@ -506,11 +680,23 @@ class MoGoAutopilotProvider :
}
override fun onAutopilotCarConfig(carConfigResp: MessagePad.CarConfigResp) {
// 乘客屏才监听
AppConfigInfo.plateNumber = carConfigResp.plateNumber
CallerBindingcarManager.getBindingcarProvider()
.getBindingcarInfo(carConfigResp.macAddress, MoGoAiCloudClientConfig.getInstance().sn)
invokeNettyConnResult("乘客屏车牌号:${carConfigResp.plateNumber},Mac地址为${carConfigResp.macAddress}")
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
if (!isInit) {
isInit = true
if (carConfigResp.dockVersion.contains("2.3.0")) {// 不支持多连接
// 司机屏转发工控机发过来的数据
listenDeviceData()
}
}
msgHandler.synMsgToAllClients()
} else {// 乘客屏
CallerBindingcarManager.getBindingcarProvider()
.getBindingcarInfo(
carConfigResp.macAddress,
MoGoAiCloudClientConfig.getInstance().sn
)
invokeNettyConnResult("乘客屏车牌号:${carConfigResp.plateNumber},Mac地址为${carConfigResp.macAddress}")
}
}
@ChainLog(
@@ -530,7 +716,6 @@ class MoGoAutopilotProvider :
}
override fun sendStatusQueryReq() {
Log.d(TAG, "---- sendStatusQueryReq ----")
AdasManager.getInstance().sendStatusQueryReq()
}
}

View File

@@ -1,7 +1,7 @@
package com.mogo.eagle.core.function.autopilot.adapter
import android.util.*
import chassis.VehicleStateOuterClass
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HdMapBuildConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ARRIVE
@@ -14,6 +14,7 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_C
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_VEHICLE
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_CONFIG
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_STATE
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_MESSAGE_PLANNING_ACTIONS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_MESSAGE_PLANNING_OBJECTS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_MESSAGE_RECT_DATA
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_ADAS_STATUS_QUERY_RESP
@@ -22,6 +23,7 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LO
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_DATA_TRACKED
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_GNSSINFO
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_ACTIONS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_WEB_SOCKET_TRAJECTORY
@@ -33,21 +35,28 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutopilotGuardian
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutopilotSNRequest
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutopilotStatusRespByQuery
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager.invokeAutopilotAbility
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager.invokeAutopilotCarConfigData
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarStatusListenerManager.invokeAutopilotCarStateData
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager.invokeAutopilotIdentifyDataUpdate
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager.invokeAutopilotIdentifyPlanningObj
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager.invokeAutopilotWarnMessage
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningActionsListenerManager.invokePNCActions
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager.invokeAutopilotRotting
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager.invokeAutopilotTrajectory
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPointCloudListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager.invokeAutopilotRecordConfig
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager.invokeAutopilotRecordResult
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotStatisticsListenerManager.invokeAutopilotStatistics
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotVehicleStateListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerStartAutopilotFailedListenerManager.invokeStartAutopilotFailed
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.network.utils.*
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.zhidao.support.adas.high.AdasManager
import com.zhidao.support.adas.high.OnAdasListener
import com.zhidao.support.adas.high.bean.AutopilotAbility
import com.zhidao.support.adas.high.bean.AutopilotStatistics
import com.zhidao.support.adas.high.common.ProtocolStatus
import com.zhjt.service.chain.ChainLog
import com.zhjt.service.chain.TracingConstants.Endpoint.Companion.PAD
@@ -57,7 +66,6 @@ import mogo_msg.MogoReportMsg
import perception.TrafficLightOuterClass
import prediction.Prediction
import record_cache.RecordPanelOuterClass
import rule_segement.MogoPointCloudOuterClass
import system_master.SystemStatusInfo
/**
@@ -75,12 +83,12 @@ class MoGoAdasListenerImpl : OnAdasListener {
//车前引导线
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_TRAJECTORY,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_TRAJECTORY,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_TRAJECTORY,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_TRAJECTORY,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onTrajectory(header: MessagePad.Header, trajectory: MessagePad.Trajectory?) {
if (HdMapBuildConfig.isMapLoaded) {
@@ -92,16 +100,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//感知物体
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA_TRACKED,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_RECT_DATA,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_DATA_TRACKED,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_RECT_DATA,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onTrackedObjects(
header: MessagePad.Header,
trackedObjects: MessagePad.TrackedObjects
header: MessagePad.Header,
trackedObjects: MessagePad.TrackedObjects
) {
if (HdMapBuildConfig.isMapLoaded) {
invokeAutopilotIdentifyDataUpdate(trackedObjects.objsList as List<TrackedObject>?)
@@ -110,12 +118,12 @@ class MoGoAdasListenerImpl : OnAdasListener {
//自车定位信息
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_GNSSINFO,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_STATE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_GNSSINFO,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_STATE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onGnssInfo(header: MessagePad.Header, gnssInfo: MessagePad.GnssInfo?) {
invokeAutopilotCarStateData(gnssInfo)
@@ -125,9 +133,9 @@ class MoGoAdasListenerImpl : OnAdasListener {
CallerMapUIServiceManager.getMapUIController()?.syncLocation2Map(gnssInfo)
// 同步更新经纬度和系统时间至 AutoPilotStatusListener
CallerAutoPilotStatusListenerManager.updateAutoPilotLatLon(
gnssInfo.satelliteTime,
gnssInfo.longitude,
gnssInfo.latitude
gnssInfo.satelliteTime,
gnssInfo.longitude,
gnssInfo.latitude
)
}
}
@@ -135,16 +143,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//自车状态(底盘),车灯等。
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_VEHICLE,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_VEHICLE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_VEHICLE,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_VEHICLE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onVehicleState(
header: MessagePad.Header,
vehicleState: VehicleStateOuterClass.VehicleState?
header: MessagePad.Header,
vehicleState: VehicleStateOuterClass.VehicleState?
) {
if (vehicleState != null) {
@@ -170,16 +178,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//自动驾驶状态
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_STATUS,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_STATUS,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onAutopilotState(
header: MessagePad.Header,
autopilotState: MessagePad.AutopilotState?
header: MessagePad.Header,
autopilotState: MessagePad.AutopilotState?
) {
if (autopilotState != null) {
//工控机模拟时间
@@ -203,7 +211,11 @@ class MoGoAdasListenerImpl : OnAdasListener {
}
AdasManager.getInstance().carConfig?.let {
autopilotStatusInfo.dockVersion = it.dockVersion
AppConfigInfo.dockerVersion = it.dockVersion
}
CallerLogger.d("Upgrade", "origin = ${autopilotStatusInfo.connectStatus} -----now = ${AppConfigInfo.isConnectAutopilot} ")
AppConfigInfo.isConnectAutopilot = autopilotStatusInfo.connectStatus
AppConfigInfo.connectStatusDescribe = autopilotStatusInfo.connectStatusDescribe
invokeAutoPilotStatus()
}
}
@@ -211,16 +223,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//监控
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_GUARDIAN,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_GUARDIAN,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onReportMessage(
header: MessagePad.Header,
mogoReportMessage: MogoReportMsg.MogoReportMessage?
header: MessagePad.Header,
mogoReportMessage: MogoReportMsg.MogoReportMessage?
) {
if (HdMapBuildConfig.isMapLoaded) {
invokeAutopilotGuardian(mogoReportMessage)
@@ -229,27 +241,27 @@ class MoGoAdasListenerImpl : OnAdasListener {
//感知红绿灯
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_TRAFFIC_LIGHT,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_TRAFFIC_LIGHT,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onPerceptionTrafficLight(
header: MessagePad.Header?,
trafficLights: TrafficLightOuterClass.TrafficLights?
header: MessagePad.Header?,
trafficLights: TrafficLightOuterClass.TrafficLights?
) {
if (trafficLights != null) {
CallerAutopilotIdentifyListenerManager.invokeAutopilotPerceptionTrafficLight(
trafficLights
trafficLights
)
}
}
override fun onPredictionObstacleTrajectory(
header: MessagePad.Header?,
predictionObjects: Prediction.mPredictionObjects?
header: MessagePad.Header?,
predictionObjects: Prediction.mPredictionObjects?
) {
//他车轨迹预测
}
@@ -267,16 +279,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//planning障碍物
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_PLANNING_OBJECTS,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_PLANNING_OBJECTS,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onPlanningObjects(
header: MessagePad.Header?,
planningObjects: MessagePad.PlanningObjects
header: MessagePad.Header?,
planningObjects: MessagePad.PlanningObjects
) {
if (HdMapBuildConfig.isMapLoaded) {
invokeAutopilotIdentifyPlanningObj(planningObjects.objsList as List<MessagePad.PlanningObject>)
@@ -284,42 +296,45 @@ class MoGoAdasListenerImpl : OnAdasListener {
}
override fun onBasicInfoReq(
header: MessagePad.Header,
basicInfoReq: MessagePad.BasicInfoReq?
header: MessagePad.Header,
basicInfoReq: MessagePad.BasicInfoReq?
) {
invokeAutopilotSNRequest()
}
//工控机基础配置信息
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_CONNECT_STATUS,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_CONFIG,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_CONNECT_STATUS,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_CAR_CONFIG,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onCarConfigResp(
header: MessagePad.Header,
carConfigResp: MessagePad.CarConfigResp?
header: MessagePad.Header,
carConfigResp: MessagePad.CarConfigResp?
) {
if (HdMapBuildConfig.isMapLoaded && carConfigResp != null) {
if (/*HdMapBuildConfig.isMapLoaded &&*/ carConfigResp != null) {
AppConfigInfo.plateNumber = carConfigResp.plateNumber//车牌号
AppConfigInfo.iPCMacAddress = carConfigResp.macAddress//工控机MAC地址
AppConfigInfo.protocolVersionNumber = carConfigResp.protocolVersionValue//工控机协议版本
invokeAutopilotCarConfigData(carConfigResp)
}
}
//全局路径规划
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ROUTE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ROUTE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onGlobalPathResp(
header: MessagePad.Header,
globalPathResp: MessagePad.GlobalPathResp?
header: MessagePad.Header,
globalPathResp: MessagePad.GlobalPathResp?
) {
if (HdMapBuildConfig.isMapLoaded) {
invokeAutopilotRotting(globalPathResp)
@@ -328,16 +343,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//数据采集badCase
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_RECORD,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_RECORD,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onRecordResult(
header: MessagePad.Header,
recordPanel: RecordPanelOuterClass.RecordPanel?
header: MessagePad.Header,
recordPanel: RecordPanelOuterClass.RecordPanel?
) {
if (recordPanel != null) {
invokeAutopilotRecordResult(recordPanel)
@@ -359,16 +374,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//到站回调
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ARRIVE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_AUTOPILOT_ARRIVE,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onArrivalNotification(
header: MessagePad.Header,
arrivalNotification: MessagePad.ArrivalNotification?
header: MessagePad.Header,
arrivalNotification: MessagePad.ArrivalNotification?
) {
if (HdMapBuildConfig.isMapLoaded) {
invokeArriveAtStation(arrivalNotification)
@@ -377,16 +392,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
//状态查询应答
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_STATUS_QUERY_RESP,
paramIndexes = [0, 1],
clientPkFileName = "sn"
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_STATUS_QUERY_RESP,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onStatusQueryResp(
header: MessagePad.Header?,
statusInfo: SystemStatusInfo.StatusInfo?
header: MessagePad.Header?,
statusInfo: SystemStatusInfo.StatusInfo?
) {
invokeAutopilotStatusRespByQuery(statusInfo)
}
@@ -395,13 +410,72 @@ class MoGoAdasListenerImpl : OnAdasListener {
* 数据采集配置应答
*/
override fun onRecordDataConfigResp(
header: MessagePad.Header?,
config: MessagePad.RecordDataConfig?
header: MessagePad.Header?,
config: MessagePad.RecordDataConfig?
) {
if(config!=null){
invokeAutopilotRecordConfig(config)
}
}
/**
* planning决策状态, 透传
*/
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_ACTIONS,
linkCode = CHAIN_LINK_ADAS,
endpoint = PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_ADAS_MESSAGE_PLANNING_ACTIONS,
paramIndexes = [0, 1],
clientPkFileName = "sn"
)
override fun onPlanningActionMsg(
header: MessagePad.Header?,
planningActionMsg: MessagePad.PlanningActionMsg?
) {
planningActionMsg?.let {
invokePNCActions(it)
}
}
/**
* 是否可以启动自动驾驶
* 使用方法查看app_ipc_monitoring/uiMainActivity/onAutopilotAbility
*/
override fun onAutopilotAbility(ability: AutopilotAbility?) {
invokeAutopilotAbility(ability)
}
/**
* 启动自动驾驶失败回调
* 根据MAP 系统监控状态返回过滤
* message.getMsg() 获取详细错误说明
* message.getCode() 可用于判断属于什么类型
*
* @param message 数据
*/
override fun onStartAutopilotFailed(message: MogoReportMsg.MogoReportMessage?) {
invokeStartAutopilotFailed(message);
}
/**
* 启动自动驾驶状态统计
* 触发机制下发启动自动驾驶命令根据MAP返回状态判断成功或失败
* 统计四种状态:成功 失败 取消 超时
*
* @param statistics 统计数据
*/
override fun onAutopilotStatistics(statistics: AutopilotStatistics?) {
invokeAutopilotStatistics(statistics);
}
/**
* 数据解析失败、数据异常回调
* @param status 错误原因
* @param bytes 原始数据
*/
override fun onError(status: ProtocolStatus, bytes: ByteArray) {
}

View File

@@ -2,7 +2,7 @@ package com.mogo.eagle.core.function.autopilot.adapter
import android.annotation.SuppressLint
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.debug.DebugConfig
import com.mogo.commons.debug.DebugConfig.*
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
@@ -11,6 +11,7 @@ import com.mogo.eagle.core.function.autopilot.network.AdasServiceModel
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_ADAS_IMPL
import com.mogo.eagle.core.utilcode.util.ToastUtils
@@ -18,11 +19,12 @@ import com.zhidao.support.adas.high.AdasManager
import com.zhidao.support.adas.high.OnAdasConnectStatusListener
import com.zhidao.support.adas.high.bean.VersionCompatibility
import com.zhidao.support.adas.high.common.Constants
import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import com.zhidao.support.adas.high.common.Constants.ENVIRONMENT.*
import com.zhidao.support.adas.high.common.Constants.TERMINAL_ROLE.DRIVER
import com.zhidao.support.adas.high.common.Constants.TERMINAL_ROLE.PASSENGER
import mogo.telematics.pad.MessagePad
import java.util.concurrent.TimeUnit
import java.util.*
import java.util.concurrent.atomic.*
/**
* ADAS-SDK与工控机连接状态回调
@@ -39,6 +41,10 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
private var connectStatus = false
private val hasUploadTaskLaunched by lazy { AtomicBoolean(false) }
private val timer = Timer()
init {
CallerCloudListenerManager.registerCloudListener(TAG, this)
}
@@ -131,9 +137,41 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
*/
private fun syncBasicInfoToAutopilot(sn: String? = null) {
CallerLogger.d("$M_ADAS_IMPL$TAG", "同步PAD的SN给工控机……")
// 设置PAD-SN给工控,网络环境
AdasManager.getInstance()
.sendBasicInfoResp(MoGoAiCloudClientConfig.getInstance().sn, DebugConfig.getNetMode())
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
// 设置PAD-SN给工控,网络环境
AdasManager.getInstance()
.sendBasicInfoResp(
MoGoAiCloudClientConfig.getInstance().sn,
getEnvironment(),
getTerminalRole()
)
} else {
// 乘客屏先不传sn
AdasManager.getInstance()
.sendBasicInfoResp(
"",
getEnvironment(),
getTerminalRole()
)
}
}
private fun getEnvironment(): Int {
return when (getNetMode()) {
NET_MODE_DEV -> DEVELOP
NET_MODE_QA -> TEST
NET_MODE_RELEASE -> PRODUCTION
NET_MODE_DEMO -> DEMO
else -> PRODUCTION
}
}
private fun getTerminalRole(): Int {
return when {
AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) -> DRIVER
AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) -> PASSENGER
else -> DRIVER
}
}
/**
@@ -141,15 +179,16 @@ class MoGoAdasMsgConnectStatusListenerImpl : OnAdasConnectStatusListener,
*/
@SuppressLint("CheckResult")
private fun updateDriveStatusTask() {
CallerLogger.d("$M_ADAS_IMPL$TAG", "updateDriveStatusTask")
Flowable.interval(0, 5, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
AdasServiceModel.getInstance()
.updateDriveStatus(mCurrentAutopilotStatus, mCurrentAutopilotSpeed)
}
if (hasUploadTaskLaunched.compareAndSet(false, true)) {
timer.schedule(object : TimerTask() {
override fun run() {
CallerLogger.d("$M_ADAS_IMPL$TAG", "updateDriveStatusTask")
AdasServiceModel.getInstance()
.updateDriveStatus(mCurrentAutopilotStatus, mCurrentAutopilotSpeed)
}
}, 0, 5000)
}
}
override fun tokenGot(sn: String) {

View File

@@ -12,6 +12,7 @@ import com.mogo.eagle.core.data.constants.MoGoConfig;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotVehicleStateListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotVehicleStateListenerManager;
@@ -60,6 +61,15 @@ public class MoGoHandAdasMsgManager implements
private int brakeLight = -1;
public void getConfig() {
com.elegant.utils.UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
CallerAutoPilotManager.INSTANCE.getCarConfig();
}
}, 0);
}
private int setTurnLightState(int turn_light) {
if (turn_light == 0) {
if (isOnTurnLight) {
@@ -106,6 +116,7 @@ public class MoGoHandAdasMsgManager implements
@Override
public void onAutopilotCarConfig(@NotNull MessagePad.CarConfigResp carConfigResp) {
if (carConfigResp != null && !TextUtils.isEmpty(carConfigResp.getMacAddress())) {
Log.d("Upgrade", "MoGoHandAdasMsgManager address = " + carConfigResp.getMacAddress());
CallerBindingcarManager.getBindingcarProvider().getBindingcarInfo(carConfigResp.getMacAddress(), MoGoAiCloudClientConfig.getInstance().getSn());
}
}
@@ -166,4 +177,5 @@ public class MoGoHandAdasMsgManager implements
public void onAutopilotBrake(float brake) {
}
}

View File

@@ -3,7 +3,7 @@ package com.mogo.eagle.core.function.autopilot.server
import com.mogo.eagle.core.data.trafficlight.TrafficLightResult
import com.mogo.eagle.core.function.api.trafficlight.IMoGoTrafficLightListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.trafficlight.CallTrafficLightListenerManager
import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager
/**
* @author xiaoyuzhou
@@ -22,7 +22,7 @@ class AsyncDataToAutopilotServer private constructor() : IMoGoTrafficLightListen
}
fun initServer() {
CallTrafficLightListenerManager.registerTrafficLightListener(TAG, this)
CallerTrafficLightListenerManager.registerTrafficLightListener(TAG, this)
}
override fun onTrafficLightStatus(trafficLightResult: TrafficLightResult) {

View File

@@ -0,0 +1,5 @@
package com.mogo.eagle.core.function.autopilot.telematic
interface EventListener {
fun connectDevice(isSupportMulti: Boolean)
}

View File

@@ -17,4 +17,8 @@ interface IMsgHandler {
fun synWriteTime()
fun getTeleTimeStamp(): Long
fun synMsgToAllClients()
fun setListener(eventListener: EventListener?)
}

View File

@@ -1,6 +1,5 @@
package com.mogo.eagle.core.function.autopilot.telematic
import android.util.Log
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.google.protobuf.TextFormat
@@ -11,8 +10,9 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_CONNECT_STATUS
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager.setDemoMode
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager.setIgnoreConditionDraw
import com.mogo.eagle.core.function.call.bindingcar.CallerBindingcarManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.telematic.MogoProtocolMsg
@@ -40,6 +40,14 @@ class TeleMsgHandler : IMsgHandler {
@Volatile
private var isReceiveSN = false
@Volatile
private var demoModeTime = 0L
@Volatile
private var timestamp = 0L
private var listener: EventListener? = null
override fun handleMsgFromServer(msg: MogoProtocolMsg?, channel: Channel?) {
msg?.let {
when (it.protocolType) {
@@ -56,32 +64,67 @@ class TeleMsgHandler : IMsgHandler {
}
}
MogoProtocolMsg.SYNC_MODE_STATUS -> {
FunctionBuildConfig.isDemoMode = when (it.body[0].toInt()) {
1 -> true
else -> false
val content = String(it.body)
if (content.contains(";")) {
val strArr = content.split(";")
if (strArr.size == 2) {
val currTime = strArr[1].toLong()
if (currTime > demoModeTime) {
FunctionBuildConfig.isDemoMode = when (strArr[0]) {
"1" -> true
else -> false
}
demoModeTime = currTime
invokeNettyConnResult("乘客屏收到的美化模式DemoMode为${FunctionBuildConfig.isDemoMode}")
} else {
invokeNettyConnResult("乘客屏收到过时的美化模式DemoMode为${FunctionBuildConfig.isDemoMode}")
}
}
}
setDemoMode(FunctionBuildConfig.isDemoMode)
}
MogoProtocolMsg.REQ_MAC_ADDRESS -> {
val carConfig = MessagePad.CarConfigResp.parseFrom(msg.body)
AppConfigInfo.plateNumber = carConfig.plateNumber
AppConfigInfo.iPCMacAddress = carConfig.macAddress
AppConfigInfo.dockerVersion = carConfig.dockVersion
listener?.connectDevice(!carConfig.dockVersion.contains("2.3.0"))
invokeNettyConnResult(
"司机屏发送给乘客屏配置信息为:${
TextFormat.printer().escapingNonAscii(false).printToString(carConfig)
}"
)
// Log.d("liyz", "TeleMsgHandler macAddress = " + carConfig.macAddress)
CallerBindingcarManager.getBindingcarProvider().getBindingcarInfo(
carConfig.macAddress,
MoGoAiCloudClientConfig.getInstance().sn
)
}
// SN
10 -> {
val sn = String(it.body)
isReceiveSN = true
NettyTcpClient.sSERVER_SN = sn
}
// 美化模式是否忽略条件直接绘制
11 -> {
val content = String(it.body)
if (content.contains(";")) {
val strArr = content.split(";")
if (strArr.size == 2) {
val currTime = strArr[1].toLong()
if (currTime > timestamp) {
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData =
when (strArr[0]) {
"1" -> true
else -> false
}
timestamp = currTime
invokeNettyConnResult("乘客屏收到的美化模式isIgnore为${FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData}")
} else {
invokeNettyConnResult("乘客屏收到过时的美化模式isIgnore为${FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData}")
}
}
}
}
else -> {
}
}
@@ -94,6 +137,7 @@ class TeleMsgHandler : IMsgHandler {
MogoProtocolMsg.REQ_MAC_ADDRESS -> {
val carConfig = AdasManager.getInstance().carConfig
if (carConfig != null) {
listener?.connectDevice(!carConfig.dockVersion.contains("2.3.0"))
val configArray = carConfig.toByteArray()
NSDNettyManager.getInstance().sendMsgToSpecifiedClient(
@@ -139,17 +183,8 @@ class TeleMsgHandler : IMsgHandler {
override fun handleClientConn2Server(channel: Channel?) {
val socketAddress = channel?.remoteAddress().toString()
CallerLogger.d("${SceneConstant.M_ADAS_IMPL}$TAG", "Client ip is:${socketAddress}")
val byteArray =
if (FunctionBuildConfig.isDemoMode) byteArrayOf(1) else byteArrayOf(0)
NSDNettyManager.getInstance().sendMsgToSpecifiedClient(
MogoProtocolMsg(
MogoProtocolMsg.SYNC_MODE_STATUS,
byteArray.size,
byteArray
), channel
) {
CallerLogger.d("${SceneConstant.M_ADAS_IMPL}$TAG", "同步美化模式状态是否成功:${it.isSuccess}")
}
setDemoMode(FunctionBuildConfig.isDemoMode)
setIgnoreConditionDraw(FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData)
}
override fun handleClientConnStatus(statusCode: Int, content: String?, channel: Channel) {
@@ -162,7 +197,7 @@ class TeleMsgHandler : IMsgHandler {
if (isReceiveSN) {
isReceiveSN = false
}
AdasManager.getInstance().startDispatchHandler()
// AdasManager.getInstance().startDispatchHandler()
ToastUtils.showShort("连接司机屏成功!")
invokeNettyConnResult("乘客屏连接司机屏成功")
val byteArray = byteArrayOf(0)
@@ -223,6 +258,10 @@ class TeleMsgHandler : IMsgHandler {
return wrTimeStamp
}
override fun setListener(eventListener: EventListener?) {
listener = eventListener
}
private fun reqServerSN() {
if (NettyTcpClient.sSERVER_SN.isNullOrEmpty()) {
ProcessLifecycleOwner.get().lifecycleScope.launch {
@@ -242,4 +281,20 @@ class TeleMsgHandler : IMsgHandler {
}
}
}
override fun synMsgToAllClients() {
if (NSDNettyManager.getInstance().isServerStart) {
val carConfig = AdasManager.getInstance().carConfig
if (carConfig != null) {
val configArray = carConfig.toByteArray()
NSDNettyManager.getInstance().sendMsgToAllClients(
MogoProtocolMsg(
MogoProtocolMsg.REQ_MAC_ADDRESS,
configArray.size, configArray
)
)
}
}
}
}

View File

@@ -0,0 +1,26 @@
package com.mogo.eagle.core.function
import com.mogo.commons.debug.DebugConfig
/**
* cmdb 域名
*/
class BindHostConst {
companion object {
private const val UPGRADE_APP_HOST_DEV = "https://eagle-qa.zhidaozhixing.com/"
private const val UPGRADE_APP_HOST = "http://eagle-mis.zhidaozhixing.com/"
@JvmStatic
fun getBaseUrl(): String {
return when (DebugConfig.getNetMode()) {
DebugConfig.NET_MODE_DEV -> UPGRADE_APP_HOST_DEV
DebugConfig.NET_MODE_QA -> UPGRADE_APP_HOST_DEV
DebugConfig.NET_MODE_DEMO -> UPGRADE_APP_HOST
DebugConfig.NET_MODE_RELEASE -> UPGRADE_APP_HOST
else -> UPGRADE_APP_HOST
}
}
}
}

View File

@@ -11,7 +11,7 @@ import retrofit2.http.Query;
/**
* @author lixiaopeng
* @description 绑定车辆
* @description 升级
* @since: 6/20/22
*/
public interface UpgradeApiService {
@@ -21,7 +21,8 @@ public interface UpgradeApiService {
* @return {@link UpgradeAppInfo}
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("unify/selectResources")
Observable<UpgradeAppInfo> getUpgradeInfo(@Query("resources") String res, @Body RequestBody requestBody);
@POST("eagleEye-mis/config/versionInfo")
// Observable<UpgradeAppInfo> getUpgradeInfo(@Query("resources") String res, @Body RequestBody requestBody);
Observable<UpgradeAppInfo> getUpgradeInfo(@Body RequestBody requestBody);
}

View File

@@ -1,23 +1,17 @@
package com.mogo.eagle.core.function.appupgrade.network;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BINDING;
import android.content.Context;
import android.util.Log;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.commons.constants.SharedPrefsConstants;
import com.mogo.eagle.core.data.bindingcar.BindingcarInfo;
import com.mogo.eagle.core.data.bindingcar.ModifyBindingcarInfo;
import com.mogo.eagle.core.data.bindingcar.UpgradeAppInfo;
import com.mogo.eagle.core.function.api.bindingcar.BindingcarCallBack;
import com.mogo.eagle.core.function.BindHostConst;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.network.MoGoRetrofitFactory;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.eagle.core.utilcode.util.AppUtils;
import com.mogo.eagle.core.utilcode.util.GsonUtils;
import com.mogo.module.common.constants.HostConst;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -35,11 +29,11 @@ import okhttp3.RequestBody;
public class UpgradeAppNetWorkManager {
private static volatile UpgradeAppNetWorkManager requestNoticeManager;
private final UpgradeApiService mUpgradeApiService;
private static final String TAG = "UpgradeAppNetWorkManager";
private static final String TAG = "Upgrade";
private UpgradeAppNetWorkManager() {
mUpgradeApiService = MoGoRetrofitFactory.getInstance(HostConst.UPGRADE_APP_HOST)
mUpgradeApiService = MoGoRetrofitFactory.getInstance(BindHostConst.getBaseUrl())
.create(UpgradeApiService.class);
}
@@ -58,18 +52,15 @@ public class UpgradeAppNetWorkManager {
/**
* 获取app升级信息
*/
public void getAppUpgradeInfo(Context context, String screenType, String carType) {
String sn = "X20202203105S688HZ";
// int versionCode = 2070000;
// String versionName = "2.7.0";
// String sn = MoGoAiCloudClientConfig.getInstance().getSn();
public void getAppUpgradeInfo(Context context, String mac, String screenType) {
// String sn = "X20202203105S688HZ";
// String mac = "48:b0:2d:3a:bc:78";
String sn = MoGoAiCloudClientConfig.getInstance().getSn();
int versionCode = AppUtils.getAppVersionCode();
String versionName = AppUtils.getAppVersionName();
UpgradeAppRequest request = new UpgradeAppRequest(sn, versionCode, versionName, screenType, carType);
CallerLogger.INSTANCE.d(M_BINDING + TAG, "getAppUpgradeInfo mac = " + mac + "---type = " + screenType + "---sn = " + sn + "---versionCode =" + versionCode);
UpgradeAppRequest request = new UpgradeAppRequest(sn, mac, screenType);
RequestBody requestBody = RequestBody.create(MediaType.get("application/json;charset=UTF-8"), GsonUtil.jsonFromObject(request));
mUpgradeApiService.getUpgradeInfo("apps_control", requestBody)
mUpgradeApiService.getUpgradeInfo(requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<UpgradeAppInfo>() {
@@ -79,18 +70,19 @@ public class UpgradeAppNetWorkManager {
@Override
public void onNext(@NonNull UpgradeAppInfo info) {
if (info != null && info.getData() != null && info.getData().size() > 0) {
CallerLogger.INSTANCE.d(TAG, "UpgradeAppInfo url = " + info.getData().get(0).getApp_url() + "----code = " + info.getData().get(0).getVersion_code());
// if (info.getData().get(0).getVersion_code() > versionCode) {
CallerHmiManager.INSTANCE.showUpgradeDialog(info.getData().get(0).getApp_url().substring(info.getData().get(0).getApp_url().lastIndexOf("/")+1), info.getData().get(0).getApp_url());
// }
if (info != null && info.result != null) {
CallerLogger.INSTANCE.d(M_BINDING + TAG, "UpgradeAppInfo url = " + info.result.getAppUrl() + "----code = " + info.result.getVersionCode() + "--versionCode =" + versionCode + "--info.result = " + info.result);
if (info.result.getVersionCode() > versionCode) {
CallerHmiManager.INSTANCE.showUpgradeDialog(info.result.getAppUrl().substring(info.result.getAppUrl().lastIndexOf("/")+1), info.result.getAppUrl(), info.result.getInstallTitle(), info.result.getInstallContent(), info.result.getInstallType());
}
} else {
CallerLogger.INSTANCE.d(M_BINDING + TAG, "UpgradeAppInfo onNext info == null");
}
}
@Override
public void onError(@NonNull Throwable e) {
CallerLogger.INSTANCE.e(TAG, "UpgradeAppInfo onError e = " + e.toString() + "---e.getMessage = " + e.getMessage());
public void onError(Throwable e) {
}
@Override

View File

@@ -6,18 +6,15 @@ package com.mogo.eagle.core.function.appupgrade.network;
* @since: 11/15/21
*/
public class UpgradeAppRequest {
private String mac;
private String sn;
private int version_code;
private String version_name;
private String screen_type;
private String car_type;
private String screenType;
public UpgradeAppRequest( String sn, int versionCode, String versionName, String type, String carType) {
public UpgradeAppRequest( String sn, String mac, String screenType) {
this.sn = sn;
this.version_code = versionCode;
this.version_name = versionName;
this.screen_type = type;
this.car_type = carType;
this.mac = mac;
this.screenType = screenType;
}
public String getSn() {
@@ -28,46 +25,20 @@ public class UpgradeAppRequest {
this.sn = sn;
}
public int getVersion_code() {
return version_code;
public String getMac() {
return mac;
}
public void setVersion_code(int version_code) {
this.version_code = version_code;
public void setMac(String mac) {
this.mac = mac;
}
public String getVersion_name() {
return version_name;
public String getScreenType() {
return screenType;
}
public void setVersion_name(String version_name) {
this.version_name = version_name;
public void setScreenType(String screenType) {
this.screenType = screenType;
}
public String getScreen_type() {
return screen_type;
}
public void setScreen_type(String screen_type) {
this.screen_type = screen_type;
}
public String getCar_type() {
return car_type;
}
public void setCar_type(String car_type) {
this.car_type = car_type;
}
@Override
public String toString() {
return "UpgradeAppRequest{" +
"sn='" + sn + '\'' +
", version_code=" + version_code +
", version_name='" + version_name + '\'' +
", screen_type='" + screen_type + '\'' +
", car_type='" + car_type + '\'' +
'}';
}
}

View File

@@ -11,6 +11,7 @@ import com.mogo.eagle.core.function.api.bindingcar.BindingcarCallBack;
import com.mogo.eagle.core.function.api.bindingcar.IMoGoBindingcarProvider;
import com.mogo.eagle.core.function.appupgrade.network.UpgradeAppNetWorkManager;
import com.mogo.eagle.core.function.bindingcar.network.BindingcarNetWorkManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.ipcupgrade.IPCUpgradeManager;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
@@ -57,6 +58,7 @@ public class BindingcarProvider implements IMoGoBindingcarProvider {
*/
@Override
public void getBindingcarInfo(String macAddress, String widevineIDWithMd5) {
Log.d("Upgrade", "getBindingcarInfo macAddress = " + macAddress + "--widevineIDWithMd5 = " + widevineIDWithMd5);
mAddress = macAddress;
mWidevineIDWithMd5 = widevineIDWithMd5;
if (getScreenType() == 1) { //司机屏
@@ -116,6 +118,10 @@ public class BindingcarProvider implements IMoGoBindingcarProvider {
}
}
/**
* 以后可能废弃
* @return
*/
private int getScreenType() {
int screenType = -1;
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
@@ -142,12 +148,33 @@ public class BindingcarProvider implements IMoGoBindingcarProvider {
}
private String getCarScreenType() {
String screenType = "";
if(AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
screenType = "1"; //taxi乘客端
}
if(AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
screenType = "2"; //taxi司机端
}
if(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
screenType = "3"; //bus 乘客端
}
if(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
screenType = "4"; //bus 司机端
}
return screenType;
}
/**
* 查询app是否需要升级
*/
@Override
public void queryAppUpgrade() {
UpgradeAppNetWorkManager.getInstance().getAppUpgradeInfo(mContext, String.valueOf(getScreenType()), String.valueOf(getCarType()));
UpgradeAppNetWorkManager.getInstance().getAppUpgradeInfo(mContext, mAddress, getCarScreenType());
}
}

View File

@@ -22,8 +22,8 @@ public interface BindingcarApiService {
* @return {@link BindingcarInfo}
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("pad/selectPadByMac")
Observable<BindingcarInfo> getBindingcarInfo(@Header("access_token") String access_token, @Body RequestBody requestBody);
@POST("eagleEye-mis/cmdbapi/pad/selectPadByMac")
Observable<BindingcarInfo> getBindingcarInfo(/*@Header("access_token") String access_token,*/ @Body RequestBody requestBody);
/**
* 绑定和修改绑定车机
@@ -31,7 +31,7 @@ public interface BindingcarApiService {
* @return {@link ModifyBindingcarInfo}
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("pad/updatePadByMac")
Observable<ModifyBindingcarInfo> modifyBindingcarInfo(@Header("access_token") String access_token, @Body RequestBody requestBody);
@POST("eagleEye-mis/cmdbapi/pad/updatePadByMac")
Observable<ModifyBindingcarInfo> modifyBindingcarInfo(/*@Header("access_token") String access_token,*/ @Body RequestBody requestBody);
}

View File

@@ -6,6 +6,7 @@ import android.util.Log;
import com.mogo.commons.constants.SharedPrefsConstants;
import com.mogo.eagle.core.data.bindingcar.BindingcarInfo;
import com.mogo.eagle.core.data.bindingcar.ModifyBindingcarInfo;
import com.mogo.eagle.core.function.BindHostConst;
import com.mogo.eagle.core.function.api.bindingcar.BindingcarCallBack;
import com.mogo.eagle.core.function.bindingcar.R;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
@@ -34,11 +35,10 @@ import okhttp3.RequestBody;
public class BindingcarNetWorkManager {
private static volatile BindingcarNetWorkManager requestNoticeManager;
private final BindingcarApiService mBindingcarApiService;
private String token = "c4a2f30cebf64972bcd11577e1c07f86"; //中台做了接口适配需要这个token
private static final String TAG = "BindingcarNetWorkManager";
private static final String TAG = "BindingcarNetManager";
private BindingcarNetWorkManager() {
mBindingcarApiService = MoGoRetrofitFactory.getInstance(HostConst.BINDING_SN_HOST)
mBindingcarApiService = MoGoRetrofitFactory.getInstance(BindHostConst.getBaseUrl())
.create(BindingcarApiService.class);
}
@@ -60,11 +60,13 @@ public class BindingcarNetWorkManager {
* @param macAddress mac地址
*/
public void getBindingcarInfo(Context context, String macAddress, String widevineIDWithMd5, int screenType) {
// String macAddress = "48:b0:2d:3a:bc:78";
// String macAddress1 = "48:b0:2d:3a:bc:78";
// String macAddress1 = "48:b0:2d:4d:b9:63";
// String sn = "X20202203105S688HZ";
BindingcarRequest request = new BindingcarRequest(macAddress, widevineIDWithMd5, screenType);
RequestBody requestBody = RequestBody.create(MediaType.get("application/json;charset=UTF-8"), GsonUtil.jsonFromObject(request));
mBindingcarApiService.getBindingcarInfo(token, requestBody)
mBindingcarApiService.getBindingcarInfo(requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BindingcarInfo>() {
@@ -76,6 +78,7 @@ public class BindingcarNetWorkManager {
public void onNext(@NonNull BindingcarInfo info) {
if (info != null && info.getData() != null) {
CallerLogger.INSTANCE.d(TAG, "getBindingcarInfo onNext info.getData() =" + info.getData().toString());
Log.d(TAG, "getBindingcarInfo onNext info.getData() =" + info.getData().toString());
if (info.getData().getCompare().equals("0")) {
CallerHmiManager.INSTANCE.showBindingcarDialog();
} else if (info.getData().getCompare().equals("3")) {
@@ -84,10 +87,12 @@ public class BindingcarNetWorkManager {
TipToast.shortTip("当前工控机没有入库");
}
//根据车辆类型切换不同的车辆模型
//根据车辆类型切换不同的车辆模型,只针对红旗做处理
// if (info.getData().getVendor().equals("一汽红旗")) { //TODO
// CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.xiaobache);
// } else if (info.getData().getVendor().equals("东风")) {
// CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.hq_h9);
// }
// else if (info.getData().getVendor().equals("东风汽车集团")) {
// CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.chuzuche);
// } else if (info.getData().getVendor().equals("金旅星辰")) {
// CallerHDMapManager.INSTANCE.changeCurrentIcon(R.raw.xiaobache);
@@ -118,7 +123,7 @@ public class BindingcarNetWorkManager {
public void modifyBindingcar(String macAddress, String widevineIDWithMd5, BindingcarCallBack callBack, int screenType) {
BindingcarRequest request = new BindingcarRequest(macAddress, widevineIDWithMd5, screenType);
RequestBody requestBody = RequestBody.create(MediaType.get("application/json;charset=UTF-8"), GsonUtil.jsonFromObject(request));
mBindingcarApiService.modifyBindingcarInfo(token, requestBody)
mBindingcarApiService.modifyBindingcarInfo(requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ModifyBindingcarInfo>() {
@@ -130,6 +135,7 @@ public class BindingcarNetWorkManager {
public void onNext(@NonNull ModifyBindingcarInfo info) {
if (info != null) {
callBack.callBackResult(info);
Log.d(TAG, "modifyBindingcar onNext code = " + info.code + "---msg = " + info.msg + "--info.toString() = " + info.toString());
CallerLogger.INSTANCE.d(TAG, "modifyBindingcar onNext code = " + info.code + "---msg = " + info.msg + "--info.toString() = " + info.toString());
}
}

View File

@@ -54,7 +54,7 @@ object VoiceControlFacade: IMoGoVoiceControlFacade, IMogoVoiceCmdCallBack, IMogo
override fun speak(context: Context, content: String, listener: IMoGoVoiceCallback) {
listeners += WeakReference(listener)
AIAssist.getInstance(context).speakTTSVoice(content, this)
AIAssist.getInstance(context).speakTTSVoiceWithLevel(content,AIAssist.LEVEL3 ,this)
}
override fun onCmdSelected(cmd: String?) {

View File

@@ -82,7 +82,6 @@ dependencies {
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.androidxrecyclerview
implementation rootProject.ext.dependencies.flexbox
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.mogoserviceapi
implementation rootProject.ext.dependencies.modulecommon

View File

@@ -11,7 +11,10 @@ import com.mogo.eagle.core.data.deva.scene.SceneModule
import com.mogo.eagle.core.data.deva.scene.SceneTAG
import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigCenter.Companion.bizConfigCenter
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigImpl
import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchManager
import com.zhjt.mogo_core_function_devatools.monitor.MonitorManager
import com.zhjt.mogo_core_function_devatools.scene.SceneManager.Companion.sceneManager
import com.zhjt.mogo_core_function_devatools.status.*
import com.zhjt.mogo_core_function_devatools.trace.TraceManager.Companion.traceManager
@@ -29,8 +32,13 @@ class DevaToolsProvider : IDevaToolsProvider {
override fun init(context: Context) {
mContext = context
traceManager.init(context)
MogoLogCatchManager.init(context)
}
override fun initBiz() {
traceManager.init(mContext!!)
bizConfigCenter.init(mContext!!)
FuncConfigImpl.init()
MogoLogCatchManager.init(mContext!!)
}
override fun startLogCatch() {
@@ -110,4 +118,12 @@ class DevaToolsProvider : IDevaToolsProvider {
override fun hideStatusBar() {
StatusManager.hide()
}
override fun startMonitor() {
mContext?.let { MonitorManager.getInstance(it)?.startMonitor() }
}
override fun stopMonitor() {
mContext?.let { MonitorManager.getInstance(it)?.stopMonitor() }
}
}

View File

@@ -107,13 +107,24 @@ internal object BadCaseManager : LifecycleEventObserver {
if(ClickUtils.isFastClick()){
if(NetworkUtils.isConnected()){
if(BadCaseConfig.dockerVersion!=null){
val initiativeBadCaseWindow = InitiativeBadCaseWindow(activity)
initiativeBadCaseWindow.setClickListener(object: InitiativeBadCaseWindow.ClickListener{
override fun closeWindow() {
initiativeBadCaseWindow.hideFloatWindow()
}
})
initiativeBadCaseWindow.showFloatWindow()
//兼容老MAP版本
if(BadCaseConfig.dockerVersion!!.contains("2.3.0")
|| BadCaseConfig.dockerVersion!!.contains("2.4.0")
|| BadCaseConfig.dockerVersion!!.contains("2.5.0")
|| BadCaseConfig.dockerVersion!!.contains("2.6.0")
|| BadCaseConfig.dockerVersion!!.contains("2.8.0")){
val initiativeBadCaseWindow = InitiativeBadCaseWindow(activity)
initiativeBadCaseWindow.setClickListener(object: InitiativeBadCaseWindow.ClickListener{
override fun closeWindow() {
initiativeBadCaseWindow.hideFloatWindow()
}
})
initiativeBadCaseWindow.showFloatWindow(null)
}else{
val caseListDialog = CaseListDialog(activity)
caseListDialog.show()
}
}else{
ToastUtils.showShort("工控机连接状态异常")
}

View File

@@ -1,35 +1,37 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz
package com.zhjt.mogo_core_function_devatools.badcase.biz
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.RadioButton
import android.widget.RadioGroup
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.GridLayoutManager
import com.mogo.eagle.core.data.badcase.RecordTypeEntity
import com.mogo.eagle.core.data.badcase.TopicEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.utilcode.util.SizeUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.RecordTemplateAdapter
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.layout_badcase_config.view.*
import mogo.telematics.pad.MessagePad
import java.lang.Exception
/**
/**
* @author XuXinChao
* @description BadCase上报信息配置页面
* @since: 2022/7/5
*/
internal class BadCaseConfigView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotRecordListener {
companion object {
@@ -37,18 +39,21 @@ defStyleAttr: Int = 0
}
private var clickListener: ClickListener? = null
private var recordTemplateAdapter: RecordTemplateAdapter? = null
private var mIdentity = BadCaseConfig.identity
private var mPreviousDuration = BadCaseConfig.previousDuration
private var mBackDuration = BadCaseConfig.backDuration
private var mType = 1
private var recordTypesList = ArrayList<RecordTypeEntity>()
private var caseTopicListDialog: CaseTopicListDialog? = null
init{
init {
LayoutInflater.from(context).inflate(R.layout.layout_badcase_config, this, true)
background = ColorDrawable(Color.parseColor("#F0151D41"))
initView()
}
private fun initView(){
private fun initView() {
//关闭BadCase配置窗口
ivConfigClose.setOnClickListener {
clickListener?.onClose()
@@ -75,41 +80,42 @@ defStyleAttr: Int = 0
//保存配置按钮
tvConfigSave.setOnClickListener {
//判断、保存录制时间信息
val preTimeStr=etInitiativePreTime.text.toString()
val afterTimeStr=etInitiativeAfterTime.text.toString()
val preTimeStr = etInitiativePreTime.text.toString()
val afterTimeStr = etInitiativeAfterTime.text.toString()
try {
if(preTimeStr.isEmpty()){
if (preTimeStr.isEmpty()) {
mPreviousDuration = BadCaseConfig.previousDuration
}else{
} else {
mPreviousDuration = preTimeStr.toInt()
}
if(afterTimeStr.isEmpty()){
if (afterTimeStr.isEmpty()) {
mBackDuration = BadCaseConfig.backDuration
}else{
} else {
mBackDuration = afterTimeStr.toInt()
}
if(mPreviousDuration<0 || mPreviousDuration>30){
if (mPreviousDuration < 0 || mPreviousDuration > 30) {
ToastUtils.showLong("前溯采集时长最长30S")
return@setOnClickListener
}
if(mBackDuration<0 || mBackDuration>300){
if (mBackDuration < 0 || mBackDuration > 300) {
ToastUtils.showLong("采集总时长最长300S")
return@setOnClickListener
}
if((mPreviousDuration+mBackDuration)<5){
if ((mPreviousDuration + mBackDuration) < 5) {
ToastUtils.showLong("采集总时长最短5S")
return@setOnClickListener
}
if((mPreviousDuration+mBackDuration)>300){
if ((mPreviousDuration + mBackDuration) > 300) {
ToastUtils.showLong("采集总时长最长300S")
return@setOnClickListener
}
BadCaseConfig.previousDuration = mPreviousDuration
BadCaseConfig.backDuration = mBackDuration
BadCaseConfig.totalDuration = BadCaseConfig.previousDuration + BadCaseConfig.backDuration
}catch (e: Exception){
BadCaseConfig.totalDuration =
BadCaseConfig.previousDuration + BadCaseConfig.backDuration
} catch (e: Exception) {
ToastUtils.showLong("输入时间格式不合法,请重新输入")
etInitiativePreTime.text = null
etInitiativeAfterTime.text = null
@@ -126,14 +132,14 @@ defStyleAttr: Int = 0
}
//现场恢复
when(BadCaseConfig.identity){
"安全员"->{
when (BadCaseConfig.identity) {
"安全员" -> {
rbSafetyOfficer.isChecked = true
}
"QA、研发"->{
"QA、研发" -> {
rbDeveloper.isChecked = true
}
"产品、运营、演示"->{
"产品、运营、演示" -> {
rbProduct.isChecked = true
}
}
@@ -141,128 +147,75 @@ defStyleAttr: Int = 0
etInitiativePreTime.hint = "${BadCaseConfig.previousDuration}S"
etInitiativeAfterTime.hint = "${BadCaseConfig.backDuration}S"
// val test1 = TestBean(1,"人工接管自动录制")
// val test2 = TestBean(2,"地图采集")
// val test3 = TestBean(3,"画龙问题排查")
// val test4 = TestBean(4,"误识别问题排查")
// val test5 = TestBean(5,"lidar+planning")
// val test6 = TestBean(6,"camera+planning")
// val test7 = TestBean(7,"bus lidar+planning")
// val test8 = TestBean(8,"bus camera+planning")
// val test99 = TestBean(99,"ai data")
//
// val list = ArrayList<TestBean>()
// list.add(test1)
// list.add(test2)
// list.add(test3)
// list.add(test4)
// list.add(test5)
// list.add(test6)
// list.add(test7)
// list.add(test8)
// list.add(test99)
// list.iterator().forEach {
// if(it.id!=99){
// val radioButton = RadioButton(context)
// val lp = RadioGroup.LayoutParams(
// RadioGroup.LayoutParams.WRAP_CONTENT,
// RadioGroup.LayoutParams.WRAP_CONTENT
// )
// //设置RadioButton边距 (int left, int top, int right, int bottom)
// lp.setMargins(
// SizeUtils.dp2px(0f),
// SizeUtils.dp2px(8f),
// SizeUtils.dp2px(10f),
// SizeUtils.dp2px(8f)
// )
// //设置RadioButton背景
// radioButton.setTextColor(Color.WHITE)
//
// radioButton.buttonDrawable = resources.getDrawable(R.drawable.badcase_radio_button_style)
// //设置文字距离四周的距离
// radioButton.setPadding(
// SizeUtils.dp2px(12f),
// SizeUtils.dp2px(5f),
// SizeUtils.dp2px(10f),
// SizeUtils.dp2px(5f)
// )
// radioButton.textSize = SizeUtils.sp2px(9f).toFloat()
// radioButton.id = it.id
// radioButton.isChecked = it.id == BadCaseConfig.type
// //设置文字
// radioButton.text = it.src
// //将radioButton添加到radioGroup中
// rgRecordConfig.addView(radioButton, lp)
// rgRecordConfig.setOnCheckedChangeListener { _, checkedId ->
// mType = checkedId
// }
// }
// }
recordTemplateAdapter = RecordTemplateAdapter()
recordTemplateAdapter?.setListener(object :RecordTemplateAdapter.ClickTemplateListener{
override fun onClick(recordTypeEntity: RecordTypeEntity) {
//弹窗Topic清单列表
showCaseTopicListDialog(recordTypeEntity)
}
})
val gridLayoutManager = GridLayoutManager(context,2)
rvTemplate.layoutManager = gridLayoutManager
rvTemplate.adapter = recordTemplateAdapter
rvTemplate.visibility = View.GONE
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
override fun onAutopilotRecordConfig(config: MessagePad.RecordDataConfig) {
super.onAutopilotRecordConfig(config)
ThreadUtils.runOnUiThread{
config.recordTypesList.iterator().forEach {
if(it.id!=99){
val radioButton = RadioButton(context)
val lp = RadioGroup.LayoutParams(
RadioGroup.LayoutParams.WRAP_CONTENT,
RadioGroup.LayoutParams.WRAP_CONTENT
)
//设置RadioButton边距 (int left, int top, int right, int bottom)
lp.setMargins(
SizeUtils.dp2px(0f),
SizeUtils.dp2px(8f),
SizeUtils.dp2px(10f),
SizeUtils.dp2px(8f)
)
//设置RadioButton背景
radioButton.setTextColor(Color.WHITE)
private fun showCaseTopicListDialog(recordTypeEntity: RecordTypeEntity){
caseTopicListDialog = CaseTopicListDialog(context)
caseTopicListDialog?.setData(recordTypeEntity)
caseTopicListDialog?.show()
}
radioButton.buttonDrawable = resources.getDrawable(R.drawable.badcase_radio_button_style)
//设置文字距离四周的距离
radioButton.setPadding(
SizeUtils.dp2px(12f),
SizeUtils.dp2px(5f),
SizeUtils.dp2px(10f),
SizeUtils.dp2px(5f)
)
radioButton.textSize = SizeUtils.sp2px(9f).toFloat()
radioButton.id = it.id
radioButton.isChecked = it.id == BadCaseConfig.type
//设置文字
radioButton.text = it.desc
//将radioButton添加到radioGroup中
rgRecordConfig.addView(radioButton, lp)
rgRecordConfig.setOnCheckedChangeListener { _, checkedId ->
mType = checkedId
}
}
}
}
}
override fun onAutopilotRecordConfig(config: MessagePad.RecordDataConfig) {
super.onAutopilotRecordConfig(config)
ThreadUtils.runOnUiThread {
if(BadCaseConfig.dockerVersion!!.contains("2.3.0")
|| BadCaseConfig.dockerVersion!!.contains("2.4.0")
|| BadCaseConfig.dockerVersion!!.contains("2.5.0")
|| BadCaseConfig.dockerVersion!!.contains("2.6.0")
|| BadCaseConfig.dockerVersion!!.contains("2.8.0")){
rvTemplate.visibility = View.GONE
}else{
config.recordTypesList.iterator().forEach {
if (it.id != 99){
val topicList = ArrayList<TopicEntity>()
it.topicsList.iterator().forEach {
topicList.add(TopicEntity(it,true,false))
}
recordTypesList.add(RecordTypeEntity(it.id,it.desc,topicList))
}
}
if(recordTypesList.size>1){
rvTemplate.visibility = View.VISIBLE
recordTemplateAdapter?.setData(recordTypesList)
recordTemplateAdapter?.notifyDataSetChanged()
}
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutopilotRecordListenerManager.addListener(TAG, this)
//获取数据采集录制模式配置列表
CallerAutoPilotManager.getBadCaseConfig()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutopilotRecordListenerManager.addListener(TAG, this)
//获取数据采集录制模式配置列表
CallerAutoPilotManager.getBadCaseConfig(0, 0, listOf())
recordTypesList.add(RecordTypeEntity(0,"自定义", arrayListOf()))
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutopilotRecordListenerManager.removeListener(TAG)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutopilotRecordListenerManager.removeListener(TAG)
recordTypesList.clear()
}
interface ClickListener{
fun onClose()
}
interface ClickListener {
fun onClose()
}
}

View File

@@ -0,0 +1,119 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.eagle.core.data.badcase.RecordCaseEntity;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.zhjt.mogo_core_function_devatools.R;
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.CaseListAdapter;
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig;
import java.util.ArrayList;
import mogo.telematics.pad.MessagePad;
import record_cache.RecordPanelOuterClass;
/**
* @author XuXinChao
* @description BadCase清单选择对话框
* @since: 2022/10/19
*/
public class CaseListDialog extends Dialog implements IMoGoAutopilotRecordListener {
private TextView tvCancel;
private RecyclerView rvCaseList;
private CaseListAdapter caseListAdapter;
private static final String TAG = "CaseListDialog";
private ArrayList<RecordCaseEntity> recordTypeEntityArrayList = new ArrayList<>();
private Activity activity;
public CaseListDialog(@NonNull Activity activity) {
super(activity, R.style.bad_case_dialog);
this.activity = activity;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_case_list);
setCanceledOnTouchOutside(false);
init();
initEvent();
}
private void init() {
tvCancel = findViewById(R.id.tvCancel);
rvCaseList = findViewById(R.id.rvCaseList);
caseListAdapter = new CaseListAdapter();
caseListAdapter.setListener(recordCaseEntity -> {
//录制Bag包弹窗
InitiativeBadCaseWindow initiativeBadCaseWindow = new InitiativeBadCaseWindow(activity);
initiativeBadCaseWindow.setClickListener(initiativeBadCaseWindow::hideFloatWindow);
initiativeBadCaseWindow.showFloatWindow(recordCaseEntity);
});
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(),2);
gridLayoutManager.setOrientation(RecyclerView.VERTICAL);
rvCaseList.setLayoutManager(gridLayoutManager);
rvCaseList.setAdapter(caseListAdapter);
}
private void initEvent() {
tvCancel.setOnClickListener(v -> dismiss());
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
CallerAutopilotRecordListenerManager.INSTANCE.addListener(TAG, this);
//获取数据采集录制模式配置列表
CallerAutoPilotManager.INSTANCE.getBadCaseConfig(0, 0,new ArrayList<>());
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
CallerAutopilotRecordListenerManager.INSTANCE.removeListener(TAG);
}
@Override
public void onAutopilotRecordResult(@NonNull RecordPanelOuterClass.RecordPanel recordPanel) {
}
@Override
public void onAutopilotRecordConfig(@NonNull MessagePad.RecordDataConfig config) {
ThreadUtils.runOnUiThread(() -> {
if(config.getRecordTypesCount()>0){
for(int index=0;index<config.getRecordTypesCount();index++){
if(config.getRecordTypes(index).getId() != 99){
ArrayList<String> topicList = new ArrayList<>();
// TODO java.lang.IndexOutOfBoundsException: Index: 38, Size: 38
// for(int position=0;index<config.getRecordTypes(index).getTopicsCount();position++){
// topicList.add(config.getRecordTypes(index).getTopicsList().get(position));
// }
recordTypeEntityArrayList.add(new RecordCaseEntity(
config.getRecordTypes(index).getId(),config.getRecordTypes(index).getDesc(),
topicList));
}
}
}
if(BadCaseConfig.customTopicList.size()>0){
recordTypeEntityArrayList.add(new RecordCaseEntity(0,"自定义A",BadCaseConfig.customTopicList));
}
caseListAdapter.setData(recordTypeEntityArrayList);
caseListAdapter.notifyDataSetChanged();
});
}
}

View File

@@ -0,0 +1,206 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.eagle.core.data.badcase.RecordTypeEntity;
import com.mogo.eagle.core.data.badcase.TopicEntity;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.zhjt.mogo_core_function_devatools.R;
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.TopicListAdapter;
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig;
import java.util.ArrayList;
import java.util.List;
import mogo.telematics.pad.MessagePad;
import record_cache.RecordPanelOuterClass;
/**
* @author XuXinChao
* @description BadCase Topic列表选择对话框
* @since: 2022/10/19
*/
public class CaseTopicListDialog extends Dialog implements IMoGoAutopilotRecordListener {
private static final String TAG = "CaseTopicListDialog";
private TextView tvCaseName;
private TextView tvSave;
private TextView tvCancel;
private ImageView ivSearch;
private EditText etSearch;
private RecyclerView rvTopicList;
private TopicListAdapter topicListAdapter;
private String searchStr;
private List<TopicEntity> allTopicList = new ArrayList<>();
private RecordTypeEntity recordType;
private List<String> addTopicList = new ArrayList<>();
private List<TopicEntity> searchTopicList = new ArrayList<>();
public CaseTopicListDialog(@NonNull Context context) {
super(context, R.style.bad_case_dialog);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_case_topic_list);
setCanceledOnTouchOutside(false);
CallerAutopilotRecordListenerManager.INSTANCE.addListener(TAG, this);
init();
initEvent();
//获取所有Topic
CallerAutoPilotManager.INSTANCE.getBadCaseConfig(1, 0, new ArrayList<>());
if(recordType!=null){
tvCaseName.setText(recordType.getDesc());
if(recordType.getTopicsList().size()>0){
topicListAdapter.setData(recordType.getTopicsList());
topicListAdapter.notifyDataSetChanged();
}
}
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
CallerAutopilotRecordListenerManager.INSTANCE.removeListener(TAG);
}
public void setData(RecordTypeEntity recordTypeEntity){
if(recordTypeEntity!=null){
recordType = recordTypeEntity;
}
}
private void init() {
tvCaseName = findViewById(R.id.tvCaseName);
tvSave = findViewById(R.id.tvSave);
tvCancel = findViewById(R.id.tvCancel);
ivSearch = findViewById(R.id.ivSearch);
etSearch = findViewById(R.id.etSearch);
rvTopicList = findViewById(R.id.rvTopicList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rvTopicList.setLayoutManager(linearLayoutManager);
topicListAdapter = new TopicListAdapter();
topicListAdapter.setListener((topicName, clicked) -> {
if(clicked){
addTopicList.add(topicName);
}else{
addTopicList.remove(topicName);
}
});
rvTopicList.setAdapter(topicListAdapter);
}
private void initEvent() {
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
searchStr = s.toString();
if(searchStr!=null && searchStr.length()>0){
ivSearch.setImageDrawable(getContext().getDrawable(R.drawable.icon_bad_case_delect));
} else {
ivSearch.setImageDrawable(getContext().getDrawable(R.drawable.icon_bad_case_search));
}
if(searchStr!=null && searchStr.length()>0){
searchTopicList.clear();
for(int index=0;index<recordType.getTopicsList().size();index++){
if(recordType.getTopicsList().get(index).getTopicName().contains(searchStr)){
searchTopicList.add(recordType.getTopicsList().get(index));
}
}
topicListAdapter.setData(searchTopicList);
topicListAdapter.notifyDataSetChanged();
}
}
});
ivSearch.setOnClickListener(v -> {
if(searchStr!=null && searchStr.length()>0){
etSearch.setText("");
ivSearch.setImageDrawable(getContext().getDrawable(R.drawable.icon_bad_case_search));
topicListAdapter.setData(recordType.getTopicsList());
topicListAdapter.notifyDataSetChanged();
}
});
tvSave.setOnClickListener(v -> {
if(recordType!=null){
Boolean success=CallerAutoPilotManager.INSTANCE.getBadCaseConfig(2,recordType.getId(),addTopicList);
if(Boolean.TRUE.equals(success)){
ToastUtils.showShort("Topic设置成功");
if(recordType.getId() == 0){
//自定义Topic
BadCaseConfig.customTopicList.clear();
BadCaseConfig.customTopicList.addAll(addTopicList);
}
addTopicList.clear();
recordType.getTopicsList().removeAll(allTopicList);
dismiss();
}else{
ToastUtils.showShort("Topic设置失败");
}
}
});
tvCancel.setOnClickListener(v -> {
recordType.getTopicsList().removeAll(allTopicList);
dismiss();
});
}
@Override
public void onAutopilotRecordConfig(MessagePad.RecordDataConfig config) {
ThreadUtils.runOnUiThread(() -> {
Log.i("houyanli","AllTopicsCount="+config.getAllTopicsCount());
if(config.getAllTopicsCount()>0){
for(int index=0;index<config.getAllTopicsCount();index++){
if(!recordType.getTopicsList().contains(config.getAllTopics(index))){
allTopicList.add(new TopicEntity(config.getAllTopics(index),false,true));
}
Log.i("houyanli","topic="+config.getAllTopics(index));
}
recordType.getTopicsList().addAll(allTopicList);
topicListAdapter.setData(recordType.getTopicsList());
topicListAdapter.notifyDataSetChanged();
}
});
}
@Override
public void onAutopilotRecordResult(@NonNull RecordPanelOuterClass.RecordPanel recordPanel) {
}
}

View File

@@ -13,6 +13,7 @@ import android.widget.ImageView
import android.widget.TextView
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.badcase.RecordCaseEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
@@ -137,13 +138,6 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
CallerAutopilotRecordListenerManager.addListener(this.hashCode().toString(),this)
// 添加 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.addListener(this.hashCode().toString(), this)
//开启录包
CallerAutoPilotManager.recordPackage(BadCaseConfig.type,
Random(SystemClock.elapsedRealtime()).nextInt(),
BadCaseConfig.totalDuration,
BadCaseConfig.previousDuration
)
viewAudioButton.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
@@ -337,7 +331,7 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
return true
}
fun showFloatWindow() {
fun showFloatWindow(recordCaseEntity: RecordCaseEntity?) {
if (mFloatLayout.parent == null) {
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
@@ -345,6 +339,14 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)-350
mWindowManager!!.addView(mFloatLayout, mWindowParams)
//开启录包
if(recordCaseEntity!=null){
CallerAutoPilotManager.recordPackage(recordCaseEntity.caseId,Random(SystemClock.elapsedRealtime()).nextInt(),
BadCaseConfig.totalDuration, BadCaseConfig.previousDuration,recordCaseEntity.topicList)
}else{
CallerAutoPilotManager.recordPackage(BadCaseConfig.type,Random(SystemClock.elapsedRealtime()).nextInt(),
BadCaseConfig.totalDuration, BadCaseConfig.previousDuration)
}
}
}

View File

@@ -0,0 +1,54 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.badcase.RecordCaseEntity
import com.zhjt.mogo_core_function_devatools.R
/**
* @author XuXinChao
* @description Case清单列表适配器
* @since: 2022/10/19
*/
class CaseListAdapter: RecyclerView.Adapter<CaseListAdapter.CaseListHolder>() {
private var data:List<RecordCaseEntity>? = null
private var caseClickListener: CaseClickListener?=null
fun setData( data: List<RecordCaseEntity>?){
this.data = data
}
fun setListener(listener: CaseClickListener){
caseClickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CaseListHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_case_list, parent, false)
return CaseListHolder(view)
}
override fun onBindViewHolder(holder: CaseListHolder, position: Int) {
data?.let {recordCaseEntity->
holder.caseName.text = recordCaseEntity[position].caseName
holder.caseName.setOnClickListener {
caseClickListener?.onClick(recordCaseEntity[position])
}
}
}
override fun getItemCount() = data?.size ?: 0
class CaseListHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var caseName: TextView = itemView.findViewById(R.id.caseName)
}
interface CaseClickListener{
fun onClick(recordCaseEntity: RecordCaseEntity)
}
}

View File

@@ -0,0 +1,55 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.badcase.RecordTypeEntity
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.biz.BadCaseConfigView
/**
* @author XuXinChao
* @description 录制模板清单列表适配器
* @since: 2022/10/19
*/
class RecordTemplateAdapter : RecyclerView.Adapter<RecordTemplateAdapter.RecordTemplateHolder>(){
private var data:List<RecordTypeEntity>? = null
private var clickTemplateListener: ClickTemplateListener? = null
fun setData( data: List<RecordTypeEntity>?){
this.data = data
}
fun setListener(listener: ClickTemplateListener){
clickTemplateListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecordTemplateHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_record_template, parent, false)
return RecordTemplateHolder(view)
}
override fun onBindViewHolder(holder: RecordTemplateHolder, position: Int) {
data?.let {recordTypeEntity->
holder.caseName.text = recordTypeEntity[position].desc
holder.caseName.setOnClickListener {
clickTemplateListener?.onClick(recordTypeEntity[position])
}
}
}
override fun getItemCount() = data?.size ?: 0
class RecordTemplateHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var caseName: TextView = itemView.findViewById(R.id.caseName)
}
interface ClickTemplateListener{
fun onClick(recordTypeEntity: RecordTypeEntity)
}
}

View File

@@ -0,0 +1,83 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.badcase.TopicEntity
import com.zhjt.mogo_core_function_devatools.R
/**
* @author XuXinChao
* @description Topic列表适配器
* @since: 2022/10/19
*/
class TopicListAdapter: RecyclerView.Adapter<TopicListAdapter.TopicListHolder>() {
private var data:MutableList<TopicEntity>? = null
private var topicClickListener: TopicClickListener? = null
fun setData( data: MutableList<TopicEntity>?){
this.data = data
}
fun setListener(listener: TopicClickListener){
topicClickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopicListHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_topic_list, parent, false)
return TopicListHolder(view)
}
override fun onBindViewHolder(holder: TopicListHolder, position: Int) {
data?.let{topicList->
holder.topic_check_box.text = topicList[position].topicName
holder.topic_check_box.setOnCheckedChangeListener(null)
holder.topic_check_box.isChecked = topicList[position].topicStatus
holder.topic_check_box.tag = topicList
holder.topic_check_box.isClickable = topicList[position].topicCanClick
holder.topic_check_box.setOnCheckedChangeListener { _, isChecked ->
topicList[position].topicStatus = isChecked
topicClickListener?.onClick(topicList[position].topicName,isChecked)
if(isChecked){
//滚动到置顶
moveItem(topicList[position],position,0)
}else{
var lastNotCan = 0 //最后一个不能选择的
for( i in 0 until itemCount){
var topicEntity = data?.get(i)
if (topicEntity != null) {
if(!topicEntity.topicCanClick){
lastNotCan = i
}
}
}
moveItem(topicList[position],position,lastNotCan)
}
}
}
}
private fun moveItem(topicEntity: TopicEntity,removePos: Int,insertedPos: Int){
data?.remove(topicEntity)
notifyItemRemoved(removePos)
notifyItemRangeChanged(removePos, itemCount - removePos)
data?.add(insertedPos, topicEntity)
notifyItemInserted(insertedPos)
notifyItemRangeChanged(insertedPos, itemCount)
}
override fun getItemCount() = data?.size ?: 0
class TopicListHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var topic_check_box: CheckBox = itemView.findViewById(R.id.topic_check_box);
}
interface TopicClickListener{
fun onClick(topicName: String,clicked: Boolean)
}
}

View File

@@ -27,7 +27,10 @@ object BadCaseConfig {
//工控机版本
@JvmField
var dockerVersion:String ?= null
@JvmField
var recordKeyList:ArrayList<Long> = ArrayList()
//自定义Topic清单列表
@JvmField
var customTopicList: ArrayList<String> = ArrayList()
}

View File

@@ -6,7 +6,6 @@ import android.os.Environment;
import android.util.Log;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.util.FileUtils;
import com.zhjt.mogo_core_function_devatools.badcase.record.fft.FftFactory;
import com.zhjt.mogo_core_function_devatools.badcase.record.listener.RecordListener;
@@ -177,14 +176,14 @@ public class RecordHelper {
AudioRecordThread() {
bufferSize = AudioRecord.getMinBufferSize(currentConfig.getSampleRate(),
currentConfig.getChannelConfig(), currentConfig.getEncodingConfig()) * RECORD_AUDIO_BUFFER_TIMES;
Logger.d(TAG, "record buffer size = %s", bufferSize);
CallerLogger.INSTANCE.d("$M_DEVA$TAG", "record buffer size = %s", bufferSize);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, currentConfig.getSampleRate(),
currentConfig.getChannelConfig(), currentConfig.getEncodingConfig(), bufferSize);
if (currentConfig.getFormat() == RecordConfig.RecordFormat.MP3) {
if (mp3EncodeThread == null) {
initMp3EncoderThread(bufferSize);
} else {
Logger.e(TAG, "mp3EncodeThread != null, 请检查代码");
CallerLogger.INSTANCE.e("$M_DEVA$TAG", "mp3EncodeThread != null, 请检查代码");
}
}
}
@@ -206,7 +205,7 @@ public class RecordHelper {
private void startPcmRecorder() {
state = RecordState.RECORDING;
notifyState();
Logger.d(TAG, "开始录制 Pcm");
CallerLogger.INSTANCE.d("$M_DEVA$TAG", "开始录制 Pcm");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(tmpFile);
@@ -224,7 +223,7 @@ public class RecordHelper {
if (state == RecordState.STOP) {
makeFile();
} else {
Logger.i(TAG, "暂停!");
CallerLogger.INSTANCE.i("$M_DEVA$TAG", "暂停!");
}
} catch (Exception e) {
notifyError("录音失败");
@@ -240,7 +239,7 @@ public class RecordHelper {
if (state != RecordState.PAUSE) {
state = RecordState.IDLE;
notifyState();
Logger.d(TAG, "录音结束");
CallerLogger.INSTANCE.d("$M_DEVA$TAG", "录音结束");
}
}
@@ -268,7 +267,7 @@ public class RecordHelper {
notifyState();
stopMp3Encoded();
} else {
Logger.d(TAG, "暂停");
CallerLogger.INSTANCE.d("$M_DEVA$TAG", "暂停");
}
}
}
@@ -283,7 +282,7 @@ public class RecordHelper {
}
});
} else {
Logger.e(TAG, "mp3EncodeThread is null, 代码业务流程有误,请检查!! ");
CallerLogger.INSTANCE.e("$M_DEVA$TAG", "mp3EncodeThread is null, 代码业务流程有误,请检查!! ");
}
}
@@ -302,7 +301,7 @@ public class RecordHelper {
break;
}
notifyFinish();
Logger.i(TAG, "录音完成! path: %s 大小:%s", resultFile.getAbsoluteFile(), resultFile.length());
CallerLogger.INSTANCE.i("$M_DEVA$TAG", "录音完成! path: %s 大小:%s", resultFile.getAbsoluteFile(), resultFile.length());
}
/**
@@ -377,7 +376,7 @@ public class RecordHelper {
private String getFilePath(String fileName) {
if (!FileUtils.createOrExistsDir(ROOT_PATH)) {
Logger.w(TAG, "文件夹创建失败:%s", ROOT_PATH);
CallerLogger.INSTANCE.w("$M_DEVA$TAG", "文件夹创建失败:%s", ROOT_PATH);
return null;
}
@@ -388,7 +387,7 @@ public class RecordHelper {
private String getTempFilePath() {
if (!FileUtils.createOrExistsDir(TEMP_PATH)) {
Logger.e(TAG, "文件夹创建失败:%s", TEMP_PATH);
CallerLogger.INSTANCE.e("$M_DEVA$TAG", "文件夹创建失败:%s", TEMP_PATH);
}
String fileName = String.format(Locale.getDefault(), "tmp_%s", FileUtils.getNowString(new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.SIMPLIFIED_CHINESE)));
return String.format(Locale.getDefault(), "%s%s.pcm", TEMP_PATH, fileName);

View File

@@ -0,0 +1,104 @@
package com.zhjt.mogo_core_function_devatools.funcconfig
import android.content.Context
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_ALIAS_CODE_FUNC_CONFIG_CHANGED
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_CLOUD_SHOW
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_LINK_LOG_CONNECT_STATUS
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsFuncConfigListenerManager
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.SPUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigConst.Companion.FUNC_CONFIG_TYPE
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigConst.Companion.defaultFuncConfig
import com.zhjt.mogo_core_function_devatools.funcconfig.network.FuncConfigNetWorkModel
import com.zhjt.service.chain.ChainLog
import com.zhjt.service.chain.TracingConstants
import com.zhjt.service_biz.BizManager
import com.zhjt.service_biz.FuncConfig
import mogo.telematics.pad.MessagePad
class FuncConfigCenter : IMogoOnMessageListener<FuncConfig>, IMoGoAutopilotCarConfigListener {
companion object {
private const val TAG = "FuncConfigCenter"
val bizConfigCenter by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
FuncConfigCenter()
}
}
private var mContext: Context? = null
private val funcConfigNetWorkModel = FuncConfigNetWorkModel()
fun init(context: Context) {
mContext = context
MogoAiCloudSocketManager.getInstance(AbsMogoApplication.getApp().applicationContext)
.registerOnMessageListener(FUNC_CONFIG_TYPE, this)
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
//未连接到工控,默认配置
val bizJson = SPUtils.getInstance("biz_config")
.getString("config", GsonUtils.toJson(defaultFuncConfig()))
refreshConfig(GsonUtils.fromJson(bizJson, FuncConfig::class.java))
}
override fun onAutopilotCarConfig(carConfigResp: MessagePad.CarConfigResp) {
if (!carConfigResp.macAddress.isNullOrEmpty()) {
UiThreadHandler.post {
funcConfigNetWorkModel.requestFuncConfig(carConfigResp.macAddress, {
SPUtils.getInstance("biz_config").put("config", GsonUtils.toJson(it))
refreshConfig(it) }, {})
}
} else {
ToastUtils.showLong("未获取到域控mac信息")
}
}
override fun target(): Class<FuncConfig> {
return FuncConfig::class.java
}
override fun onMsgReceived(obj: FuncConfig?) {
obj?.let {
invokeUpdate(it)
}
}
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_CONNECT_STATUS,
linkCode = CHAIN_LINK_CLOUD_SHOW,
endpoint = TracingConstants.Endpoint.PAD,
nodeAliasCode = CHAIN_ALIAS_CODE_FUNC_CONFIG_CHANGED,
paramIndexes = [0],
clientPkFileName = "sn"
)
private fun refreshConfig(funcConfig: FuncConfig) {
BizManager.updateBizConfigData(funcConfig)
invokeUpdate(funcConfig)
}
private fun invokeUpdate(funcConfig: FuncConfig) {
funcConfig.business.forEach { business ->
CallerDevaToolsFuncConfigListenerManager.invokeDevaToolsFuncConfigBizUpdate(
business.biz.uppercase(),
business.data
)
}
}
fun onDestroy() {
MogoAiCloudSocketManager.getInstance(AbsMogoApplication.getApp().applicationContext)
.unregisterLifecycleListener(FUNC_CONFIG_TYPE)
CallerAutopilotCarConfigListenerManager.removeListener(TAG)
mContext = null
}
}

View File

@@ -0,0 +1,123 @@
package com.zhjt.mogo_core_function_devatools.funcconfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_AUTOPILOT_LANE_SELECTION
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_AVW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BAG_RECORD
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BEAUTY_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BSW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BYPASS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_CLW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_DNPW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_EBW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_FCW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_FULL_LOG
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_HLW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_IVP
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_IVP_GREEN
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_IVS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_LCW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_LIMIT_SPEED_SET
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_LTA
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_OPT_LINE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_ACTIONS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_WARNING
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RAIN_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RTS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_SLW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_TJW
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_TRACE_LOG
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_VIP
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_VRU
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_VRU_RI
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_WARNING_UPLOAD
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.FOUNDATION
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2I
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2N
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2V
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.zhjt.mogo_core_function_devatools.BuildConfig
import com.zhjt.mogo_core_function_devatools.env.EnvChangeManager
import com.zhjt.service_biz.Business
import com.zhjt.service_biz.FuncConfig
import com.zhjt.service_biz.SubBiz
class FuncConfigConst {
companion object{
const val FUNC_CONFIG_TYPE = 500001
fun defaultFuncConfig(): FuncConfig {
val businessList = mutableListOf<Business>()
val v2nSubList = mutableListOf<SubBiz>()
v2nSubList.add(SubBiz(BIZ_VIP, lock = false, state = true, dependNode = "", data = ""))
v2nSubList.add(SubBiz(BIZ_OPT_LINE, lock = false, state = false, dependNode = "", data = ""))
v2nSubList.add(SubBiz(BIZ_VRU, lock = false, state = true, dependNode = "", data = ""))
v2nSubList.add(SubBiz(BIZ_VRU_RI, lock = false, state = false, dependNode = "", data = ""))
v2nSubList.add(SubBiz(BIZ_HLW, lock = false, state = true, dependNode = "", data = ""))
businessList.add(Business(V2N, v2nSubList))
val v2iSubList = mutableListOf<SubBiz>()
v2iSubList.add(SubBiz(BIZ_IVP_GREEN, lock = false, state = true, dependNode = "", data = ""))
v2iSubList.add(SubBiz(BIZ_IVP, lock = false, state = true, dependNode = "", data = ""))
v2iSubList.add(SubBiz(BIZ_RTS, lock = false, state = true, dependNode = "", data = ""))
v2iSubList.add(SubBiz(BIZ_SLW, lock = false, state = true, dependNode = "", data = ""))
v2iSubList.add(SubBiz(BIZ_IVS, lock = false, state = true, dependNode = "", data = ""))
v2iSubList.add(SubBiz(BIZ_TJW, lock = false, state = true, dependNode = "", data = ""))
businessList.add(Business(V2I,v2iSubList))
val v2vSubList = mutableListOf<SubBiz>()
v2vSubList.add(SubBiz(BIZ_AVW, lock = false, state = true, dependNode = "", data = ""))
v2vSubList.add(SubBiz(BIZ_LCW, lock = false, state = true, dependNode = "", data = ""))
v2vSubList.add(SubBiz(BIZ_BSW, lock = false, state = true, dependNode = "", data = ""))
v2vSubList.add(SubBiz(BIZ_EBW, lock = false, state = true, dependNode = "", data = ""))
v2vSubList.add(SubBiz(BIZ_FCW, lock = false, state = true, dependNode = "", data = ""))
v2vSubList.add(SubBiz(BIZ_LTA, lock = false, state = true, dependNode = "", data = ""))
v2vSubList.add(SubBiz(BIZ_CLW, lock = false, state = true, dependNode = "", data = ""))
v2vSubList.add(SubBiz(BIZ_DNPW, lock = false, state = true, dependNode = "", data = ""))
businessList.add(Business(V2V,v2vSubList))
val foundationSubList = mutableListOf<SubBiz>()
foundationSubList.add(SubBiz(BIZ_BEAUTY_MODE, lock = false, state = false, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_RAIN_MODE, lock = false, state = false, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_FULL_LOG, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_TRACE_LOG, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_BAG_RECORD, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_WARNING_UPLOAD, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_LIMIT_SPEED_SET, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_BYPASS, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_AUTOPILOT_LANE_SELECTION, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_PNC_ACTIONS, lock = false, state = true, dependNode = "", data = ""))
foundationSubList.add(SubBiz(BIZ_PNC_WARNING, lock = false, state = true, dependNode = "", data = ""))
businessList.add(Business(FOUNDATION,foundationSubList))
return FuncConfig(0, AppUtils.getAppVersionCode(), getChannelCode(), getEnv(), businessList)
}
private fun getEnv():Int{
return if(EnvChangeManager.getEnvConfig()!= null){
EnvChangeManager.getEnvConfig()!!.netMode
}else {
0
}
}
// todo 新增车型需要更新(清扫车)
fun getChannelCode(): Int{
return when{
AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)
&& AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) -> 1
AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)
&& AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) -> 2
AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)
&& AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) -> 3
AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)
&& AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) -> 4
else -> 0
}
}
}
}

View File

@@ -0,0 +1,38 @@
package com.zhjt.mogo_core_function_devatools.funcconfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BEAUTY_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_WARNING
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RAIN_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_WARNING_UPLOAD
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.FOUNDATION
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsFuncConfigListener
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsFuncConfigListenerManager
object FuncConfigImpl {
private const val TAG = "FuncConfigImpl"
fun init() {
CallerDevaToolsFuncConfigListenerManager.registerDevaToolsFuncConfigListener(FOUNDATION,
TAG,false,
object : IMoGoDevaToolsFuncConfigListener {
override fun updateBizData(
type: String,
state: Boolean,
lock: Boolean,
data: String?
) {
when (type) {
BIZ_BEAUTY_MODE -> FunctionBuildConfig.isDemoMode = state
BIZ_RAIN_MODE -> FunctionBuildConfig.isRainMode = state
BIZ_WARNING_UPLOAD -> FunctionBuildConfig.isReportWarning = state
BIZ_PNC_WARNING -> FunctionBuildConfig.isPNCWarning = state
}
}
}
)
}
}

View File

@@ -0,0 +1,16 @@
package com.zhjt.mogo_core_function_devatools.funcconfig.network
import com.mogo.eagle.core.data.BaseResponse
import com.zhjt.service_biz.FuncConfig
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST
interface FuncConfigApiService {
//FuncConfig
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("eagleEye-mis/config/abilityInfo")
suspend fun funcConfig(@Body map: MutableMap<String, Any>): BaseResponse<FuncConfig>
}

View File

@@ -0,0 +1,22 @@
package com.zhjt.mogo_core_function_devatools.funcconfig.network
import com.mogo.commons.debug.DebugConfig
class FuncConfigHost {
companion object{
private const val HOST_DEV = "https://eagle-qa.zhidaozhixing.com"
private const val HOST_RELEASE = "https://eagle.zhidaozhixing.com"
fun get(): String{
return when (DebugConfig.getNetMode()) {
DebugConfig.NET_MODE_DEV -> HOST_DEV
DebugConfig.NET_MODE_QA -> HOST_DEV
DebugConfig.NET_MODE_DEMO -> HOST_RELEASE
DebugConfig.NET_MODE_RELEASE -> HOST_RELEASE
else -> HOST_RELEASE
}
}
}
}

View File

@@ -0,0 +1,72 @@
package com.zhjt.mogo_core_function_devatools.funcconfig.network
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.BaseResponse
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.network.apiCall
import com.mogo.eagle.core.network.request
import com.mogo.eagle.core.utilcode.util.DeviceUtils
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigConst
import com.zhjt.service_biz.FuncConfig
class FuncConfigNetWorkModel {
private fun getNetWorkApi(baseUrl: String = FuncConfigHost.get()): FuncConfigApiService {
return MoGoRetrofitFactory.getInstanceNoCallAdapter(baseUrl)
.create(FuncConfigApiService::class.java)
}
private var retryTime = 0
private var success: ((FuncConfig) -> Unit)? = null
private var error: ((String) -> Unit)? = null
fun requestFuncConfig(
mac:String,
onSuccess: ((FuncConfig) -> Unit)? = null,
onError: ((String) -> Unit)? = null
) {
request<BaseResponse<FuncConfig>> {
val map = mutableMapOf<String, Any>()
start {
if (success == null) {
success = onSuccess
}
if (error == null) {
error = onError
}
//todo test
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["mac"] = DeviceUtils.getMacAddress()
map["channelVersion"] = FuncConfigConst.getChannelCode()
}
loader {
apiCall {
getNetWorkApi().funcConfig(map)
}
}
onSuccess {
if (it.result != null) {
success?.invoke(it.result)
} else {
if (retryTime < 3) {
retryTime += 1
requestFuncConfig(mac)
} else {
error?.invoke("FuncConfig error msg is null")
}
}
}
onError {
if (retryTime < 3) {
retryTime += 1
requestFuncConfig(mac)
} else if (it.message != null) {
error?.invoke(it.message ?: "FuncConfig error msg is null")
}
}
}
}
}

View File

@@ -12,6 +12,8 @@ import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.constants.MoGoConfig
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_FULL_LOG
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.FOUNDATION
import com.mogo.eagle.core.function.api.map.deva.IMoGoMapDevaProvider
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
@@ -34,6 +36,7 @@ import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companio
import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companion.LOG_PUSH_TYPE
import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companion.START_CATCH_LOG
import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchConst.Companion.STOP_CATCH_LOG
import com.zhjt.service_biz.BizConfig
import java.io.File
@SuppressLint("StaticFieldLeak")
@@ -136,6 +139,7 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
return false
}
@BizConfig(FOUNDATION, "", BIZ_FULL_LOG)
fun startCatchLog(duration: Int = 10, logPrefixName: String? = null) {
if (catchingList.contains(manualContent.pkgName + logPrefixName)) {
TipToast.shortTip("已经在抓取日志了,请稍后再试")
@@ -156,7 +160,7 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
private fun startCatchLog(content: RemoteLogPushContent, logPrefixName: String? = null) {
CallerLogger.d("$M_DEVA$TAG", "startCatchLog path : ${content.pkgName + logPrefixName}")
if(MoGoAiCloudClientConfig.getInstance().sn == null){
if (MoGoAiCloudClientConfig.getInstance().sn == null) {
ThreadUtils.runOnUiThread {
TipToast.shortTip("缺少设备唯一ID请检查网络")
}
@@ -247,14 +251,14 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
}
override fun uploadFile(filePath: String) {
if(!mapCacheUpload){
if (!mapCacheUpload) {
return
}
val file = File(filePath)
if (file.isFile) {
CallerLogger.d("$M_DEVA$TAG", "uploadFile path : $filePath")
LogInfoManagerFactory.handleSingleUploadFile(filePath)
}else{
} else {
CallerLogger.d("$M_DEVA$TAG", "file absPath : ${file.absolutePath}")
}
}

View File

@@ -0,0 +1,108 @@
package com.zhjt.mogo_core_function_devatools.monitor
import android.annotation.SuppressLint
import android.content.Context
import android.os.Process
import android.util.Log
import com.zhjt.mogo_core_function_devatools.monitor.db.CpuInfo
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb
import com.zhjt.mogo_core_function_devatools.monitor.utils.CpuUtils
import java.text.SimpleDateFormat
class CpuMonitor private constructor(var context: Context) {
var isRunning = false
private val pid by lazy {
Process.myPid()
}
private val cpuInfoList by lazy {
ArrayList<CpuInfo>()
}
private val dateFormat by lazy {
SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
}
companion object {
private const val TAG = "CpuMonitor"
const val INTERVAL_PERF = 1000L
@SuppressLint("StaticFieldLeak")
@Volatile
private var sInstance: CpuMonitor? = null
fun getInstance(context: Context): CpuMonitor? {
if (sInstance == null) {
synchronized(CpuMonitor::class.java) {
if (sInstance == null) {
sInstance = CpuMonitor(context)
}
}
}
return sInstance
}
}
/**
* 请先运行Shizuku的服务
*/
@Synchronized
fun startRun() {
if (!isRunning) {
Thread(CpuRunnable()).start()
isRunning = true
}
}
@Synchronized
fun isStarted() = isRunning
@Synchronized
fun stop() {
isRunning = false
}
fun saveCpuInfos() {
synchronized(this) {
MonitorDb.getDb(context).monitorDao().saveAllCpuInfos(*cpuInfoList.toTypedArray())
cpuInfoList.clear()
}
}
private fun getCpuValue(): Double {
var value = 0.0
try {
// 应用获取当前进程CPU使用时间Binder服务端获取系统CPU时间中间用耗时不如使用top命令
// value = UserServiceManager.getCpuUsage(Process.myPid())
value = CpuUtils.getCpuUsageForO()
return value
} catch (e: Exception) {
Log.e(TAG, e.message ?: "未知异常!")
}
return value
}
inner class CpuRunnable : Runnable {
override fun run() {
while (isRunning) {
val cpu = getCpuValue()
if (cpu > 0) {
synchronized(this@CpuMonitor) {
cpuInfoList.add(
CpuInfo(
saveTime = dateFormat.format(System.currentTimeMillis()),
cpuPercent = cpu
)
)
}
}
try {
Thread.sleep(INTERVAL_PERF)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
}
}

View File

@@ -0,0 +1,121 @@
package com.zhjt.mogo_core_function_devatools.monitor
import android.annotation.SuppressLint
import android.content.Context
import android.os.Process.myPid
import android.util.Log
import com.zhjt.mogo_core_function_devatools.monitor.db.MemInfo
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb
import com.zhjt.mogo_core_function_devatools.monitor.utils.HookUtils
import com.zhjt.mogo_core_function_devatools.monitor.utils.MemUtils
import java.text.SimpleDateFormat
class MemMonitor private constructor(var context: Context) {
var isRunning = false
private val memInfoList by lazy {
ArrayList<MemInfo>()
}
private val dateFormat by lazy {
SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
}
companion object {
private const val TAG = "MemMonitor"
const val INTERVAL_PERF = 1000L
@SuppressLint("StaticFieldLeak")
@Volatile
private var sInstance: MemMonitor? = null
fun getInstance(context: Context): MemMonitor? {
if (sInstance == null) {
synchronized(MemMonitor::class.java) {
if (sInstance == null) {
sInstance = MemMonitor(context)
}
}
}
return sInstance
}
}
@Synchronized
fun startRun() {
if (!isRunning) {
Thread(MemoryRunnable()).start()
isRunning = true
}
}
@Synchronized
fun isStarted() = isRunning
@Synchronized
fun stop() {
isRunning = false
}
fun saveMemInfos() {
synchronized(this) {
MonitorDb.getDb(context).monitorDao().saveAllMemInfos(*memInfoList.toTypedArray())
memInfoList.clear()
}
}
/**
* 单位MB
*/
private fun getMemoryValue(): Double {
var value = 0.0
try {
value = MemUtils.getPssMemValue(context, intArrayOf(myPid()))
return value
} catch (e: Exception) {
Log.e(TAG, e.message ?: "未知异常!")
}
return value
}
/**
* 单位MB
*/
private fun getMemoryArray(): DoubleArray {
var value = doubleArrayOf()
try {
value = MemUtils.getPssArray(context, intArrayOf(myPid()))
return value
} catch (e: Exception) {
Log.e(TAG, e.message ?: "未知异常!")
}
return value
}
inner class MemoryRunnable : Runnable {
override fun run() {
while (isRunning) {
// 0: 总PSS1: dalvik总Pss, 2: native总Pss, 3: other总Pss
val pssArray = getMemoryArray()
if (pssArray[0] > 0) {
synchronized(this@MemMonitor) {
memInfoList.add(
MemInfo(
saveTime = dateFormat.format(System.currentTimeMillis()),
totalPss = pssArray[0],
dalvikPss = pssArray[1],
nativePss = pssArray[2],
otherPss = pssArray[3]
)
)
}
}
try {
Thread.sleep(INTERVAL_PERF)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
}
}

View File

@@ -0,0 +1,64 @@
package com.zhjt.mogo_core_function_devatools.monitor
import android.annotation.SuppressLint
import android.content.Context
import android.os.Looper
import com.mogo.eagle.core.utilcode.util.ToastUtils
import java.util.*
class MonitorManager private constructor(var context: Context) {
private var timer: Timer? = null
private var isStarted = false
companion object {
@SuppressLint("StaticFieldLeak")
@Volatile
private var sInstance: MonitorManager? = null
fun getInstance(context: Context): MonitorManager? {
if (sInstance == null) {
synchronized(MonitorManager::class.java) {
if (sInstance == null) {
sInstance = MonitorManager(context)
}
}
}
return sInstance
}
}
/**
* 主线程中执行
*/
fun startMonitor() {
if (Thread.currentThread() == Looper.getMainLooper().thread) {
if (!isStarted) {
CpuMonitor.getInstance(context)?.startRun()
MemMonitor.getInstance(context)?.startRun()
if (timer == null) {
timer = Timer()
}
timer!!.schedule(object : TimerTask() {
override fun run() {
CpuMonitor.getInstance(context)?.saveCpuInfos()
MemMonitor.getInstance(context)?.saveMemInfos()
}
}, 1000, 60000)
isStarted = true
ToastUtils.showShort("性能监控启动成功!")
} else {
ToastUtils.showShort("性能监控已启动,请勿重复启动!")
}
}
}
fun stopMonitor() {
CpuMonitor.getInstance(context)?.stop()
MemMonitor.getInstance(context)?.stop()
timer?.cancel()
timer = null
isStarted = false
ToastUtils.showShort("性能监控停止成功!")
}
}

View File

@@ -0,0 +1,18 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "t_cpu")
data class CpuInfo(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val uuid: Long = 0,
@ColumnInfo(name = "save_time")
val saveTime: String?,
@ColumnInfo(name = "cpu_percent")
val cpuPercent: Double
)

View File

@@ -0,0 +1,27 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "t_memory")
data class MemInfo(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val uuid: Long = 0,
@ColumnInfo(name = "save_time")
val saveTime: String,
@ColumnInfo(name = "total_pss")
val totalPss: Double,
@ColumnInfo(name = "dalvik_pss")
val dalvikPss: Double,
@ColumnInfo(name = "native_pss")
val nativePss: Double,
@ColumnInfo(name = "other_pss")
val otherPss: Double
)

View File

@@ -0,0 +1,24 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import androidx.room.*
@Dao
interface MonitorDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveCpu(info: CpuInfo)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveAllCpuInfos(vararg cpuInfo: CpuInfo)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveMemory(info: MemInfo)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveAllMemInfos(vararg memInfo: MemInfo)
@Query("SELECT * FROM t_cpu WHERE id =:id")
fun getAllCPUById(id: Long): List<CpuInfo>
@Query("SELECT * FROM t_memory WHERE id =:id")
fun getAllMemById(id: Long): List<MemInfo>
}

View File

@@ -0,0 +1,27 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [CpuInfo::class, MemInfo::class], version = 1, exportSchema = false)
abstract class MonitorDb: RoomDatabase() {
abstract fun monitorDao(): MonitorDao
companion object {
const val INTERNAL_DB_NAME = "mogo_monitor.db"
private var db: MonitorDb? = null
@JvmStatic
fun getDb(context: Context): MonitorDb {
if (db == null) {
db = Room.databaseBuilder(context.applicationContext, MonitorDb::class.java, INTERNAL_DB_NAME)
.fallbackToDestructiveMigration()
.build()
}
return db!!
}
}
}

View File

@@ -0,0 +1,17 @@
package com.zhjt.mogo_core_function_devatools.monitor.remote;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
public interface IUserInterface extends IInterface {
String DESCRIPTOR = "rikka.shizuku.demo.IUserInterface";
int TRANSACTION_exec = IBinder.FIRST_CALL_TRANSACTION;
int TRANSACTION_getCpuUsage = IBinder.FIRST_CALL_TRANSACTION + 1;
String exec(String cmd) throws RemoteException;
double getCpuUsage(int pid) throws RemoteException;
}

View File

@@ -0,0 +1,141 @@
package com.zhjt.mogo_core_function_devatools.monitor.remote;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.zhjt.mogo_core_function_devatools.monitor.utils.CpuUtils;
/**
* Server端Binder类
*/
public class RemoteUserServiceImp extends Binder implements IUserInterface {
public RemoteUserServiceImp() {
attachInterface(this, DESCRIPTOR);
}
public static IUserInterface asInterface(IBinder obj) {
if ((obj == null)) {
return null;
}
IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin instanceof IUserInterface) {
return ((IUserInterface) iin);
}
return new Proxy(obj);
}
@Override
public String exec(String cmd) throws RemoteException {
return "";
}
@Override
public double getCpuUsage(int pid) throws RemoteException {
return CpuUtils.getCpuUsagePercentWithPid(pid);
}
/**
* 处理Client端请求
*
* @param code
* @param data
* @param reply
* @param flags
* @return
* @throws RemoteException
*/
@Override
protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
final String descriptor = DESCRIPTOR;
switch (code) {
case TRANSACTION_exec:
data.enforceInterface(descriptor);
String _arg0;
_arg0 = data.readString();
String _result = this.exec(_arg0);
reply.writeNoException();
reply.writeString(_result);
return true;
default:
return super.onTransact(code, data, reply, flags);
}
}
@Nullable
@Override
public String getInterfaceDescriptor() {
return super.getInterfaceDescriptor();
}
/**
* 返回给Client端并被封装成BinderProxy
*
* @return
*/
@Override
public IBinder asBinder() {
return this;
}
public static class Proxy implements IUserInterface {
private IBinder mRemote;
public Proxy(IBinder remote) {
mRemote = remote;
}
public String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public IBinder asBinder() {
// 返回Server端Binder对象
return mRemote;
}
@Override
public String exec(String cmd) throws RemoteException {
// 参数传递给Server端并挂起当前线程等待Server端执行完返回结果
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(cmd);
mRemote.transact(TRANSACTION_exec, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public double getCpuUsage(int pid) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
double _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(pid);
mRemote.transact(TRANSACTION_getCpuUsage, _data, _reply, 0);
_reply.readException();
_result = _reply.readDouble();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
}

View File

@@ -0,0 +1,182 @@
package com.zhjt.mogo_core_function_devatools.monitor.remote
//import rikka.shizuku.Shizuku
//import android.content.ServiceConnection
//import android.content.ComponentName
//import android.os.IBinder
//import rikka.shizuku.Shizuku.UserServiceArgs
//import android.content.pm.PackageManager
//import android.util.Log
//import com.mogo.eagle.core.utilcode.util.AppUtils
//import com.mogo.eagle.core.utilcode.util.ToastUtils
//import rikka.shizuku.Shizuku.OnBinderReceivedListener
//import rikka.shizuku.Shizuku.OnBinderDeadListener
//import rikka.shizuku.Shizuku.OnRequestPermissionResultListener
//import java.lang.StringBuilder
object UserServiceManager {
// private const val TAG = "UserServiceManager"
// private const val REQUEST_CODE_BIND = 1
// private const val REQUEST_CODE_UNBIND = 2
//
// private var userServiceProxy: IUserInterface? = null
// private var isFirst = true
//
// fun init() {
// if (isFirst) {
// addListener()
// isFirst = false
// }
// bindUserService()
// }
//
// fun stopService() {
// removeListener()
// unbindUserService()
// }
//
// fun isServiceActive(): Boolean {
// var isActive = false
// val service = userServiceProxy
// if (service != null && service is IBinder && service.isBinderAlive) {
// isActive = true
// }
// return isActive
// }
//
// private fun addListener() {
// Shizuku.addBinderReceivedListenerSticky(BINDER_RECEIVED_LISTENER)
// Shizuku.addBinderDeadListener(BINDER_DEAD_LISTENER)
// Shizuku.addRequestPermissionResultListener(REQUEST_PERMISSION_RESULT_LISTENER)
// }
//
// private fun removeListener() {
// Shizuku.removeBinderReceivedListener(BINDER_RECEIVED_LISTENER)
// Shizuku.removeBinderDeadListener(BINDER_DEAD_LISTENER)
// Shizuku.removeRequestPermissionResultListener(REQUEST_PERMISSION_RESULT_LISTENER)
// }
//
// private fun bindUserService() {
// if (checkPermission(REQUEST_CODE_BIND)) {
// val res = StringBuilder()
// try {
// if (Shizuku.getVersion() < 10) {
// res.append("requires Shizuku API 10")
// } else {
// Shizuku.bindUserService(userServiceArgs, userServiceConnection)
// }
// } catch (tr: Throwable) {
// tr.printStackTrace()
// res.append(tr.toString())
// }
// }
// }
//
// private fun unbindUserService() {
// if (checkPermission(REQUEST_CODE_UNBIND)) {
// val res = StringBuilder()
// try {
// if (Shizuku.getVersion() < 10) {
// res.append("requires Shizuku API 10")
// } else {
// Shizuku.unbindUserService(userServiceArgs, userServiceConnection, true)
// }
// } catch (tr: Throwable) {
// tr.printStackTrace()
// res.append(tr.toString())
// }
// }
// }
//
// fun exec(cmd: String): String {
// return userServiceProxy?.exec(cmd) ?: ""
// }
//
// /**
// * 单位:%保留1位小数
// */
// fun getCpuUsage(pid: Int): Double {
// return userServiceProxy?.getCpuUsage(pid) ?: -1.0
// }
//
// private val userServiceConnection: ServiceConnection = object : ServiceConnection {
// override fun onServiceConnected(componentName: ComponentName, binder: IBinder?) {
// if (binder != null && binder.pingBinder()) {
// val service = RemoteUserServiceImp.asInterface(binder)
// userServiceProxy = service
// ToastUtils.showShort("监控权限获取成功!")
// }
// }
//
// override fun onServiceDisconnected(componentName: ComponentName) {}
// }
//
// private val userServiceArgs by lazy {
// val appInfo = AppUtils.getAppInfo()
// UserServiceArgs(
// ComponentName(
// appInfo?.packageName ?: "com.mogo.launcher.f",
// RemoteUserServiceImp::class.java.name
// )
// )
// .daemon(false)
// .processNameSuffix("service")
// .debuggable(true)
// .version(appInfo?.versionCode ?: 1)
// }
//
// private fun checkPermission(code: Int): Boolean {
// if (Shizuku.isPreV11()) {
// Log.w(TAG, "Version is preV11!")
// return false
// }
// try {
// return if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) {
// true
// } else if (Shizuku.shouldShowRequestPermissionRationale()) {
// Log.e(TAG, "User denied permission (shouldShowRequestPermissionRationale=true)")
// false
// } else {
// Shizuku.requestPermission(code)
// false
// }
// } catch (e: Throwable) {
// Log.e(TAG, Log.getStackTraceString(e))
// ToastUtils.showLong("请先打开Shizuku并启动它")
// }
// return false
// }
//
// private fun onRequestPermissionsResult(requestCode: Int, grantResult: Int) {
// if (grantResult == PackageManager.PERMISSION_GRANTED) {
// when (requestCode) {
// REQUEST_CODE_BIND -> {
// bindUserService()
// }
// REQUEST_CODE_UNBIND -> {
// unbindUserService()
// }
// else -> {}
// }
// } else {
// Log.e(TAG, "User denied permission")
// }
// }
//
// private val BINDER_RECEIVED_LISTENER = OnBinderReceivedListener {
// if (Shizuku.isPreV11()) {
// Log.w(TAG, "Shizuku pre-v11 is not supported")
// } else {
// Log.d(TAG, "Binder received")
// }
// }
// private val BINDER_DEAD_LISTENER = OnBinderDeadListener { Log.w(TAG, "Binder dead") }
// private val REQUEST_PERMISSION_RESULT_LISTENER =
// OnRequestPermissionResultListener { requestCode: Int, grantResult: Int ->
// onRequestPermissionsResult(
// requestCode,
// grantResult
// )
// }
}

View File

@@ -0,0 +1,298 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils;
import android.os.Process;
import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
/**
* CPU相关工具类。
*/
public class CpuUtils {
private static boolean initCpu = true;
private static double oCpu = 0.0;
private static double oIdle = 0.0;
private static double pJif = 0.0;
private static double pCpu = 0.0;
private static double aCpu = 0.0;
private static double opCpu = 0.0;
private static double oaCpu = 0.0;
/**
* 8.0以上获取cpu的方式
*
* @return
*/
public static double getCpuUsageForO() {
java.lang.Process process = null;
try {
process = Runtime.getRuntime().exec("top -n 1");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
int cpuIndex = -1;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (TextUtils.isEmpty(line)) {
continue;
}
int tempIndex = getCPUIndex(line);
if (tempIndex != -1) {
cpuIndex = tempIndex;
continue;
}
if (line.startsWith(String.valueOf(Process.myPid()))) {
if (cpuIndex == -1) {
continue;
}
String[] param = line.split("\\s+");
if (param.length <= cpuIndex) {
continue;
}
String cpu = param[cpuIndex];
if (cpu.endsWith("%")) {
cpu = cpu.substring(0, cpu.lastIndexOf("%"));
}
return Double.parseDouble(cpu) / Runtime.getRuntime().availableProcessors();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
return 0;
}
private static int getCPUIndex(String line) {
if (line.contains("CPU")) {
String[] titles = line.split("\\s+");
for (int i = 0; i < titles.length; i++) {
if (titles[i].contains("CPU")) {
return i;
}
}
}
return -1;
}
/**
* 获取应用的CPU占用率单位%保留1位小数
* @param pid
* @return
*/
public static double getCpuUsagePercentWithPid(int pid) {
double usage = 0.0;
String[] result1;
String[] result2;
if (pid >= 0) {
result1 = getCpuWithPid(pid);
if (null != result1) {
pCpu = Double.parseDouble(result1[1])
+ Double.parseDouble(result1[2]);
}
result2 = getSystemCpu();
if (null != result2) {
aCpu = 0.0;
for (int i = 2; i < result2.length; i++) {
if (result2[i] != null) {
aCpu += Double.parseDouble(result2[i]);
}
}
}
if ((aCpu - oaCpu) != 0) {
usage = DoubleUtils.div(((pCpu - opCpu) * 100.00),
(aCpu - oaCpu), 1);
if (usage < 0) {
usage = 0;
}
else if (usage > 100)
{
usage = 100;
}
}
opCpu = pCpu;
oaCpu = aCpu;
}
pJif = pCpu;
return usage;
}
/**
* 获取CPU使用率
*
* @return CPU使用率单位%
*/
public static double getSysCpuUsagePercent() {
double usage = 0.0;
if (initCpu) {
initCpu = false;
RandomAccessFile reader = null;
try {
reader = new RandomAccessFile("/proc/stat",
"r");
String load;
load = reader.readLine();
String[] toks = load.split(" ");
oIdle = Double.parseDouble(toks[5]);
oCpu = Double.parseDouble(toks[2])
+ Double.parseDouble(toks[3])
+ Double.parseDouble(toks[4])
+ Double.parseDouble(toks[6])
+ Double.parseDouble(toks[8])
+ Double.parseDouble(toks[7]);
} catch (IOException e) {
e.printStackTrace();
}
finally
{
FileUtil.closeRandomAccessFile(reader);
}
} else {
RandomAccessFile reader = null;
try {
reader = new RandomAccessFile("/proc/stat", "r");
String load;
load = reader.readLine();
String[] toks = load.split(" ");
double cIdle = Double.parseDouble(toks[5]);
double cCpu = Double.parseDouble(toks[2])
+ Double.parseDouble(toks[3])
+ Double.parseDouble(toks[4])
+ Double.parseDouble(toks[6])
+ Double.parseDouble(toks[8])
+ Double.parseDouble(toks[7]);
if (0 != ((cCpu + cIdle) - (oCpu + oIdle))) {
usage = DoubleUtils.div((100.00 * ((cCpu - oCpu))),
((cCpu + cIdle) - (oCpu + oIdle)), 1);
if (usage < 0) {
usage = 0;
}
else if (usage > 100)
{
usage = 100;
}
}
oCpu = cCpu;
oIdle = cIdle;
} catch (IOException e) {
e.printStackTrace();
} finally {
FileUtil.closeRandomAccessFile(reader);
}
}
return usage;
}
private static String[] getCpuWithPid(int pid) {
String cpuPath = "/proc/" + pid + "/stat";
String cpu = "";
String[] result = new String[3];
File f = new File(cpuPath);
// 部分进程信息无法读取
if (!f.exists() || !f.canRead())
{
return result;
}
FileReader fr = null;
BufferedReader localBufferedReader = null;
try {
fr = new FileReader(f);
localBufferedReader = new BufferedReader(fr, 8192);
cpu = localBufferedReader.readLine();
if (null != cpu) {
String[] cpuSplit = cpu.split(" ");
result[0] = cpuSplit[1];
result[1] = cpuSplit[13];
result[2] = cpuSplit[14];
}
}catch (IOException e) {
e.printStackTrace();
}
FileUtil.closeReader(localBufferedReader);
return result;
}
private static String[] getSystemCpu() {
String cpuPath = "/proc/stat";
String cpu = "";
String[] result = new String[7];
File f = new File(cpuPath);
if (!f.exists() || !f.canRead())
{
return result;
}
FileReader fr = null;
BufferedReader localBufferedReader = null;
try {
fr = new FileReader(f);
localBufferedReader = new BufferedReader(fr, 8192);
cpu = localBufferedReader.readLine();
if (null != cpu) {
result = cpu.split(" ");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
FileUtil.closeReader(localBufferedReader);
return result;
}
public static String getCpuUsageByCmd() {
java.lang.Process process;
StringBuilder sb = new StringBuilder();
String line;
String cmd = "dumpsys cpuinfo";
try {
process = Runtime.getRuntime().exec(
new String[] { "sh", "-c", cmd });
BufferedReader br = new BufferedReader(new InputStreamReader(
process.getInputStream()));
while (((line = br.readLine()) != null)) {
// 去掉空白行数据
line = line.trim();
if (line.equals("")) {
continue;
}
sb.append(line);
sb.append("\r\n");
}
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 获取进程的CPU使用时间片
*
* @return 进程的CPU使用时间片
*/
public long getJif() {
return (long)pJif;
}
}

View File

@@ -0,0 +1,44 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils
import java.lang.Exception
import java.math.BigDecimal
object DoubleUtils {
fun mul(d1: Double, d2: Double): Double {
val bd1 = BigDecimal(d1.toString())
val bd2 = BigDecimal(d2.toString())
return try {
bd1.multiply(bd2).toDouble()
} catch (e: Exception) {
e.printStackTrace()
0.0
}
}
@JvmStatic
fun div(d1: Double, d2: Double, scale: Int): Double {
val bd1 = BigDecimal(d1.toString())
val bd2 = BigDecimal(d2.toString())
return try {
// 直接向下取整
bd1.divide(bd2, scale, BigDecimal.ROUND_DOWN).toDouble()
} catch (e: Exception) {
e.printStackTrace()
0.0
}
}
/**
* 四舍五入
* scale:保留多少个小数位
*/
@JvmStatic
fun keepDecimal(v: Double, scale: Int = 1): Double {
if (scale < 0) {
throw IllegalArgumentException("The scale must be a positive integer or zero")
}
return BigDecimal(v).setScale(scale, BigDecimal.ROUND_HALF_UP).toDouble()
}
}

View File

@@ -0,0 +1,304 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils
import android.net.LocalSocket
import android.util.Log
import java.io.*
import java.lang.Exception
import java.net.Socket
import java.nio.channels.FileChannel
object FileUtil {
private const val TAG = "FileUtil"
const val separator = "/"
fun isPathStringValid(path: String?): Boolean {
if (null == path || path.isEmpty()) {
return false
}
if (path.contains(":") || path.contains("*") || path.contains("?")
|| path.contains("\"") || path.contains("<")
|| path.contains(">") || path.contains("|")
) {
Log.w(TAG, "filename can not contains:*:?\"<>|")
return false
}
return true
}
fun isPath(path: String): Boolean {
return path.contains(separator) || path.contains("\\")
}
fun getPath(path: String): String {
val la = path.lastIndexOf(separator)
return path.substring(0, la)
}
fun convertValidFilePath(path: String, defPosfix: String): String {
var filePath = path
if (path.contains(separator) || path.contains("\\")) {
val la = filePath.lastIndexOf(".")
if (la < 0) {
filePath = path + defPosfix
} else {
val temp = filePath.substring(la)
if (temp.contains(separator) || temp.contains("\\")) {
// "."是目录名的一部分而不是后缀名的情况
filePath = path + defPosfix
}
// else fileName = fileName
}
} else {
if (!path.contains(".")) // 没有有后缀
{
filePath = filePath + defPosfix
}
}
return filePath
}
fun isFileExists(file: String?): Boolean {
try {
val f = File(file)
if (!f.exists()) {
return false
}
} catch (e: Exception) {
e.printStackTrace()
return false
}
return true
}
fun isFileValid(f: File): Boolean {
if (!f.exists()) {
try {
f.createNewFile()
} catch (e: IOException) {
return false
}
f.delete()
}
return true
}
fun isFileValid(parent: File?, name: String?): Boolean {
val f = File(parent, name)
return isFileValid(f)
}
/**
* 删除存在的文件
*
* @param filePath
*/
fun delExistFile(filePath: String?) {
val f = File(filePath)
if (f.exists()) f.delete()
}
/**
* 关闭bufferReader
*
* @param br
*/
@JvmStatic
fun closeReader(br: Reader?) {
if (br != null) {
try {
br.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 关闭Writer
*
* @param wr
*/
fun closeWriter(wr: Writer?) {
if (wr != null) {
try {
wr.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* flush Writer
*
* @param wr
*/
fun flushWriter(wr: Writer?) {
if (wr != null) {
try {
wr.flush()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 输入流的关闭
*
* @param in
*/
fun closeInputStream(`in`: InputStream?) {
if (`in` != null) {
try {
`in`.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 输出流的关闭
*
* @param out
*/
fun closeOutputStream(out: OutputStream?) {
if (out != null) {
try {
out.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 文件管道的关闭
*
* @param chl
*/
fun closeFileChannel(chl: FileChannel?) {
if (chl != null) {
try {
chl.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* RandomAccessFile的关闭
*
* @param f RandomAccessFile对象
*/
@JvmStatic
fun closeRandomAccessFile(f: RandomAccessFile?) {
if (f != null) {
try {
f.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* Socket的关闭
*
* @param s Socket对象
*/
fun colseSocket(s: Socket?) {
if (s != null) {
try {
s.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* LocalSocket的关闭
*
* @param s Socket对象
*/
fun colseLocalSocket(s: LocalSocket?) {
if (s != null) {
try {
s.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
fun deleteFile(file: File) {
if (file.exists()) { // 判断文件是否存在
if (file.isFile) { // 判断是否是文件
file.delete() // delete()方法 你应该知道 是删除的意思;
} else if (file.isDirectory) { // 否则如果它是一个目录
val files = file.listFiles() // 声明目录下所有的文件 files[];
for (i in files.indices) { // 遍历目录下所有的文件
deleteFile(files[i]) // 把每个文件 用这个方法进行迭代
}
}
file.delete()
} else {
Log.e(TAG, "文件不存在!" + "n")
}
}
/**
* 拷贝文件
*
* @param s 源文件
* @param t 目标文件
*/
fun copyFile(s: File?, t: File) {
var fi: FileInputStream? = null
var fo: FileOutputStream? = null
var `in`: FileChannel? = null
var out: FileChannel? = null
try {
if (!t.exists()) {
t.createNewFile()
}
fi = FileInputStream(s)
fo = FileOutputStream(t)
`in` = fi.channel
out = fo.channel
// 连接两个通道并且从in通道读取然后写入out通道
`in`.transferTo(0, `in`.size(), out)
} catch (e: IOException) {
e.printStackTrace()
} finally {
closeOutputStream(fo)
closeInputStream(fi)
closeFileChannel(`in`)
closeFileChannel(out)
}
}
fun copyInputToFile(`in`: InputStream?, path: String?) {
var bis: BufferedInputStream? = null
var fos: FileOutputStream? = null
try {
val buffer = ByteArray(10 * 1024)
bis = BufferedInputStream(`in`)
fos = FileOutputStream(path)
var a = bis.read(buffer, 0, buffer.size)
while (a != -1) {
fos.write(buffer, 0, a)
fos.flush()
a = bis.read(buffer, 0, buffer.size)
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
closeOutputStream(fos)
closeInputStream(bis)
closeInputStream(`in`)
}
}
}

View File

@@ -0,0 +1,54 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils;
import android.os.Debug;
import android.util.Log;
import java.lang.reflect.Field;
public class HookUtils {
private static final String TAG = "HookUtils";
/**
* 单位为MB
* 0: 总PSS1: dalvik总Pss, 2: native总Pss, 3: other总Pss
* @param memoryInfo
* @return
*/
public static double[] getPssArray(Debug.MemoryInfo memoryInfo) {
double[] pssArray = new double[4];
if (memoryInfo != null) {
double totalPss = DoubleUtils.keepDecimal(memoryInfo.getTotalPss() / 1024.0, 3);
// Log.d(TAG, "===========Hook PSS 开始:===========\n");
// Log.d(TAG, "总PSS内存为" + totalPss);
pssArray[0] = totalPss;
try {
Field dalvikField = memoryInfo.getClass().getField("dalvikSwappedOutPss");
double dalvikPss = DoubleUtils.keepDecimal(memoryInfo.dalvikPss / 1024.0, 3);
double dalvikSwappedOutPss = DoubleUtils.keepDecimal((int) dalvikField.get(memoryInfo) / 1024.0, 3);
pssArray[1] = dalvikPss + dalvikSwappedOutPss;
// Log.d(TAG, "dalvikPss is:" + dalvikSwappedOutPss);
// Log.d(TAG, "dalvikSwappedOutPss is:" + dalvikPss + "\n\n");
Field nativeField = memoryInfo.getClass().getField("nativeSwappedOutPss");
double nativePss = DoubleUtils.keepDecimal(memoryInfo.nativePss / 1024.0, 3);
double nativeSwappedOutPss = DoubleUtils.keepDecimal((int) nativeField.get(memoryInfo) / 1024.0, 3);
pssArray[2] = nativePss + nativeSwappedOutPss;
// Log.d(TAG, "nativePss is:" + nativePss);
// Log.d(TAG, "nativeSwappedOutPss is:" + nativeSwappedOutPss + "\n\n");
Field otherField = memoryInfo.getClass().getField("otherSwappedOutPss");
double otherPss = DoubleUtils.keepDecimal(memoryInfo.otherPss / 1024.0, 3);
double otherSwappedOutPss = DoubleUtils.keepDecimal((int) otherField.get(memoryInfo) / 1024.0, 3);
pssArray[3] = otherPss + otherSwappedOutPss;
// Log.d(TAG, "otherPss is:" + otherPss);
// Log.d(TAG, "otherSwappedOutPss is:" + otherSwappedOutPss + "\n\n");
//
// Log.d(TAG, "===========Hook PSS 结束!===========\n");
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
}
return pssArray;
}
}

View File

@@ -0,0 +1,180 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Debug;
import java.lang.reflect.Method;
/**
* 内存信息工具类。
*/
public class MemUtils {
public static double[] getPssArray(Context context, int[] pids) {
Debug.MemoryInfo[] memoryArray = getMemoryInfo(context, pids);
if (memoryArray.length > 0) {
return HookUtils.getPssArray(memoryArray[0]);
} else {
return new double[4];
}
}
/**
* 单位MB
*/
public static double getPssMemValue(Context context, int[] pids) {
double value = 0.0;
Debug.MemoryInfo[] memoryArray = getMemoryInfo(context, pids);
if (memoryArray.length > 0) {
value = DoubleUtils.keepDecimal(memoryArray[0].getTotalPss() / 1024.0, 1);
}
return value;
}
/**
* 只能获取本应用的PSS内存占系统百分比单位%保留1位小数
* @return
*/
public static double getPidMemPercent() {
double percent = 0.0;
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
int pidTotalPss = memInfo.getTotalPss();
long systemTotalMem = getTotalMem();
percent = DoubleUtils.keepDecimal(pidTotalPss * 100.0 / systemTotalMem, 1);
return percent;
}
/**
* 获取本应用进程总pss内存单位MB
*/
public static double getPssMem() {
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
return DoubleUtils.keepDecimal(memInfo.getTotalPss() / 1024.0, 1);
}
/**
* 获取系统空闲内存占用百分比: 单位%
* @return
*/
public static double getSystemMemPercent() {
double percent = 0.0;
long[] memInfo = getMemInfo();
long free = memInfo[1] + memInfo[2] + memInfo[3];
long total = memInfo[0];
percent = DoubleUtils.keepDecimal(free * 100.0 / total, 1);
return percent;
}
/**
* 获取空闲内存
*
* @return 空闲内存单位KB
*/
public static long getFreeMem() {
long[] memInfo = getMemInfo();
return memInfo[1] + memInfo[2] + memInfo[3];
}
/**
* 获取总内存
*
* @return 总内存单位KB
*/
public static long getTotalMem() {
long[] memInfo = getMemInfo();
return memInfo[0];
}
/**
* 获取内存信息total、free、buffers、cached单位KB
*
* @return 内存信息
*/
public static long[] getMemInfo() {
long memInfo[] = new long[4];
try {
Class<?> procClazz = Class.forName("android.os.Process");
Class<?> paramTypes[] = new Class[] { String.class, String[].class,
long[].class };
Method readProclines = procClazz.getMethod("readProcLines",
paramTypes);
Object args[] = new Object[3];
final String[] memInfoFields = new String[] { "MemTotal:",
"MemFree:", "Buffers:", "Cached:" };
long[] memInfoSizes = new long[memInfoFields.length];
memInfoSizes[0] = 30;
memInfoSizes[1] = -30;
args[0] = "/proc/meminfo";
args[1] = memInfoFields;
args[2] = memInfoSizes;
if (null != readProclines) {
readProclines.invoke(null, args);
for (int i = 0; i < memInfoSizes.length; i++) {
memInfo[i] = memInfoSizes[i];
}
}
} catch (Exception e) {
e.printStackTrace();
}
return memInfo;
}
public static long[] getHeapNative() {
int Native_HeapSize = 0;
int Native_HeapAlloc = 1;
long[] value = new long[2];
value[Native_HeapSize] = Debug.getNativeHeapSize() >> 10;
value[Native_HeapAlloc] = Debug.getNativeHeapAllocatedSize() >> 10;
return value;
}
public static long[] getHeapDalvik() {
int Total_HeapSize = 0;
int Total_HeapAlloc = 1;
long[] value_total = new long[2];
value_total[Total_HeapSize] = Runtime.getRuntime().totalMemory() >> 10;
value_total[Total_HeapAlloc] = (Runtime.getRuntime().totalMemory() - Runtime
.getRuntime().freeMemory()) >> 10;
long[] value_native = getHeapNative();
int Dalvik_HeapSize = 0;
int Dalvik_HeapAlloc = 1;
long[] value_dalvik = new long[2];
value_dalvik[Dalvik_HeapSize] = value_total[Total_HeapSize]
- value_native[0];
value_dalvik[Dalvik_HeapAlloc] = value_total[Total_HeapAlloc]
- value_native[1];
return value_dalvik;
}
/**
* 获取堆内存数据精确到KB Get VM Heap Size by calling:
* Runtime.getRuntime().totalMemory(); Get Allocated VM Memory by calling:
* Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
* Get VM Heap Size Limit by calling: Runtime.getRuntime().maxMemory() Get
* Native Allocated Memory by calling: Debug.getNativeHeapAllocatedSize();
*/
public static long[] getVM() {
long[] value = new long[5];
value[0] = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime()
.freeMemory()) >> 10;
value[1] = Runtime.getRuntime().totalMemory() >> 10;
value[2] = Debug.getNativeHeapAllocatedSize() >> 10;
value[3] = Debug.getNativeHeapSize() >> 10;
value[4] = Debug.getGlobalAllocSize() >> 10;
return value;
}
private static Debug.MemoryInfo[] getMemoryInfo(Context context, int[] pids) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
return am.getProcessMemoryInfo(pids);
}
}

View File

@@ -5,7 +5,6 @@ import com.mogo.eagle.core.data.deva.scene.SceneModule
import com.mogo.eagle.core.data.deva.scene.SceneModuleTAG
import com.mogo.eagle.core.data.deva.scene.SceneTAG
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.Scene.Companion.scene
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_ADAS_IMPL
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
@@ -71,7 +70,6 @@ class SceneManager {
//默认未创建的符合scene tag首次初始化logger=true
scene.addChangeListener { change ->
Logger.i("emArrow","scene change : $change")
sceneModuleTAG.map.iterator().forEach { map ->
val sceneModule = map.value
sceneModule.name?.let {

View File

@@ -12,6 +12,7 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.*
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.util.*
import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus
import com.zhjt.mogo_core_function_devatools.status.entity.GpsStatus
@@ -41,51 +42,51 @@ object StatusManager {
private const val TAG = "StatusManager"
private lateinit var model: StatusModel
private var timer: Job? = null
// private var timer: Job? = null
private var hasInit = false
private val listeners by lazy { CopyOnWriteArrayList<IStatusListener>() }
private var container: WeakReference<ViewGroup>? = null
private val listener = object : IMoGoAutopilotStatusListener {
override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
super.onAutopilotGuardian(guardianInfo)
guardianInfo?.code?.takeIf {
Logger.d(TAG, "-- onAutopilotGuardian ---: code: $it")
it.contains("RTK_STATUS", true) || it.contains("CAN", true) || it == "ILCT_RTK_OR_SLAM_CHANGE"
}?.run {
Logger.d(TAG, "-- onAutopilotGuardian trigger req ---: code: $this")
req()
}
}
}
// private val listener = object : IMoGoAutopilotStatusListener {
// override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
// super.onAutopilotGuardian(guardianInfo)
// guardianInfo?.code?.takeIf {
// CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian ---: code: $it")
// it.contains("RTK_STATUS", true) || it.contains("CAN", true) || it == "ILCT_RTK_OR_SLAM_CHANGE"
// }?.run {
// CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian trigger req ---: code: $this")
// req()
// }
// }
// }
private val appStateListener = object : IAppStateListener {
override fun onAppStateChanged(isForeground: Boolean) {
if (isForeground) {
req()
} else {
timer?.cancel()
}
}
}
// private val appStateListener = object : IAppStateListener {
//
// override fun onAppStateChanged(isForeground: Boolean) {
// if (isForeground) {
// req()
// } else {
// timer?.cancel()
// }
// }
// }
private val flows: ArrayList<IFlow<out Status>> by lazy {
ArrayList()
}
private fun req() {
timer?.cancel()
model.viewModelScope.launch(Dispatchers.IO) {
CallerAutoPilotManager.sendStatusQueryReq()
while (true) {
delay(60000) //一分钟主动请求一次
CallerAutoPilotManager.sendStatusQueryReq()
}
}.also {
timer = it
}
}
// private fun req() {
// timer?.cancel()
// model.viewModelScope.launch(Dispatchers.IO) {
// CallerAutoPilotManager.sendStatusQueryReq()
// while (true) {
// delay(60000) //一分钟主动请求一次
// CallerAutoPilotManager.sendStatusQueryReq()
// }
// }.also {
// timer = it
// }
// }
fun init(ctx: Context) {
if (hasInit) {
@@ -108,9 +109,9 @@ object StatusManager {
private fun onCreate(ctx: Context) {
val values = model.status.value?.second ?: throw IllegalStateException("state is not right.")
CallerAutoPilotStatusListenerManager.addListener(TAG, listener)
AppStateManager.registerAppStateListener(appStateListener)
req()
// CallerAutoPilotStatusListenerManager.addListener(TAG, listener)
// AppStateManager.registerAppStateListener(appStateListener)
// req()
values.map {
when (it) {
is CanStatus -> CanImpl(ctx)
@@ -165,9 +166,9 @@ object StatusManager {
private fun onDestroy(ctx: Context) {
hasInit = false
CallerAutoPilotStatusListenerManager.removeListener(TAG)
AppStateManager.unRegisterAppStateListener(appStateListener)
timer?.cancel()
// CallerAutoPilotStatusListenerManager.removeListener(TAG)
// AppStateManager.unRegisterAppStateListener(appStateListener)
// timer?.cancel()
flows.forEach {
it.onDestroy()
}

View File

@@ -145,7 +145,25 @@ class CanStatus(var enabled: Boolean = false): Status() {
*/
class TracingStatus(var state: Tracing = UNKNOWN): Status() {
enum class Tracing(val code: String? = "") {
enum class Tracing(val code: String? = "", var extra: Map<String, String>? = null) {
/**
* 类型切换
*/
MAP_TRA_TYPE("IMAP_TRA_TYPE"),
/**
* 地图数据存在
*/
MAP_DATA_EXIST("IMAP_DATA_EXIST"),
/**
* 地图数据不存在
*/
MAP_DATA_NOT_EXIST("EMAP_DATA_NOT_EXIST"),
/**
* 寻迹-已找到轨迹文件
*/
@@ -182,12 +200,10 @@ class TracingStatus(var state: Tracing = UNKNOWN): Status() {
UNKNOWN;
fun isException(): Boolean {
val c1 = when (this) {
TRACK_FINDED, TRACK_NOT_EXIST, TRACK_LOAD_FAIL, ROUTE_FAILED, UNKNOWN -> true
else -> false
if (this == TRACK_LOADED || this == ROUTE_LOADED) {
return false
}
val c2 = CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().state != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
return c1 and c2
return true
}
}
@@ -212,14 +228,46 @@ class TracingStatus(var state: Tracing = UNKNOWN): Status() {
override fun isException(): Boolean = state.isException()
}
fun String.toState(): Tracing? {
fun String.toState(msg: String?): Tracing? {
val ss = msg?.split("|")
var extra: Map<String, String>? = null
if (ss != null && ss.isNotEmpty()) {
val sb = StringBuilder()
for (element in ss) {
sb.append(element)
sb.append(",")
}
if (sb.isNotEmpty()) {
sb.setLength(sb.length - 1)
}
extra = mutableMapOf("extra" to sb.toString())
}
return when(this) {
"IMAP_TRA_EXIST" -> TRACK_FINDED
"IMAP_TRA_LOADED" -> TRACK_LOADED
"EMAP_TRA_NOT_EXIST" -> TRACK_NOT_EXIST
"EMAP_TRA_LOAD_FAILED" -> TRACK_LOAD_FAIL
"IMAP_TRA_ROUTING" -> ROUTE_LOADED
"IMAP_TRA_EXIST" -> TRACK_FINDED.apply {
this.extra = extra
}
"IMAP_TRA_LOADED" -> TRACK_LOADED.apply {
this.extra = extra
}
"EMAP_TRA_NOT_EXIST" -> TRACK_NOT_EXIST.apply {
this.extra = extra
}
"EMAP_TRA_LOAD_FAILED" -> TRACK_LOAD_FAIL.apply {
this.extra = extra
}
"IMAP_TRA_ROUTING" -> ROUTE_LOADED.apply {
this.extra = extra
}
"EMAP_HADMAP_ENGINE_NO_ROUTING_INFO" -> ROUTE_FAILED
"IMAP_TRA_TYPE" -> MAP_TRA_TYPE.apply {
this.extra = extra
}
"MAP_DATA_EXIST" -> MAP_DATA_EXIST.apply {
this.extra = extra
}
"MAP_DATA_NOT_EXIST" -> MAP_DATA_NOT_EXIST.apply {
this.extra = extra
}
else -> null
}
}

View File

@@ -97,7 +97,7 @@ internal class CanImpl(ctx: Context): IFlow<CanStatus>(ctx), IMoGoAutopilotVehic
private fun timeOutCheck() {
job?.safeCancel()
launch(Dispatchers.Default) {
launch(Dispatchers.Unconfined) {
delay(4000)
send(CanStatus(isCanEnabled()))
}.also { job = it }

View File

@@ -35,21 +35,39 @@ internal class GpsImpl(ctx: Context): IFlow<GpsStatus>(ctx) {
}
private val onClose = {
send(false, PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION))
send(false, isGrandFineLocation())
}
private val onOpen = {
send(true, PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION))
send(true, isGrandFineLocation())
}
private fun isGrandFineLocation(): Boolean = try {
PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
} catch (t: Throwable) {
t.printStackTrace()
false
}
private val onStateListener = object : IAppStateListener {
override fun onAppStateChanged(isForeground: Boolean) {
if (isForeground) {
send(isLocationEnabled(), isGrandFineLocation())
}
}
}
override fun onCreate() {
val isGranted = PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
val isGranted = isGrandFineLocation()
AppStateManager.registerAppStateListener(onStateListener)
send(isLocationEnabled(), isGranted)
if (!isGranted) {
PermissionUtils.requestAccessFineLocation(object : SimpleCallback {
override fun onGranted() {
Log.d(TAG,"权限: ${Manifest.permission.ACCESS_FINE_LOCATION} 被授予了....")
send(enabled = isLocationEnabled(), isGranted = false)
send(enabled = isLocationEnabled(), isGranted = true)
}
override fun onDenied() {
@@ -80,6 +98,7 @@ internal class GpsImpl(ctx: Context): IFlow<GpsStatus>(ctx) {
} catch (t: Throwable) {
t.printStackTrace()
}
AppStateManager.unRegisterAppStateListener(onStateListener)
}
}

View File

@@ -78,12 +78,21 @@ internal class NetsImpl(ctx: Context): IFlow<NetStatus>(ctx) {
private var loopCheckAndSendJob: Job? = null
private fun checkAndSend() {
val connectionInfo = wifiMgr.connectionInfo
val enabled = isNetConnected()
val name = if (isLocationEnabled()) connectionInfo.ssid?.replace(Regex("[\\W]"), "") else "WI-FI"
loopCheckAndSendJob?.safeCancel()
launch(Dispatchers.Default) { delay(1000); checkAndSend() }.also { loopCheckAndSendJob = it }
send(enabled, name)
launch(Dispatchers.Unconfined) {
val connectionInfo = wifiMgr.connectionInfo
val enabled = isNetConnected()
val name =
try {
if (isLocationEnabled()) connectionInfo.ssid?.replace(Regex("[\\W]"), "") else "WI-FI"
} catch (t: Throwable) {
t.printStackTrace()
"WI-FI"
}
send(enabled, name)
delay(1000);
checkAndSend()
}.also { loopCheckAndSendJob = it }
}
private fun isLocationEnabled() =

View File

@@ -4,7 +4,8 @@ import android.content.*
import android.util.*
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.call.autopilot.*
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.zhjt.mogo_core_function_devatools.status.entity.RTKStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
import kotlinx.coroutines.*
@@ -31,7 +32,7 @@ internal class RTKImpl(ctx: Context): IFlow<RTKStatus>(ctx), IMoGoAutopilotStatu
override fun onCreate() {
send(RTKStatus(getDesc(), getCode()))
Logger.d(TAG, "-- onCreate --")
CallerLogger.d("$M_DEVA$TAG", "-- onCreate --")
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerAutopilotCarStatusListenerManager.addListener(TAG, this)
if (CallerAutoPilotManager.isConnected()) {
@@ -44,7 +45,7 @@ internal class RTKImpl(ctx: Context): IFlow<RTKStatus>(ctx), IMoGoAutopilotStatu
return
}
check?.takeIf { it.isActive }?.cancel()
launch {
launch(Dispatchers.Unconfined) {
CallerAutoPilotManager.sendStatusQueryReq()
delay(5000)
isOldVersion.set(true)
@@ -67,7 +68,7 @@ internal class RTKImpl(ctx: Context): IFlow<RTKStatus>(ctx), IMoGoAutopilotStatu
override fun onAutopilotIpcConnectStatusChanged(status: Int, reason: String?) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
if (!CallerAutoPilotManager.isConnected()) {
Logger.d(TAG, "工控机断开了....")
CallerLogger.d("$M_DEVA$TAG", "工控机断开了....")
healthInfo.set(null)
send(RTKStatus("", -1))
}
@@ -82,7 +83,7 @@ internal class RTKImpl(ctx: Context): IFlow<RTKStatus>(ctx), IMoGoAutopilotStatu
if (isRTKEnabled()) {
send(RTKStatus("RTK", 0))
timeOutCheck?.takeIf { it.isActive }?.cancel()
launch {
launch(Dispatchers.Unconfined) {
delay(4000)
send(RTKStatus("", -1))
}.also {
@@ -114,7 +115,7 @@ internal class RTKImpl(ctx: Context): IFlow<RTKStatus>(ctx), IMoGoAutopilotStatu
override fun onDestroy() {
super.onDestroy()
isOldVersion.set(false)
Logger.d(TAG, "-- onDestroy --")
CallerLogger.d("$M_DEVA$TAG", "-- onDestroy --")
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerAutopilotCarStatusListenerManager.removeListener(TAG)
}

View File

@@ -1,9 +1,9 @@
package com.zhjt.mogo_core_function_devatools.status.flow.trace
import android.content.*
import android.util.*
import com.mogo.eagle.core.data.autopilot.*
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener.Companion.STATUS_AUTOPILOT_RUNNING
import com.mogo.eagle.core.function.call.autopilot.*
import com.zhjt.mogo_core_function_devatools.status.entity.*
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.*
@@ -20,7 +20,8 @@ internal class TracingImpl(ctx: Context): IFlow<TracingStatus>(ctx), IMoGoAutopi
override fun onCreate() {
val code = CallerAutoPilotStatusListenerManager.getAutoPilotReportMessageCode()
val state = code.toState() ?: UNKNOWN
val msg = CallerAutoPilotStatusListenerManager.getAutoPilotReportMessageContent()
val state = code.toState(msg) ?: UNKNOWN
old = state
send(TracingStatus(state))
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
@@ -30,27 +31,30 @@ internal class TracingImpl(ctx: Context): IFlow<TracingStatus>(ctx), IMoGoAutopi
override fun onAutopilotGuardian(guardianInfo: MogoReportMessage?) {
super.onAutopilotGuardian(guardianInfo)
val current = guardianInfo?.code
val newState = current?.toState()
if (newState != null && newState != old) {
send(TracingStatus(newState))
val newState = current?.toState(guardianInfo.msg)
if (newState != null) {
old = newState
send(TracingStatus(newState))
}
}
override fun onAutopilotIpcConnectStatusChanged(status: Int, reason: String?) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
if (!CallerAutoPilotManager.isConnected()) {
old = UNKNOWN
send(TracingStatus(UNKNOWN))
}
}
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
super.onAutopilotStatusResponse(autoPilotStatusInfo)
if (autoPilotStatusInfo.state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
if (autoPilotStatusInfo.state != STATUS_AUTOPILOT_RUNNING) {
old = UNKNOWN
send(TracingStatus(UNKNOWN))
return
}
if (old.isException() && autoPilotStatusInfo.state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
if (old.isException()) {
old = TRACK_LOADED
send(TracingStatus(TRACK_LOADED))
}
}

View File

@@ -6,8 +6,9 @@ import android.widget.*
import androidx.core.content.*
import androidx.recyclerview.widget.*
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.util.*
import com.zhjt.mogo_core_function_devatools.*
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.R.drawable
import com.zhjt.mogo_core_function_devatools.status.entity.*
@@ -15,10 +16,13 @@ import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.*
import com.zhjt.mogo_core_function_devatools.status.ui.adapter.StatusAdapter.StatusViewHolder
import kotlinx.coroutines.*
internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): RecyclerView.Adapter<StatusViewHolder>() {
companion object {
const val TAG = "StatusAdapter"
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StatusViewHolder =
StatusViewHolder(LayoutInflater.from(ctx).inflate(R.layout.layout_status_bar_item, parent, false))
@@ -69,7 +73,7 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
}
is TracingStatus -> {
when(status.state) {
ROUTE_FAILED, TRACK_LOAD_FAIL, TRACK_NOT_EXIST, TRACK_FINDED, UNKNOWN -> {
MAP_DATA_NOT_EXIST, MAP_DATA_EXIST, MAP_TRA_TYPE, ROUTE_FAILED, TRACK_LOAD_FAIL, TRACK_NOT_EXIST, TRACK_FINDED, UNKNOWN -> {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_trace_unkown)
}
TRACK_LOADED -> {
@@ -116,7 +120,26 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
else ->
"定位异常"
}
is TracingStatus -> "轨迹类型:${ if (status.state == TRACK_LOADED) "循迹" else if (status.state == ROUTE_LOADED) "自主算路" else "暂无轨迹" }"
is TracingStatus -> {
val extra = status.state.extra
val extraDesc = if (extra != null && extra.isNotEmpty()) extra.values.joinToString(",") else ""
CallerLogger.d("$M_DEVA$TAG", "traceing_state: $status -> extra: $extraDesc :: extra: $extra")
when(status.state) {
//"轨迹类型:${ if (status.state == TRACK_LOADED) "循迹" else if (status.state == ROUTE_LOADED) "自主算路" else "暂无轨迹" }"
MAP_TRA_TYPE -> {
"暂无轨迹"
}
MAP_DATA_EXIST -> "地图数据存在,正在加载${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
MAP_DATA_NOT_EXIST -> "地图数据不存在${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_FINDED -> "轨迹类型:循迹(已找到轨迹)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_LOADED -> "轨迹类型:循迹(加载成功)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_NOT_EXIST -> "轨迹类型:循迹(未找到轨迹)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_LOAD_FAIL -> "轨迹类型:循迹(加载失败)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
ROUTE_LOADED -> "轨迹类型:自主算路(加载成功)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
ROUTE_FAILED -> "轨迹类型:自主算路(加载失败)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
UNKNOWN -> "暂无轨迹"
}
}
}
}
}

View File

@@ -57,6 +57,13 @@ class TraceManager : IMoGoCloudListener {
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_TRAFFIC_LIGHT)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS] =
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_PLANNING_OBJECTS)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_ACTIONS] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_PLANNING_ACTIONS)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_NATIVE_LEAK] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_RECORD_NATIVE_LEAK)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_CLOUD_V2N] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_CLOUD_WEB_SOCKET_V2N)
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS] =
ChainLogParam(true, "ADAS连接状态")
@@ -70,8 +77,16 @@ class TraceManager : IMoGoCloudListener {
ChainLogParam(false, "ADAS车前引导线")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_VEHICLE] =
ChainLogParam(false, "ADAS车辆底盘数据")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT] =
ChainLogParam(false, "ADAS红绿灯数据")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS] =
ChainLogParam(false, "ADAS PLANNING 感知障碍物")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_ACTIONS] =
ChainLogParam(true, "ADAS PLANNING 决策行为")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_NATIVE_LEAK] =
ChainLogParam(true, "Native Leak Record")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_CLOUD_V2N] =
ChainLogParam(true, "Cloud WebSocket V2N")
FileWriteManager.getInstance()
.init(context, MoGoAiCloudClientConfig.getInstance().sn, pkgName, fwBuildMap)

View File

@@ -77,7 +77,6 @@ class UpgradeManager : IDownload {
if (downloadUrl != null) {
AppUtils.installApp(Config.downLoadPath + downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1))
}
findKey(downloadUrl) {
CallerDevaToolsUpgradeListenerManager.invokeUpgradeFinish(it)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#3B4577" />
<corners android:radius="32px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#29305E" />
<corners android:radius="48px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#29305E" />
<corners android:radius="20px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#2B6EFF" />
<corners android:radius="20px" />
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/case_list_select" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="@drawable/case_list_select" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="@drawable/case_list_select" android:state_selected="true" />
<item android:drawable="@drawable/case_list_select" android:state_focused="true" />
<item android:drawable="@drawable/case_list_normal" />
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#33E1E5FF" />
<corners android:radius="32px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#29305E" />
<corners android:radius="32px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#3B4577" />
<corners android:radius="24px" />
</shape>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.RoundConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="1110px"
android:layout_height="668px"
android:background="#3B4577"
app:roundLayoutRadius="32px"
>
<TextView
android:id="@+id/tvCaseListTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="case清单"
android:textColor="#FFFFFFFF"
android:textSize="56px"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="50px"
/>
<TextView
android:id="@+id/tvCancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消"
android:textColor="#FFFFFFFF"
android:textSize="52px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingBottom="50px"
android:gravity="center"
/>
<View
android:id="@+id/viewCancelDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#66B8BFE8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvCancel"
android:layout_marginBottom="50px"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvCaseList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCaseListTitle"
app:layout_constraintBottom_toTopOf="@id/viewCancelDivider"
android:layout_margin="50px"
/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="1270px"
android:layout_height="959px"
>
<TextView
android:id="@+id/tvCaseName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="56px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="50px"
/>
<View
android:id="@+id/viewVerticalLine"
android:layout_width="2px"
android:layout_height="160px"
android:background="#66B8BFE8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<View
android:id="@+id/viewHorizontalLine"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="#66B8BFE8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/viewVerticalLine"
/>
<TextView
android:id="@+id/tvSave"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/viewHorizontalLine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/viewVerticalLine"
android:text="保存"
android:textColor="#FFFFFFFF"
android:textSize="52px"
android:gravity="center"
/>
<TextView
android:id="@+id/tvCancel"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/viewHorizontalLine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/viewVerticalLine"
app:layout_constraintRight_toRightOf="parent"
android:text="取消"
android:textColor="#FFFFFFFF"
android:textSize="52px"
android:gravity="center"
/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clSearchLayout"
android:layout_width="1030px"
android:layout_height="96px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCaseName"
android:layout_marginTop="50px"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="@drawable/bad_case_search_bg"
>
<ImageView
android:id="@+id/ivSearch"
android:layout_width="38px"
android:layout_height="42px"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:src="@drawable/icon_bad_case_search"
android:layout_marginEnd="40px"
/>
<EditText
android:id="@+id/etSearch"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/ivSearch"
android:hint="topic搜索"
android:textSize="38px"
android:textColor="#FFFFFFFF"
android:textColorHint="#B3FFFFFF"
android:background="@null"
android:layout_marginStart="40px"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTopicList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="@id/clSearchLayout"
app:layout_constraintRight_toRightOf="@id/clSearchLayout"
app:layout_constraintTop_toBottomOf="@id/clSearchLayout"
app:layout_constraintBottom_toTopOf="@id/viewHorizontalLine"
android:layout_marginTop="50px"
android:layout_marginBottom="20dp"
android:scrollbars="vertical"
android:fadeScrollbars="false"
style="@style/rv_vertical_style"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/caseName"
android:layout_width="match_parent"
android:layout_height="116px"
android:textColor="#FFFFFFFF"
android:textSize="43px"
android:background="@drawable/case_list_selector"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:clickable="true"
android:focusable="true"
>
</TextView>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/caseName"
android:layout_width="match_parent"
android:layout_height="84px"
android:textColor="#FFFFFFFF"
android:textSize="34px"
android:background="@drawable/case_list_selector"
android:gravity="center"
android:layout_marginTop="20dp"
android:clickable="true"
android:focusable="true"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
>
</TextView>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topic_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@drawable/badcase_radio_button_style"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:textColor="#FFFFFFFF"
android:textSize="38px"
android:paddingStart="5dp"
android:gravity="center_vertical"
>
</CheckBox>

View File

@@ -308,15 +308,18 @@
android:layout_marginStart="@dimen/dp_30"
/>
<RadioGroup
android:id="@+id/rgRecordConfig"
android:layout_width="0dp"
android:layout_height="match_parent"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTemplate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/tvRecordTemplate"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvRecordTemplate"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="@dimen/dp_20"
android:background="@drawable/template_list_bg"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginBottom="@dimen/dp_50"
android:paddingBottom="10dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="bad_case_dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@drawable/bad_case_dialog_bg</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="rv_vertical_style">
<item name="android:scrollbarSize">5dp</item>
<item name="android:scrollbars">horizontal</item>
<item name="android:scrollbarThumbVertical">@drawable/rv_scroll_bar_thumb</item>
<item name="android:scrollbarTrackVertical">@drawable/rv_scroll_bar_track</item>
</style>
</resources>

View File

@@ -93,7 +93,7 @@ public class DispatchDialogManager {
}
private void voice() {
AIAssist.getInstance(mContext).speakTTSVoice("请立即停车!请立即停车!");
AIAssist.getInstance(mContext).speakTTSVoiceWithLevel("请立即停车!请立即停车!",AIAssist.LEVEL0);
}
public void releaseDialog() {

View File

@@ -75,6 +75,8 @@ dependencies {
implementation rootProject.ext.dependencies.android_start_up
implementation rootProject.ext.dependencies.cicle_indicator
implementation rootProject.ext.dependencies.koomnative
implementation rootProject.ext.dependencies.koomxhook
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
api rootProject.ext.dependencies.mogoaicloudservicesdk
api rootProject.ext.dependencies.mogocommons
@@ -137,6 +139,7 @@ dependencies {
api project(':core:mogo-core-function-call')
api project(':core:mogo-core-function-api')
api project(':libraries:mogo-adas')
api project(':libraries:map-usbcamera')
api project(':libraries:mogo-adas-other')
}

View File

@@ -2,8 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.eagle.core.function.hmi">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

View File

@@ -1,7 +1,9 @@
package com.mogo.eagle.core.function.hmi.ui.bindingcar
import android.content.Context
import android.opengl.Visibility
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
@@ -21,22 +23,23 @@ class UpgradeAppDialog(context: Context) : BaseFloatDialog(context), LifecycleOb
private val TAG = "UpgradeAppDialog"
private var confirmTv: TextView? = null
private var cancleTv: TextView? = null
private var upgradeTitleTv: TextView? = null
private var upgradeContentTv: TextView? = null
private var verticalLineView: View? = null
private var confirmForceTv: TextView? = null
private var tag: String? = null
private var downloarUrl: String? = null
private var mServiceApis: IMogoServiceApis? = null
private val statusChangedListenerForCheckNotice = IMogoStatusChangedListener { descriptor, isTrue ->
if (descriptor == StatusDescriptor.MAIN_PAGE_IS_BACKGROUND) {
dismiss()
}
}
init {
setContentView(R.layout.dialog_upgrade_app)
setCanceledOnTouchOutside(true)
upgradeTitleTv = findViewById(R.id.tv_upgrade_title)
upgradeContentTv = findViewById(R.id.tv_upgrade_content)
confirmTv = findViewById(R.id.tv_upgrade_confirm)
cancleTv = findViewById(R.id.tv_upgrade_cancel)
verticalLineView = findViewById(R.id.view_vertical_line)
confirmForceTv = findViewById(R.id.tv_upgrade_confirm_force)
confirmTv?.setOnClickListener {
downloadApp()
@@ -45,6 +48,11 @@ class UpgradeAppDialog(context: Context) : BaseFloatDialog(context), LifecycleOb
cancleTv?.setOnClickListener {
dismiss()
}
confirmForceTv?.setOnClickListener {
downloadApp()
}
}
/**
@@ -61,12 +69,31 @@ class UpgradeAppDialog(context: Context) : BaseFloatDialog(context), LifecycleOb
super.dismiss()
}
fun showUpgradeAppDialog(name: String, url: String) {
// 升级类型 1:提示升级 2:静默升级 3:强制升级
fun showUpgradeAppDialog(name: String, url: String, title: String, content: String, installType: String) {
if (isShowing) {
return
}
tag = name
downloarUrl = url
upgradeTitleTv?.text = title
upgradeContentTv?.text = content
if (installType.equals("1")) {
confirmForceTv?.visibility = View.GONE
confirmTv?.visibility = View.VISIBLE
cancleTv?.visibility = View.VISIBLE
verticalLineView?.visibility = View.VISIBLE
} else if (installType.equals("3")) {
confirmTv?.visibility = View.GONE
cancleTv?.visibility = View.GONE
verticalLineView?.visibility = View.GONE
confirmForceTv?.visibility = View.VISIBLE
} else if (installType.equals("2")) {
//静默安装
}
show()
}

View File

@@ -0,0 +1,119 @@
package com.mogo.eagle.core.function.hmi.ui.pnc
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo
import com.mogo.eagle.core.data.autopilot.pnc.PncActionsHelper
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_ACTIONS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.FOUNDATION
import com.mogo.eagle.core.data.trafficlight.TrafficLightResult
import com.mogo.eagle.core.data.trafficlight.currentRoadTrafficLight
import com.mogo.eagle.core.data.trafficlight.isRed
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener.Companion.STATUS_AUTOPILOT_RUNNING
import com.mogo.eagle.core.function.api.trafficlight.IMoGoTrafficLightListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningActionsListenerManager
import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.service_biz.BizConfig
import kotlinx.android.synthetic.main.view_pnc_actions.view.*
import mogo.telematics.pad.MessagePad
class PncActionsView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotPlanningActionsListener,
IMoGoTrafficLightListener, IMoGoAutopilotStatusListener {
companion object {
const val TAG = "PncActionsView"
}
@Volatile
private var mTrafficLightResult: TrafficLightResult? = null
private var mAutoPilotStatusInfo: AutopilotStatusInfo? = null
init {
LayoutInflater.from(context).inflate(R.layout.view_pnc_actions, this, true)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerAutopilotPlanningActionsListenerManager.addListener(TAG, this)
CallerTrafficLightListenerManager.registerTrafficLightListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerAutopilotPlanningActionsListenerManager.removeListener(TAG)
CallerTrafficLightListenerManager.unRegisterTrafficLightListener(TAG)
}
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
super.onAutopilotStatusResponse(autoPilotStatusInfo)
mAutoPilotStatusInfo = autoPilotStatusInfo
if (mAutoPilotStatusInfo!!.state != STATUS_AUTOPILOT_RUNNING) {
UiThreadHandler.post {
this.background = null
tvHmiPncActions.text = ""
}
}
}
@BizConfig(FOUNDATION, "", BIZ_PNC_ACTIONS)
override fun pncActions(planningActionMsg: MessagePad.PlanningActionMsg) {
mAutoPilotStatusInfo?.let {
if (it.state == STATUS_AUTOPILOT_RUNNING) {
UiThreadHandler.post {
var actions: String? = null
planningActionMsg.actionMsg?.let {
actions = PncActionsHelper.getAction(it.drivingState.number, it.drivingAction.number)
//如果是存在云端红绿灯数据条件下,设置云端数据
if (PncActionsHelper.isWaitingTrafficlight(it.drivingState.number, it.drivingAction.number)
&& mTrafficLightResult != null
&& getWaitTrafficlightTime().isNotBlank()) {
actions += ",预计${getWaitTrafficlightTime()}秒后通过"
} else {
mTrafficLightResult = null
}
}
// update view
if (actions.isNullOrEmpty()) {
this.background = null
tvHmiPncActions.text = ""
} else {
this.background = AppCompatResources.getDrawable(context, R.drawable.pnc_actions_bg)
tvHmiPncActions.text = actions
}
}
}
}
}
override fun onTrafficLightStatus(trafficLightResult: TrafficLightResult) {
mTrafficLightResult = trafficLightResult
}
private fun getWaitTrafficlightTime(): String {
return if (mTrafficLightResult != null
&& mTrafficLightResult!!.currentRoadTrafficLight() != null
&& mTrafficLightResult!!.currentRoadTrafficLight()!!.isRed()
) {
mTrafficLightResult!!.currentRoadTrafficLight()!!.remain.toString()
} else {
""
}
}
}

View File

@@ -9,9 +9,9 @@ import android.graphics.Color
import android.os.Build
import android.text.Html
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.*
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.PopupMenu
import androidx.constraintlayout.widget.ConstraintLayout
@@ -21,12 +21,17 @@ import androidx.recyclerview.widget.LinearLayoutManager
import chassis.Chassis
import com.mogo.cloud.passport.MoGoAiCloudClient
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.autopilot.*
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.constants.MoGoConfig
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BAG_RECORD
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_BEAUTY_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_FULL_LOG
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RAIN_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_WARNING_UPLOAD
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.scene.SceneModule
import com.mogo.eagle.core.data.enums.TrafficTypeEnum
@@ -36,10 +41,12 @@ import com.mogo.eagle.core.data.obu.ObuStatusInfo
import com.mogo.eagle.core.data.report.ReportEntity
import com.mogo.eagle.core.data.upgrade.UpgradeVersionEntity
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsFuncConfigListener
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener
import com.mogo.eagle.core.function.api.obu.IMoGoObuStatusListener
import com.mogo.eagle.core.function.call.autopilot.*
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsFuncConfigListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
@@ -50,12 +57,11 @@ import com.mogo.eagle.core.function.call.map.CallerSmpManager
import com.mogo.eagle.core.function.call.obu.CallerOBUManager
import com.mogo.eagle.core.function.call.obu.CallerObuListenerManager
import com.mogo.eagle.core.function.call.setting.CallerMoGoUiSettingManager
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.logcatch.ILogViewListener
import com.mogo.eagle.core.function.hmi.ui.logcatch.LogInfoView
import com.mogo.eagle.core.function.hmi.ui.upgrade.UpgradeListAdapter
import com.mogo.eagle.core.network.*
import com.mogo.eagle.core.function.hmi.ui.widget.DemoModeView
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel
@@ -65,6 +71,7 @@ import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.map.MogoMap
import com.mogo.map.MogoMapUIController
import com.mogo.map.uicontroller.VisualAngleMode
import com.mogo.map.uicontroller.VisualAngleMode.*
import com.mogo.module.service.routeoverlay.*
@@ -92,8 +99,8 @@ class DebugSettingView @JvmOverloads constructor(
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoObuStatusListener,
IMoGoAutopilotStatusListener, IMoGoAutopilotCarStateListener,
IMoGoMapLocationListener, IMoGoAutopilotIdentifyListener,
IMoGoAutopilotPlanningListener, IMoGoAutopilotCarConfigListener,
IMoGoAutopilotVehicleStateListener {
IMoGoAutopilotPlanningListener,
IMoGoAutopilotVehicleStateListener, IMoGoDevaToolsFuncConfigListener {
private val TAG = "DebugSettingView"
@@ -151,6 +158,8 @@ class DebugSettingView @JvmOverloads constructor(
SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
}
private var isStarted = false
init {
LayoutInflater.from(context).inflate(R.layout.view_debug_setting, this, true)
initView()
@@ -177,15 +186,19 @@ class DebugSettingView @JvmOverloads constructor(
// 添加 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.addListener(TAG, this)
// 添加 地图样式改变 监听
CallerMapLocationListenerManager.addListener(TAG, this)
CallerMapLocationListenerManager.addListener(TAG, this, false)
// 添加 域控制器感知数据 监听
CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
// 添加 规划路径相关回调 监听
CallerAutopilotPlanningListenerManager.addListener(TAG, this)
// 添加 工控机基础信息回调 监听
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
//添加 车辆底盘数据回调 监听
CallerAutopilotVehicleStateListenerManager.addListener(TAG, this)
//添加 业务配置监听
CallerDevaToolsFuncConfigListenerManager.registerDevaToolsFuncConfigListener(
FuncBizConfig.FOUNDATION, TAG, true, this
)
if (logInfoView != null) {
logInfoView!!.onEnterForeground()
}
@@ -206,16 +219,17 @@ class DebugSettingView @JvmOverloads constructor(
// 移除 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.removeListener(TAG)
// 移除 地图样式改变 监听
CallerMapLocationListenerManager.removeListener(TAG)
CallerMapLocationListenerManager.removeListener(TAG, false)
// 移除 域控制器感知数据 监听
CallerAutopilotIdentifyListenerManager.removeListener(TAG)
// 移除 规划路径相关回调 监听
CallerAutopilotPlanningListenerManager.removeListener(TAG)
// 移除 工控机基础信息回调 监听
CallerAutopilotCarConfigListenerManager.removeListener(TAG)
//移除 车辆底盘数据回调 监听
// 移除 车辆底盘数据回调 监听
CallerAutopilotVehicleStateListenerManager.removeListener(TAG)
// 移除 业务配置监听
CallerDevaToolsFuncConfigListenerManager.unRegisterDevaToolsFuncConfigListener( FuncBizConfig.FOUNDATION, TAG)
if (logInfoView != null) {
logInfoView!!.onEnterBackground()
}
@@ -247,6 +261,23 @@ class DebugSettingView @JvmOverloads constructor(
}
}
/**
* 魔戒控制
*/
tbMojie.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
buttonView.setCompoundDrawables(null, null, iconDown, null)
btnOpenAllGestures.visibility = View.VISIBLE
} else {
buttonView.setCompoundDrawables(null, null, iconRight, null)
btnOpenAllGestures.visibility = View.GONE
}
}
btnOpenAllGestures.setOnClickListener {
MogoMapUIController.getInstance().setAllGesturesEnabled(true)
}
/**
* 版本信息
*/
@@ -535,24 +566,33 @@ class DebugSettingView @JvmOverloads constructor(
}
}
Log.i(
"1026-emArrow",
"debug setting FunctionBuildConfig.isDemoMode : ${FunctionBuildConfig.isDemoMode}"
)
// 演示模式,上一次勾选的数据
tbIsDemoMode.isChecked = FunctionBuildConfig.isDemoMode
// 演示模式
tbIsDemoMode.setOnCheckedChangeListener { _, isChecked ->
CallerHmiManager.updateStatusBarRightView(isChecked, "demoMode", DemoModeView(context))
CallerAutoPilotManager.setDemoMode(isChecked)
if(!isChecked){
if (!isChecked) {
//关闭美化模式时,通知工控机
CallerAutoPilotManager.setIPCDemoMode(isChecked)
}
FunctionBuildConfig.isDemoMode = isChecked
tbIsDrawAutopilotTrajectoryData.isEnabled = !isChecked
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = isChecked
if (!FunctionBuildConfig.isDemoMode) {
tbIsDrawAutopilotTrajectoryData.isChecked = false
}
}
//只在司机端设置美化模式开关功能
if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
tbIsDemoMode.visibility = View.GONE
}
// 雨天模式,上一次勾选的数据
tbIsRainMode.isChecked = FunctionBuildConfig.isRainMode
//雨天模式
@@ -565,6 +605,15 @@ class DebugSettingView @JvmOverloads constructor(
tbIsRainMode.visibility = View.GONE
}
tbBeautyMode.isChecked = FunctionBuildConfig.isBeautyMode
//感知优化模式
tbBeautyMode.setOnCheckedChangeListener { _, isChecked ->
FunctionBuildConfig.isBeautyMode = isChecked
if (!FunctionBuildConfig.isBeautyMode) {
tbBeautyMode.isChecked = false
}
}
//重启工控机所有节点
btnIpcReboot.onClick {
CallerAutoPilotManager.sendIpcReboot()
@@ -585,36 +634,64 @@ class DebugSettingView @JvmOverloads constructor(
}
// 初始化 GSP数据源 数据
rgGpsProvider.check(
when (FunctionBuildConfig.gpsProvider) {
0 -> {
R.id.rbGpsProviderAndroid
}
1 -> {
R.id.rbGpsProviderRTK
}
2 -> {
R.id.rbGpsProviderOBU
}
0 -> R.id.rbGpsProviderAndroid
1 -> R.id.rbGpsProviderRTK
2 -> R.id.rbGpsProviderOBU
else -> R.id.rbGpsProviderAndroid
}
)
rgGpsProvider.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.rbGpsProviderAndroid -> {
FunctionBuildConfig.gpsProvider = 0
R.id.rbGpsProviderAndroid -> FunctionBuildConfig.gpsProvider = 0
R.id.rbGpsProviderRTK -> FunctionBuildConfig.gpsProvider = 1
R.id.rbGpsProviderOBU -> FunctionBuildConfig.gpsProvider = 2
}
}
// 初始化 tracker感知数据源 数据
trackerProvider.check(
when (FunctionBuildConfig.debugTrackerProvider) {
0 -> R.id.trackerProviderOrigin
1 -> R.id.trackerProviderObu
else -> R.id.trackerProviderOrigin
}
)
trackerProvider.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.trackerProviderOrigin -> {
FunctionBuildConfig.debugTrackerProvider = 0
// update tracker provider view
trackerIPCProvider.visibility = View.VISIBLE
}
R.id.rbGpsProviderRTK -> {
FunctionBuildConfig.gpsProvider = 1
}
R.id.rbGpsProviderOBU -> {
FunctionBuildConfig.gpsProvider = 2
R.id.trackerProviderObu -> {
FunctionBuildConfig.debugTrackerProvider = 1
// update tracker provider view
trackerIPCProvider.visibility = View.GONE
}
}
}
// 初始化 trackerIPC 感知数据源 数据
trackerIPCProvider.check(
when (FunctionBuildConfig.trackerIPCProvider) {
0 -> R.id.trackerIPCUnion
1 -> R.id.trackerIPC
2 -> R.id.trackerIPCObu
3 -> R.id.trackerIPCV2I
else -> R.id.trackerIPCUnion
}
)
trackerIPCProvider.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.trackerIPCUnion -> FunctionBuildConfig.trackerIPCProvider = 0
R.id.trackerIPC -> FunctionBuildConfig.trackerIPCProvider = 1
R.id.trackerIPCObu -> FunctionBuildConfig.trackerIPCProvider = 2
R.id.trackerIPCV2I -> FunctionBuildConfig.trackerIPCProvider = 3
}
}
// 初始化 ADAS感知数据是否绘制 选择情况
tbIsDrawIdentifyData.isChecked = FunctionBuildConfig.isDrawIdentifyData
@@ -751,20 +828,21 @@ class DebugSettingView @JvmOverloads constructor(
}
//状态中心-后台优化状态
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val backgroundStatus = "后台运行:" + if (BackgrounderPermission.getInstance()
.isPermissionLongBackgroundRunning(context)
) "<font color='green'>已优化</font>" else "<font color='red'>未优化</font>"
tvBackgroundOperation.text = Html.fromHtml(backgroundStatus, Html.FROM_HTML_MODE_LEGACY)
tvBackgroundOperation.setOnClickListener {
BackgrounderPermission.getInstance().showPermissionLongBackgroundRunningDialog(context)
BackgrounderPermission.getInstance()
.showPermissionLongBackgroundRunningDialog(context)
}
BackgrounderPermission.getInstance().setListener {
val str =
"后台运行:" + if (it) "<font color='green'>已优化</font>" else "<font color='red'>未优化</font>"
tvBackgroundOperation.text = Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY)
}
}else {
} else {
tvBackgroundOperation.visibility = GONE
}
//设置工控机连接状态
@@ -774,7 +852,8 @@ class DebugSettingView @JvmOverloads constructor(
/**
* 设置鹰眼本地参数配置监听
*/
@SuppressLint("SetTextI18n") private fun setEagleEyeConfigListener() {
@SuppressLint("SetTextI18n")
private fun setEagleEyeConfigListener() {
//初始化刹车加速度阈值信息
val brakeThreshold = SharedPrefsMgr.getInstance(context)
.getFloat(MoGoConfig.BRAKE_ACCELERATION_THRESHOLD, -2.5F)
@@ -801,6 +880,17 @@ class DebugSettingView @JvmOverloads constructor(
}
}
btnBrakeThreshold.setOnLongClickListener {
if (!isStarted) {
CallerDevaToolsManager.startMonitor()
isStarted = true
} else {
CallerDevaToolsManager.stopMonitor()
isStarted = false
}
true
}
//设置连接司机屏IP
btnConnectServerIp.setOnClickListener {
val ip = etConnectServerIp.text.toString()
@@ -815,7 +905,7 @@ class DebugSettingView @JvmOverloads constructor(
FunctionBuildConfig.isReportWarning = isChecked
}
//异常上报开关只在司机端展示
if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)){
if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
tbReportWarning.visibility = GONE
}
@@ -826,7 +916,7 @@ class DebugSettingView @JvmOverloads constructor(
p.menuInflater.inflate(R.menu.menu_env_pop, p.menu)
MenuCompat.setGroupDividerEnabled(p.menu, true)
p.setOnMenuItemClickListener { item ->
when(item.itemId) {
when (item.itemId) {
R.id.group_hy -> {
return@setOnMenuItemClickListener false
}
@@ -1034,7 +1124,10 @@ class DebugSettingView @JvmOverloads constructor(
accelerationIsShow = isChecked
}
tbRouteDynamicEffect.isChecked = AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) && !AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)
tbRouteDynamicEffect.isChecked =
AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) && !AppIdentityModeUtils.isBus(
FunctionBuildConfig.appIdentityMode
)
tbRouteDynamicEffect.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
@@ -1379,6 +1472,19 @@ class DebugSettingView @JvmOverloads constructor(
}
}
/**
* ADAS红绿灯数据
*/
cbAdasTrafficlight.setOnCheckedChangeListener { _, isChecked ->
val map = CallerDevaToolsManager.getTraceInfo()
val param = map[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT]
param?.let {
it.record = isChecked
map[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT] = param
CallerDevaToolsManager.refreshTraceInfo(map)
}
}
/**
* ADAS PLANNING OBJ 感知障碍物
*/
@@ -1412,6 +1518,10 @@ class DebugSettingView @JvmOverloads constructor(
vehicle?.let {
cbAdasVehicle.isChecked = it.record
}
val trafficlight = traceInfoMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT]
trafficlight?.let {
cbAdasTrafficlight.isChecked = it.record
}
}
/**
@@ -1499,50 +1609,6 @@ class DebugSettingView @JvmOverloads constructor(
*/
@SuppressLint("SetTextI18n")
private fun drawAppInfo() {
AppConfigInfo.appName = AppUtils.getAppName()
if (AppConfigInfo.appVersionCode == 0) {
AppConfigInfo.appVersionCode = AppUtils.getAppVersionCode()
}
if (AppConfigInfo.appVersionName.isNullOrEmpty()) {
AppConfigInfo.appVersionName = AppUtils.getAppVersionName()
}
if (AppConfigInfo.appPackageName.isNullOrEmpty()) {
AppConfigInfo.appPackageName = AppUtils.getAppPackageName()
}
if (AppConfigInfo.uniqueDeviceId.isNullOrEmpty()) {
AppConfigInfo.uniqueDeviceId = DeviceIdUtils.getDeviceId(AbsMogoApplication.getApp())
}
if (AppConfigInfo.widevineIDMd5.isNullOrEmpty()) {
AppConfigInfo.widevineIDMd5 =
DeviceIdUtils.getWidevineIDWithMd5(AbsMogoApplication.getApp())
}
if (MoGoAiCloudClient.getInstance().aiCloudClientConfig != null) {
AppConfigInfo.mogoSN = MoGoAiCloudClient.getInstance().aiCloudClientConfig.sn
AppConfigInfo.mogoToken = MoGoAiCloudClient.getInstance().aiCloudClientConfig.token
}
AppConfigInfo.netMode = DebugConfig.getNetMode()
if (MogoMap.getInstance().mogoMap != null) {
AppConfigInfo.mapSdkVersion = MogoMap.getInstance().mogoMap.mapVersion
}
AppConfigInfo.isConnectNet = NetworkUtils.isConnected(context)
AppConfigInfo.isConnectSocket = DebugConfig.isDownloadSnapshot()
when {
AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) -> {// 司机端
AppConfigInfo.isDriver = true
AppConfigInfo.isConnectedNetty = CallerTelematicManager.getServerStarted()
}
AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) -> {
AppConfigInfo.isDriver = false
AppConfigInfo.isConnectedNetty = CallerTelematicManager.getClientConnStatus()
AppConfigInfo.serverSn = CallerTelematicManager.getServerToken()
}
else -> {
}
}
AppConfigInfo.teleTimeStamp = CallerAutoPilotManager.getTeleTimeStamp()
/**
* 设备绑定关系
*/
@@ -1738,16 +1804,14 @@ class DebugSettingView @JvmOverloads constructor(
*/
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
mAutoPilotStatusInfo = autoPilotStatusInfo
AppConfigInfo.isConnectAutopilot = autoPilotStatusInfo.connectStatus
AppConfigInfo.connectStatusDescribe = autoPilotStatusInfo.connectStatusDescribe
setAutopilotConnectStatus()
}
/**
* 设置工控机连接状态
*/
private fun setAutopilotConnectStatus(){
ThreadUtils.runOnUiThread{
private fun setAutopilotConnectStatus() {
ThreadUtils.runOnUiThread {
tvAutopilotConnectStatus.text = Html.fromHtml(
"工控机连接状态:${
if (AppConfigInfo.isConnectAutopilot) {
@@ -1793,6 +1857,62 @@ class DebugSettingView @JvmOverloads constructor(
}
}
override fun updateBizView(type: String, lock: Boolean) {
when (type) {
BIZ_BEAUTY_MODE -> {
tbIsDemoMode.isClickable = !lock
if (lock) {
tbIsDemoMode.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
tbIsDemoMode.background =
resources.getDrawable(R.drawable.radio_button_normal_background_right)
}
}
BIZ_RAIN_MODE -> {
tbIsRainMode.isClickable = !lock
if (lock) {
tbIsRainMode.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
tbIsRainMode.background =
resources.getDrawable(R.drawable.radio_button_normal_background_right)
}
}
BIZ_WARNING_UPLOAD -> {
tbReportWarning.isClickable = !lock
if (lock) {
tbReportWarning.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
tbReportWarning.background = null
}
}
BIZ_BAG_RECORD -> {
if (lock) {
btnRecordBag.isClickable = false
btnRecordBag.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
btnRecordBag.isClickable = true
btnRecordBag.requestFocus()
btnRecordBag.background = null
}
}
BIZ_FULL_LOG -> {
if (lock) {
tbLogCatch.isClickable = false
tbLogCatch.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
tbLogCatch.isClickable = true
tbLogCatch.requestFocus()
tbLogCatch.background = null
}
}
}
}
override fun onAutopilotCarStateData(gnssInfo: MessagePad.GnssInfo?) {
mGnssInfo = gnssInfo
//实时加速度列表
@@ -1858,18 +1978,6 @@ class DebugSettingView @JvmOverloads constructor(
mRouteInfoSize = globalPathResp?.wayPointsList?.size ?: 0
}
/**
* 工控机基础信息回调
*/
override fun onAutopilotCarConfig(carConfigResp: MessagePad.CarConfigResp) {
carConfigResp.let {
AppConfigInfo.plateNumber = it.plateNumber//车牌号
AppConfigInfo.iPCMacAddress = it.macAddress//工控机MAC地址
AppConfigInfo.protocolVersionNumber = it.protocolVersionValue//工控机协议版本
}
}
/**
* 工控机异常回调
*/
@@ -1915,7 +2023,7 @@ class DebugSettingView @JvmOverloads constructor(
}
}
override fun onLocationChanged(location: MogoLocation?, from: Int) {
override fun onLocationChanged(location: MogoLocation?, from: Int, isGps: Boolean) {
}
/**
@@ -1990,7 +2098,8 @@ class DebugSettingView @JvmOverloads constructor(
private fun toastMsg(msg: String) {
//当司机屏处于美化演示模式、msg为空时不弹吐司
if (!FunctionBuildConfig.isDemoMode && msg.isNotEmpty()
&& AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
&& AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)
) {
ToastUtils.showLong(msg)
}
}
@@ -2048,4 +2157,5 @@ class DebugSettingView @JvmOverloads constructor(
fun showReportListWindow(show: Boolean)
}
}

View File

@@ -0,0 +1,232 @@
package com.mogo.eagle.core.function.hmi.ui.setting
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsFuncConfigListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsFuncConfigListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.obu.CallerOBUManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.module.service.routeoverlay.RouteStrategy
import kotlinx.android.synthetic.main.view_debug_setting.view.*
import kotlinx.android.synthetic.main.view_sop_setting.view.*
import kotlinx.android.synthetic.main.view_sop_setting.view.tbRouteDynamicEffect
/**
* SOP设置窗口
*/
class SOPSettingView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoDevaToolsFuncConfigListener {
companion object {
const val TAG = "SOPSettingView"
}
init {
LayoutInflater.from(context).inflate(R.layout.view_sop_setting, this, true)
initView()
}
private fun initView() {
//绕障类功能开关
tbObstacleAvoidance.isChecked = FunctionBuildConfig.isDetouring
tbObstacleAvoidance.setOnCheckedChangeListener { _, isChecked ->
CallerAutoPilotManager.sendDetouring(isChecked)
FunctionBuildConfig.isDetouring = isChecked
}
tbMarkingObstacles.isChecked = FunctionBuildConfig.isPNCWarning
//危险障碍物颜色标记开关
tbMarkingObstacles.setOnCheckedChangeListener { _, isChecked ->
FunctionBuildConfig.isPNCWarning = isChecked
}
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
tbMarkingObstacles.visibility = View.GONE
}
//引导线动态效果
tbRouteDynamicEffect.isChecked =
AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode) && !AppIdentityModeUtils.isBus(
FunctionBuildConfig.appIdentityMode
)
tbRouteDynamicEffect.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
RouteStrategy.enable(true)
} else {
RouteStrategy.enable(false)
}
}
//红绿灯标识
tbTrafficLight.isChecked = HmiBuildConfig.isShowTrafficLightView
tbTrafficLight.setOnCheckedChangeListener { _, isChecked ->
if (!isChecked) {
HmiBuildConfig.isShowTrafficLightView = false
} else {
HmiBuildConfig.isShowTrafficLightView = true
CallerHmiManager.disableWarningTrafficLight()
}
}
//限速标识
tbSpeedLimit.isChecked = HmiBuildConfig.isShowLimitingVelocityView
tbSpeedLimit.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
HmiBuildConfig.isShowLimitingVelocityView = true
} else {
HmiBuildConfig.isShowLimitingVelocityView = false
CallerHmiManager.disableLimitingVelocity()
}
}
// 演示模式,上一次勾选的数据
tbDemoMode.isChecked = FunctionBuildConfig.isDemoMode
// 演示模式
tbDemoMode.setOnCheckedChangeListener { _, isChecked ->
CallerAutoPilotManager.setDemoMode(isChecked)
if (!isChecked) {
//关闭美化模式时,通知工控机
CallerAutoPilotManager.setIPCDemoMode(isChecked)
}
FunctionBuildConfig.isDemoMode = isChecked
}
//只在司机端设置美化模式开关功能
if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
tbDemoMode.visibility = View.GONE
}
// 雨天模式,上一次勾选的数据
tbRainMode.isChecked = FunctionBuildConfig.isRainMode
//雨天模式
tbRainMode.setOnCheckedChangeListener { _, isChecked ->
CallerAutoPilotManager.setRainMode(isChecked)
FunctionBuildConfig.isRainMode = isChecked
}
//雨天模式按钮只在司机屏生效,乘客屏不显示
if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
tbRainMode.visibility = View.GONE
}
//OBU控制总开关
tbObu.isChecked = CallerOBUManager.isConnected()
tbObu.setOnCheckedChangeListener { _, isChecked ->
if (!isChecked) {
if (AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
CallerOBUManager.resetObuIpAddress("192.168.1.199")
} else if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
CallerOBUManager.resetObuIpAddress("192.168.8.199")
}
} else {
//断开链接
CallerOBUManager.disConnectObu()
}
}
//是否开启异常上报
tbIPCReport.isChecked = FunctionBuildConfig.isReportWarning
tbIPCReport.setOnCheckedChangeListener { _, isChecked ->
FunctionBuildConfig.isReportWarning = isChecked
}
//变道绕障的目标障碍物速度阈值
tvSpeed.text = "${FunctionBuildConfig.detouringSpeed} m/s"
ivSpeedReduce.setOnClickListener {
if (FunctionBuildConfig.detouringSpeed <= 3) {
ToastUtils.showShort("阈值最小可为3 m/s")
} else {
FunctionBuildConfig.detouringSpeed--
tvSpeed.text = "${FunctionBuildConfig.detouringSpeed} m/s"
}
}
ivSpeedAdd.setOnClickListener {
if (FunctionBuildConfig.detouringSpeed >= 7) {
ToastUtils.showShort("阈值最大可为7 m/s")
} else {
FunctionBuildConfig.detouringSpeed++
tvSpeed.text = "${FunctionBuildConfig.detouringSpeed} m/s"
}
}
btnSpeedSet.setOnClickListener {
val isSuccess =
CallerAutoPilotManager.sendDetouringSpeed(FunctionBuildConfig.detouringSpeed.toDouble())
if (isSuccess == true) {
ToastUtils.showShort("变道绕障的目标障碍物速度阈值设置成功")
} else {
ToastUtils.showShort("变道绕障的目标障碍物速度阈值设置失败")
}
}
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
tvSpeedThresholdTitle.visibility = View.GONE
ivSpeedReduce.visibility = View.GONE
tvSpeed.visibility = View.GONE
ivSpeedAdd.visibility = View.GONE
btnSpeedSet.visibility = View.GONE
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
//添加 业务配置监听
CallerDevaToolsFuncConfigListenerManager.registerDevaToolsFuncConfigListener(
FuncBizConfig.FOUNDATION, TAG, true, this
)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
// 移除 业务配置监听
CallerDevaToolsFuncConfigListenerManager.unRegisterDevaToolsFuncConfigListener(FuncBizConfig.FOUNDATION, TAG)
}
override fun updateBizView(type: String, lock: Boolean) {
when (type) {
FuncBizConfig.BIZ_BEAUTY_MODE -> {
tbDemoMode.isClickable = !lock
if (lock) {
tbDemoMode.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
tbDemoMode.background =
resources.getDrawable(R.drawable.radio_button_normal_background_right)
}
}
FuncBizConfig.BIZ_RAIN_MODE -> {
tbRainMode.isClickable = !lock
if (lock) {
tbRainMode.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
tbRainMode.background =
resources.getDrawable(R.drawable.radio_button_normal_background_right)
}
}
FuncBizConfig.BIZ_PNC_WARNING -> {
tbMarkingObstacles.isClickable = !lock
if (lock) {
tbMarkingObstacles.background =
resources.getDrawable(R.drawable.radio_button_lock_background)
} else {
tbMarkingObstacles.background =
resources.getDrawable(R.drawable.radio_button_normal_background_right)
}
}
}
}
}

View File

@@ -0,0 +1,18 @@
package com.mogo.eagle.core.function.hmi.ui.takeover
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.function.hmi.R
class TakeOverView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
init {
LayoutInflater.from(context).inflate(R.layout.view_take_over, this, true)
}
}

View File

@@ -2,32 +2,35 @@ package com.mogo.eagle.core.function.hmi.ui.tools
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Process
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import com.mogo.cloud.passport.MoGoAiCloudClient
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo
import com.mogo.eagle.core.data.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.temp.EventLogout
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager
import com.mogo.eagle.core.function.call.bindingcar.CallerBindingcarManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.utils.KeyBoardUtil
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import kotlinx.android.synthetic.main.view_auto_pilot_check.view.*
import mogo.telematics.pad.MessagePad
import org.greenrobot.eventbus.EventBus
import kotlin.system.exitProcess
/**
* @author ChenFufeng
@@ -57,15 +60,13 @@ class AutoPilotAndCheckView @JvmOverloads constructor(
companion object {
private var maxAcceleration: Double = 2.0
private var speedLimit: Double = 0.0
private var speedLimit: Int = 0
}
@SuppressLint("ClickableViewAccessibility")
private fun initView() {
background = ColorDrawable(Color.parseColor("#F0151D41"))
if (keyBoardUtil == null) {
keyBoardUtil = KeyBoardUtil(sKeyBoardView, etInputSpeed)
}
keyBoardUtil?.setActionListener { inputContent ->
inputContent.toIntOrNull()?.let { speed ->
when {
@@ -74,10 +75,6 @@ class AutoPilotAndCheckView @JvmOverloads constructor(
ToastUtils.showShort("超过最大限速值60设置失败")
}
else -> {
llSpeedPosition.background =
resources.getDrawable(R.drawable.pilot_speed_bg)
keyBoardUtil?.hideKeyboard()
etInputSpeed.clearFocus()
// 设置自动驾驶速度
val isSuccess = CallerAutoPilotManager.setAutoPilotSpeed(speed)
when {
@@ -92,10 +89,15 @@ class AutoPilotAndCheckView @JvmOverloads constructor(
}
}
}
KeyBoardUtil.hideSystemSoftKeyboard(context, etInputSpeed)
ivCloseIcon.setOnClickListener {
clickListener?.onClose(it)
}
rlKillLayout.setOnClickListener {
killApp()
}
sopLayout.setOnClickListener {
clickListener?.showSOPSettingView()
}
viewCheckStatus.setOnClickListener {
clickListener?.go2CheckPage()
}
@@ -105,59 +107,90 @@ class AutoPilotAndCheckView @JvmOverloads constructor(
ivDebugFeedback.onClick {
clickListener?.showFeedbackView()
}
etInputSpeed.setOnFocusChangeListener { v, hasFocus ->
when {
hasFocus -> {
llSpeedPosition.background =
resources.getDrawable(R.drawable.pilot_speed_high_light_bg)
if (keyBoardUtil == null) {
keyBoardUtil = KeyBoardUtil(sKeyBoardView, etInputSpeed)
}
keyBoardUtil?.showKeyboard()
}
else -> llSpeedPosition.background =
resources.getDrawable(R.drawable.pilot_speed_bg)
}
}
etInputSpeed.setOnTouchListener { v, event ->
var curTime = System.currentTimeMillis()
if (curTime - lastTime < 1000) {
return@setOnTouchListener true
}
if (!connectStatus) {
ToastUtils.showShort("设置车速失败,请启动域控制器")
keyBoardUtil?.hideKeyboard()
return@setOnTouchListener true
} else {
return@setOnTouchListener false
}
}
updateSpeedSettingViews()
if (AppConfigInfo.isConnectAutopilot) {
CallerAutoPilotManager.getCarConfig()
}
if (maxAcceleration > 0) {
tvAcceleration.text = "加速度 $maxAcceleration m/s²"
}
// if (maxAcceleration > 0) {
// tvAcceleration.text = "加速度 $maxAcceleration m/s²"
// }
tvAcceleration.text = "每次调整车速±5km/h,点击确定生效"
if (speedLimit > 0) {
etInputSpeed.setText((speedLimit * 3.6).toInt().toString())
tvSpeed.text = speedLimit.toString()
}else{
tvSpeed.text = "0"
}
// // 比如需要设置默认速度
// val speed = "30"
// etInputSpeed.setText(speed)
// etInputSpeed.setSelection(speed.length)
ivSpeedReduce.setOnClickListener {
if(speedLimit>=5){
speedLimit -= 5
tvSpeed.text = speedLimit.toString()
}else{
ToastUtils.showShort("车速不能再减了")
}
}
ivSpeedAdd.setOnClickListener {
if(speedLimit<=55){
speedLimit += 5
tvSpeed.text = speedLimit.toString()
}else{
ToastUtils.showShort("车速不能再加了")
}
}
//速度确认
tvSureModify.setOnClickListener {
val isSuccess = CallerAutoPilotManager.setAutoPilotSpeed(speedLimit)
when {
isSuccess -> {
//速度显示
tvSpeed.text = speedLimit.toString()
ToastUtils.showShort("车速设置成功,立即生效")
}
else -> {
ToastUtils.showShort("设置车速失败,请启动域控制器")
}
}
}
initOchView()
}
private fun initOchView() {
actvLoginout.onClick {
EventBus.getDefault().post(EventLogout())
}
actvLoginout.visibility = View.VISIBLE
CallerHmiManager.setBusOperationView(toolBusOperationView)
when (DebugConfig.getProductFlavor()) {
"fPadLenovoOchTaxi" -> {
//出租车司机
}
"fPadLenovoOchBus" ->{
//小巴车司机
}
else -> {
}
}
}
private fun killApp() {
Intent(Intent.ACTION_MAIN).apply {
addCategory(Intent.CATEGORY_HOME)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(this)
Process.killProcess(Process.myPid())
exitProcess(0)
}
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
private fun updateSpeedSettingViews() {
tvSpeedTitle.visibility = View.VISIBLE
llSpeedPosition.visibility = View.VISIBLE
}
fun showAdUpgradeStatus(ipcUpgradeStateInfo: IPCUpgradeStateInfo) {
systemVersionView?.showAdUpgradeStatus(ipcUpgradeStateInfo)
}
@@ -184,19 +217,20 @@ class AutoPilotAndCheckView @JvmOverloads constructor(
fun onClose(v: View)
fun showDebugPanelView()
fun showFeedbackView()
fun showSOPSettingView()
}
override fun onAutopilotCarConfig(carConfigResp: MessagePad.CarConfigResp) {
UiThreadHandler.post {
tvAcceleration?.let {
maxAcceleration = carConfigResp.maxAcceleration
speedLimit = carConfigResp.speedLimit
tvAcceleration.text = "加速度 ${carConfigResp.maxAcceleration} m/s²"
etInputSpeed.setText((carConfigResp.speedLimit * 3.6).toInt().toString())
AppConfigInfo.plateNumber = carConfigResp.plateNumber//车牌号
AppConfigInfo.iPCMacAddress = carConfigResp.macAddress//工控机MAC地址
AppConfigInfo.protocolVersionNumber = carConfigResp.protocolVersionValue//工控机协议版本
}
// tvAcceleration?.let {
// maxAcceleration = carConfigResp.maxAcceleration
// speedLimit = carConfigResp.speedLimit
//// tvAcceleration.text = "加速度 ${carConfigResp.maxAcceleration} m/s²"
// tvSpeed.text = (carConfigResp.speedLimit * 3.6).toInt().toString()
// }
maxAcceleration = carConfigResp.maxAcceleration
speedLimit = (carConfigResp.speedLimit * 3.6).toInt()
tvSpeed.text = speedLimit.toString()
}
}
}

View File

@@ -0,0 +1,61 @@
package com.mogo.eagle.core.function.hmi.ui.tools
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import com.mogo.eagle.core.function.api.hmi.view.IOchBusView
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.SharedPrefs
import com.mogo.eagle.core.utilcode.util.StringUtils
import kotlinx.android.synthetic.main.view_och_bus_operation.view.*
import org.greenrobot.eventbus.EventBus
/**
* @author: wangmingjun
* @date: 2022/8/23
*/
class BusOperationView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0)
: IOchBusView(context, attrs, defStyleAttr) {
init {
LayoutInflater.from(context).inflate(R.layout.view_och_bus_operation,this,true)
context?.let {
actvAccountPhone.text = phoneMask(SharedPrefs.getInstance(it).getString("och_account",""))
}
}
override fun showBusOperation() {
ochBusOperationStatus.visibility = View.VISIBLE
}
override fun changerOperationStatus(isOut: Boolean) {
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
context?.let {
actvAccountPhone.text = phoneMask(SharedPrefs.getInstance(it).getString("och_account",""))
}
}
/**
* 用户电话号码的打码隐藏加星号加*
* 一般都是中间四位
* @return 处理完成的手机号码
*/
fun phoneMask(phone: String?): String? {
var res = ""
if (!StringUtils.isEmpty(phone)&&phone?.length==11) {
val stringBuilder = StringBuilder(phone)
res = stringBuilder.replace(3, 7, "****").toString()
}
return res
}
}

View File

@@ -0,0 +1,42 @@
package com.mogo.eagle.core.function.hmi.ui.tools
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.mogo.eagle.core.function.hmi.R
/**
* @author lixiaopeng
* 蒙层view
*/
class MaskView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(
context,
attrs,
defStyleAttr
) {
private val TAG = "MaskView"
init {
LayoutInflater.from(context).inflate(R.layout.view_mask, this, true)
initView()
}
companion object {
private var speedLimit: Double = 0.0
}
@SuppressLint("ClickableViewAccessibility")
private fun initView() {
// background = ColorDrawable(Color.parseColor("#F0151D41"))
}
}

View File

@@ -0,0 +1,109 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
import com.mogo.eagle.core.function.hmi.R
import java.lang.ref.WeakReference
class BatteryGroupView : LinearLayout, IMoGoSkinModeChangeListener {
constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : super(context, attrs, defStyleAttr) {
}
private var batteryHandler: BatteryHandler = BatteryHandler(this)
private var view: View =
LayoutInflater.from(context).inflate(R.layout.view_battery_group, this, true)
private var batteryView: BatteryView = (view as BatteryGroupView).findViewById(R.id.viewBattery)
private var ivBatteryCharge: ImageView = (view as BatteryGroupView).findViewById(R.id.ivBatteryCharge)
private var mSkinMode = 0
private val batteryStateReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
Intent.ACTION_BATTERY_CHANGED -> {
val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0)
val charge = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
val percentage = (level * 100) / scale
val message = Message.obtain()
message.what = 0
message.arg1 = percentage
message.arg2 = charge
batteryHandler.sendMessage(message)
}
}
}
}
companion object {
const val TAG = "BatteryGroupView"
class BatteryHandler(batteryGroupView: BatteryGroupView) : Handler() {
//虚引用
private var stateViewWeakReference: WeakReference<BatteryGroupView>? = null
init {
stateViewWeakReference = WeakReference(batteryGroupView)
}
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
val batteryGroupView = stateViewWeakReference?.get()
batteryGroupView?.let {
if (msg.what == 0) {
it.batteryView.setPower(msg.arg1)
val isCharging = msg.arg2 == BatteryManager.BATTERY_STATUS_CHARGING ||
msg.arg2 == BatteryManager.BATTERY_STATUS_FULL
it.batteryView.setCharging(isCharging)
if (isCharging) {
it.ivBatteryCharge.visibility = View.VISIBLE
when(it.mSkinMode){
0 -> it.ivBatteryCharge.setImageResource(R.drawable.battery_charge_light)
1 -> it.ivBatteryCharge.setImageResource(R.drawable.battery_charge_dark)
}
} else {
it.ivBatteryCharge.visibility = View.GONE
}
}
}
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED)
context.registerReceiver(batteryStateReceiver, intentFilter)
// 添加换肤监听
CallerSkinModeListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
context.unregisterReceiver(batteryStateReceiver)
CallerSkinModeListenerManager.removeListener(TAG)
}
override fun onSkinModeChange(skinMode: Int) {
mSkinMode = skinMode
}
}

View File

@@ -0,0 +1,165 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
import com.mogo.eagle.core.function.hmi.R
import kotlin.math.abs
class BatteryView : View , IMoGoSkinModeChangeListener {
companion object{
const val TAG = "BatteryView"
}
private val radius = context.resources.getDimension(R.dimen.dp_4) // 圆角角度
private val border = context.resources.getDimension(R.dimen.dp_3) // 外边缘宽度
private val margin = context.resources.getDimension(R.dimen.dp_6) // 边框与内部电量距离
private val width = context.resources.getDimension(R.dimen.dp_57) // 电池宽度
private val height = context.resources.getDimension(R.dimen.dp_28) // 电池高度
private val headWidth = context.resources.getDimension(R.dimen.dp_3) // 电池头宽度
private val headHeight = context.resources.getDimension(R.dimen.dp_8) // 电池头高度
private val headRadius = context.resources.getDimension(R.dimen.dp_1) // 电池头圆角角度
private val batteryNumSize = context.resources.getDimension(R.dimen.dp_20) // 电量显示文字大小
private var batteryColor = context.resources.getColor(R.color.color_27FFFFFF) // 电量内部颜色
private var powerColor = Color.WHITE
//默认满电
private var mPower = 100
//是否充电
private var mIsCharging = false
constructor(
context: Context,
attrs: AttributeSet? = null
) : super(context, attrs, 0) {
}
constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : super(context, attrs, defStyleAttr) {
}
@SuppressLint("NewApi")
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(width.toInt(), height.toInt())
}
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//电池头
val paint = Paint()
paint.style = Paint.Style.FILL
paint.strokeWidth = 0f
paint.isAntiAlias = true
paint.color = powerColor
val rectHead =
RectF(width - headWidth, (height - headHeight) / 2, width, (height + headHeight) / 2)
canvas.drawRoundRect(rectHead, headRadius, headRadius, paint)
//边框
paint.strokeWidth = border
paint.style = Paint.Style.STROKE
val rectF =
RectF(radius / 2, radius / 2, width - headWidth - radius / 2, height - radius / 2)
canvas.drawRoundRect(rectF, radius, radius, paint)
//文字画笔
val textPaint = Paint()
textPaint.color = powerColor
textPaint.isAntiAlias = true
textPaint.textSize = batteryNumSize
textPaint.textAlign = Paint.Align.CENTER
//画数字
val fontMetrics = textPaint.fontMetrics
canvas.drawText(mPower.toString(), rectF.centerX(), abs(fontMetrics.top), textPaint)
//电池电量
val powerValues = mPower / 100.0f
val paintPower = Paint(paint)
paintPower.style = Paint.Style.FILL
//低电量
val lowerPaint = Paint(paint)
lowerPaint.style = Paint.Style.FILL
lowerPaint.color = powerColor
if (mPower < 20) {
lowerPaint.color = Color.RED
} else {
lowerPaint.color = batteryColor
}
//画电量
if (powerValues != 0f) {
val right = (width - margin - headWidth) * powerValues
val bottom = height - margin
val rect = RectF(margin, margin, right, bottom)
//画矩形
canvas.drawRoundRect(rect, radius, radius, lowerPaint)
}
}
/**
* 设置当前电量
*/
fun setPower(power: Int) {
if (this.mPower < 0) {
this.mPower = 0
}
if (this.mPower > 100) {
this.mPower = 100
}
this.mPower = power
if(isAttachedToWindow){
invalidate()
}
}
/**
* 是否充电中
*/
fun setCharging(charging: Boolean) {
this.mIsCharging = charging
invalidate()
}
override fun onSkinModeChange(skinMode: Int) {
when (skinMode) {
0 -> {
batteryColor = resources.getColor(R.color.color_27FFFFFF)
powerColor = Color.WHITE
}
1 -> {
batteryColor = resources.getColor(R.color.color_1E111111)
powerColor = resources.getColor(R.color.color_2C2E30)
}
}
invalidate()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
// 添加换肤监听
CallerSkinModeListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerSkinModeListenerManager.removeListener(TAG)
}
}

View File

@@ -0,0 +1,23 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.RelativeLayout
import com.mogo.eagle.core.function.hmi.R
/**
* 魔戒蓝牙控件
* 放置于StatusBar右侧位置
*/
class BlueToothView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {
init {
LayoutInflater.from(context).inflate(R.layout.view_blue_tooth, this, true)
}
}

View File

@@ -6,7 +6,6 @@ import android.content.res.TypedArray
import android.graphics.*
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.view.animation.LinearInterpolator
import android.view.animation.OvershootInterpolator
@@ -81,7 +80,6 @@ class CircularProgressView @JvmOverloads constructor(
mRectF = RectF(mRectL.toFloat(), mRectT.toFloat(), (mRectL + mRectLength).toFloat(),
(mRectT + mRectLength).toFloat())
Log.d(TAG, "onMeasure:" + mRectF.toString() + "," + "width:" + measuredWidth.toString() + "," + "PaddingLeft:" + getPaddingLeft().toString())
}
/**
@@ -107,7 +105,6 @@ class CircularProgressView @JvmOverloads constructor(
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
Log.d(TAG, "onDraw")
canvas?.let {
mRectF?.let { it1 -> it.drawArc(it1, 0.0f, 360.0f, false, mBackPaint) }
mRectF?.let { it1 ->
@@ -154,7 +151,6 @@ class CircularProgressView @JvmOverloads constructor(
val animator = ValueAnimator.ofInt(mProgress, progress)
animator.addUpdateListener {
mProgress = it.animatedValue as Int
Log.d(TAG, "setProgress" + mProgress.toString())
invalidate()
}
animator.interpolator = LinearInterpolator()

View File

@@ -0,0 +1,23 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.RelativeLayout
import com.mogo.eagle.core.function.hmi.R
/**
* 演示模式控件
* 放置于StatusBar右侧位置
*/
class DemoModeView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {
init {
LayoutInflater.from(context).inflate(R.layout.view_demo_mode, this, true)
}
}

View File

@@ -1,17 +1,15 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import com.mogo.commons.AbsMogoApplication
import android.content.*
import android.util.*
import android.view.*
import android.widget.*
import com.mogo.commons.*
import com.mogo.eagle.core.function.hmi.R
import com.mogo.map.MogoMapUIController
import com.mogo.map.MogoMarkerManager
import com.mogo.map.uicontroller.VisualAngleMode
import com.mogo.module.common.MogoApisHandler
import com.mogo.module.common.constants.DataTypes
import com.mogo.eagle.core.function.v2x.events.scenario.scene.airoad.*
import com.mogo.map.*
import com.mogo.map.uicontroller.*
import com.mogo.module.common.constants.*
import kotlinx.android.synthetic.main.view_perspective_switch.view.*
/**
@@ -34,15 +32,20 @@ class PerspectiveSwitchView @JvmOverloads constructor(
override fun onClick(v: View?) {
//切换地图的远近视图
if (MogoMapUIController.getInstance().currentMapVisualAngle.isLongSight) {
MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
.visibleAllMarkers()
// MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
// .visibleAllMarkers()
MogoMapUIController.getInstance().changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null)
textSwitch.setText(R.string.module_map_model_normal)
} else if (MogoMapUIController.getInstance().currentMapVisualAngle.isMediumSight) {
MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
.inVisibleWithoutMarkers(DataTypes.TYPE_MARKER_ADAS)
// MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
// .inVisibleWithoutMarkers(DataTypes.TYPE_MARKER_ADAS)
MogoMapUIController.getInstance().changeMapVisualAngle(VisualAngleMode.MODE_LONG_SIGHT, null)
textSwitch.setText(R.string.module_map_model_faster)
} else {
// MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
// .visibleAllMarkers()
MogoMapUIController.getInstance().changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null)
textSwitch.setText(R.string.module_map_model_normal)
}
}
}

View File

@@ -7,6 +7,7 @@ import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
@@ -49,7 +50,9 @@ class SingleTrafficLightView @JvmOverloads constructor(
override fun showWarningTrafficLight(checkLightId: Int,lightSource: Int) {
super.showWarningTrafficLight(checkLightId,lightSource)
mCurrentLightId = checkLightId
updateTrafficLightIcon(checkLightId,lightSource)
if(!HmiBuildConfig.isShowTrafficLightView){
updateTrafficLightIcon(checkLightId,lightSource)
}
}
/**

View File

@@ -1,17 +1,17 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.graphics.Color
import android.graphics.*
import android.location.Location
import android.util.AttributeSet
import android.util.*
import android.view.Gravity
import android.widget.FrameLayout
import com.alibaba.android.arouter.launcher.ARouter
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.MogoMapUIController
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.map.*
import com.mogo.map.navi.IMogoCarLocationChangedListener2
import com.mogo.service.IMogoServiceApis
import java.util.*
@@ -38,6 +38,11 @@ class SpeedPanelView @JvmOverloads constructor(
var mSpeedLimmit = 60;
private val timer by lazy {
Timer()
}
init {
initEvent(context)
@@ -61,29 +66,30 @@ class SpeedPanelView @JvmOverloads constructor(
}
}
private val timerTask = object : TimerTask() {
override fun run() {
if (mLatLng != null) {
mSpeedLimmit = MogoMapUIController.getInstance()
.getLimitSpeed(mLatLng!!.longitude, mLatLng!!.latitude, mLatLng!!.bearing)
UiThreadHandler.post {
val speed = (mLatLng!!.speed * 3.6f).toInt()
mSpeedChartView.setArcColor(Color.parseColor(if (speed > mSpeedLimmit) "#DB3137" else "#3E77F6"))
mSpeedChartView.setValues(speed)
setBackgroundResource(if (speed > mSpeedLimmit) R.drawable.yi_biao_pan_bg_speeding else R.drawable.yi_biao_pan_bg_nor)
private var timerTask : TimerTask? = null
override fun onAttachedToWindow() {
super.onAttachedToWindow() // 注册位置回调
mMogoServiceApis.registerCenterApi.registerCarLocationChangedListener(TAG, this)
// 开启定时查询速度
timerTask?.cancel()
val task = object : TimerTask() {
override fun run() {
if (mLatLng != null) {
mSpeedLimmit = MogoMapUIController.getInstance()
.getLimitSpeed(mLatLng!!.longitude, mLatLng!!.latitude, mLatLng!!.bearing)
UiThreadHandler.post {
val speed = (mLatLng!!.speed * 3.6f).toInt()
mSpeedChartView.setArcColor(Color.parseColor(if (speed > mSpeedLimmit) "#DB3137" else "#3E77F6"))
mSpeedChartView.setValues(speed)
setBackgroundResource(if (speed > mSpeedLimmit) R.drawable.yi_biao_pan_bg_speeding else R.drawable.yi_biao_pan_bg_nor)
}
}
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
// 注册位置回调
mMogoServiceApis.registerCenterApi
.registerCarLocationChangedListener(TAG, this)
// 开启定时查询速度
Timer().schedule(timerTask, Date(), 100)
this.timerTask = task
timer.schedule(task, Date(), 100)
}
override fun onDetachedFromWindow() {
@@ -92,7 +98,7 @@ class SpeedPanelView @JvmOverloads constructor(
mMogoServiceApis.registerCenterApi
.unregisterMogoLocationListener(TAG)
try {
timerTask.cancel()
timerTask?.cancel()
} catch (e: Exception) {
e.printStackTrace()
}

View File

@@ -0,0 +1,90 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.RelativeLayout
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.BarUtils
import com.mogo.eagle.core.utilcode.util.ScreenUtils
import kotlinx.android.synthetic.main.view_status_bar.view.*
import java.util.concurrent.CopyOnWriteArrayList
class StatusBarView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr), IMoGoSkinModeChangeListener {
companion object {
const val TAG = "StatusBarView"
}
init {
LayoutInflater.from(context).inflate(R.layout.view_status_bar, this, true)
}
private val rightViewList = CopyOnWriteArrayList<String>()
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val layoutParamsLeft =
LayoutParams(ScreenUtils.getScreenWidth() / 3, BarUtils.getStatusBarHeight())
viewStatusBarLeft.layoutParams = layoutParamsLeft
val layoutParamsRight =
LayoutParams(ScreenUtils.getScreenWidth() / 3 * 2, BarUtils.getStatusBarHeight())
layoutParamsRight.addRule(ALIGN_PARENT_END)
layoutParamsRight.addRule(CENTER_HORIZONTAL)
layoutParamsRight.addRule(CENTER_IN_PARENT)
layoutParamsRight.marginEnd = context.resources.getDimension(R.dimen.dp_44).toInt()
viewStatusBarRight.layoutParams = layoutParamsRight
viewStatusBarRight.addView(BatteryGroupView(this.context))
// 添加换肤监听
CallerSkinModeListenerManager.addListener(TAG, this)
}
override fun onSkinModeChange(skinMode: Int) {
when (skinMode) {
0 -> setStatusBarDarkOrLight(false)
1 -> setStatusBarDarkOrLight(true)
}
}
fun setStatusBarDarkOrLight(light: Boolean) {
if (light) {
setTextColor(resources.getColor(R.color.color_2C2E30))
} else {
setTextColor(resources.getColor(R.color.color_FFFFFF))
}
}
fun updateRightView(insert: Boolean, tag: String, viewGroup: ViewGroup) {
if (insert) {
rightViewList.add(0, tag)
viewStatusBarRight.addView(viewGroup, 0)
} else {
rightViewList.forEachIndexed { index, s ->
if (s == tag) {
rightViewList.removeAt(index)
viewStatusBarRight.removeViewAt(index)
}
}
}
}
private fun setTextColor(color: Int) {
viewTextClock.setTextColor(color)
viewStatusBarTag.setTextColor(color)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerSkinModeListenerManager.removeListener(TAG)
}
}

View File

@@ -3,7 +3,6 @@ package com.mogo.eagle.core.function.hmi.ui.widget;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.RotateAnimation;
@@ -54,12 +53,10 @@ public class SteeringWheelView extends ConstraintLayout {
public SteeringWheelView(@NonNull Context context) {
super(context);
Log.d(TAG, "1");
}
public SteeringWheelView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
Log.d(TAG, "2");
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
LayoutInflater.from(context).inflate(R.layout.hmi_steering_wheel_bus, this);
} else {
@@ -94,12 +91,10 @@ public class SteeringWheelView extends ConstraintLayout {
public SteeringWheelView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Log.d(TAG, "3");
}
public SteeringWheelView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
Log.d(TAG, "4");
}
private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener() {
@@ -127,7 +122,6 @@ public class SteeringWheelView extends ConstraintLayout {
int state = autopilotStatusInfo.getState();
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "state = %s", state);
if (autopilotIV != null) {
Log.d(TAG, "autopilotIV != null");
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
// TODO
@@ -151,7 +145,7 @@ public class SteeringWheelView extends ConstraintLayout {
}
}
} else {
Log.d(TAG, "autopilotIV=null");
CallerLogger.INSTANCE.d(TAG, "autopilotIV=null");
}
}
});
@@ -192,7 +186,6 @@ public class SteeringWheelView extends ConstraintLayout {
*/
@Override
public void onAutopilotLightSwitchData(@org.jetbrains.annotations.Nullable Chassis.LightSwitch lightSwitch) {
Log.d(TAG, "车辆转向灯:" + lightSwitch.toString());
}
/**
@@ -201,7 +194,6 @@ public class SteeringWheelView extends ConstraintLayout {
*/
@Override
public void onAutopilotBrakeLightData(boolean brakeLight) {
Log.d(TAG, "刹车灯:" + String.valueOf(brakeLight));
}
/**
@@ -219,7 +211,6 @@ public class SteeringWheelView extends ConstraintLayout {
*/
@Override
public void onAutopilotSteeringData(float steering) {
Log.d(TAG, "steering原始值====" + String.valueOf(steering));
if (Math.abs(steering) < 1) {
steering = 0;
}
@@ -227,7 +218,6 @@ public class SteeringWheelView extends ConstraintLayout {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "steering忽略小数点后====" + String.valueOf((int) steeringValue));
if (steeringTVL != null && steeringValue > 0) {
steeringTVR.setVisibility(View.INVISIBLE);
steeringTVL.setVisibility(View.VISIBLE);
@@ -237,7 +227,7 @@ public class SteeringWheelView extends ConstraintLayout {
steeringTVR.setVisibility(View.VISIBLE);
steeringTVR.setText(String.valueOf((int) -steeringValue) + "°");
} else {
Log.d(TAG, "onAutopilotSteeringData error");
CallerLogger.INSTANCE.d(TAG, "onAutopilotSteeringData error");
}
animationWithSteeringData(-steeringValue);
if (steeringCircularV != null) {
@@ -260,7 +250,7 @@ public class SteeringWheelView extends ConstraintLayout {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "乘客屏档位" + gear.toString());
CallerLogger.INSTANCE.d(TAG, "乘客屏档位" + gear.toString());
if (tapPositionView != null) {
tapPositionView.updateWithGear(gear);
}
@@ -288,7 +278,6 @@ public class SteeringWheelView extends ConstraintLayout {
* @param steering
*/
private void animationWithSteeringData(float steering) {
Log.d(TAG, "方向盘转动" + String.valueOf(steering));
rotateAnimation = new RotateAnimation(fromDegrees, steering,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);

Some files were not shown because too many files have changed in this diff Show More