Merge branch 'release_robotaxi-d_231031_6.2.0.2' into 6.2.0_merge_master

# Conflicts:
#	OCH/sweeper/driver/src/main/java/com/mogo/och/sweeper/cloud/fragment/BaseSweeperCloudTabFragment.java
#	OCH/sweeper/driver/src/main/java/com/mogo/och/sweeper/cloud/model/SweeperCloudTaskModel.java
#	OCH/sweeper/driver/src/main/java/com/mogo/och/sweeper/operate/model/SweeperOperateTaskModel.java
#	OCH/sweeper/sweeper/build.gradle
#	OCH/sweeper/sweeper/src/main/java/com/mogo/och/sweeper/SweeperProvider.java
#	OCH/sweeper/sweeper/src/main/java/com/mogo/och/sweeper/view/BusArcView.java
#	app/script/functions/och.gradle
#	app/src/main/java/com/mogo/launcher/startup/ConfigStartUp.kt
#	core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/SOPSettingView.kt
#	core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_sop_setting.xml
#	core/function-impl/mogo-core-function-hmi/src/main/res/values/strings.xml
#	core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/config/FunctionBuildConfig.kt
This commit is contained in:
yangyakun
2023-12-04 11:01:17 +08:00
1322 changed files with 15039 additions and 15346 deletions

View File

@@ -67,6 +67,7 @@ dependencies {
kapt rootProject.ext.dependencies.androidxroomcompiler
implementation rootProject.ext.dependencies.androidxroomktx
implementation rootProject.ext.dependencies.localbroadcastmanager
compileOnly project(':core:function-impl:mogo-core-function-map')
implementation project(':foudations:mogo-commons')
implementation project(':core:mogo-core-utils')

View File

@@ -2,6 +2,7 @@ package com.mogo.eagle.function.biz.dispatch
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
@@ -9,6 +10,7 @@ import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.autopilot.AutopilotRouteInfo
import com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBean
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.map.MogoLatLng
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
@@ -31,11 +33,12 @@ import com.mogo.eagle.function.biz.dispatch.network.DispatchServiceModel.Compani
import com.mogo.eagle.function.biz.dispatch.network.DispatchServiceModel.Companion.DISPATCH_STOP_MANUAL_CANCEL
import com.mogo.eagle.function.biz.dispatch.network.DispatchServiceModel.Companion.DISPATCH_STOP_TIMER_CANCEL
import com.mogo.eagle.function.biz.dispatch.network.DispatchServiceModel.Companion.dispatchServiceModel
import com.mogo.eagle.function.biz.v2x.V2XBizTrace
import com.zhjt.mogo.adas.data.bean.MogoReport
import com.zhjt.service.chain.ChainLog
import mogo.telematics.pad.MessagePad
import mogo_msg.MogoReportMsg
//todo emArrow 添加biz链路日志
//负责监听自动驾驶状态并进行状态上报,自动驾驶路线上报,接收调度指令展示指令弹窗
class DispatchAutoPilotManager private constructor() :
IMogoOnMessageListener<DispatchAdasAutoPilotLocReceiverBean>,
@@ -61,7 +64,7 @@ class DispatchAutoPilotManager private constructor() :
private var isDispatch = false
private var isArriveEnd = false
private val handler: Handler = object : Handler() {
private val handler: Handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if (msg.what == MSG_TYPE_SHOW_DIALOG) {
@@ -109,6 +112,12 @@ class DispatchAutoPilotManager private constructor() :
return DispatchAdasAutoPilotLocReceiverBean::class.java
}
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_V2X,
linkCode = ChainConstant.CHAIN_SOURCE_CLOUD,
nodeAliasCode = ChainConstant.CHAIN_CODE_DISPATCH_RECEIVE,
paramIndexes = [0]
)
override fun onMsgReceived(adasAutoPilotLocReceiverBean: DispatchAdasAutoPilotLocReceiverBean?) {
CallerLogger.i("$M_BIZ$TAG","onMsgReceived 收到云调度长链接, adasAutoPilotLocReceiver:${adasAutoPilotLocReceiverBean?:""}")
if (adasAutoPilotLocReceiverBean != null && adasAutoPilotLocReceiverBean.startLat != 0.0 && adasAutoPilotLocReceiverBean.startLon != 0.0) {
@@ -130,6 +139,12 @@ class DispatchAutoPilotManager private constructor() :
}
}
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_V2X,
linkCode = ChainConstant.CHAIN_SOURCE_CLOUD,
nodeAliasCode = ChainConstant.CHAIN_CODE_DISPATCH_START,
paramIndexes = [-1]
)
private fun startAutoPilot() {
val currentAutopilot = AutopilotControlParameters()
// currentAutopilot.isSpeakVoice = false
@@ -146,34 +161,42 @@ class DispatchAutoPilotManager private constructor() :
}
}
if(it.trajUrl == null){
V2XBizTrace.onAck(M_BIZ + TAG, "trajUrl-null")
ToastUtils.showShort("trajUrl数据为空")
return
}
if(it.trajMd5 == null){
V2XBizTrace.onAck(M_BIZ + TAG, "trajMd5-null")
ToastUtils.showShort("trajMd5数据为空")
return
}
if(it.stopUrl == null){
V2XBizTrace.onAck(M_BIZ + TAG, "stopUrl-null")
ToastUtils.showShort("stopUrl数据为空")
return
}
if(it.stopMd5 == null){
V2XBizTrace.onAck(M_BIZ + TAG, "stopMd5-null")
ToastUtils.showShort("stopMd5数据为空")
return
}
if(it.vehicleModel == null){
V2XBizTrace.onAck(M_BIZ + TAG, "vehicleModel-null")
ToastUtils.showShort("vehicleModel数据为空")
return
}
if(it.lineName == null){
V2XBizTrace.onAck(M_BIZ + TAG, "lineName-null")
ToastUtils.showShort("lineName数据为空")
return
}
if(it.startLocAddress == null){
V2XBizTrace.onAck(M_BIZ + TAG, "startLocAddress-null")
ToastUtils.showShort("startLocAddress数据为空")
return
}
if(it.endLocAddress == null){
V2XBizTrace.onAck(M_BIZ + TAG, "endLocAddress-null")
ToastUtils.showShort("endLocAddress数据为空")
return
}
@@ -191,7 +214,7 @@ class DispatchAutoPilotManager private constructor() :
currentAutopilot.endLatLon =
AutopilotControlParameters.AutoPilotLonLat(it.endLat, it.endLon)
currentAutopilot.vehicleType = 10
CallerLogger.d(M_BIZ + TAG, "开启自动驾驶====$currentAutopilot")
V2XBizTrace.onAck(M_BIZ + TAG, "开启自动驾驶====$currentAutopilot")
CallerAutoPilotControlManager.startAutoPilot(currentAutopilot)
}
}
@@ -213,6 +236,7 @@ class DispatchAutoPilotManager private constructor() :
* 停止调度确认
*/
fun stopAffirm(){
V2XBizTrace.onAck(M_BIZ + TAG,"stopAffirm")
CallerHmiManager.dismissDispatchDialog()
receiverBean?.taskId?.let{
dispatchServiceModel.dispatchResultUpload(DISPATCH_STOP_AFFIRM, it,
@@ -230,6 +254,7 @@ class DispatchAutoPilotManager private constructor() :
}
fun cancel(manualTrigger: Boolean) {
V2XBizTrace.onAck(M_BIZ + TAG,"cancel")
CallerHmiManager.dismissDispatchDialog()
receiverBean?.taskId?.let {
dispatchServiceModel.dispatchResultUpload(
@@ -241,6 +266,7 @@ class DispatchAutoPilotManager private constructor() :
* 停止调度取消
*/
fun stopCancel(manualTrigger: Boolean){
V2XBizTrace.onAck(M_BIZ + TAG,"stopCancel:$manualTrigger")
CallerHmiManager.dismissDispatchDialog()
receiverBean?.taskId?.let{
dispatchServiceModel.dispatchResultUpload(
@@ -263,9 +289,6 @@ class DispatchAutoPilotManager private constructor() :
if (isArriveEnd) {
return
}
//todo 确认是否要根据停靠时自动驾驶状态,再次开启自动驾驶
// 确保处于调度中并且返回的自动驾驶状态为1才开启自动驾驶
// 上述等待鄂州项目复盘后,产品输出完成方案后再进操作!!!
if (isDispatch) {
startAutoPilot()
}
@@ -324,6 +347,8 @@ class DispatchAutoPilotManager private constructor() :
//语音提示到站
AIAssist.getInstance(mContext).speakTTSVoice("云调度完成,车辆已到达${it.endLocAddress}")
}
}else{
V2XBizTrace.onAck(M_BIZ + TAG, mapOf("arriveErrorMsg" to "不在到站距离范围内", "ArriveAtStation" to arrivalNotification, "distanceFromSelf" to distanceFromSelf))
}
}

View File

@@ -30,7 +30,6 @@ import okhttp3.RequestBody;
* @since: 10/28/21
*/
public class NoticeNetWorkManager {
private static volatile NoticeNetWorkManager requestNoticeManager;
private final INoticeApiService mNoticeApiService;
private NoticeNetWorkManager() {
@@ -39,14 +38,11 @@ public class NoticeNetWorkManager {
}
public static NoticeNetWorkManager getInstance() {
if (requestNoticeManager == null) {
synchronized (NoticeNetWorkManager.class) {
if (requestNoticeManager == null) {
requestNoticeManager = new NoticeNetWorkManager();
}
}
}
return requestNoticeManager;
return Holder.requestNoticeManager;
}
private static final class Holder{
private static final NoticeNetWorkManager requestNoticeManager = new NoticeNetWorkManager();
}
/**
@@ -88,7 +84,7 @@ public class NoticeNetWorkManager {
* 反馈交警是否接受事故任务
*
* @param infoId 事故id
* @param sn
* @param sn sn
* @param status 是否接受 0否 1是
*/
public void sendAccidentAcceptStatus(String infoId, String sn, int status) {

View File

@@ -11,6 +11,7 @@ import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.call.obu.CallerObuSaveMessageListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.function.biz.v2x.V2XBizTrace
import com.mogo.eagle.function.biz.v2x.v2n.utils.V2XEventAnalyticsManager
/**
@@ -53,7 +54,7 @@ object V2xObuEventManager : IMoGoObuSaveMessageListener {
}
}
obuDataMap[type] = System.currentTimeMillis()
CallerLogger.d("${SceneConstant.M_OBU}${TAG}", "onMoGoObuSaveMessage type = $type ---content = $content ---tts = $tts ")
V2XBizTrace.onAck("${SceneConstant.M_OBU}${TAG}", mapOf("type" to type,"content" to content,"tts" to tts))
CallerMsgBoxManager.saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,

View File

@@ -1,6 +1,5 @@
package com.mogo.eagle.function.biz.v2x.redlightwarning
import android.util.Log
import com.mogo.eagle.core.data.biz.trafficlight.*
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
@@ -235,9 +234,6 @@ class RedLightWarningManager : IMoGoTrafficLightListener, IMoGoVipSetListener,
EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ID_IVP_GREEN.poiType),
speed
)
if (content.isEmpty() || tts.isEmpty()) {
Log.d("MsgBox-RedLightWarManaG", "alertContent或ttsContent为空!")
}
CallerMsgBoxManager.saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,

View File

@@ -7,6 +7,7 @@ import androidx.annotation.*
import androidx.localbroadcastmanager.content.*
import com.mogo.eagle.core.data.config.*
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_V2X_MSG
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_SOURCE_ADAS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_SOURCE_CLOUD
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_V2X
import com.mogo.eagle.core.data.enums.*
@@ -114,7 +115,7 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IV2XCallback,
V2XScenarioManager.getInstance().handlerMessage(v2XMessageEntity)
V2XBizTrace.onAck("巡航处理 handlerMessage v2XMessageEntity", " $v2XMessageEntity")
}else{
V2XBizTrace.onAck("事件未触发", mapOf("roadEvent" to v2XRoadEventEntity, "distance" to distance))
V2XBizTrace.onAck("事件未触发,巡航处理", mapOf("roadEvent" to v2XRoadEventEntity, "distance" to distance))
}
}
}
@@ -171,10 +172,12 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IV2XCallback,
is V2XEvent.RoadEventX -> {
if (!AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode) || !FunctionBuildConfig.v2nMainSwitch || !FunctionBuildConfig.isNewV2NData) {
handleRoadMarkerEvent(event.data.toRoadMarker())
}else{
V2XBizTrace.onAck("事件未触发,被开关拦截",mapOf("roadEvent" to event, "v2nMainSwitch" to FunctionBuildConfig.v2nMainSwitch,"isNewV2NData" to FunctionBuildConfig.isNewV2NData))
}
}
else -> {
Logger.e(TAG, "onAck other event: $event")
V2XBizTrace.onAck("事件未触发,不识别的新事件",mapOf("roadEvent" to event))
}
}
}
@@ -182,7 +185,7 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IV2XCallback,
@RequiresApi(Build.VERSION_CODES.N)
@ChainLog(
linkChainLog = CHAIN_TYPE_V2X,
linkCode = CHAIN_SOURCE_CLOUD,
linkCode = CHAIN_SOURCE_ADAS,
nodeAliasCode = CHAIN_CODE_V2X_MSG,
paramIndexes = [0]
)
@@ -301,6 +304,7 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IV2XCallback,
val msgBoxBean =
MsgBoxBean(MsgBoxType.V2X, V2XMsg("", "查询到当前全程共${count}个事件", "",CommunicationType.V2N.name))
msgBoxBean.sourceType = DataSourceType.SUMMARY
V2XBizTrace.onAck("$M_V2X$TAG", mapOf("v2xEventsSummary" to msgBoxBean))
CallerMsgBoxManager.saveMsgBox(msgBoxBean)
//消息埋点
V2XEventAnalyticsManager.triggerV2XEvent("summary","查询到当前全程共${count}个事件",

View File

@@ -12,7 +12,9 @@ import com.mogo.eagle.core.data.v2x.V2XEvent
import com.mogo.eagle.core.data.v2x.V2XMarkerResponse
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.eagle.function.biz.v2x.V2XBizTrace
import com.mogo.eagle.function.biz.v2x.v2n.network.V2XRefreshModel
import com.mogo.eagle.function.biz.v2x.v2n.network.callback.IV2XCallback
import com.mogo.eagle.function.biz.v2x.v2n.network.callback.IV2XRefreshCallback
@@ -160,6 +162,7 @@ class V2XPoiLoader private constructor() {
val msgBoxBean =
MsgBoxBean(MsgBoxType.V2X, V2XMsg("", "查询到当前全程共${size}个事件", "",CommunicationType.V2N.name))
msgBoxBean.sourceType = DataSourceType.SUMMARY
V2XBizTrace.onAck("${SceneConstant.M_V2X}$TAG", mapOf("v2xEventsSummary" to msgBoxBean))
CallerMsgBoxManager.saveMsgBox(msgBoxBean)
//消息埋点
V2XEventAnalyticsManager.triggerV2XEvent("summary","查询到当前全程共${size}个事件",

View File

@@ -6,7 +6,9 @@ import com.mogo.eagle.core.data.map.entity.MarkerLocation;
import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils;
import com.mogo.eagle.function.biz.v2x.V2XBizTrace;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -96,7 +98,15 @@ public class V2XAlarmServer {
showedEvents.add(v2XRoadEventEntity);
return v2XRoadEventEntity;
}
}else{
HashMap map = new HashMap<String,Double>();
map.put("diffAngle",diffAngle);
V2XBizTrace.Companion.onAck("事件未触发,未达到触发角度",map);
}
}else{
HashMap map = new HashMap<String,Double>();
map.put("distance",distance);
V2XBizTrace.Companion.onAck("事件未触发,未达到触发距离",map);
}
}
}

View File

@@ -9,15 +9,15 @@ import com.mogo.eagle.core.data.enums.WarningDirectionEnum.ALERT_WARNING_TOP
import com.mogo.eagle.core.data.map.entity.*
import com.mogo.eagle.core.data.msgbox.*
import com.mogo.eagle.core.data.msgbox.MsgBoxType.V2X
import com.mogo.eagle.core.function.angle.scenes.Default
import com.mogo.eagle.core.function.angle.scenes.RoadEvent
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.api.hmi.warning.*
import com.mogo.eagle.core.function.api.map.angle.*
import com.mogo.eagle.core.function.call.autopilot.*
import com.mogo.eagle.core.function.call.hmi.*
import com.mogo.eagle.core.function.call.map.*
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.utilcode.mogo.*
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.eagle.function.biz.v2x.V2XBizTrace
import com.mogo.eagle.function.biz.v2x.v2n.scenario.scene.airoad.*
@@ -33,7 +33,6 @@ import mogo.v2x.MogoV2X.RSI_PB
*/
internal object V2NIdentifyDrawer {
private const val TAG = "V2NIdentifyDataSubscriber"
private const val MSG_WHAT_DRAW_SHIGONE = 0x1010 // 道路施工
@@ -44,6 +43,7 @@ internal object V2NIdentifyDrawer {
if (msg.what == MSG_WHAT_DRAW_SHIGONE || msg.what == MSG_WHAT_DRAW_SHIGU) {
val events = msg.obj as? List<*>
if (events == null || events.isEmpty()) {
V2XBizTrace.onAck(TAG, mapOf("shiGong-shiGu" to ""))
return@Callback true
}
val car = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84()
@@ -51,6 +51,7 @@ internal object V2NIdentifyDrawer {
DrivingDirectionUtils.getDegreeOfCar2Poi(car.longitude, car.latitude, itx.longitude, itx.latitude, car.heading.toInt()) < 90
}
if (filtered.isEmpty()) {
V2XBizTrace.onAck(TAG, mapOf("shiGong-shiGu-filter" to ""))
return@Callback true
}
filtered.forEach { itx ->
@@ -78,7 +79,7 @@ internal object V2NIdentifyDrawer {
val distance = CoordinateUtils.calculateLineDistance(itx.longitude, itx.latitude, car.longitude, car.latitude)
val alertContent = getAlertContent(poiType, distance.toDouble())
val ttsContent = getTtsContent(poiType, distance.toDouble())
V2XBizTrace.onAck("V2NIdentifyDrawer","绘制poi事件:$poiType")
V2XBizTrace.onAck(TAG,"绘制poi事件:$poiType")
saveMsgBox(MsgBoxBean(V2X, V2XMsg(poiType, alertContent, ttsContent,CommunicationType.V2N.name)))
CallerHmiManager.warningV2X(poiType, alertContent, ttsContent, object : IMoGoWarningStatusListener {
override fun onShow() {
@@ -100,6 +101,7 @@ internal object V2NIdentifyDrawer {
} else if (msg.what == MSG_WHAT_DRAW_YONGDU) {
val events = msg.obj as? List<*>
if (events == null || events.isEmpty()) {
V2XBizTrace.onAck(TAG, mapOf("yongDu" to ""))
return@Callback true
}
val car = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84()
@@ -109,6 +111,7 @@ internal object V2NIdentifyDrawer {
DrivingDirectionUtils.getDegreeOfCar2Poi(car.longitude, car.latitude, eventLon, eventLat, car.heading.toInt()) < 90
}
if (filtered.isEmpty()) {
V2XBizTrace.onAck(TAG, mapOf("yongDu-filter" to ""))
return@Callback true
}
filtered.forEach { itx ->
@@ -137,6 +140,7 @@ internal object V2NIdentifyDrawer {
val distance = CoordinateUtils.calculateLineDistance(lon, lat, car.longitude, car.latitude)
val alertContent = getAlertContent(poiType, distance.toDouble())
val ttsContent = getTtsContent(poiType, distance.toDouble())
V2XBizTrace.onAck(TAG,"绘制poi事件:$poiType")
saveMsgBox(MsgBoxBean(V2X, V2XMsg(poiType, alertContent, ttsContent,CommunicationType.V2N.name)))
CallerHmiManager.warningV2X(poiType, alertContent, ttsContent, object : IMoGoWarningStatusListener {
override fun onShow() {
@@ -221,7 +225,6 @@ internal object V2NIdentifyDrawer {
override fun onAutopilotV2nCongestionEvent(header: Header, rsi: RSI_PB) {
super.onAutopilotV2nCongestionEvent(header, rsi)
Logger.d(TAG, "--- onAutopilotV2nCongestionEvent -- : rsi: ${ GsonUtils.toJson(rsi) }")
try {
V2XBizTrace.onAck("onAutopilotV2nCongestionEvent", rsi)
} catch (t: Throwable) {

View File

@@ -101,7 +101,7 @@ class AiRoadMarker {
300f, call = { result ->
//施工中心点后方的自车行驶方向上300米距离
result?.let {
V2XBizTrace.onAck("$TAG --- marker --- 3 --- l1:", it)
V2XBizTrace.onAck("$TAG -marker-3-l1:", it)
l1 = result
}
countDown.incrementAndGet()
@@ -113,7 +113,7 @@ class AiRoadMarker {
location.heading.toFloat(),
-300f, call = { result ->
result?.let {
V2XBizTrace.onAck("$TAG --- marker --- 3 --- l2:", it)
V2XBizTrace.onAck("$TAG -marker-3-l2:", it)
l2 = result
}
countDown.incrementAndGet()
@@ -136,14 +136,14 @@ class AiRoadMarker {
return@post
}
if (l1 == null || l2 == null) {
V2XBizTrace.onAck("$TAG --- marker --- 3 --- line null return ----", "")
V2XBizTrace.onAck("$TAG -marker-3-line null return ----", "")
return@post
}
if (l1.points.isEmpty() || l2.points.isEmpty()) {
V2XBizTrace.onAck("$TAG --- marker --- 3 --- line points null return ----", "")
V2XBizTrace.onAck("$TAG -marker-3-line points null return ----", "")
return@post
}
V2XBizTrace.onAck("$TAG --- marker --- 4 --- l2:", l2)
V2XBizTrace.onAck("$TAG -marker-4-l2:", l2)
val points = LinkedList<MogoLatLng>()
if (l2.points.isNotEmpty()) {
points.addAll(l2.points.reversed().map {
@@ -152,7 +152,7 @@ class AiRoadMarker {
}
val centerX = marker.poi_lon
val centerY = marker.poi_lat
V2XBizTrace.onAck("$TAG --- marker --- 5 --- marker:", marker)
V2XBizTrace.onAck("$TAG -marker-5-marker:", marker)
val farthestPoint = marker.polygon?.let {
var find: Pair<Double, Double> = Pair(centerX, centerY)
var min = Long.MAX_VALUE
@@ -172,7 +172,7 @@ class AiRoadMarker {
MogoLatLng(find.second, find.first)
} ?: MogoLatLng(centerY, centerX)
marker.farthestPoint = Pair(farthestPoint.lon, farthestPoint.lat)
V2XBizTrace.onAck("$TAG --- marker --- 6 --- marker:", marker)
V2XBizTrace.onAck("$TAG -marker-6-marker:", marker)
if (l1.points.isNotEmpty()) {
for (l in l1.points) {
if (DrivingDirectionUtils.getDegreeOfCar2Poi2(
@@ -204,7 +204,7 @@ class AiRoadMarker {
builder.points(points)
builder.colors(colors)
builder.setVisible(true)
V2XBizTrace.onAck("$TAG --- marker --- 7 --- points:", "${points.size}")
V2XBizTrace.onAck("$TAG -marker-7-points:", "${points.size}")
val line = overlayManager?.showOrUpdateLine(builder.build())
if (line != null) {
this.line.set(line)
@@ -220,9 +220,9 @@ class AiRoadMarker {
private fun removeLine() {
val old = line.get()
V2XBizTrace.onAck("$TAG --- removeRedLine --- 1", "")
V2XBizTrace.onAck("$TAG -removeRedLine-1", "")
if (old != null) {
V2XBizTrace.onAck("$TAG --- removeRedLine --- 2", "")
V2XBizTrace.onAck("$TAG -removeRedLine-2", "")
line.set(null)
old.delegate?.remove()
}
@@ -230,7 +230,7 @@ class AiRoadMarker {
private fun unMarker(marker: Marker) {
v2nDrawHandler.post {
V2XBizTrace.onAck("$TAG --- unMarker ---", "")
V2XBizTrace.onAck("$TAG -unMarker-", "")
this.marker.set(null)
removeLine()
roadMarker.removeMarkers()
@@ -240,7 +240,7 @@ class AiRoadMarker {
}
fun receive() {
V2XBizTrace.onAck("$TAG --- receive --- 1 ---", "")
V2XBizTrace.onAck("$TAG -receive-1-", "")
val poi = this.marker.get()
val car = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84()
if (poi != null) {
@@ -251,7 +251,7 @@ class AiRoadMarker {
poi.poi_lat
)
V2XBizTrace.onAck(
"$TAG --- receive --- 2 ---",
"$TAG -receive-2-",
"car:[${car.longitude}, ${car.latitude}] -> poi:[${poi.poi_lon}, ${poi.poi_lat}] --> distance:$distance"
)
if (distance < 500) {

View File

@@ -12,9 +12,9 @@ import com.mogo.eagle.core.data.map.entity.V2XRoadEventEntity;
import com.mogo.eagle.core.data.msgbox.MsgBoxBean;
import com.mogo.eagle.core.data.msgbox.MsgBoxType;
import com.mogo.eagle.core.data.msgbox.V2XMsg;
import com.mogo.eagle.core.function.angle.scenes.Default;
import com.mogo.eagle.core.function.angle.scenes.RoadEvent;
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener;
import com.mogo.eagle.core.function.api.map.angle.Default;
import com.mogo.eagle.core.function.api.map.angle.RoadEvent;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager;

View File

@@ -29,6 +29,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.function.biz.v2x.v2n.utils.V2XEventAnalyticsManager;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
@@ -68,7 +69,7 @@ public class V2XFrontWarningScenario extends AbsV2XScenario implements IMoGoChas
if (mMarkerEntity != null) {
CallerLogger.d(M_V2X + TAG, "----- show --- 2 --:\n" + mMarkerEntity);
String v2xType = getV2XTypeForFrontWarning(mMarkerEntity);
V2XMessageEntity entity = getV2XMessageEntity();
// V2XMessageEntity entity = getV2XMessageEntity();
if (!v2xType.equals("0")) {
if (getAlertContentForFrontWarning(mMarkerEntity).toString() == null
|| getAlertContentForFrontWarning(mMarkerEntity).toString().isEmpty()
@@ -112,8 +113,8 @@ public class V2XFrontWarningScenario extends AbsV2XScenario implements IMoGoChas
private CharSequence getAlertContentForFrontWarning(V2XWarningTarget entity) {
double dis = entity.getDistance();
//距离四舍五入保留整数
BigDecimal bg = new BigDecimal(dis);
double disBig = bg.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
BigDecimal bg = BigDecimal.valueOf(dis);
double disBig = bg.setScale(0, RoundingMode.HALF_UP).doubleValue();
String distance = String.format(Locale.getDefault(), "%.0f", disBig) + "";
String content = entity.getWarningContent();
SpannableStringBuilder ssb = new SpannableStringBuilder(content + distance);

View File

@@ -4,7 +4,6 @@ import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
@@ -269,9 +268,6 @@ class VipCarManager : IMogoOnMessageListener<VipMessage>, IMoGoTrafficLightListe
alertContent: CharSequence,
ttsContent: String,
) {
if (alertContent.toString().isEmpty() || ttsContent.isEmpty()) {
Log.d("MsgBox-VipCarManager", "alertContent或ttsContent为空!")
}
CallerMsgBoxManager.saveMsgBox(
MsgBoxBean(MsgBoxType.V2X, V2XMsg(v2xType, alertContent.toString(), ttsContent,CommunicationType.V2N.name))
)

View File

@@ -62,6 +62,7 @@ dependencies {
implementation project(':libraries:mogo-obu')
implementation project(':libraries:mogo-adas')
implementation rootProject.ext.dependencies.mogoaicloudtelematic
compileOnly project(':core:function-impl:mogo-core-function-map')
implementation project(':core:mogo-core-function-call')
implementation project(":foudations:mogo-commons")
}

View File

@@ -21,7 +21,7 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_SEND
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_MULTI_CONNECT
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_SOURCE_ADAS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_INIT_STATUS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_STATUS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_SOCKET_AUTOPILOT
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotControlProvider
@@ -347,7 +347,7 @@ class MoGoAutopilotControlProvider :
startAutoPilot(controlParameters, Constants.AUTOPILOT_SOURCE.PAD)
}
//todo chainlog
//todo emArrow chainlog
override fun startAutoPilotByMoFang(controlParameters: AutopilotControlParameters?) {
if (controlParameters==null){
startAutoPilotWithNoParameter(Constants.AUTOPILOT_SOURCE.MO_FANG)
@@ -649,6 +649,16 @@ class MoGoAutopilotControlProvider :
return AdasManager.getInstance().sendFusionMode(cmd)
}
/**
* 超车的最大速度闻值(double, m/s, 范围[3, 12.5])
*
* @param maxSpeed m/s, 范围[3, 12.5]
* @return boolean
*/
override fun sendOvertakeMaxSpeed(maxSpeed: Double): Boolean {
return AdasManager.getInstance().sendOvertakeMaxSpeed(maxSpeed)
}
override fun sendSetParamReq(param: Map<AdasConstants.MapSystemParamType, Any>): Boolean {
return AdasManager.getInstance().sendSetParamReq(param)
}
@@ -983,7 +993,7 @@ class MoGoAutopilotControlProvider :
}
@ChainLog(
linkChainLog = CHAIN_TYPE_INIT_STATUS,
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = CHAIN_SOURCE_ADAS,
nodeAliasCode = CHAIN_CODE_MULTI_CONNECT,
paramIndexes = [0]

View File

@@ -17,13 +17,15 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_AD
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_VEHICLE
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_CAR_CONFIG
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_CAR_LOC
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_FM_MSG
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_MAP_PARAM
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_PARALLEL
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_P_ACTIONS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_P_OBJECTS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_STATUS_QUERY_RESP
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_SOURCE_ADAS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_GNSS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_INIT_STATUS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_STATUS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_SOCKET_AUTOPILOT
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_SOCKET_TRAJECTORY
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_SOCKET_VEHICLE
@@ -50,7 +52,6 @@ import com.mogo.eagle.core.function.call.obu.CallerObuMapMathListenerManager
import com.mogo.eagle.core.function.call.obu.CallerObuWarningRsiListenerManager
import com.mogo.eagle.core.function.call.obu.CallerObuWarningRsmListenerManager
import com.mogo.eagle.core.function.call.obu.CallerObuWarningSpatListenerManager
import com.mogo.eagle.core.function.call.v2x.*
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.DeviceUtils
import com.mogo.support.obu.ObuScene
@@ -364,7 +365,7 @@ class MoGoAdasListenerImpl : OnAdasListener {
//工控机基础配置信息
@ChainLog(
linkChainLog = CHAIN_TYPE_INIT_STATUS,
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = CHAIN_SOURCE_ADAS,
nodeAliasCode = CHAIN_CODE_ADAS_CAR_CONFIG,
paramIndexes = [0, 1]
@@ -449,6 +450,13 @@ class MoGoAdasListenerImpl : OnAdasListener {
invokeSystemStatus(statusInf)
}
//FM消息回调
@ChainLog(
linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT,
linkCode = CHAIN_SOURCE_ADAS,
nodeAliasCode = CHAIN_CODE_ADAS_FM_MSG,
paramIndexes = [0, 1]
)
override fun onFaultManagementState(header: MessagePad.Header?, fmInfo: FmInfo.FaultResultMsg) {
CallerFaultManagementStateListenerManager.invokeFaultManagementState(fmInfo)
}
@@ -872,6 +880,12 @@ class MoGoAdasListenerImpl : OnAdasListener {
* @param getParamResp 配置参数
* @param adasParam 解析后的配置参数
*/
@ChainLog(
linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT,
linkCode = CHAIN_SOURCE_ADAS,
nodeAliasCode = CHAIN_CODE_ADAS_MAP_PARAM,
paramIndexes = [0, 1, 2]
)
override fun onGetParamResp(
header: MessagePad.Header,
getParamResp: MessagePad.SetParamReq,

View File

@@ -9,7 +9,7 @@ import com.mogo.eagle.core.data.biz.trafficlight.TrafficLightResult
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_INIT_STATUS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_STATUS
import com.mogo.eagle.core.data.multidisplay.TelematicConstant
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.setDemoMode
@@ -17,7 +17,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.telematic.CallerTelematicListenerManager
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
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
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
@@ -35,7 +35,7 @@ import mogo.telematics.pad.MessagePad
class TeleMsgHandler : IMsgHandler {
companion object{
companion object {
private const val TAG = "TeleMsgHandler"
}
@@ -65,9 +65,10 @@ class TeleMsgHandler : IMsgHandler {
AdasManager.getInstance().decoderRaw(it.body)
} catch (e: Exception) {
e.printStackTrace()
invokeNettyConnResult("乘客屏解析数据过程中出现异常:${e.message}")
invokeReqStatusLog(mapOf("dataParseError" to "${e.message}"))
}
}
MogoProtocolMsg.SYNC_MODE_STATUS -> {
val content = String(it.body)
if (content.contains(";")) {
@@ -75,25 +76,30 @@ class TeleMsgHandler : IMsgHandler {
if (strArr.size == 2) {
val currTime = strArr[1].toLong()
if (currTime > demoModeTime) {
FunctionBuildConfig.isDemoMode = when (strArr[0]) {
val demoMode = when (strArr[0]) {
"1" -> true
else -> false
}
CallerTelematicListenerManager.dispatchDemoMode(demoMode)
demoModeTime = currTime
invokeNettyConnResult("乘客屏收到的美化模式DemoMode为${FunctionBuildConfig.isDemoMode}")
invokeNettyConnResult("乘客屏收到的美化模式DemoMode为${demoMode}")
} else {
invokeNettyConnResult("乘客屏收到过时的美化模式DemoMode为:${FunctionBuildConfig.isDemoMode}")
invokeNettyConnResult("乘客屏收到过时的美化模式DemoMode")
}
}
}
}
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"))
CallerDevaToolsManager.getBindingCarInfo(carConfig.macAddress, MoGoAiCloudClientConfig.getInstance().sn)
CallerDevaToolsManager.getBindingCarInfo(
carConfig.macAddress,
MoGoAiCloudClientConfig.getInstance().sn
)
invokeNettyConnResult(
"司机屏发送给乘客屏配置信息为:${
TextFormat.printer().escapingNonAscii(false).printToString(carConfig)
@@ -129,21 +135,36 @@ class TeleMsgHandler : IMsgHandler {
}
}
}
TelematicConstant.BUSINESS_STRING -> {
CallerTelematicListenerManager.invokeReceivedMsg(TelematicConstant.BUSINESS_STRING, it.body)
CallerTelematicListenerManager.invokeReceivedMsg(
TelematicConstant.BUSINESS_STRING,
it.body
)
}
TelematicConstant.SHOW_TRAFFIC_LIGHT -> {
val trafficLightJson = String(it.body)
CallerTrafficLightListenerManager.invokeTrafficLightStatus(GsonUtils.fromJson(trafficLightJson, TrafficLightResult::class.java))
CallerTrafficLightListenerManager.invokeTrafficLightStatus(
GsonUtils.fromJson(
trafficLightJson,
TrafficLightResult::class.java
)
)
}
TelematicConstant.HIDE_TRAFFIC_LIGHT -> {
ThreadUtils.runOnUiThread {
CallerTrafficLightListenerManager.invokeEnterCrossRoad(false)
}
}
TelematicConstant.CONTROL_PASSENGER_DRIVER_MONITOR -> {
ThreadUtils.runOnUiThread {
CallerTelematicListenerManager.invokeReceivedMsg(TelematicConstant.CONTROL_PASSENGER_DRIVER_MONITOR,it.body)
CallerTelematicListenerManager.invokeReceivedMsg(
TelematicConstant.CONTROL_PASSENGER_DRIVER_MONITOR,
it.body
)
}
}
@@ -152,16 +173,19 @@ class TeleMsgHandler : IMsgHandler {
"0" -> {
HmiBuildConfig.isShowRunRedLightView = false
}
"1" -> {
HmiBuildConfig.isShowRunRedLightView = true
}
}
}
TelematicConstant.OBU_GREENWAVE_WARNING -> {
when (String(it.body)) {
"0" -> {
HmiBuildConfig.isShowGreenWaveView = false
}
"1" -> {
HmiBuildConfig.isShowGreenWaveView = true
}
@@ -188,8 +212,8 @@ class TeleMsgHandler : IMsgHandler {
MogoProtocolMsg.REQ_MAC_ADDRESS,
configArray.size, configArray
), channel
) {
invokeNettyConnResult("司机屏发送配置信息到乘客屏是否成功:${it.isSuccess}")
) { future ->
invokeReqStatusLog(mapOf("dSendParam2P" to future.isSuccess))
}
} else {
queryCarConfig()
@@ -199,22 +223,28 @@ class TeleMsgHandler : IMsgHandler {
MogoProtocolMsg.NORMAL_DATA -> {
AdasManager.getInstance().sendWsMessage(it.body)
}
10 -> {
val sn = MoGoAiCloudClientConfig.getInstance().sn
if (!sn.isNullOrEmpty()) {
val snArray = sn.toByteArray()
NSDNettyManager.getInstance().sendMsgToSpecifiedClient(
MogoProtocolMsg(10, snArray.size, snArray), channel
) {
invokeNettyConnResult("司机屏发送SN(${sn})到乘客屏是否成功:${it.isSuccess}")
) { future ->
invokeReqStatusLog(mapOf("dSendSN2P" to future.isSuccess, "sn" to sn))
}
} else {
invokeNettyConnResult("司机屏SN未获取到不发送给乘客屏")
}
}
TelematicConstant.BUSINESS_STRING -> {
CallerTelematicListenerManager.invokeReceivedMsg(TelematicConstant.BUSINESS_STRING, it.body)
CallerTelematicListenerManager.invokeReceivedMsg(
TelematicConstant.BUSINESS_STRING,
it.body
)
}
else -> {
}
}
@@ -245,32 +275,35 @@ class TeleMsgHandler : IMsgHandler {
}
// AdasManager.getInstance().startDispatchHandler()
ToastUtils.showShort("连接司机屏成功!")
invokeNettyConnResult("乘客屏连接司机屏成功")
invokeReqStatusLog(mapOf("dpConnectStatus" to true))
val byteArray = byteArrayOf(0)
NSDNettyManager.getInstance().sendMogoProtocolMsgToServer(
MogoProtocolMsg(MogoProtocolMsg.REQ_MAC_ADDRESS, byteArray.size, byteArray)
) {
invokeNettyConnResult("乘客屏请求配置信息的数据发送是否成功:${it}")
invokeReqStatusLog(mapOf("pReqParamSendResult" to it))
}
// 请求司机屏SN
reqServerSN()
}
ConnectState.STATUS_CONNECT_CLOSED -> {// 由于重连机制会回调多次
if (isFirstDisc) {
isFirstDisc = false
AppConfigInfo.plateNumber = ""
AppConfigInfo.iPCMacAddress = ""
ToastUtils.showLong("断开和司机屏的连接!")
invokeNettyConnResult("断开和司机屏的连接!")
invokeReqStatusLog(mapOf("dpConnectStatus" to false))
AdasManager.getInstance().stopDispatchHandler()
}
}
ConnectState.STATUS_CONNECT_ERROR -> {
AppConfigInfo.plateNumber = ""
ToastUtils.showLong("和司机端连接异常!")
invokeNettyConnResult("乘客屏和司机屏连接异常,错误为:$content")
invokeReqStatusLog(mapOf("dpConnectErrorMsg" to "$content"))
AdasManager.getInstance().stopDispatchHandler()
}
else -> {
AdasManager.getInstance().stopDispatchHandler()
}
@@ -280,7 +313,7 @@ class TeleMsgHandler : IMsgHandler {
override fun handleServerConnStatus(statusCode: Int, content: String?, channel: Channel) {}
@ChainLog(
linkChainLog = CHAIN_TYPE_INIT_STATUS,
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_ADAS,
nodeAliasCode = ChainConstant.CHAIN_CODE_MULTI_CONNECT,
paramIndexes = [0]
@@ -289,6 +322,16 @@ class TeleMsgHandler : IMsgHandler {
CallerLogger.d("${SceneConstant.M_D_C}$TAG", status)
}
@ChainLog(
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_ADAS,
nodeAliasCode = ChainConstant.CHAIN_CODE_MULTI_CONNECT,
paramIndexes = [0]
)
private fun invokeReqStatusLog(param: Map<String, Any>) {
CallerLogger.d("${SceneConstant.M_D_C}$TAG", param.toString())
}
/**
* 记录最新的司机屏发送数据的时间戳
* 或乘客屏解析数据的时间戳
@@ -317,7 +360,7 @@ class TeleMsgHandler : IMsgHandler {
NSDNettyManager.getInstance().sendMogoProtocolMsgToServer(
MogoProtocolMsg(10, byteArray.size, byteArray)
) {
invokeNettyConnResult("乘客屏请求司机屏SN的数据发送是否成功${it}")
invokeReqStatusLog(mapOf("pReqSNSendResult" to it))
}
delay(700)
}

View File

@@ -8,12 +8,12 @@ import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.enums.TrafficLightEnum
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.function.angle.scenes.CrossRoad
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuWarningMapListener
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuWarningRsiListener
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuWarningRsmListener
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuWarningSpatListener
import com.mogo.eagle.core.function.api.hmi.warning.*
import com.mogo.eagle.core.function.api.map.angle.*
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.map.*
@@ -310,6 +310,19 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuWarningRsiListener
saveObuToDcData(appId, alertContent, ttsContent,CommunicationType.V2I)
showWarning(appId, alertContent, ttsContent, direction)
}
if (alertContent.isEmpty() || ttsContent.isEmpty()) {
return
}
//大于10m才提示rsi,超速不限制
if (appId == "6666") {
saveObuToDcData(appId, alertContent, ttsContent,CommunicationType.V2I)
showWarning(appId, alertContent, ttsContent, direction)
} else {
if (Math.round(rsiWarningData.warningMsgList[0].distance) > 10) {
saveObuToDcData(appId, alertContent, ttsContent,CommunicationType.V2I)
showWarning(appId, alertContent, ttsContent, direction)
}
}
}
// 删除

View File

@@ -6,6 +6,7 @@ import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.data.enums.*
import com.mogo.eagle.core.data.obu.MogoObuConst
import com.mogo.eagle.core.function.angle.scenes.CrossRoad
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.function.api.map.angle.*
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
@@ -598,6 +599,20 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
saveObuData(appId, alertContent, ttsContent,CommunicationType.V2I)
showWarning(appId, alertContent, ttsContent, direction)
}
//不显示弹框,语音提示,数据在消息盒子里面展示,此处不在处理弹框
if (alertContent.isEmpty() || ttsContent.isEmpty()) {
return
}
//大于10m才提示rsi。超速不限制
if (appId == "6666") {
saveObuData(appId, alertContent, ttsContent,CommunicationType.V2I)
showWarning(appId, alertContent, ttsContent, direction)
} else {
if (Math.round(data.warningMsgList[0].distance) > 10) {
saveObuData(appId, alertContent, ttsContent,CommunicationType.V2I)
showWarning(appId, alertContent, ttsContent, direction)
}
}
}
MogoObuShowConstants.STATUS.DELETE -> { // 删除
@@ -856,6 +871,9 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
) { //右后
ttsContent = String.format(ttsContent, "")
alertContent = String.format(alertContent, "")
} else{
ttsContent = "注意周围车辆"
alertContent = "盲区预警"
}
}

View File

@@ -31,7 +31,7 @@ class SpeedLimitDispatcher : ILimitingVelocityListener {
/**
* 地图限速数据
*/
// @BizConfig(FuncBizConfig.V2I, "", FuncBizConfig.BIZ_SLW) //todo arrow 重新考虑放的位置
// @BizConfig(FuncBizConfig.V2I, "", FuncBizConfig.BIZ_SLW) //todo emArrow 重新考虑放的位置
override fun onUnion(limitingVelocity: Int, sourceType: DataSourceType) {
super.onUnion(limitingVelocity, sourceType)
when (sourceType) { // obu 优先级高于 map体现链路能力

View File

@@ -66,6 +66,13 @@ object DataManager {
mutableListOf<MsgBoxBean>()
}
/**
* FSM消息(缓存数据库时使用)
*/
private val fmInfoList by lazy {
mutableListOf<MsgBoxBean>()
}
private val scope by lazy {
Utils.getApp().lifeCycleScope
}
@@ -122,6 +129,12 @@ object DataManager {
}
CallerMsgBoxListenerManager.invokeListener(MsgCategory.NOTICE, msg)
}
MsgBoxType.FMINFO -> {
CallerMsgBoxListenerManager.invokeListener(MsgCategory.FM_INFO, msg)
}
MsgBoxType.VOICE -> {
CallerMsgBoxListenerManager.invokeListener(MsgCategory.VOICE_INFO, msg)
}
MsgBoxType.OBU, MsgBoxType.NOTICE, MsgBoxType.OPERATION -> {
synchronized(this) {
notifyList.add(msg)

View File

@@ -8,35 +8,36 @@ import com.mogo.eagle.core.utilcode.util.SPUtils
* @description 消息盒子配置
* @since: 2022/12/1
*/
class MsgBoxConfig {
object MsgBoxConfig {
companion object{
//当前用户的Tab选择记录
private const val userRecord = "USER_RECORD"
//当前用户的Tab选择记录
private const val userRecord = "USER_RECORD"
/**
* 获取当前用户Tab选择记录
*/
fun getUserRecord(): Int{
return SPUtils.getInstance().getInt(userRecord,0)
}
/**
* 设置当前用户Tab选择记录
*/
fun setUserRecord(record: Int){
SPUtils.getInstance().put(userRecord,record)
}
//通知消息缓存列表
@JvmField
var noticeList: ArrayList<MsgBoxBean> = ArrayList()
//车辆系统信息缓存列表
@JvmField
var systemInfoList: ArrayList<MsgBoxBean> = ArrayList()
//录包信息缓存列表
@JvmField
var recordBagList: ArrayList<MsgBoxBean> = ArrayList()
/**
* 获取当前用户Tab选择记录
*/
fun getUserRecord(): Int{
return SPUtils.getInstance().getInt(userRecord,0)
}
/**
* 设置当前用户Tab选择记录
*/
fun setUserRecord(record: Int){
SPUtils.getInstance().put(userRecord,record)
}
//通知消息缓存列表
@JvmField
var noticeList: ArrayList<MsgBoxBean> = ArrayList()
//车辆系统信息缓存列表
@JvmField
var systemInfoList: ArrayList<MsgBoxBean> = ArrayList()
//录包信息缓存列表
@JvmField
var recordBagList: ArrayList<MsgBoxBean> = ArrayList()
//播放小智语音消息时的未播放消息缓存列表
@JvmField
var unPlayList: ArrayList<MsgBoxBean> = ArrayList()
}

View File

@@ -0,0 +1,164 @@
package com.mogo.eagle.core.function.msgbox
import com.zhjt.mogo.adas.data.bean.MogoReport
/**
* FM信息对照表
*/
class MsgFmData{
/**
* 当出现多个建议操作时,按照整车下电重启、请求人工驾驶接管、请求平行驾驶接管、系统重启、联系硬件工程师、联系运维工程师、联系软件工程师优先级递减的顺序,只展示最高优先级的内容
*/
enum class FaultAction(
val faultType: String,//故障处理类别
val faultAction: String,//故障处理行为定义
val faultActionCode: String,//故障处理行为标识
val faultActionDesc: String,//故障处理行为描述
val faultLevel: Int//故障处理级别
){
//请求平行驾驶接管
FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER("恢复策略","请求平行驾驶接管","FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER","如planing出站时规划失败",5),
//请求人工驾驶接管
FM_ACT_NEED_MANNUAL_DERVING("恢复策略","请求人工驾驶接管","FM_ACT_NEED_MANNUAL_DERVING","如planing规划失败且存在弱网判断",6),
//系统重启
FM_ACT_NEED_RESTART_SYSTEM("恢复策略","系统重启","FM_ACT_NEED_RESTART_SYSTEM","如检测到出现多个节点奔溃",4),
//整车下电重启
FM_ACT_MUST_VEHICLE_POWER_RESET("恢复策略","整车下电重启","FM_ACT_MUST_VEHICLE_POWER_RESET","如底盘无数据,需要下电重启",7),
//请联系硬件工程师
FM_ACT_CONTACT_HARDWARE_ENGINEER("人工处理","请联系硬件工程师","FM_ACT_CONTACT_HARDWARE_ENGINEER","硬件接线,域控启动等故障",3),
//请联系运维工程师
FM_ACT_CONTACT_OPERATIONS_ENGINEER("人工处理","请联系运维工程师","FM_ACT_CONTACT_OPERATIONS_ENGINEER","系统配置不对,网络等故障",2),
//请联系软件工程师
FM_ACT_CONTACT_SOFTWARE_ENGINEER("人工处理","请联系软件工程师","FM_ACT_CONTACT_SOFTWARE_ENGINEER","节点挂掉,无法启动等故障",1);
companion object{
//获取故障建议操作级别
fun getFaultLevel(faultActionCode: String): Int{
return when(faultActionCode){
//请求平行驾驶接管
FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER.faultActionCode -> FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER.faultLevel
//请求人工驾驶接管
FM_ACT_NEED_MANNUAL_DERVING.faultActionCode -> FM_ACT_NEED_MANNUAL_DERVING.faultLevel
//系统重启
FM_ACT_NEED_RESTART_SYSTEM.faultActionCode -> FM_ACT_NEED_RESTART_SYSTEM.faultLevel
//整车下电重启
FM_ACT_MUST_VEHICLE_POWER_RESET.faultActionCode -> FM_ACT_MUST_VEHICLE_POWER_RESET.faultLevel
//请联系硬件工程师
FM_ACT_CONTACT_HARDWARE_ENGINEER.faultActionCode -> FM_ACT_CONTACT_HARDWARE_ENGINEER.faultLevel
//请联系运维工程师
FM_ACT_CONTACT_OPERATIONS_ENGINEER.faultActionCode ->FM_ACT_CONTACT_OPERATIONS_ENGINEER.faultLevel
//请联系软件工程师
FM_ACT_CONTACT_SOFTWARE_ENGINEER.faultActionCode -> FM_ACT_CONTACT_SOFTWARE_ENGINEER.faultLevel
else -> 0
}
}
//获取故障建议操作
fun getFaultAction(faultActionLevel: Int): String{
return when(faultActionLevel){
//请求平行驾驶接管
FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER.faultLevel -> FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER.faultAction
//请求人工驾驶接管
FM_ACT_NEED_MANNUAL_DERVING.faultLevel -> FM_ACT_NEED_MANNUAL_DERVING.faultAction
//系统重启
FM_ACT_NEED_RESTART_SYSTEM.faultLevel -> FM_ACT_NEED_RESTART_SYSTEM.faultAction
//整车下电重启
FM_ACT_MUST_VEHICLE_POWER_RESET.faultLevel -> FM_ACT_MUST_VEHICLE_POWER_RESET.faultAction
//请联系硬件工程师
FM_ACT_CONTACT_HARDWARE_ENGINEER.faultLevel -> FM_ACT_CONTACT_HARDWARE_ENGINEER.faultAction
//请联系运维工程师
FM_ACT_CONTACT_OPERATIONS_ENGINEER.faultLevel ->FM_ACT_CONTACT_OPERATIONS_ENGINEER.faultAction
//请联系软件工程师
FM_ACT_CONTACT_SOFTWARE_ENGINEER.faultLevel -> FM_ACT_CONTACT_SOFTWARE_ENGINEER.faultAction
else -> ""
}
}
//获取故障建议操作Code值
fun getFaultActionCode(faultActionLevel: Int): String{
return when(faultActionLevel){
//请求平行驾驶接管
FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER.faultLevel -> FM_ACT_NEED_PARALLEL_DERVING_TAKEOVER.faultActionCode
//请求人工驾驶接管
FM_ACT_NEED_MANNUAL_DERVING.faultLevel -> FM_ACT_NEED_MANNUAL_DERVING.faultActionCode
//系统重启
FM_ACT_NEED_RESTART_SYSTEM.faultLevel -> FM_ACT_NEED_RESTART_SYSTEM.faultActionCode
//整车下电重启
FM_ACT_MUST_VEHICLE_POWER_RESET.faultLevel -> FM_ACT_MUST_VEHICLE_POWER_RESET.faultActionCode
//请联系硬件工程师
FM_ACT_CONTACT_HARDWARE_ENGINEER.faultLevel -> FM_ACT_CONTACT_HARDWARE_ENGINEER.faultActionCode
//请联系运维工程师
FM_ACT_CONTACT_OPERATIONS_ENGINEER.faultLevel ->FM_ACT_CONTACT_OPERATIONS_ENGINEER.faultActionCode
//请联系软件工程师
FM_ACT_CONTACT_SOFTWARE_ENGINEER.faultLevel -> FM_ACT_CONTACT_SOFTWARE_ENGINEER.faultActionCode
else -> ""
}
}
}
}
enum class FaultResult(
val resultType: String,//影响类别
val resultDefine: String,//故障影响定义
val resultCode: String,//故障影响的标识
val resultDesc: String//后果对应的处理描述
){
//无法作业
FM_RST_FUNCTION_LOST("功能影响","无法作业","FM_RST_FUNCTION_LOST","需要禁止作业,如扫盘故障,清扫车无法清扫作业"),
//无法开放运营
FM_RST_FORBID_OPEN_WORK("功能影响","无法开放运营","FM_RST_FORBID_OPEN_WORK","需要禁止运营,如安全带故障,可以自驾,不能载人"),
//无法平行驾驶
FM_RST_FORBID_PARALLEL_DERVING("驾驶影响","无法平行驾驶","FM_RST_FORBID_PARALLEL_DERVING","需要禁止平行驾驶"),
//无法自动驾驶
FM_RST_FORBID_AUTOPILOT_DERVING("驾驶影响","无法自动驾驶","FM_RST_FORBID_AUTOPILOT_DERVING","需要禁止自驾"),
//无法手动驾驶
FM_RST_FORBID_MANNUAL_DERVING("驾驶影响","无法手动驾驶","FM_RST_FORBID_MANNUAL_DERVING","需要禁止行车,如底盘存在故障,需要通知出来"),
//失控,无法策略停车
FM_RST_OUT_OF_CONTROL("安全影响","失控,无法策略停车","FM_RST_OUT_OF_CONTROL","需要立即紧急通知到人车辆失控如驾驶中controller挂掉发送102重启");
companion object{
//获取结果原因描述
fun getResultDefine(resultCode: String): String{
return when(resultCode){
//无法作业
FM_RST_FUNCTION_LOST.resultCode -> FM_RST_FUNCTION_LOST.resultDefine
//无法开放运营
FM_RST_FORBID_OPEN_WORK.resultCode -> FM_RST_FORBID_OPEN_WORK.resultDefine
//无法平行驾驶
FM_RST_FORBID_PARALLEL_DERVING.resultCode -> FM_RST_FORBID_PARALLEL_DERVING.resultDefine
//无法自动驾驶
FM_RST_FORBID_AUTOPILOT_DERVING.resultCode -> FM_RST_FORBID_AUTOPILOT_DERVING.resultDefine
//无法手动驾驶
FM_RST_FORBID_MANNUAL_DERVING.resultCode -> FM_RST_FORBID_MANNUAL_DERVING.resultDefine
//失控,无法策略停车
FM_RST_OUT_OF_CONTROL.resultCode -> FM_RST_OUT_OF_CONTROL.resultDefine
else -> ""
}
}
}
}
companion object{
@JvmStatic
fun getFmPolicyName(policyCode: String?): String{
return when(policyCode){
"FM_DP_NO_ACTION" -> "报告"
"FM_DP_ONLY_WARNING" -> "警示"
"FM_DP_SPEED_LIMIT1" -> "一级降速"
"FM_DP_SPEED_LIMIT2" -> "二级降速"
"FM_DP_SPEED_LIMIT3" -> "三级降速"
"FM_DP_PNC_CHOOSE_STOP" -> "择机靠边停车"
"FM_DP_COMFORTABLE_STOP" -> "立刻舒适停车"
"FM_DP_EMERGENCY_STOP" -> "就地紧急停车"
else -> "暂无"
}
}
}
}

View File

@@ -102,6 +102,8 @@ dependencies {
implementation project(':core:mogo-core-utils')
implementation project(':core:mogo-core-function-call')
implementation project(':core:mogo-core-res')
compileOnly rootProject.ext.dependencies.apm_insight
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -8,4 +8,5 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>

View File

@@ -23,6 +23,7 @@ import com.mogo.eagle.core.function.api.devatools.strict.*
import com.mogo.eagle.core.function.api.devatools.download.*
import com.mogo.eagle.core.function.api.devatools.logcat.*
import com.mogo.eagle.core.function.api.devatools.mofang.*
import com.mogo.eagle.core.function.api.devatools.perf.IMoGoCpuUsageProvider
import com.mogo.eagle.core.function.api.lookaround.*
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.w
@@ -53,6 +54,7 @@ import com.zhjt.mogo_core_function_devatools.mofang.*
import com.zhjt.mogo_core_function_devatools.monitor.MonitorManager
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb.Companion.getDb
import com.zhjt.mogo_core_function_devatools.perf.MoGoCpuUsageProviderImpl
import com.zhjt.mogo_core_function_devatools.report.IPCReportManager.Companion.iPCReportManager
import com.zhjt.mogo_core_function_devatools.scene.SceneManager.Companion.sceneManager
import com.zhjt.mogo_core_function_devatools.status.StatusManager
@@ -86,6 +88,8 @@ class DevaToolsProvider : IDevaToolsProvider {
private val block by lazy { MoGoBlockProviderImpl() }
private val usage by lazy { MoGoCpuUsageProviderImpl() }
@Volatile
private var mDockerVersion: String? = null
@@ -109,7 +113,7 @@ class DevaToolsProvider : IDevaToolsProvider {
iPCReportManager.initServer()
BindingCarManager.init(mContext!!)
apmEnvProvider.init(if(DebugConfig.isDebug()) "0" else "1", "${ DebugConfig.getNetMode() }", mDockerVersion ?: "")
BadCaseManager.init()
BadCaseManager.init(mContext!!)
if (DebugConfig.isDebug()) {
SdtManager.init(mContext!!, true, DetectResultImpl())
// 监听弱网
@@ -173,7 +177,7 @@ class DevaToolsProvider : IDevaToolsProvider {
if (plugin is TracePlugin) {
if (tag == SharePluginInfo.TAG_PLUGIN_EVIL_METHOD) {
isEvil = true
printEvilMsg(issue.toString())
printEvilMsg(mapOf("evilMethod" to issue.toString()))
}
}
}
@@ -216,7 +220,7 @@ class DevaToolsProvider : IDevaToolsProvider {
nodeAliasCode = ChainConstant.CHAIN_CODE_RECORD_ANR,
paramIndexes = [0]
)
private fun printEvilMsg(evilMethod: String) {
private fun printEvilMsg(evilMethod: Map<String,String>) {
w("TraceCanary", evilMethod)
}
@@ -393,5 +397,7 @@ class DevaToolsProvider : IDevaToolsProvider {
override fun logRecord(): IMoGoLogRecordProvider = logRecordProvider
override fun block(): IMoGoBlockProvider? = null
override fun block(): IMoGoBlockProvider? = block
override fun usage(): IMoGoCpuUsageProvider? = usage
}

View File

@@ -6,7 +6,7 @@ import android.widget.Toast
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_INIT_ENV_RESTART
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_SOURCE_INIT
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_INIT_STATUS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_STATUS
import com.mogo.eagle.core.function.api.devatools.apm.*
import com.mogo.eagle.core.utilcode.util.*
import com.zhjt.mogo_core_function_devatools.apm.config.*
@@ -84,7 +84,7 @@ class ApmEnvProviderImpl: IApmEnvProvider, CoroutineScope {
val appRelaunched = ApmEnvConfig.isAppRelaunched()
if ((!isEnvValid || (buildTypeChanged || netTypeChanged || dockerVersionChanged)) && !appRelaunched) {
ApmEnvConfig.setAppRelaunched(true)
restartApp("buildType:$buildType,netType:$netType,dockerVersion:$dockerVersion")
restartApp(mapOf<String,Any>("buildType" to buildType, "netType" to netType,"dockerVersion" to dockerVersion))
return@launch
}
if (isFirstDockerVersionSet) {
@@ -110,12 +110,12 @@ class ApmEnvProviderImpl: IApmEnvProvider, CoroutineScope {
}
@ChainLog(
linkChainLog = CHAIN_TYPE_INIT_STATUS,
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = CHAIN_SOURCE_INIT,
nodeAliasCode = CHAIN_CODE_INIT_ENV_RESTART,
paramIndexes = [0]
)
private fun restartApp(envStr:String) {
private fun restartApp(envStr:Map<String,Any>) {
launch(Dispatchers.Main) {
Toast.makeText(Utils.getApp(), "发现系统环境不一致,正在重启...", Toast.LENGTH_SHORT).show()
delay(50)

View File

@@ -24,11 +24,11 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.tts.base.SpeechUtils
import com.zhjt.mogo_core_function_devatools.badcase.biz.*
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.entity.AutoPilotRecord
import com.zhjt.mogo_core_function_devatools.ext.enqueuePop
import kotlinx.coroutines.*
import me.jessyan.autosize.utils.AutoSizeUtils
import record_cache.RecordPanelOuterClass
@@ -41,8 +41,9 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
@Volatile
private var record: AutoPilotRecord? = null
fun init() {
fun init(context: Context) {
CallerAutopilotRecordListenerManager.addListener(TAG, this)
SpeechUtils.init(context)
}
/**
@@ -179,8 +180,11 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
}
override fun onFinish() {
passiveBadCaseWindow.hideFloatWindow()
BadCaseConfig.windowNum--
//如果有页面操作,则不自动关闭窗口
if(!passiveBadCaseWindow.isOperated()){
passiveBadCaseWindow.hideFloatWindow()
BadCaseConfig.windowNum--
}
}
}
countDownTimer.start()
@@ -233,7 +237,7 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
MsgBoxBean(
MsgBoxType.RECORD, RecordBagMsg(
recordPanel.key, recordPanel.stat, recordPanel.id,
recordPanel.type, recordPanel.filename, recordPanel.note
recordPanel.type, recordPanel.filename, recordPanel.note,false
)
)
)

View File

@@ -6,15 +6,18 @@ import android.graphics.PixelFormat
import android.os.SystemClock
import android.util.DisplayMetrics
import android.view.*
import android.widget.RadioButton
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.data.deva.badcase.AiDataEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.api.devatools.badcase.BadCaseNetListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsNetManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
@@ -23,11 +26,18 @@ import com.mogo.eagle.core.utilcode.util.BarUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
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.AiDataListAdapter
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.BadCaseNetManager
import com.zhjt.mogo_core_function_devatools.badcase.repository.store.BadCaseReasonStore
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONObject
import record_cache.RecordPanelOuterClass
import java.lang.StringBuilder
import java.util.*
/**
@@ -36,7 +46,7 @@ import java.util.*
* @since: 2022/7/12
*/
class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener,
IMoGoAutopilotRecordListener {
IMoGoAutopilotRecordListener , BadCaseNetListener {
companion object {
const val TAG = "AIDataCollectWindow"
@@ -49,18 +59,12 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
private lateinit var tvCollectNum: TextView //采集弹窗数量
private lateinit var tvCollectTime: TextView //采集时间
private lateinit var rbLargeCar: RadioButton //大型车
private lateinit var rbTrafficLight: RadioButton //交通灯
private lateinit var rbWater: RadioButton //积水
private lateinit var rbConstruction: RadioButton //施工
private lateinit var rbAccident: RadioButton //车祸路段
private lateinit var rbRain: RadioButton //中雨交通流
private lateinit var rbNightTraffic: RadioButton //夜间交通流
private lateinit var tvCollectReport: TextView //上报按钮
private lateinit var tvCollectCancel: TextView //取消按钮
private var collectReason: String = "大型车:大货、大巴、特种车辆"
private var collectReason: StringBuilder = StringBuilder()
private var aiDataListAdapter: AiDataListAdapter?= null
@Volatile
private var recordKey: String? = null //录制bag包key
@@ -77,6 +81,7 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
private var mInScreenY = 0f
private var clickListener: ClickListener? = null
private var rvCollectList: RecyclerView ?= null
init {
initFloatWindow();
@@ -93,15 +98,7 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
mFloatLayout.setOnTouchListener(this)
tvCollectNum = mFloatLayout.findViewById(R.id.tvCollectNum)
tvCollectTime = mFloatLayout.findViewById(R.id.tvCollectTime)
rbLargeCar = mFloatLayout.findViewById(R.id.rbLargeCar)
rbTrafficLight = mFloatLayout.findViewById(R.id.rbTrafficLight)
rbWater = mFloatLayout.findViewById(R.id.rbWater)
rbConstruction = mFloatLayout.findViewById(R.id.rbConstruction)
rbAccident = mFloatLayout.findViewById(R.id.rbAccident)
rbRain = mFloatLayout.findViewById(R.id.rbRain)
rbNightTraffic = mFloatLayout.findViewById(R.id.rbNightTraffic)
rvCollectList = mFloatLayout.findViewById(R.id.rvCollectList)
tvCollectReport = mFloatLayout.findViewById(R.id.tvCollectReport)
tvCollectCancel = mFloatLayout.findViewById(R.id.tvCollectCancel)
if (BadCaseConfig.windowNum < 1) {
@@ -120,107 +117,39 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
20,
12
)
//大型车
rbLargeCar.setOnClickListener {
setRadioButtonStatus(
largeCarStatus = true,
trafficLightStatus = false,
waterStatus = false,
constructionStatus = false,
accidentStatus = false,
rainStatus = false,
nightTrafficStatus = false
)
collectReason = "大型车:大货、大巴、特种车辆"
}
//交通灯
rbTrafficLight.setOnClickListener {
setRadioButtonStatus(
largeCarStatus = false,
trafficLightStatus = true,
waterStatus = false,
constructionStatus = false,
accidentStatus = false,
rainStatus = false,
nightTrafficStatus = false
)
collectReason = "交通灯:水平、箭头、雨天交通灯"
}
//积水
rbWater.setOnClickListener {
setRadioButtonStatus(
largeCarStatus = false,
trafficLightStatus = false,
waterStatus = true,
constructionStatus = false,
accidentStatus = false,
rainStatus = false,
nightTrafficStatus = false
)
collectReason = "积水距离10米内面积大于1平米"
}
//施工
rbConstruction.setOnClickListener {
setRadioButtonStatus(
largeCarStatus = false,
trafficLightStatus = false,
waterStatus = false,
constructionStatus = true,
accidentStatus = false,
rainStatus = false,
nightTrafficStatus = false
)
collectReason = "施工:锥桶、路障"
}
//车祸路段
rbAccident.setOnClickListener {
setRadioButtonStatus(
largeCarStatus = false,
trafficLightStatus = false,
waterStatus = false,
constructionStatus = false,
accidentStatus = true,
rainStatus = false,
nightTrafficStatus = false
)
collectReason = "车祸路段:有三角板"
}
//中雨交通流
rbRain.setOnClickListener {
setRadioButtonStatus(
largeCarStatus = false,
trafficLightStatus = false,
waterStatus = false,
constructionStatus = false,
accidentStatus = false,
rainStatus = true,
nightTrafficStatus = false
)
collectReason = "中雨交通流"
}
//夜间交通流
rbNightTraffic.setOnClickListener {
setRadioButtonStatus(
largeCarStatus = false,
trafficLightStatus = false,
waterStatus = false,
constructionStatus = false,
accidentStatus = false,
rainStatus = false,
nightTrafficStatus = true
)
collectReason = "夜间交通流"
}
val linearLayoutManager = LinearLayoutManager(mActivity)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
rvCollectList?.layoutManager = linearLayoutManager
aiDataListAdapter = AiDataListAdapter()
aiDataListAdapter?.setListener(object: AiDataListAdapter.AiDataClickListener{
override fun onClick(reason: String, isChecked: Boolean) {
if(isChecked){
collectReason.append(reason)
}else{
val index = collectReason.indexOf(reason)
collectReason.delete(index,index+reason.length)
}
}
})
rvCollectList?.adapter = aiDataListAdapter
//注册网络接口获取数据监听
CallerDevaToolsNetManager.addListener(TAG,this)
//获取数据
BadCaseNetManager.badCaseNetManager.getAiData()
//上报
tvCollectReport.setOnClickListener {
if(collectReason.isBlank()){
ToastUtils.showShort("请选择最少一个原因")
return@setOnClickListener
}
GlobalScope.launch {
val uploadResult = presenter.upload(mutableMapOf<String, String>().also { itx ->
itx["carLicense"] = AppConfigInfo.plateNumber ?: "" //车牌号
itx["filename"] = recordFileName ?: "" //bag包文件地址
itx["filesize"] = "0" //bag包文件大小
itx["key"] = recordKey ?: "" //key
itx["reason"] = collectReason //采集原因
itx["reason"] = collectReason.toString() //采集原因
itx["duration"] = "20" //采集时长固定为20S
itx["startTime"] = System.currentTimeMillis().toString() //上报时间(时间戳格式)
itx["channel"] = "AI" //渠道
@@ -279,24 +208,6 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
}
private fun setRadioButtonStatus(
largeCarStatus: Boolean,
trafficLightStatus: Boolean,
waterStatus: Boolean,
constructionStatus: Boolean,
accidentStatus: Boolean,
rainStatus: Boolean,
nightTrafficStatus: Boolean
) {
rbLargeCar.isChecked = largeCarStatus
rbTrafficLight.isChecked = trafficLightStatus
rbWater.isChecked = waterStatus
rbConstruction.isChecked = constructionStatus
rbAccident.isChecked = accidentStatus
rbRain.isChecked = rainStatus
rbNightTraffic.isChecked = nightTrafficStatus
}
override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
when (motionEvent?.action) {
MotionEvent.ACTION_DOWN -> {
@@ -336,6 +247,8 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
fun hideFloatWindow() {
//注销采集结果回调监听
CallerAutopilotRecordListenerManager.removeListener(this.hashCode().toString())
//注销网络接口监听
CallerDevaToolsNetManager.removeListener(this)
// 移除 ADAS车辆状态&定位 监听
CallerChassisLocationWGS84ListenerManager.removeListener(this.hashCode().toString())
if (mFloatLayout.parent != null) mWindowManager!!.removeView(mFloatLayout)
@@ -349,4 +262,35 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
fun closeWindow()
}
override fun onAiDataResponse(list: List<AiDataEntity>) {
if(list.isNotEmpty()){
//刷新列表
aiDataListAdapter?.setData(list)
}
}
override fun onAiDataError() {
//数据请求错误,使用缓存数据
if(BadCaseReasonStore.getAiDataRecord().isNotEmpty()){
val list = ArrayList<AiDataEntity>()
val result = JSONArray(BadCaseReasonStore.getAiDataRecord())
if(result.length()>0){
for(i in 0 until result.length()){
val jsonObject = result[i] as JSONObject
val id = jsonObject.optInt("id")
val name = jsonObject.optString("name")
val content = jsonObject.optString("content")
val entity = AiDataEntity(id, name, content,false)
list.add(entity)
}
}
if(list.isNotEmpty()){
//刷新列表
aiDataListAdapter?.setData(list)
}
}else{
ToastUtils.showShort("AI数据采集数据请求错误且无缓存数据可用")
}
}
}

View File

@@ -48,10 +48,10 @@ public class CaseTopicListDialog extends Dialog implements IMoGoAutopilotRecordL
private RecyclerView rvTopicList;
private TopicListAdapter topicListAdapter;
private String searchStr;
private List<TopicEntity> allTopicList = new ArrayList<>();
private final List<TopicEntity> allTopicList = new ArrayList<>();
private RecordTypeEntity recordType;
private List<String> addTopicList = new ArrayList<>();
private List<TopicEntity> searchTopicList = new ArrayList<>();
private final List<String> addTopicList = new ArrayList<>();
private final List<TopicEntity> searchTopicList = new ArrayList<>();
public CaseTopicListDialog(@NonNull Context context) {
super(context, R.style.bad_case_dialog);

View File

@@ -3,45 +3,68 @@ package com.zhjt.mogo_core_function_devatools.badcase.biz
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.PixelFormat
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.os.SystemClock
import android.util.DisplayMetrics
import android.util.Log
import android.view.*
import android.widget.CheckBox
import android.view.animation.Animation
import android.view.animation.ScaleAnimation
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.iflytek.cloud.ErrorCode
import com.iflytek.cloud.InitListener
import com.iflytek.cloud.RecognizerListener
import com.iflytek.cloud.RecognizerResult
import com.iflytek.cloud.SpeechError
import com.iflytek.cloud.SpeechRecognizer
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.badcase.BagDescriptionEntity
import com.mogo.eagle.core.data.deva.badcase.BagInfoEntity
import com.mogo.eagle.core.data.deva.badcase.BagManagerEntity
import com.mogo.eagle.core.data.deva.badcase.RecordCaseEntity
import com.mogo.eagle.core.data.deva.badcase.RecordOptionEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.api.devatools.badcase.BadCaseNetListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsNetManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.eagle.core.utilcode.util.BarUtils
import com.mogo.eagle.core.utilcode.util.JsonParser
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.tts.base.SpeechUtils
import com.zhidao.loglib.call.LogInfoManagerFactory
import com.zhidao.loglib.upload.OnUploadListener
import com.zhidao.loglib.upload.UploadManager
import com.zhidao.loglib.util.FileUtil
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseAnalyticsManager
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.BadReasonListAdapter
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.badcase.record.RecordManager
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.BadCaseNetManager
import com.zhjt.mogo_core_function_devatools.badcase.repository.store.BadCaseReasonStore
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import record_cache.RecordPanelOuterClass
import java.io.File
import java.lang.StringBuilder
import java.util.*
@@ -51,7 +74,7 @@ import java.util.*
* @since: 2022/7/13
*/
class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchListener,
IMoGoAutopilotRecordListener {
IMoGoAutopilotRecordListener, BadCaseNetListener {
companion object {
const val TAG = "InitiativeBadCaseWindow"
@@ -67,23 +90,22 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
private lateinit var tvInitiativeTime: TextView
private lateinit var tvInitiativeIdentity: TextView
private lateinit var rbOne: CheckBox
private lateinit var rbTwo: CheckBox
private lateinit var rbThree: CheckBox
private lateinit var rbFour: CheckBox
private lateinit var rbFive: CheckBox
private lateinit var rbSix: CheckBox
private lateinit var viewAudioBg: ImageView
private lateinit var viewAudioButton: ImageView
private lateinit var tvAudioCountDown: TextView
private lateinit var tvInitiativeReport: TextView
private lateinit var tvInitiativeCancel: TextView
private lateinit var rvInitiativeList: RecyclerView
private var badReasonListAdapter: BadReasonListAdapter ?= null
private var audioStatus = false
private var audioFileName:String?=null //录音文件名称
private var uploadReason: StringBuilder = StringBuilder() //上报原因,标签
private var reasonDetail: String ?= null //语音转写
private var uploadReasonTotal: String = ""
@Volatile
private var recordKey: Long = 0 //录制bag包key
@Volatile
@@ -102,6 +124,17 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
private var clickListener: ClickListener? = null
// 语音听写对象
private var mIat: SpeechRecognizer? = null
var ret = 0 // 函数调用返回值
// 用HashMap存储听写结果
private val mIatResults: HashMap<String, String> = LinkedHashMap()
private var isUploadCos = false //是否在上传Cos操作
private var isLoadData = false //是否已经加载数据
init {
initFloatWindow()
}
@@ -115,22 +148,37 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
mFloatLayout = LayoutInflater.from(mActivity).inflate(R.layout.view_initiative_bad_case, null) as View
mFloatLayout.setOnTouchListener(this)
// 初始化识别无UI识别对象
// 使用SpeechRecognizer对象可根据回调消息自定义界面
mIat = SpeechRecognizer.createRecognizer(mActivity, mInitListener)
tvInitiativeNum = mFloatLayout.findViewById(R.id.tvInitiativeNum)
tvInitiativeTime = mFloatLayout.findViewById(R.id.tvInitiativeTime)
tvInitiativeIdentity = mFloatLayout.findViewById(R.id.tvInitiativeIdentity)
rbOne = mFloatLayout.findViewById(R.id.rbOne)
rbTwo = mFloatLayout.findViewById(R.id.rbTwo)
rbThree = mFloatLayout.findViewById(R.id.rbThree)
rbFour = mFloatLayout.findViewById(R.id.rbFour)
rbFive = mFloatLayout.findViewById(R.id.rbFive)
rbSix = mFloatLayout.findViewById(R.id.rbSix)
viewAudioBg = mFloatLayout.findViewById(R.id.viewAudioBg)
viewAudioButton = mFloatLayout.findViewById(R.id.viewAudioButton)
tvAudioCountDown = mFloatLayout.findViewById(R.id.tvAudioCountDown)
tvInitiativeReport = mFloatLayout.findViewById(R.id.tvInitiativeReport)
tvInitiativeCancel = mFloatLayout.findViewById(R.id.tvInitiativeCancel)
rvInitiativeList = mFloatLayout.findViewById(R.id.rvInitiativeList)
val linearLayoutManager = LinearLayoutManager(mActivity)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
rvInitiativeList.layoutManager = linearLayoutManager
badReasonListAdapter = BadReasonListAdapter(mActivity)
badReasonListAdapter?.setListener(object: BadReasonListAdapter.ReasonClickListener{
override fun onClick(reason: String, isChecked: Boolean) {
if(isChecked){
uploadReason.append(reason)
}else{
val index = uploadReason.indexOf(reason)
uploadReason.delete(index,index+reason.length)
}
}
})
rvInitiativeList.adapter = badReasonListAdapter
if(BadCaseConfig.windowNum<1){
BadCaseConfig.windowNum = 1
}
@@ -139,49 +187,47 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
tvInitiativeTime.text = "时间:${millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat())}"
tvInitiativeIdentity.text = "身份:${BadCaseConfig.identity}"
/**
* 获取录包原因数据
*/
BadCaseNetManager.badCaseNetManager.getRecordOption(1,AppConfigInfo.iPCMacAddress)
// BadCaseNetManager.badCaseNetManager.getRecordOption(1,"48:b0:2d:3a:9c:8f")
//采集结果回调监听
CallerAutopilotRecordListenerManager.addListener(this.hashCode().toString(),this)
viewAudioButton.setOnClickListener {
//主动录包采集原因回调监听
CallerDevaToolsNetManager.addListener(this.hashCode().toString(),this)
viewAudioBg.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
}
//上报
tvInitiativeReport.setOnClickListener {
if(!rbOne.isChecked && !rbTwo.isChecked && !rbThree.isChecked &&
!rbFour.isChecked && !rbFive.isChecked && !rbSix.isChecked){
TipToast.shortTip("请选择至少一个Case")
if(uploadReason.isBlank()){
ToastUtils.showShort("请选择最少一个原因")
return@setOnClickListener
}
uploadReason.clear()
if(rbOne.isChecked){
uploadReason.append("严重画龙 ")
}
if(rbTwo.isChecked){
uploadReason.append("速度过慢 ")
}
if(rbThree.isChecked){
uploadReason.append("感知、定位、地图等其他 ")
}
if(rbFour.isChecked){
uploadReason.append("速度过快 ")
}
if(rbFive.isChecked){
uploadReason.append("存在碰撞风险 ")
}
if(rbSix.isChecked){
uploadReason.append("点刹、顿挫")
}
tvInitiativeReport.text = "上报中..."
if(audioStatus){
audioStatus = !audioStatus
setAudio(audioStatus)
audioStatus = false
setAudio(false)
Handler().postDelayed({
uploadAudio()
uploadAudio()
},1000)
}else{
//停止语音听写
mIat?.stopListening()
//结束倒计时
countDownTimer?.cancel()
countDownTimer?.onFinish()
//将倒计时置空
countDownTimer = null
uploadAudio()
}
}
//取消
tvInitiativeCancel.setOnClickListener {
BadCaseConfig.windowNum--
clickListener?.closeWindow()
@@ -194,21 +240,107 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
it.format = PixelFormat.RGBA_8888
it.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
it.gravity = Gravity.START or Gravity.TOP
it.width = 924
it.height = 668
it.width = 859
it.height = 850
it.alpha = 1.0f
}
}
/**
* 初始化监听器。
*/
private val mInitListener = InitListener { code ->
if (code != ErrorCode.SUCCESS) {
ToastUtils.showShort("讯飞语音听写初始化失败,错误码:$code")
}
}
/**
* 听写监听器。
*/
private val mRecognizerListener: RecognizerListener = object : RecognizerListener{
override fun onVolumeChanged(p0: Int, p1: ByteArray?) {
//showTip("当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length);
}
override fun onBeginOfSpeech() {
// 此回调表示sdk内部录音机已经准备好了用户可以开始语音输入
}
override fun onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
}
override fun onResult(results: RecognizerResult?, isLast: Boolean) {
results?.let {
printResult(it)
}
}
override fun onError(p0: SpeechError?) {
// Tips
// 错误码10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
}
override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) {
// 以下代码用于获取与云端的会话id当业务出错时将会话id提供给技术支持人员可用于查询会话日志定位出错原因
// 若使用本地能力会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
}
/**
* 显示结果
*/
private fun printResult(results: RecognizerResult) {
val text: String = JsonParser.parseIatResult(results.resultString)
var sn: String? = null
// 读取json结果中的sn字段
try {
val resultJson = JSONObject(results.resultString)
sn = resultJson.optString("sn")
} catch (e: JSONException) {
e.printStackTrace()
}
mIatResults[sn!!] = text
val resultBuffer = java.lang.StringBuilder()
for (key in mIatResults.keys) {
resultBuffer.append(mIatResults[key])
}
Log.i(TAG, "语音内容=$resultBuffer")
reasonDetail = resultBuffer.toString()
}
var countDownTimer: CountDownTimer?=null
private fun setAudio(status: Boolean){
if(status){
//开始录音
mIat?.let {
//清空之前的内容
mIatResults.clear()
SpeechUtils.setParam(it)
// 不显示听写对话框
ret = it.startListening(mRecognizerListener)
if (ret != ErrorCode.SUCCESS) {
ToastUtils.showShort("听写失败,错误码:$ret,请点击网址https://www.xfyun.cn/document/error-code查询解决方案")
}
}
audioFileName = "Audio_${System.currentTimeMillis()}_BadCase"
RecordManager.getInstance().start(audioFileName)
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_select)
//开始录音,展示放大缩小动效
val scaleAnimation = ScaleAnimation(
1.0f, 0.8f, 1.0f, 0.8f,
Animation.RELATIVE_TO_SELF, 0.8f, Animation.RELATIVE_TO_SELF, 0.8f
)
scaleAnimation.duration = 1000
scaleAnimation.repeatCount = -1
viewAudioButton.startAnimation(scaleAnimation)
tvAudioCountDown.visibility = View.VISIBLE
//开始倒计时
if(countDownTimer==null){
@@ -222,13 +354,15 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
tvAudioCountDown.visibility = View.GONE
//结束录音
RecordManager.getInstance().stop()
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_normal)
//结束动画
viewAudioButton.clearAnimation()
}
}
countDownTimer?.start()
}
}else{
//停止语音听写
mIat?.stopListening()
//结束倒计时
countDownTimer?.cancel()
countDownTimer?.onFinish()
@@ -242,17 +376,26 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
val singlePath = "/mnt/sdcard/mogo/DataCollection/${audioFileName}.wav"
val file = File(singlePath)
if(file.exists()){
LogInfoManagerFactory.createAudioUpload(mActivity.applicationContext,
isUploadCos = true
LogInfoManagerFactory.createAudioUpload(mActivity.applicationContext,DebugConfig.isDebug(),
TAG, MoGoAiCloudClientConfig.getInstance().sn,singlePath,
object : OnUploadListener {
override fun onUploadSuccess(key: String, filePath: String, downloadUrl: String) {
CallerLogger.d("$M_DEVA$TAG", "语音文件上传成功downloadUrl=$downloadUrl")
//将语音文件上传Cos监听移除
removeUploadListener(singlePath)
//上传到服务器
upload(downloadUrl)
if(key == TAG){
FileUtil.deleteFile(File(filePath))
override fun onUploadSuccess(key: String, filePath: String, downloadUrl: String?) {
if(downloadUrl == null){
ToastUtils.showShort("上传语音文件失败,请检查网络")
ThreadUtils.runOnUiThread {
tvInitiativeReport.text = "上报"
}
}else{
CallerLogger.d("$M_DEVA$TAG", "语音文件上传成功downloadUrl=$downloadUrl")
if(downloadUrl.isNotBlank() && downloadUrl.contains(".wav")){
CallerDevaToolsNetManager.invokeUploadCosSuccess(downloadUrl)
//将语音文件上传Cos监听移除
removeUploadListener(singlePath)
if(key == TAG){
FileUtil.deleteFile(File(filePath))
}
}
}
}
@@ -287,12 +430,17 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
*/
private fun upload(downloadUrl: String?){
GlobalScope.launch{
uploadReasonTotal = if(reasonDetail.isNullOrEmpty()){
uploadReason.toString()
}else{
"$uploadReason 语音内容:$reasonDetail"
}
val uploadResult = presenter.upload(mutableMapOf<String, String>().also { itx ->
itx["carLicense"] = AppConfigInfo.plateNumber?:"" //车牌号
itx["filename"] = recordFileName?:"" //bag包文件地址
itx["filesize"] = "0" //bag包文件大小
itx["key"] = recordKey.toString() //key
itx["reason"] = uploadReason.toString() //采集原因
itx["reason"] = uploadReasonTotal //采集原因
itx["duration"] = BadCaseConfig.totalDuration.toString() //采集时长固定为20S
itx["startTime"] = System.currentTimeMillis().toString() //上报时间(时间戳格式)
itx["channel"] = "1" //渠道
@@ -305,6 +453,9 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
})
if (uploadResult == null || uploadResult.code != 200) {
TipToast.shortTip("上报失败")
ThreadUtils.runOnUiThread {
tvInitiativeReport.text = "上报"
}
} else {
TipToast.shortTip("上报成功")
//将上报BI的结果同步给工控机记录保存
@@ -320,13 +471,13 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
BadCaseAnalyticsManager.bagRecordUpload(recordKey.toString(),recordFileName?:"",uploadStamp,
"100",AppConfigInfo.plateNumber,BadCaseConfig.totalDuration.toString(),MoGoAiCloudClientConfig.getInstance().sn,
BadCaseConfig.dockerVersion ?:"",AppUtils.getAppVersionName(),loc.latitude.toString(),loc.longitude.toString(),
BadCaseConfig.identity,downloadUrl?:"",uploadReason.toString(),System.currentTimeMillis().toString(),"1")
BadCaseConfig.identity,downloadUrl?:"",uploadReasonTotal,System.currentTimeMillis().toString(),"1")
//日志
CallerLogger.i("$M_DEVA$TAG", "BadCase Initiative Analytics="+"key="+recordKey+" filename="+recordFileName+
" receiveTime="+uploadStamp+" stat="+"100"+" plateNumber="+AppConfigInfo.plateNumber+
" totalDuration="+ BadCaseConfig.totalDuration +" carSn="+MoGoAiCloudClientConfig.getInstance().sn+" mapVersion="+BadCaseConfig.dockerVersion+
" eyeVersion="+AppUtils.getAppVersionName()+" latitude="+ loc.latitude +" longitude="+ loc.longitude+
" identity="+BadCaseConfig.identity + " downloadUrl="+downloadUrl +" uploadReason="+uploadReason+
" identity="+BadCaseConfig.identity + " downloadUrl="+downloadUrl +" uploadReason="+uploadReasonTotal+
" uploadTime="+System.currentTimeMillis()+" channel="+"1")
BadCaseConfig.windowNum--
clickListener?.closeWindow()
@@ -336,7 +487,7 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
if(receiveTime!=null){
try {
uploadStamp=TimeUtils.dateToStamp(receiveTime,"yyyyMMddHHmmss")
}catch (e: Exception){
}catch (_: Exception){
}
}
}
@@ -371,7 +522,8 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
// mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.x = 0
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()-950
mWindowManager!!.addView(mFloatLayout, mWindowParams)
//开启录包
@@ -391,7 +543,8 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
// mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.x = 0
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()-950
mWindowManager!!.addView(mFloatLayout, mWindowParams)
//已经录包无需再次启动录包,只要将录包信息同步到弹窗
@@ -406,7 +559,12 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
fun hideFloatWindow() {
//注销采集结果回调监听
CallerAutopilotRecordListenerManager.removeListener(this.hashCode().toString())
if (mFloatLayout.parent != null) mWindowManager!!.removeView(mFloatLayout)
//注销采集原因回调监听
CallerDevaToolsNetManager.removeListener(this.hashCode().toString())
if (mFloatLayout.parent != null){
mWindowManager!!.removeView(mFloatLayout)
}
}
override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) {
@@ -414,8 +572,8 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
ThreadUtils.runOnUiThread {
if(recordKey==null){
recordKey = recordPanel.key
BadCaseConfig.recordKeyList.add(recordPanel.key)
}
BadCaseConfig.recordKeyList.add(recordPanel.key)
if(recordFileName==null){
recordFileName = recordPanel.filename
}
@@ -431,4 +589,57 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
fun closeWindow()
}
override fun onInitiativeResponse(list: List<RecordOptionEntity>) {
if(!isLoadData && list.isNotEmpty()){
badReasonListAdapter?.setData(list)
isLoadData = true
}
}
override fun onInitiativeError() {
if(!isLoadData && BadCaseReasonStore.getInitiativeDataRecord().isNotEmpty()){
val list = ArrayList<RecordOptionEntity>()
val result = JSONArray(BadCaseReasonStore.getInitiativeDataRecord())
if(result.length() > 0){
for(i in 0 until result.length()){
val entity = RecordOptionEntity()
val jsonObject = result[i] as JSONObject
val optionName = jsonObject.optString("optionName")
entity.optionName = optionName
val optionCode = jsonObject.optString("optionCode")
entity.optionCode = optionCode
val children = jsonObject.optJSONArray("children")
if (children != null) {
if(children.length() > 0){
for(index in 0 until children.length()){
val childJson = children[index] as JSONObject
val child = RecordOptionEntity()
val childOptionNme = childJson.optString("optionName")
val childOptionCode = childJson.optString("optionCode")
child.optionName = childOptionNme
child.optionCode = childOptionCode
entity.children.add(child)
}
}
}
list.add(entity)
}
}
if(list.isNotEmpty()){
isLoadData = true
badReasonListAdapter?.setData(list)
}
}else{
ToastUtils.showShort("主动录包数据采集错误且无缓存数据可用")
}
}
override fun onUploadCosSuccess(cosUrl: String) {
if(isUploadCos){
//上传到服务器
upload(cosUrl)
}
}
}

View File

@@ -4,29 +4,46 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.util.DisplayMetrics
import android.util.Log
import android.view.*
import android.view.animation.Animation
import android.view.animation.ScaleAnimation
import android.widget.CheckBox
import android.widget.CompoundButton
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayout
import com.iflytek.cloud.ErrorCode
import com.iflytek.cloud.InitListener
import com.iflytek.cloud.RecognizerListener
import com.iflytek.cloud.RecognizerResult
import com.iflytek.cloud.SpeechError
import com.iflytek.cloud.SpeechRecognizer
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.badcase.BagDescriptionEntity
import com.mogo.eagle.core.data.deva.badcase.BagManagerEntity
import com.mogo.eagle.core.data.deva.badcase.RecordOptionEntity
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.RecordBagMsg
import com.mogo.eagle.core.function.api.devatools.badcase.BadCaseNetListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsNetManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.tts.base.SpeechUtils
import com.zhidao.loglib.call.LogInfoManagerFactory
import com.zhidao.loglib.upload.OnUploadListener
import com.zhjt.mogo_core_function_devatools.R
@@ -37,9 +54,17 @@ import kotlinx.coroutines.launch
import com.zhidao.loglib.upload.UploadManager
import com.zhidao.loglib.util.FileUtil
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseAnalyticsManager
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.BadReasonListAdapter
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.BadCaseNetManager
import com.zhjt.mogo_core_function_devatools.badcase.repository.store.BadCaseReasonStore
import me.jessyan.autosize.utils.AutoSizeUtils
import org.greenrobot.eventbus.EventBus
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.File
import java.lang.Exception
import java.lang.StringBuilder
/**
* @author XuXinChao
@@ -47,7 +72,7 @@ import java.io.File
* @since: 2022/7/17
*/
class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListener,
CompoundButton.OnCheckedChangeListener {
BadCaseNetListener {
companion object {
const val TAG = "PassiveBadCaseWindow"
@@ -63,13 +88,18 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
private var bagManagerEntity: BagManagerEntity = BagManagerEntity()
private var uploadReason: String = String() //上报原因,标签
private var uploadReason: StringBuilder = StringBuilder() //上报原因,标签
private var recordKey: String?=null //录制bag包key
private var recordFileName: String?=null //录制文件包名
private var receiveTime: String ?= null //接收时间
private var stat: String = ""
private var boxBean: MsgBoxBean ?= null
private var hasOperated: Boolean = false //是否有页面操作
private lateinit var rvPassiveList : RecyclerView
private var badReasonListAdapter: BadReasonListAdapter?= null
private var mInViewX = 0f
private var mInViewY = 0f
private var mDownInScreenX = 0f
@@ -84,13 +114,26 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
private lateinit var tvPassiveTime: TextView
private lateinit var tvPassiveIdentity: TextView
private lateinit var viewAudioBg: ImageView
private lateinit var viewAudioButton: ImageView
private lateinit var tvAudioCountDown: TextView
private lateinit var tvPassiveReport: TextView
private lateinit var tvPassiveCancel: TextView
private lateinit var flReasonLayout: FlexboxLayout
// 语音听写对象
private var mIat: SpeechRecognizer? = null
var ret = 0 // 函数调用返回值
// 用HashMap存储听写结果
private val mIatResults: HashMap<String, String> = LinkedHashMap()
private var reasonDetail: String ?= null //语音转写
private var uploadReasonTotal: String = ""
private var isUploadCos = false //是否在上传Cos操作
private var isLoadData = false //是否已经加载数据
init {
initFloatWindow()
@@ -104,14 +147,43 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
private fun initFloatWindow(){
mFloatLayout = LayoutInflater.from(mActivity).inflate(R.layout.view_passive_bad_case, null) as View
mFloatLayout.setOnTouchListener(this)
// 初始化识别无UI识别对象
// 使用SpeechRecognizer对象可根据回调消息自定义界面
mIat = SpeechRecognizer.createRecognizer(mActivity, mInitListener)
tvPassiveNum = mFloatLayout.findViewById(R.id.tvPassiveNum)
tvPassiveTime = mFloatLayout.findViewById(R.id.tvPassiveTime)
tvPassiveIdentity = mFloatLayout.findViewById(R.id.tvPassiveIdentity)
viewAudioBg = mFloatLayout.findViewById(R.id.viewAudioBg)
viewAudioButton = mFloatLayout.findViewById(R.id.viewAudioButton)
tvAudioCountDown = mFloatLayout.findViewById(R.id.tvAudioCountDown)
tvPassiveReport = mFloatLayout.findViewById(R.id.tvPassiveReport)
tvPassiveCancel = mFloatLayout.findViewById(R.id.tvPassiveCancel)
flReasonLayout = mFloatLayout.findViewById(R.id.flReasonLayout)
rvPassiveList = mFloatLayout.findViewById(R.id.rvPassiveList)
val linearLayoutManager = LinearLayoutManager(mActivity)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
rvPassiveList.layoutManager = linearLayoutManager
badReasonListAdapter = BadReasonListAdapter(mActivity)
badReasonListAdapter?.setListener(object: BadReasonListAdapter.ReasonClickListener{
override fun onClick(reason: String, isChecked: Boolean) {
hasOperated = true
if(isChecked){
uploadReason.append(reason)
}else{
val index = uploadReason.indexOf(reason)
uploadReason.delete(index,index+reason.length)
}
}
})
rvPassiveList.adapter = badReasonListAdapter
/**
* 获取录包原因数据
*/
BadCaseNetManager.badCaseNetManager.getRecordOption(2,AppConfigInfo.iPCMacAddress)
// BadCaseNetManager.badCaseNetManager.getRecordOption(2,"48:b0:2d:3a:9c:8f")
CallerDevaToolsNetManager.addListener(this.hashCode().toString(),this)
if(BadCaseConfig.windowNum<1){
BadCaseConfig.windowNum = 1
}
@@ -119,16 +191,19 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
BadCaseConfig.windowNum++
tvPassiveTime.text = "时间:${millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat())}"
tvPassiveIdentity.text = "身份:${BadCaseConfig.identity}"
viewAudioButton.setOnClickListener {
viewAudioBg.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
hasOperated = true
}
tvPassiveReport.setOnClickListener {
hasOperated = true
if(uploadReason.isEmpty()){
TipToast.shortTip("请选择至少一个Case")
return@setOnClickListener
}
tvPassiveReport.text = "上报中..."
if(audioStatus){
audioStatus = !audioStatus
setAudio(audioStatus)
@@ -136,6 +211,13 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
uploadAudio()
},1000)
}else{
//停止语音听写
mIat?.stopListening()
//结束倒计时
countDownTimer?.cancel()
countDownTimer?.onFinish()
//将倒计时置空
countDownTimer = null
uploadAudio()
}
//删除记录
@@ -144,6 +226,7 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
}
tvPassiveCancel.setOnClickListener {
hasOperated = true
BadCaseConfig.windowNum--
clickListener?.closeWindow()
//删除记录
@@ -157,19 +240,107 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
it.format = PixelFormat.RGBA_8888
it.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
it.gravity = Gravity.START or Gravity.TOP
it.width = 924
it.height = 668
it.width = 859
it.height = 850
it.alpha = 1.0f
}
}
/**
* 初始化监听器。
*/
private val mInitListener = InitListener { code ->
Log.i(TAG, "SpeechRecognizer init() code = $code")
if (code != ErrorCode.SUCCESS) {
ToastUtils.showShort("讯飞语音听写初始化失败,错误码:$code")
}
}
/**
* 听写监听器。
*/
private val mRecognizerListener: RecognizerListener = object : RecognizerListener{
override fun onVolumeChanged(p0: Int, p1: ByteArray?) {
//showTip("当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length);
}
override fun onBeginOfSpeech() {
// 此回调表示sdk内部录音机已经准备好了用户可以开始语音输入
}
override fun onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
}
override fun onResult(results: RecognizerResult?, isLast: Boolean) {
results?.let {
printResult(it)
}
}
override fun onError(p0: SpeechError?) {
// Tips
// 错误码10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
}
override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) {
// 以下代码用于获取与云端的会话id当业务出错时将会话id提供给技术支持人员可用于查询会话日志定位出错原因
// 若使用本地能力会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
}
/**
* 显示结果
*/
private fun printResult(results: RecognizerResult) {
val text: String = JsonParser.parseIatResult(results.resultString)
var sn: String? = null
// 读取json结果中的sn字段
try {
val resultJson = JSONObject(results.resultString)
sn = resultJson.optString("sn")
} catch (e: JSONException) {
e.printStackTrace()
}
mIatResults[sn!!] = text
val resultBuffer = java.lang.StringBuilder()
for (key in mIatResults.keys) {
resultBuffer.append(mIatResults[key])
}
Log.i(TAG, "语音内容=$resultBuffer")
reasonDetail = resultBuffer.toString()
}
private fun setAudio(status: Boolean){
if(status){
//开始录音
mIat?.let {
//清空之前的内容
mIatResults.clear()
SpeechUtils.setParam(it)
// 不显示听写对话框
ret = it.startListening(mRecognizerListener)
if (ret != ErrorCode.SUCCESS) {
ToastUtils.showShort("听写失败,错误码:$ret,请点击网址https://www.xfyun.cn/document/error-code查询解决方案")
}
}
audioFileName = "Audio_${System.currentTimeMillis()}_BadCase"
RecordManager.getInstance().start(audioFileName)
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_select)
//开始录音,展示放大缩小动效
val scaleAnimation = ScaleAnimation(
1.0f, 0.8f, 1.0f, 0.8f,
Animation.RELATIVE_TO_SELF, 0.8f, Animation.RELATIVE_TO_SELF, 0.8f
)
scaleAnimation.duration = 1000
scaleAnimation.repeatCount = -1
viewAudioButton.startAnimation(scaleAnimation)
tvAudioCountDown.visibility = View.VISIBLE
//开始倒计时
if(countDownTimer==null){
@@ -183,13 +354,15 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
tvAudioCountDown.visibility = View.GONE
//结束录音
RecordManager.getInstance().stop()
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_normal)
//结束动画
viewAudioButton.clearAnimation()
}
}
countDownTimer?.start()
}
}else{
//停止语音听写
mIat?.stopListening()
//结束倒计时
countDownTimer?.cancel()
countDownTimer?.onFinish()
@@ -203,17 +376,26 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
val singlePath = "/mnt/sdcard/mogo/DataCollection/${audioFileName}.wav"
val file = File(singlePath)
if(file.exists()){
LogInfoManagerFactory.createAudioUpload(mActivity.applicationContext,
isUploadCos = true
LogInfoManagerFactory.createAudioUpload(mActivity.applicationContext, DebugConfig.isDebug(),
TAG, MoGoAiCloudClientConfig.getInstance().sn,singlePath,
object : OnUploadListener {
override fun onUploadSuccess(key: String, filePath: String, downloadUrl: String) {
CallerLogger.d("$M_DEVA$TAG", "语音文件上传成功downloadUrl=$downloadUrl")
//将语音文件上传Cos监听移除
removeUploadListener(singlePath)
//上传到服务器
upload(downloadUrl)
if(key == TAG){
FileUtil.deleteFile(File(filePath))
override fun onUploadSuccess(key: String, filePath: String, downloadUrl: String?) {
if(downloadUrl == null){
ToastUtils.showShort("上传语音文件失败,请检查网络")
ThreadUtils.runOnUiThread {
tvPassiveReport.text = "上报"
}
}else{
CallerLogger.d("$M_DEVA$TAG", "语音文件上传成功downloadUrl=$downloadUrl")
if(downloadUrl.isNotBlank() && downloadUrl.contains(".wav")){
CallerDevaToolsNetManager.invokeUploadCosSuccess(downloadUrl)
//将语音文件上传Cos监听移除
removeUploadListener(singlePath)
if(key == TAG){
FileUtil.deleteFile(File(filePath))
}
}
}
}
@@ -248,12 +430,17 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
*/
private fun upload(downloadUrl: String?){
GlobalScope.launch{
uploadReasonTotal = if(reasonDetail.isNullOrEmpty()){
uploadReason.toString()
}else{
"$uploadReason 语音内容:$reasonDetail"
}
val uploadResult = presenter.upload(mutableMapOf<String, String>().also { itx ->
itx["carLicense"] = AppConfigInfo.plateNumber //车牌号
itx["filename"] = recordFileName?:"" //bag包文件地址
itx["filesize"] = "0" //bag包文件大小
itx["key"] = recordKey?:"" //key
itx["reason"] = uploadReason //采集原因
itx["reason"] = uploadReasonTotal //采集原因
itx["duration"] = BadCaseConfig.totalDuration.toString() //采集时长固定为20S
itx["startTime"] = System.currentTimeMillis().toString() //上报时间(时间戳格式)
itx["channel"] = "0" //渠道
@@ -267,12 +454,15 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
})
if (uploadResult == null || uploadResult.code != 200) {
TipToast.shortTip("上报失败")
ThreadUtils.runOnUiThread{
tvPassiveReport.text = "上报"
}
} else {
TipToast.shortTip("上报成功")
//将上报BI的结果同步给工控机记录保存
recordKey?.let {
val hasAudio = downloadUrl != null
val descReqEntity = BagDescriptionEntity(uploadReason,hasAudio,downloadUrl.toString(),true)
val descReqEntity = BagDescriptionEntity(uploadReason.toString(),hasAudio,downloadUrl.toString(),true)
bagManagerEntity.reqType = 5
bagManagerEntity.keyReq = it.toLong()
bagManagerEntity.descReq = descReqEntity
@@ -283,13 +473,13 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
BadCaseAnalyticsManager.bagRecordUpload(recordKey?:"",recordFileName?:"",receiveTime?:System.currentTimeMillis().toString(),
stat,AppConfigInfo.plateNumber,BadCaseConfig.totalDuration.toString(),MoGoAiCloudClientConfig.getInstance().sn,
BadCaseConfig.dockerVersion ?:"",AppUtils.getAppVersionName(),loc.latitude.toString(),loc.longitude.toString(),
BadCaseConfig.identity,downloadUrl?:"",uploadReason,System.currentTimeMillis().toString(),"0")
BadCaseConfig.identity,downloadUrl?:"",uploadReasonTotal,System.currentTimeMillis().toString(),"0")
//日志
CallerLogger.i("$M_DEVA$TAG", "BadCase Passive Analytics="+"key="+recordKey+" filename="+recordFileName+
" receiveTime="+receiveTime+" stat="+"100"+" plateNumber="+AppConfigInfo.plateNumber+
" totalDuration="+ BadCaseConfig.totalDuration +" carSn="+MoGoAiCloudClientConfig.getInstance().sn+" mapVersion="+BadCaseConfig.dockerVersion+
" eyeVersion="+AppUtils.getAppVersionName()+" latitude="+ loc.latitude +" longitude="+ loc.longitude+
" identity="+BadCaseConfig.identity + " downloadUrl="+downloadUrl +" uploadReason="+uploadReason+
" identity="+BadCaseConfig.identity + " downloadUrl="+downloadUrl +" uploadReason="+uploadReasonTotal+
" uploadTime="+System.currentTimeMillis()+" channel="+"0")
BadCaseConfig.windowNum--
clickListener?.closeWindow()
@@ -316,6 +506,7 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
}
MotionEvent.ACTION_MOVE -> {
hasOperated = true
// 更新浮动窗口位置参数
mInScreenX = motionEvent.rawX
// mInScreenY = motionEvent.rawY - BarUtils.getStatusBarHeight()
@@ -334,57 +525,29 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
// mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.x = 0
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()-950
mWindowManager!!.addView(mFloatLayout, mWindowParams)
}
GlobalScope.launch{
presenter.loadBadCases(true).also {
ThreadUtils.runOnUiThread {
it.iterator().forEach {
val checkBox = CheckBox(mActivity)
checkBox.setTextColor(Color.WHITE)
val lp = FlexboxLayout.LayoutParams(FlexboxLayout.LayoutParams.WRAP_CONTENT,
FlexboxLayout.LayoutParams.WRAP_CONTENT)
checkBox.buttonDrawable = mActivity.resources.getDrawable(R.drawable.badcase_radio_button_style)
checkBox.setPadding(SizeUtils.dp2px(10f),
SizeUtils.dp2px(10f),
SizeUtils.dp2px(10f),
SizeUtils.dp2px(10f))
checkBox.textSize = AutoSizeUtils.dp2px(mActivity,18f).toFloat()
checkBox.text = it.reason
checkBox.isChecked = it.isChecked
checkBox.setOnCheckedChangeListener(this@PassiveBadCaseWindow)
flReasonLayout.addView(checkBox,lp)
}
}
}
}
}
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
buttonView?.text?.let {
if(isChecked){
if(!uploadReason.contains(it)){
uploadReason += it
}
}else{
if(uploadReason.contains(it)){
uploadReason = uploadReason.replace(it.toString(),"")
}
}
}
}
fun hideFloatWindow() {
//注销采集原因回调监听
CallerDevaToolsNetManager.removeListener(this.hashCode().toString())
// 移除 ADAS车辆状态&定位 监听
if (mFloatLayout.parent != null) mWindowManager!!.removeView(mFloatLayout)
}
/**
* 页面是否有操作
*/
fun isOperated(): Boolean{
return hasOperated
}
fun setRecord(msgBoxBean: MsgBoxBean){
boxBean = msgBoxBean
val recordBagMsg = (msgBoxBean.bean as RecordBagMsg)
@@ -402,4 +565,56 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
fun closeWindow()
}
override fun onPassiveResponse(list: List<RecordOptionEntity>) {
if(!isLoadData && list.isNotEmpty()){
badReasonListAdapter?.setData(list)
isLoadData = true
}
}
override fun onPassiveError() {
if(!isLoadData && BadCaseReasonStore.getPassiveDataRecord().isNotEmpty()){
val list = ArrayList<RecordOptionEntity>()
val result = JSONArray(BadCaseReasonStore.getPassiveDataRecord())
if(result.length() > 0){
for(i in 0 until result.length()){
val entity = RecordOptionEntity()
val jsonObject = result[i] as JSONObject
val optionName = jsonObject.optString("optionName")
entity.optionName = optionName
val optionCode = jsonObject.optString("optionCode")
entity.optionCode = optionCode
val children = jsonObject.optJSONArray("children")
if (children != null) {
if(children.length() > 0){
for(index in 0 until children.length()){
val childJson = children[index] as JSONObject
val child = RecordOptionEntity()
val childOptionNme = childJson.optString("optionName")
val childOptionCode = childJson.optString("optionCode")
child.optionName = childOptionNme
child.optionCode = childOptionCode
entity.children.add(child)
}
}
}
list.add(entity)
}
}
if(list.isNotEmpty()){
isLoadData = true
badReasonListAdapter?.setData(list)
}
}else{
ToastUtils.showShort("被动录包数据采集错误且无缓存数据可用")
}
}
override fun onUploadCosSuccess(cosUrl: String) {
if(isUploadCos){
//上传到服务器
upload(cosUrl)
}
}
}

View File

@@ -0,0 +1,62 @@
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 android.widget.RadioButton
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.deva.badcase.AiDataEntity
import com.zhjt.mogo_core_function_devatools.R
/**
* AI数据采集适配器
*/
class AiDataListAdapter: RecyclerView.Adapter<AiDataListAdapter.AiDataHolder>() {
private var data:List<AiDataEntity> ?= null
private var clickListener: AiDataClickListener ?= null
fun setData(data: List<AiDataEntity>){
this.data = data
notifyDataSetChanged()
}
fun setListener(listener: AiDataClickListener){
clickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AiDataHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_ai_data, parent, false)
return AiDataHolder(view)
}
override fun onBindViewHolder(holder: AiDataHolder, position: Int) {
data?.let {
val entity = it[position]
if(entity.content.isBlank()){
holder.rbDataSelect.text = entity.name
}else{
holder.rbDataSelect.text = "${entity.name}${entity.content}"
}
holder.rbDataSelect.isChecked = entity.isChecked
holder.rbDataSelect.tag = entity
holder.rbDataSelect.setOnCheckedChangeListener { _, isChecked ->
clickListener?.onClick(holder.rbDataSelect.text.toString(),isChecked)
entity.isChecked = isChecked
}
}
}
override fun getItemCount() = data?.size ?: 0
class AiDataHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var rbDataSelect: CheckBox = itemView.findViewById(R.id.rbDataSelect)
}
interface AiDataClickListener{
fun onClick(reason: String,isChecked: Boolean)
}
}

View File

@@ -0,0 +1,84 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.app.Activity
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayout
import com.mogo.eagle.core.data.deva.badcase.RecordOptionEntity
import com.mogo.eagle.core.utilcode.util.SizeUtils
import com.zhjt.mogo_core_function_devatools.R
import me.jessyan.autosize.utils.AutoSizeUtils
/**
* 主动录包和被动录包采集原因列表适配器
*/
class BadReasonListAdapter(activity: Activity): RecyclerView.Adapter<BadReasonListAdapter.BadReasonHolder>() {
init {
activity.also { this.mActivity = it }
}
private var data:List<RecordOptionEntity> ?= null
private var clickListener: ReasonClickListener ?= null
private var mActivity: Activity
fun setData(data: List<RecordOptionEntity>){
this.data = data
notifyDataSetChanged()
}
fun setListener(listener: ReasonClickListener){
clickListener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BadReasonHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_case_reason, parent, false)
return BadReasonHolder(view)
}
override fun onBindViewHolder(holder: BadReasonHolder, position: Int) {
data?.let {
val entity = it[position]
holder.tvReasonTitle.text = entity.optionName
if(entity.children.size>0){
entity.children.forEach { child->
val checkBox = CheckBox(mActivity)
checkBox.setTextColor(Color.WHITE)
val lp = FlexboxLayout.LayoutParams(FlexboxLayout.LayoutParams.WRAP_CONTENT,
FlexboxLayout.LayoutParams.WRAP_CONTENT)
checkBox.buttonDrawable = mActivity.resources.getDrawable(R.drawable.badcase_radio_button_style)
checkBox.setPadding(
SizeUtils.dp2px(15f),
SizeUtils.dp2px(5f),
SizeUtils.dp2px(15f),
SizeUtils.dp2px(5f))
checkBox.textSize = AutoSizeUtils.dp2px(mActivity,15f).toFloat()
checkBox.text = child.optionName
checkBox.setOnCheckedChangeListener{ _, isChecked ->
clickListener?.onClick(checkBox.text.toString(),isChecked)
}
holder.flReasonLayout.addView(checkBox,lp)
}
}
}
}
override fun getItemCount() = data?.size ?: 0
class BadReasonHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var tvReasonTitle: TextView = itemView.findViewById(R.id.tvReasonTitle)
var flReasonLayout: FlexboxLayout = itemView.findViewById(R.id.flReasonLayout)
}
interface ReasonClickListener{
fun onClick(reason: String,isChecked: Boolean)
}
}

View File

@@ -13,7 +13,7 @@ import com.zhjt.mogo_core_function_devatools.R
* @description Case清单列表适配器
* @since: 2022/10/19
*/
class CaseListAdapter: RecyclerView.Adapter<CaseListAdapter.CaseListHolder>() {
open class CaseListAdapter: RecyclerView.Adapter<CaseListAdapter.CaseListHolder>() {
private var data:List<RecordCaseEntity>? = null
private var caseClickListener: CaseClickListener?=null

View File

@@ -13,7 +13,7 @@ import com.zhjt.mogo_core_function_devatools.R
* @description Topic列表适配器
* @since: 2022/10/19
*/
class TopicListAdapter: RecyclerView.Adapter<TopicListAdapter.TopicListHolder>() {
open class TopicListAdapter: RecyclerView.Adapter<TopicListAdapter.TopicListHolder>() {
private var data:MutableList<TopicEntity>? = null
private var topicClickListener: TopicClickListener? = null

View File

@@ -6,14 +6,12 @@ import android.text.TextUtils;
//播放试听
public class Audition implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener{
private static volatile Audition INSTANCE;
public MediaPlayer mediaPlayer;
private String oldPath;
private OnAuditionListener listener;
public interface OnAuditionListener {
void onAuditionCompletion();
}
public void registerOnAuditionListener(OnAuditionListener listener) {
@@ -28,16 +26,12 @@ public class Audition implements MediaPlayer.OnPreparedListener, MediaPlayer.OnC
}
public static Audition getInstance() {
if (INSTANCE == null) {
synchronized (Audition.class) {
if (INSTANCE == null) {
INSTANCE = new Audition();
}
}
}
return INSTANCE;
return Holder.INSTANCE;
}
private static final class Holder{
private static final Audition INSTANCE = new Audition();
}
public boolean isPlaying() {
return mediaPlayer != null && mediaPlayer.isPlaying();

View File

@@ -5,7 +5,6 @@ import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_DEV
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Environment;
import android.util.Log;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.FileUtils;
@@ -42,7 +41,7 @@ public class RecordHelper {
private File resultFile = null;
private File tmpFile = null;
private List<File> files = new ArrayList<>();
private final List<File> files = new ArrayList<>();
private Mp3EncodeThread mp3EncodeThread;
public RecordHelper(RecordConfig config) {
@@ -69,7 +68,9 @@ public class RecordHelper {
return;
}
String path = getFilePath(fileName);
resultFile = new File(path);
if(path!=null){
resultFile = new File(path);
}
String tempFilePath = getTempFilePath();
tmpFile = new File(tempFilePath);
audioRecordThread = new AudioRecordThread();
@@ -134,7 +135,7 @@ public class RecordHelper {
}
}
private FftFactory fftFactory = new FftFactory(FftFactory.Level.Original);
private final FftFactory fftFactory = new FftFactory(FftFactory.Level.Original);
private void notifyData(final byte[] data) {
if (listener != null) {
@@ -192,14 +193,10 @@ public class RecordHelper {
@Override
public void run() {
super.run();
switch (currentConfig.getFormat()) {
case MP3:
startMp3Recorder();
break;
default:
startPcmRecorder();
break;
if (currentConfig.getFormat() == RecordConfig.RecordFormat.MP3) {
startMp3Recorder();
} else {
startPcmRecorder();
}
}
@@ -275,12 +272,9 @@ public class RecordHelper {
private void stopMp3Encoded() {
if (mp3EncodeThread != null) {
mp3EncodeThread.stopSafe(new Mp3EncodeThread.EncordFinishListener() {
@Override
public void onFinish() {
notifyFinish();
mp3EncodeThread = null;
}
mp3EncodeThread.stopSafe(() -> {
notifyFinish();
mp3EncodeThread = null;
});
} else {
CallerLogger.e("$M_DEVA$TAG", "mp3EncodeThread is null, 代码业务流程有误,请检查!! ");
@@ -382,8 +376,7 @@ public class RecordHelper {
}
String format = currentConfig.getFormat().getExtension();
String filePath = String.format(Locale.getDefault(), "%s%s%s", ROOT_PATH, fileName, format);
return filePath;
return String.format(Locale.getDefault(), "%s%s%s", ROOT_PATH, fileName, format);
}
private String getTempFilePath() {

View File

@@ -7,9 +7,7 @@ import com.zhjt.mogo_core_function_devatools.badcase.record.listener.RecordListe
public class RecordManager {
private static final String TAG = RecordManager.class.getSimpleName();
@SuppressLint("StaticFieldLeak")
private volatile static RecordManager instance;
private final RecordHelper recordHelper;
/**
* 录音配置
@@ -21,14 +19,11 @@ public class RecordManager {
}
public static RecordManager getInstance() {
if (instance == null) {
synchronized (RecordManager.class) {
if (instance == null) {
instance = new RecordManager();
}
}
}
return instance;
return Holder.instance;
}
private static final class Holder{
private static final RecordManager instance = new RecordManager();
}
// /**

View File

@@ -1,9 +1,15 @@
package com.zhjt.mogo_core_function_devatools.badcase.repository.net
import android.util.Log
import com.mogo.commons.constants.HostConst
import com.mogo.eagle.core.data.BaseResponse
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
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.GsonUtils
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.BadCaseApi
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult
@@ -55,4 +61,57 @@ internal class BadCaseNetModel {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "upload_error:$t")
null
}
private fun getNetWorkApi(baseUrl: String = HostConst.getHost()): BadCaseApi{
return MoGoRetrofitFactory.getInstanceNoCallAdapter(baseUrl)
.create(BadCaseApi::class.java)
}
/**
* 获取AI数据采集配置项数据
*/
fun getAiData(onSuccess: ((String) -> Unit),onError: ((String) -> Unit)){
request<BaseResponse<Any?>>{
loader{
apiCall{
getNetWorkApi().getAiData()
}
}
onSuccess{
if(it.msg == "success"){
onSuccess.invoke(GsonUtils.toJson(it.result))
}else{
onError.invoke(it.msg)
}
}
onError{
it.message?.let { it1 -> onError.invoke(it1) }
}
}
}
/**
* 客户端根据录包类型和车辆 mac 地址查询录包数据
* @param optionType 选项类型1-主动录包;2-被动录包
* @param mac 设备mac地址
*/
fun getRecordOption(optionType: Int,mac: String,onSuccess: ((String) -> Unit),onError: ((String) -> Unit)){
request<BaseResponse<Any?>>{
loader {
getNetWorkApi().getRecordOption(optionType, mac)
}
onSuccess{
if(it.msg == "success"){
onSuccess.invoke(GsonUtils.toJson(it.result))
}else{
onError.invoke(it.msg)
}
}
onError {
it.message?.let { it1 -> onError.invoke(it1) }
}
}
}
}

View File

@@ -1,5 +1,8 @@
package com.zhjt.mogo_core_function_devatools.badcase.repository.net.api
import com.mogo.eagle.core.data.BaseResponse
import com.mogo.eagle.core.data.deva.badcase.AiDataEntity
import com.mogo.eagle.core.data.deva.badcase.RecordOptionEntity
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult
import retrofit2.Response
@@ -13,4 +16,18 @@ internal interface BadCaseApi {
@GET("eagle-eye-dns/yycp-vehicle-management-service/tool/badcase/reasons")
suspend fun get(@Query("channel", encoded = true) channel: String, @Query("pageNo") pageNo: Int): Response<BadCaseResponse>
/**
* 获取AI数据采集列表数据
*/
@GET("eagleEye-mis/dataGather/select/active")
suspend fun getAiData(): BaseResponse<List<AiDataEntity>>
/**
* 客户端根据录包类型和车辆 mac 地址查询录包数据
* @param optionType 选项类型1-主动录包;2-被动录包
* @param mac 设备mac地址
*/
@GET("eagleEye-mis/recordPackageOption/client/list")
suspend fun getRecordOption(@Query("optionType") optionType: Int,@Query("mac") mac: String): BaseResponse<List<RecordOptionEntity>>
}

View File

@@ -0,0 +1,109 @@
package com.zhjt.mogo_core_function_devatools.badcase.repository.net.api
import android.util.Log
import com.mogo.eagle.core.data.deva.badcase.AiDataEntity
import com.mogo.eagle.core.data.deva.badcase.RecordOptionEntity
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsNetManager
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.BadCaseNetModel
import com.zhjt.mogo_core_function_devatools.badcase.repository.store.BadCaseReasonStore
import org.json.JSONArray
import org.json.JSONObject
class BadCaseNetManager {
companion object{
val badCaseNetManager: BadCaseNetManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
BadCaseNetManager()
}
}
private val badCaseNetModel = BadCaseNetModel()
/**
* 获取AI数据采集数据
*/
fun getAiData(){
badCaseNetModel.getAiData(
onSuccess =
{
val list = ArrayList<AiDataEntity>()
val result = JSONArray(it)
if(result.length()>0){
for(i in 0 until result.length()){
val jsonObject = result[i] as JSONObject
val id = jsonObject.optInt("id")
val name = jsonObject.optString("name")
val content = jsonObject.optString("content")
val entity = AiDataEntity(id, name, content,false)
list.add(entity)
}
}
//将结果回调到调用页面
CallerDevaToolsNetManager.invokeAiDataResponse(list)
//缓存数据
BadCaseReasonStore.setAiDataRecord(it)
},
onError =
{
CallerDevaToolsNetManager.invokeAiDataError()
})
}
fun getRecordOption(optionType: Int,mac: String){
badCaseNetModel.getRecordOption(optionType,mac,
onSuccess =
{
val list = ArrayList<RecordOptionEntity>()
val result = JSONArray(it)
if(result.length() > 0){
for(i in 0 until result.length()){
val entity = RecordOptionEntity()
val jsonObject = result[i] as JSONObject
val optionName = jsonObject.optString("optionName")
entity.optionName = optionName
val optionCode = jsonObject.optString("optionCode")
entity.optionCode = optionCode
val children = jsonObject.optJSONArray("children")
if (children != null) {
if(children.length() > 0){
for(index in 0 until children.length()){
val childJson = children[index] as JSONObject
val child = RecordOptionEntity()
val childOptionNme = childJson.optString("optionName")
val childOptionCode = childJson.optString("optionCode")
child.optionName = childOptionNme
child.optionCode = childOptionCode
entity.children.add(child)
}
}
}
list.add(entity)
}
}
//将结果回调到调用页面
if(optionType == 1){
//主动录包
CallerDevaToolsNetManager.invokeInitiativeResponse(list)
//缓存数据
BadCaseReasonStore.setInitiativeDataRecord(it)
} else if(optionType == 2){
//被动录包
CallerDevaToolsNetManager.invokePassiveResponse(list)
//缓存数据
BadCaseReasonStore.setPassiveDataRecord(it)
}
},
onError =
{
if(optionType == 1){
//主动录包
CallerDevaToolsNetManager.invokeInitiativeError()
}else if(optionType == 2){
//被动录包
CallerDevaToolsNetManager.invokePassiveError()
}
}
)
}
}

View File

@@ -0,0 +1,56 @@
package com.zhjt.mogo_core_function_devatools.badcase.repository.store
import com.mogo.eagle.core.utilcode.util.SPUtils
object BadCaseReasonStore {
//AI数据采集
private const val aiData = "AI_DATA"
//主动录包
private const val initiativeData = "INITIATIVE_DATA"
//被动录包
private const val passiveData = "PASSIVE_DATA"
/**
* 获取AI数据采集缓存数据
*/
fun getAiDataRecord(): String{
return SPUtils.getInstance().getString(aiData,"")
}
/**
* 设置AI数据采集缓存数据
*/
fun setAiDataRecord(data: String){
SPUtils.getInstance().put(aiData,data)
}
/**
* 获取主动录包缓存数据
*/
fun getInitiativeDataRecord(): String{
return SPUtils.getInstance().getString(initiativeData,"")
}
/**
* 设置主动录包缓存数据
*/
fun setInitiativeDataRecord(data: String){
SPUtils.getInstance().put(initiativeData,data)
}
/**
* 获取被动录包缓存数据
*/
fun getPassiveDataRecord(): String{
return SPUtils.getInstance().getString(passiveData,"")
}
/**
* 设置被动录包缓存数据
*/
fun setPassiveDataRecord(data: String){
SPUtils.getInstance().put(passiveData,data)
}
}

View File

@@ -1,35 +1,36 @@
package com.zhjt.mogo_core_function_devatools.binding
import android.annotation.*
import android.annotation.SuppressLint
import android.content.Context
import android.text.TextUtils
import com.elegant.utils.UiThreadHandler
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.constants.SharedPrefsConstants
import com.mogo.eagle.core.data.app.AppConfigInfo.role
import com.mogo.eagle.core.data.deva.bindingcar.ModifyBindingcarInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.data.deva.bindingcar.ModifyBindingcarInfo
import com.mogo.eagle.core.data.obu.MogoObuConst
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener
import com.mogo.eagle.core.function.api.cloud.IMoGoCloudListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager
import com.mogo.eagle.core.function.call.cloud.CallerCloudListenerManager
import com.mogo.eagle.core.function.call.obu.CallerObuApiManager
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils.isDriver
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils.isPassenger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr
import com.zhjt.mogo_core_function_devatools.trace.TraceManager
import com.zhjt.mogo_core_function_devatools.upgrade.IPCUpgradeManager.Companion.ipcUpgradeManager
import com.zhjt.mogo_core_function_devatools.upgrade.ObuUpgradeAppNetWorkManager
import com.zhjt.mogo_core_function_devatools.upgrade.UpgradeAppNetWorkManager
import mogo.telematics.pad.MessagePad
/**
* //todo emArrow 链路biz
* 车辆绑定
*/
@SuppressLint("StaticFieldLeak")
object BindingCarManager : IMoGoAutopilotCarConfigListener {
object BindingCarManager : IMoGoAutopilotCarConfigListener, IMoGoCloudListener {
private const val TAG = "BindingCarManager"
@@ -45,11 +46,18 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
private var mWidevineIDWithMd5 //google 数字版权
: String? = null
@Volatile
private var bind = false
@Volatile
private var carConfigResp: MessagePad.CarConfigResp? = null
fun init(context: Context) {
mContext = context
SharedPrefsMgr.getInstance(mContext!!).putLong("typeDriver", 0)
SharedPrefsMgr.getInstance(mContext!!).putLong("typePassenger", 0)
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
CallerCloudListenerManager.addListener(TraceManager.TAG, this)
ipcUpgradeManager.init(context)
}
@@ -61,12 +69,28 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
override fun onAutopilotCarConfig(carConfigResp: MessagePad.CarConfigResp) {
CallerLogger.d("${M_DEVA}${TAG}", "onAutopilotCarConfig ----------> ")
if (!TextUtils.isEmpty(carConfigResp.macAddress)) {
CallerLogger.d("${M_DEVA}${TAG}",
"onAutopilotCarConfig carConfigResp.macAddress = ${carConfigResp.macAddress} ")
CallerLogger.d(
"${M_DEVA}${TAG}",
"onAutopilotCarConfig carConfigResp.macAddress = ${carConfigResp.macAddress} "
)
if (MoGoAiCloudClientConfig.getInstance().sn.isNullOrEmpty()) {
return
}
this.carConfigResp = carConfigResp
getBindingCarInfo(carConfigResp.macAddress, MoGoAiCloudClientConfig.getInstance().sn)
}
}
override fun tokenGot(token: String, sn: String) {
super.tokenGot(token, sn)
if (bind) {
return
}
this.carConfigResp?.let {
getBindingCarInfo(it.macAddress, sn)
}
}
/**
* 获取macaddress,每次连接请求一次
*
@@ -87,7 +111,8 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
queryObuUpgrade(obuVersion)
}
}
CallerLogger.d("${M_DEVA}${TAG}",
CallerLogger.d(
"${M_DEVA}${TAG}",
"getBindingcarInfo macAddress = $macAddress--widevineIDWithMd5 = $widevineIDWithMd5 ---screenType = $screenType"
)
SharedPrefsMgr.getInstance(mContext!!).putString(SharedPrefsConstants.APP_MAC, macAddress)
@@ -97,6 +122,7 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
} else if (screenType == 2) { //乘客屏
passengerScreen(macAddress, widevineIDWithMd5)
}
bind = true
}
/**
@@ -121,7 +147,12 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
}
fun modifyCarInfo(callBack: (ModifyBindingcarInfo) -> Unit) {
BindingCarNetWorkManager.instance.modifyBindingCar(mAddress, mWidevineIDWithMd5, callBack, screenType)
BindingCarNetWorkManager.instance.modifyBindingCar(
mAddress,
mWidevineIDWithMd5,
callBack,
screenType
)
}
private fun driverScreen(macAddress: String, widevineIDWithMd5: String) {
@@ -177,10 +208,10 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
* 查询app是否需要升级
*/
fun queryAppUpgrade() {
CallerLogger.d(M_DEVA+"UPGRADE", "---- 1 ----")
CallerLogger.d(M_DEVA + "UPGRADE", "---- 1 ----")
var macAddress = mAddress
if (TextUtils.isEmpty(macAddress)) {
CallerLogger.d(M_DEVA+"UPGRADE", "---- 2 ----")
CallerLogger.d(M_DEVA + "UPGRADE", "---- 2 ----")
macAddress = SharedPrefsMgr.getInstance(mContext!!)
.getString(SharedPrefsConstants.APP_MAC)
}
@@ -188,7 +219,7 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
if (!TextUtils.equals(macAddress, mAddress)) {
mAddress = macAddress
}
CallerLogger.d(M_DEVA+"UPGRADE", "---- 3 ----[mac: $macAddress]")
CallerLogger.d(M_DEVA + "UPGRADE", "---- 3 ----[mac: $macAddress]")
UpgradeAppNetWorkManager.instance
?.getAppUpgradeInfo(mContext, macAddress, role.toString() + "")
}
@@ -200,10 +231,20 @@ object BindingCarManager : IMoGoAutopilotCarConfigListener {
*/
fun queryObuUpgrade(obuVersionName: String) {
mObuVersion = obuVersionName
CallerLogger.d("${M_DEVA}${MogoObuConst.TAG_UPGRADE_OBU}", "screenType = $screenType ----role = $role")
CallerLogger.d(
"${M_DEVA}${MogoObuConst.TAG_UPGRADE_OBU}",
"screenType = $screenType ----role = $role"
)
if (screenType == 1) {
CallerLogger.d("${M_DEVA}${MogoObuConst.TAG_UPGRADE_OBU}","queryObuUpgrade isConnected = ${CallerObuApiManager.isConnected()} --- mAddress = $mAddress")
ObuUpgradeAppNetWorkManager.instance?.getObuUpgradeInfo(if(!mAddress.isNullOrEmpty()) mAddress else SharedPrefsMgr.getInstance(mContext!!).getString(SharedPrefsConstants.APP_MAC), obuVersionName)
CallerLogger.d(
"${M_DEVA}${MogoObuConst.TAG_UPGRADE_OBU}",
"queryObuUpgrade isConnected = ${CallerObuApiManager.isConnected()} --- mAddress = $mAddress"
)
ObuUpgradeAppNetWorkManager.instance?.getObuUpgradeInfo(
if (!mAddress.isNullOrEmpty()) mAddress else SharedPrefsMgr.getInstance(
mContext!!
).getString(SharedPrefsConstants.APP_MAC), obuVersionName
)
}
}
}

View File

@@ -8,6 +8,7 @@ import com.mogo.eagle.core.data.deva.bindingcar.BindingCarInfo
import com.mogo.eagle.core.data.deva.bindingcar.BindingCarRequest
import com.mogo.eagle.core.data.deva.bindingcar.ModifyBindingcarInfo
import com.mogo.eagle.core.data.config.HdMapBuildConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager.showBindingCarDialog
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager.showModifyBindingCarDialog
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
@@ -20,6 +21,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.GsonUtils
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.service.chain.ChainLog
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@@ -65,6 +67,7 @@ class BindingCarNetWorkManager private constructor() {
MediaType.get("application/json;charset=UTF-8"),
GsonUtil.jsonFromObject(request)
)
bindLog(mapOf("bingReq" to request))
mBindingCarApiService.getBindingCarInfo(requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -72,7 +75,7 @@ class BindingCarNetWorkManager private constructor() {
override fun onSubscribe(d: Disposable) {}
override fun onNext(info: BindingCarInfo) {
if (info != null && info.getData() != null) {
d(SceneConstant.M_DEVA + TAG, "getBindingCarInfo data =" + info.getData().toString() + "---getDefaultId() : ${getDefaultId()}")
bindLog(mapOf("bindResult" to true,"carType" to getDefaultId(),"msg" to info))
SharedPrefsMgr.getInstance(context).putString(
SharedPrefsConstants.CAR_INFO,
GsonUtils.toJson(info.getData())
@@ -91,6 +94,7 @@ class BindingCarNetWorkManager private constructor() {
override fun onError(e: Throwable) {
SharedPrefsMgr.getInstance(context).putString(SharedPrefsConstants.CAR_INFO, "")
bindLog(mapOf("bindResult" to false,"msg" to e.toString()))
e(SceneConstant.M_DEVA + TAG, "getBindingCarInfo onError e = " + e.toString() + "---e.getMessage = " + e.message + "---getDefaultId() : ${getDefaultId()}")
}
@@ -115,6 +119,7 @@ class BindingCarNetWorkManager private constructor() {
widevineIDWithMd5,
screenType
)
bindLog(mapOf("bindingReq" to request))
val requestBody = RequestBody.create(
MediaType.get("application/json;charset=UTF-8"),
GsonUtil.jsonFromObject(request)
@@ -127,13 +132,13 @@ class BindingCarNetWorkManager private constructor() {
override fun onNext(info: ModifyBindingcarInfo) {
if (info != null) {
callBack.invoke(info)
d(SceneConstant.M_DEVA + TAG, "modifyBindingCar onNext code = " + info.code + "---msg = " + info.msg + "--info.toString() = " + info.toString())
bindLog(mapOf("bindingStatus" to true,"bindMsg" to info))
updateCarVrIconRes(info.data.brandId)
}
}
override fun onError(e: Throwable) {
e(SceneConstant.M_DEVA + TAG, "modifyBindingCar onError e = " + e.toString() + "---e.getMessage = " + e.message)
bindLog(mapOf("bindingStatus" to false,"bindMsg" to e.toString()))
}
override fun onComplete() {}
@@ -177,6 +182,16 @@ class BindingCarNetWorkManager private constructor() {
}
}
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_INIT,
nodeAliasCode = ChainConstant.CHAIN_CODE_BINDING_CAR,
paramIndexes = [0]
)
private fun bindLog(msg:Map<String,Any>){
d(SceneConstant.M_DEVA + TAG, "bindLog : $msg")
}
private fun getDefaultId(): String {
return when (HdMapBuildConfig.currentCarVrIconRes) {
R.raw.chuzuche -> "1"

View File

@@ -5,19 +5,19 @@ import com.zhjt.service.chain.*
internal class MainBlockLinkedLog {
fun record(extra: Map<String, List<String>>) {
fun record(json: String) {
try {
recordInternal(extra)
recordInternal(json)
} catch (t: Throwable) {
t.printStackTrace()
}
}
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_HMI,
linkChainLog = ChainConstant.CHAIN_TYPE_ANR_LEAK,
linkCode = ChainConstant.CHAIN_SOURCE_HMI,
nodeAliasCode = ChainConstant.CHAIN_CODE_MAIN_BLOCK,
paramIndexes = [0]
)
private fun recordInternal(extra: Map<String, List<String>>) {}
private fun recordInternal(json: String) {}
}

View File

@@ -4,6 +4,7 @@ import android.content.*
import android.util.*
import android.view.*
import androidx.metrics.performance.*
import com.apm.insight.log.VLog
import com.mogo.eagle.core.block.runtime.*
import com.mogo.eagle.core.block.runtime.config.*
import com.mogo.eagle.core.block.runtime.config.recorder.*
@@ -11,14 +12,20 @@ import com.mogo.eagle.core.block.runtime.config.recorder.IMessageRecorder.OnDump
import com.mogo.eagle.core.block.runtime.listener.*
import com.mogo.eagle.core.block.runtime.report.*
import com.mogo.eagle.core.function.api.devatools.block.*
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.utilcode.util.GsonUtils
import java.util.concurrent.TimeUnit.SECONDS
internal class MoGoBlockProviderImpl: IMoGoBlockProvider, IBlockListener {
companion object {
private const val TAG = "BLOCK_REPORT"
}
@Volatile
private var hasInit = false
private val linkedLog by lazy { MainBlockLinkedLog() }
// private val linkedLog by lazy { MainBlockLinkedLog() }
override fun init(ctx: Context) {
BlockDetector.init(BlockMetrics.Builder()
@@ -26,8 +33,8 @@ internal class MoGoBlockProviderImpl: IMoGoBlockProvider, IBlockListener {
.multiplier(2.0f)
.isDebug(false)
.period(5, SECONDS)
.junkRateThreshold(0.8f)
.recorder(null, 1000, 512)
.junkRateThreshold(0.6f)
.recorder(null, 500, 500)
.build())
hasInit = true
}
@@ -49,7 +56,26 @@ internal class MoGoBlockProviderImpl: IMoGoBlockProvider, IBlockListener {
override fun OnDumped(data: Map<Int, List<String>>) {
map["history"] = data[0] ?: emptyList()
map["pending"] = data[1] ?: emptyList()
linkedLog.record(map)
val cpu = CallerDevaToolsManager.usage()?.dump()
if (!cpu.isNullOrEmpty()) {
val mainThreadUsage = cpu.remove("MainThreadUsage")
val processUsage = cpu.remove("ProcessUsage")
if (mainThreadUsage != null && processUsage != null) {
map["cpu"] = ArrayList<String>().also {
it.add("main-thread: ${ "%.2f".format(mainThreadUsage * 1.0f * 100 / processUsage) }% ($mainThreadUsage, $processUsage)")
for (e in cpu.entries.sortedByDescending { e -> e.value }) {
it.add("${e.key}: ${ "%.2f".format(e.value * 1.0f * 100 / processUsage) }% (${e.value}, $processUsage)")
}
}
}
}
val msg = GsonUtils.toJson(map)
try {
VLog.w(TAG, msg)
} catch (t: Throwable) {
Log.e(TAG, "onDumped error", t)
}
// linkedLog.record(msg)
}
})
}
@@ -81,7 +107,6 @@ internal class MoGoBlockProviderImpl: IMoGoBlockProvider, IBlockListener {
}
override fun recorder(): IMessageRecorder {
return BlockDetector.recorder()
}
}

View File

@@ -6,7 +6,7 @@ import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_FUNC_CONFIG_CHANGED
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_SOURCE_CLOUD
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_INIT_STATUS
import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_TYPE_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
@@ -71,7 +71,7 @@ class FuncConfigCenter : IMogoOnMessageListener<FuncConfig>, IMoGoAutopilotCarCo
}
@ChainLog(
linkChainLog = CHAIN_TYPE_INIT_STATUS,
linkChainLog = CHAIN_TYPE_STATUS,
linkCode = CHAIN_SOURCE_CLOUD,
nodeAliasCode = CHAIN_CODE_FUNC_CONFIG_CHANGED,
paramIndexes = [0]

View File

@@ -104,7 +104,7 @@ internal class MoGoLogRecordProviderImpl: IMoGoLogRecordProvider,
}
})
.crashConfig(CrashConfig.Builder()
.enabled(true)
.enabled(false)
.crashDir(File(context.getExternalFilesDir(null), "logcat/crash"))
.javaCrash(true)
.anr(true)

View File

@@ -186,7 +186,7 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
content,
this
)
logInfoManager?.start()
logInfoManager?.start(DebugConfig.isDebug())
logInfoManager?.registerLogOutListener { lineLog ->
CallerDevaToolsListenerManager.invokeDevaToolsLogCatchLines(lineLog)
}

View File

@@ -21,23 +21,23 @@ class DynamicConfigImpl: IDynamicConfig {
}
override fun get(key: String?, defStr: String?): String {
return ""
return defStr ?: ""
}
override fun get(key: String?, defInt: Int): Int {
return 0
return defInt
}
override fun get(key: String?, defLong: Long): Long {
return 0L
return defLong
}
override fun get(key: String?, defBool: Boolean): Boolean {
return false
return true
}
override fun get(key: String?, defFloat: Float): Float {
return 0f
return defFloat
}
}

View File

@@ -11,31 +11,66 @@ internal class MoFangAnalyticUtils {
// 魔方连接状态
const val EVENT_MOFANG_CONNECT = "event_mofang_connect"
const val EVENT_SUB_START_CONNECT = "event_sub_start_connect"
const val EVENT_SUB_CONNECT_SUCCESS = "event_sub_connect_success"
const val EVENT_SUB_START_DISCONNECT = "event_sub_start_disconnect"
const val EVENT_SUB_DISCONNECT_SUCCESS = "event_sub_disconnect_success"
const val EVENT_SUB_DISCONNECT_SLEEP = "event_sub_disconnect_sleep"
const val EVENT_SUB_BLUETOOTH_SETTING_REQ = "event_sub_ble_set_req"
const val EVENT_SUB_BLUETOOTH_OPEN_DENY = "event_sub_ble_open_deny"
const val EVENT_SUB_BLUETOOTH_OPEN_AGREE = "event_sub_ble_open_agree"
const val EVENT_SUB_IS_VALID = "event_sub_is_ipt_valid"
const val EVENT_SUB_IS_INVALID = "event_sub_is_ipt_invalid"
const val EVENT_MOFANG_CONNECT_PARAMS_START_CONNECT = "event_sub_start_connect"
const val EVENT_MOFANG_CONNECT_PARAMS_CONNECT_SUCCESS = "event_sub_connect_success"
const val EVENT_MOFANG_CONNECT_PARAMS_START_DISCONNECT = "event_sub_start_disconnect"
const val EVENT_MOFANG_CONNECT_PARAMS_DISCONNECT_SUCCESS = "event_sub_disconnect_success"
const val EVENT_MOFANG_CONNECT_PARAMS_DISCONNECT_SLEEP = "event_sub_disconnect_sleep"
const val EVENT_MOFANG_CONNECT_PARAMS_SETTING_REQ = "event_sub_ble_set_req"
const val EVENT_MOFANG_CONNECT_PARAMS_OPEN_DENY = "event_sub_ble_open_deny"
const val EVENT_MOFANG_CONNECT_PARAMS_OPEN_AGREE = "event_sub_ble_open_agree"
const val EVENT_MOFANG_CONNECT_PARAMS_IS_VALID = "event_sub_is_ipt_valid"
const val EVENT_MOFANG_CONNECT_PARAMS_IS_INVALID = "event_sub_is_ipt_invalid"
// 魔方电量
const val EVENT_BATTERY = "event_mofang_battery"
const val EVENT_BATTERY_VALUE = "battery"
const val EVENT_BATTERY_PARAMS_VALUE = "battery"
const val EVENT_BATTERY_PARAMS_DUR = "dur"
// 收到魔方按键指令
const val EVENT_INPUT = "event_mofang_input"
const val EVENT_INPUT_SUB_KEYCODE = "keycode"
const val EVENT_INPUT_SUB_TYPE = "input_type" // 1:单击2:长按, 3:组合键
const val EVENT_INPUT_PARAMS_KEYCODE = "keycode"
const val EVENT_INPUT_PARAMS_TYPE = "input_type" // 1:单击2:长按, 3:组合键
// 执行魔方按键指令
const val EVENT_EXECUTE = "event_mofang_execute"
const val EVENT_EXECUTE_SUB_KEYCODE = "keycode"
const val EVENT_EXECUTE_SUB_TYPE = "input_type" // 1:单击2:长按, 3:组合键
const val EVENT_EXECUTE_PARAMS_KEYCODE = "keycode"
const val EVENT_EXECUTE_PARAMS_TYPE = "input_type" // 1:单击2:长按, 3:组合键
const val EVENT_EXECUTE_PARAMS_LON = "lon" // 执行时自车经度
const val EVENT_EXECUTE_PARAMS_LAT = "lat" // 执行时自车纬度
const val EVENT_EXECUTE_PARAMS_SPEED = "speed" // 执行时自车速度
const val EVENT_EXECUTE_PARAMS_ACC = "acc" // 执行时自车加速度
const val EVENT_EXECUTE_PARAMS_HEADING = "head" // 执行时自车航向角
const val EVENT_EXECUTE_PARAMS_LINE_ID = "line_id" // 执行时的路线id
const val EVENT_EXECUTE_PARAMS_DOCKER_VERSION = "docker" // docker版本
// 魔方按键指令回执-工控机收到
const val EVENT_EXECUTE_FEEDBACK_RECEIVE = "event_mofang_fb_receive"
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_NODE = "node"
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_CODE = "code"
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_MSG = "msg"
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LON = "lon" // 时自车经度
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LAT = "lat" // 执行时自车纬度
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_SPEED = "speed" // 执行时自车速度
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_ACC = "acc" // 执行时自车加速度
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_HEADING = "head" // 执行时自车航向角
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LINE_ID = "line_id" // 执行时的路线id
const val EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_DOCKER_VERSION = "docker" // docker版本
// 魔方按键指令回执-工控机执行
const val EVENT_EXECUTE_FEEDBACK_EXECUTE = "event_mofang_fb_execute"
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_NODE = "node"
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_CODE = "code"
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_MSG = "msg"
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LON = "lon" // 执行时自车经度
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LAT = "lat" // 执行时自车纬度
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_SPEED = "speed" // 执行时自车速度
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_ACC = "acc" // 执行时自车加速度
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_HEADING = "head" // 执行时自车航向角
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LINE_ID = "line_id" // 执行时的路线id
const val EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_DOCKER_VERSION = "docker" // docker版本
private val handler by lazy { HandlerThread("mofang-analytic-worker", Process.THREAD_PRIORITY_BACKGROUND).let { it.start(); Handler(it.looper) } }

View File

@@ -3,13 +3,47 @@ package com.zhjt.mogo_core_function_devatools.mofang
import android.os.*
import android.util.*
import android.view.KeyEvent
import com.mogo.commons.utils.MogoAnalyticUtils
import com.mogo.eagle.core.data.config.*
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.*
import com.mogo.eagle.core.network.utils.GsonUtil
import com.mogo.eagle.core.utilcode.mogo.*
import com.zhjt.mogo.adas.data.bean.MogoReport.Code.Info.IMF
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_SUB_KEYCODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_SUB_TYPE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_ACC
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_CODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_DOCKER_VERSION
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_HEADING
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LAT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LINE_ID
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LON
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_MSG
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_NODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_SPEED
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_ACC
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_CODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_DOCKER_VERSION
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_HEADING
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LAT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LINE_ID
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LON
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_MSG
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_NODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_SPEED
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_ACC
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_DOCKER_VERSION
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_HEADING
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_KEYCODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_LAT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_LINE_ID
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_LON
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_SPEED
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_EXECUTE_PARAMS_TYPE
import mogo_msg.MogoReportMsg
import java.util.concurrent.atomic.AtomicBoolean
internal class MoFangCommandExecutor {
@@ -32,9 +66,51 @@ internal class MoFangCommandExecutor {
this.linkedLog = log
}
private val isRegister by lazy { AtomicBoolean(false) }
private val listener = object : IMoGoAutopilotStatusListener {
override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
super.onAutopilotGuardian(guardianInfo)
guardianInfo?.also {
when (it.code) {
IMF.SPEED_CHANGE_RECEIVE -> {
reportIPCReceive(it.src, it.code, it.msg)
}
IMF.SPEED_CHANGE_EXECUTE -> {
reportIPCExecute(it.src, it.code, it.msg)
}
IMF.SPEED_RESET_RECEIVE -> {
reportIPCReceive(it.src, it.code, it.msg)
}
IMF.SPEED_RESET_EXECUTE -> {
reportIPCExecute(it.src, it.code, it.msg)
}
IMF.LAN_CHANG_RECEIVE -> {
reportIPCReceive(it.src, it.code, it.msg)
}
IMF.LAN_CHANG_EXECUTE -> {
reportIPCExecute(it.src, it.code, it.msg)
}
IMF.HORN_RECEIVE -> {
reportIPCReceive(it.src, it.code, it.msg)
}
IMF.HORN_EXECUTE -> {
reportIPCExecute(it.src, it.code, it.msg)
}
}
}
}
}
private val handlerCallback = Handler.Callback { msg ->
if (isRegister.compareAndSet(false, true)) {
CallerAutoPilotStatusListenerManager.addListener(TAG, listener)
}
val message = whatToString(msg.what, ", msg_info:[obj:${msg.obj}, arg1: ${msg.arg1}, arg2: ${msg.arg2}]")
linkedLog?.record(mapOf("收到:${System.currentTimeMillis()}" to "$message"))
val location = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84()
when(msg.what) {
MSG_WHAT_KEY_CODE_A, MSG_WHAT_KEY_CODE_B, MSG_WHAT_KEY_CODE_AB, MSG_WHAT_KEY_CODE_AL -> {
var send = false
@@ -42,7 +118,17 @@ internal class MoFangCommandExecutor {
val acc = msg.obj as? Double
if (acc != null) {
send = acc != 0.0
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(EVENT_EXECUTE_SUB_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""), EVENT_EXECUTE_SUB_TYPE to (getInputTypeByWhat(msg.what) ?: "")))
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(
EVENT_EXECUTE_PARAMS_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_TYPE to (getInputTypeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_LON to location.longitude,
EVENT_EXECUTE_PARAMS_LAT to location.latitude,
EVENT_EXECUTE_PARAMS_SPEED to location.gnssSpeed,
EVENT_EXECUTE_PARAMS_ACC to location.acceleration,
EVENT_EXECUTE_PARAMS_HEADING to location.heading,
EVENT_EXECUTE_PARAMS_LINE_ID to CallerAutoPilotStatusListenerManager.getLineId(),
EVENT_EXECUTE_PARAMS_DOCKER_VERSION to (CallerAutoPilotStatusListenerManager.getDockerVersion() ?: "")
))
linkedLog?.record(mapOf("执行:${System.currentTimeMillis()}" to "$message, $acc"))
CallerAutoPilotControlManager.sendOperatorSetAcceleratedSpeed(acc)
}
@@ -61,7 +147,17 @@ internal class MoFangCommandExecutor {
return@Callback true
}
val isLeft = msg.arg1 == -1
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(EVENT_EXECUTE_SUB_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""), EVENT_EXECUTE_SUB_TYPE to (getInputTypeByWhat(msg.what) ?: "")))
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(
EVENT_EXECUTE_PARAMS_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_TYPE to (getInputTypeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_LON to location.longitude,
EVENT_EXECUTE_PARAMS_LAT to location.latitude,
EVENT_EXECUTE_PARAMS_SPEED to location.gnssSpeed,
EVENT_EXECUTE_PARAMS_ACC to location.acceleration,
EVENT_EXECUTE_PARAMS_HEADING to location.heading,
EVENT_EXECUTE_PARAMS_LINE_ID to CallerAutoPilotStatusListenerManager.getLineId(),
EVENT_EXECUTE_PARAMS_DOCKER_VERSION to (CallerAutoPilotStatusListenerManager.getDockerVersion() ?: "")
))
if (isLeft) {
linkedLog?.record(mapOf("执行:${System.currentTimeMillis()}" to "$message"))
Log.d(TAG, "--- 左变道执行了 ----")
@@ -81,7 +177,17 @@ internal class MoFangCommandExecutor {
val autoPilotStatusInfo = CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo()
val parameters = autoPilotStatusInfo.autopilotControlParameters
val json = GsonUtil.jsonFromObject(parameters)
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(EVENT_EXECUTE_SUB_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""), EVENT_EXECUTE_SUB_TYPE to (getInputTypeByWhat(msg.what) ?: "")))
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(
EVENT_EXECUTE_PARAMS_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_TYPE to (getInputTypeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_LON to location.longitude,
EVENT_EXECUTE_PARAMS_LAT to location.latitude,
EVENT_EXECUTE_PARAMS_SPEED to location.gnssSpeed,
EVENT_EXECUTE_PARAMS_ACC to location.acceleration,
EVENT_EXECUTE_PARAMS_HEADING to location.heading,
EVENT_EXECUTE_PARAMS_LINE_ID to CallerAutoPilotStatusListenerManager.getLineId(),
EVENT_EXECUTE_PARAMS_DOCKER_VERSION to (CallerAutoPilotStatusListenerManager.getDockerVersion() ?: "")
))
linkedLog?.record(mapOf("执行:${System.currentTimeMillis()}" to "$message, $json"))
Log.d(TAG, "--- 启动自驾 ----入参:$json")
//清扫车有FSM模块魔方启动自驾时需要将Source修改为魔方以便telamatics做区分并在转发时增加flag标记
@@ -103,7 +209,17 @@ internal class MoFangCommandExecutor {
if (value != null && value != 0.0) {
send = value != 2.0
Log.d(TAG, "--- 长按鸣笛 ---入参:$value")
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(EVENT_EXECUTE_SUB_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""), EVENT_EXECUTE_SUB_TYPE to (getInputTypeByWhat(msg.what) ?: "")))
MoFangAnalyticUtils.track(EVENT_EXECUTE, mutableMapOf(
EVENT_EXECUTE_PARAMS_KEYCODE to (getKeycodeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_TYPE to (getInputTypeByWhat(msg.what) ?: ""),
EVENT_EXECUTE_PARAMS_LON to location.longitude,
EVENT_EXECUTE_PARAMS_LAT to location.latitude,
EVENT_EXECUTE_PARAMS_SPEED to location.gnssSpeed,
EVENT_EXECUTE_PARAMS_ACC to location.acceleration,
EVENT_EXECUTE_PARAMS_HEADING to location.heading,
EVENT_EXECUTE_PARAMS_LINE_ID to CallerAutoPilotStatusListenerManager.getLineId(),
EVENT_EXECUTE_PARAMS_DOCKER_VERSION to (CallerAutoPilotStatusListenerManager.getDockerVersion() ?: "")
))
linkedLog?.record(mapOf("执行:${System.currentTimeMillis()}" to "$message, $value"))
CallerAutoPilotControlManager.sendOperatorSetHorn(value)
}
@@ -300,4 +416,167 @@ internal class MoFangCommandExecutor {
}
return false
}
private fun reportIPCReceive(node: String?, code: String, message: String?) {
try {
val location = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84()
when (code) {
IMF.HORN_RECEIVE -> {
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_RECEIVE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_CODE] = "E2"
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_MSG] = message ?: ""
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
IMF.LAN_CHANG_RECEIVE -> {
if (message != null && message.contains("$$")) {
val isLeft = message.substringBefore("$$") == "-1"
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_RECEIVE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_CODE] = if (isLeft) "C1" else "D1"
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_MSG] = message
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
}
IMF.SPEED_RESET_RECEIVE -> {
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_RECEIVE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_CODE] = "B1"
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_MSG] = message ?: ""
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
IMF.SPEED_CHANGE_RECEIVE -> {
if (message != null && message.contains("$$")) {
val isSpeedUp = try {
message.substringBefore("$$").toFloat() > 0f
} catch (ignore: Throwable) {
null
}
if (isSpeedUp != null) {
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_RECEIVE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_CODE] = if (isSpeedUp) "AB" else "A1"
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_MSG] = message
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_RECEIVE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
}
}
}
} catch (t: Throwable) {
t.printStackTrace()
}
}
private fun reportIPCExecute(node:String?, code: String, message: String?) {
try {
val location = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84()
when (code) {
IMF.HORN_EXECUTE -> {
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_EXECUTE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_CODE] = "E2"
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_MSG] = message ?: ""
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
IMF.LAN_CHANG_EXECUTE -> {
if (message != null && message.contains("$$")) {
val isLeft = message.substringBefore("$$") == "-1"
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_EXECUTE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_CODE] = if (isLeft) "C1" else "D1"
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_MSG] = message
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
}
IMF.SPEED_RESET_EXECUTE -> {
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_EXECUTE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_CODE] = "B1"
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_MSG] = message ?: ""
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
IMF.SPEED_CHANGE_EXECUTE -> {
if (message != null && message.contains("$$")) {
val isSpeedUp = try {
message.substringBefore("$$").toFloat() > 0f
} catch (ignore: Throwable) {
null
}
if (isSpeedUp != null) {
MogoAnalyticUtils.track(EVENT_EXECUTE_FEEDBACK_EXECUTE, mutableMapOf<String, Any>().also {
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_NODE] = node ?: ""
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_CODE] = if (isSpeedUp) "AB" else "A1"
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_MSG] = message
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LON] = location.longitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LAT] = location.latitude
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_ACC] = location.acceleration
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_SPEED] = location.gnssSpeed
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_HEADING] = location.heading
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_LINE_ID] = CallerAutoPilotStatusListenerManager.getLineId()
it[EVENT_EXECUTE_FEEDBACK_EXECUTE_PARAMS_DOCKER_VERSION] = CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
})
}
}
}
}
} catch (t: Throwable) {
t.printStackTrace()
}
}
}

View File

@@ -14,7 +14,7 @@ internal class MoFangLinkedLog {
}
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_HMI,
linkChainLog = ChainConstant.CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_HMI,
nodeAliasCode = ChainConstant.CHAIN_CODE_MO_FANG_CONNECT,
paramIndexes = [0]

View File

@@ -5,6 +5,7 @@ import android.app.*
import android.bluetooth.*
import android.graphics.*
import android.graphics.drawable.ColorDrawable
import android.os.SystemClock
import android.util.*
import android.view.*
import android.view.Window.Callback
@@ -23,21 +24,22 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
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.mofang.MoFangAnalyticUtils.Companion.EVENT_BATTERY
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_BATTERY_VALUE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_BATTERY_PARAMS_DUR
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_BATTERY_PARAMS_VALUE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_INPUT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_INPUT_SUB_KEYCODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_INPUT_SUB_TYPE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_INPUT_PARAMS_KEYCODE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_INPUT_PARAMS_TYPE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_BLUETOOTH_OPEN_AGREE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_BLUETOOTH_OPEN_DENY
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_BLUETOOTH_SETTING_REQ
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_CONNECT_SUCCESS
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_DISCONNECT_SLEEP
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_DISCONNECT_SUCCESS
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_IS_INVALID
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_IS_VALID
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_START_CONNECT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_SUB_START_DISCONNECT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_OPEN_AGREE
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_OPEN_DENY
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_SETTING_REQ
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_CONNECT_SUCCESS
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_DISCONNECT_SLEEP
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_DISCONNECT_SUCCESS
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_IS_INVALID
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_IS_VALID
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_START_CONNECT
import com.zhjt.mogo_core_function_devatools.mofang.MoFangAnalyticUtils.Companion.EVENT_MOFANG_CONNECT_PARAMS_START_DISCONNECT
import kotlinx.coroutines.*
import me.jessyan.autosize.utils.AutoSizeUtils
import java.util.concurrent.ConcurrentHashMap
@@ -63,6 +65,8 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
private var job: Job? = null
private var batteryTime : Long = -1
override fun enableTest(enable: Boolean) {
isTest.set(enable)
SPUtils.getInstance().put(SP_KEY_TEST_ENABLE, enable)
@@ -85,7 +89,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
}
override fun onBluetoothStartConnect() {
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_START_CONNECT to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_START_CONNECT to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("connect" to "real-start"))
}
@@ -102,7 +106,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
override fun disconnect() {
try {
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_START_DISCONNECT to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_START_DISCONNECT to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("disconnect" to "start"))
MoFangManager.disconnect()
linkedLog.record(mapOf("disconnect" to "success"))
@@ -142,7 +146,13 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
override fun onBluetoothBatteryChanged(battery: Int) {
linkedLog.record(mapOf("callback" to "onBluetoothBatteryChanged:$battery"))
MoFangAnalyticUtils.track(EVENT_BATTERY, mutableMapOf(EVENT_BATTERY_VALUE to "$battery"))
val now = SystemClock.elapsedRealtime()
val dur = if (batteryTime < 0) 0 else (now - batteryTime)
batteryTime = now
MoFangAnalyticUtils.track(EVENT_BATTERY, mutableMapOf(
EVENT_BATTERY_PARAMS_VALUE to "$battery",
EVENT_BATTERY_PARAMS_DUR to dur
))
UiThreadHandler.post {
listeners.values.forEach {
it.onMoFangBatteryChanged(battery)
@@ -157,7 +167,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
} catch (t: Throwable) {
t.printStackTrace()
}
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_CONNECT_SUCCESS to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_CONNECT_SUCCESS to "${System.currentTimeMillis()}"))
UiThreadHandler.post {
listeners.values.forEach {
it.onMoFangConnected()
@@ -172,7 +182,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
} catch (t: Throwable) {
t.printStackTrace()
}
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_DISCONNECT_SUCCESS to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_DISCONNECT_SUCCESS to "${System.currentTimeMillis()}"))
UiThreadHandler.post {
listeners.values.forEach {
it.onMoFangDisconnected()
@@ -186,7 +196,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
showToast("[$keycodesText]")
}
try {
MoFangAnalyticUtils.track(EVENT_INPUT, mutableMapOf(EVENT_INPUT_SUB_KEYCODE to keycodesText, EVENT_INPUT_SUB_TYPE to "3"))
MoFangAnalyticUtils.track(EVENT_INPUT, mutableMapOf(EVENT_INPUT_PARAMS_KEYCODE to keycodesText, EVENT_INPUT_PARAMS_TYPE to "3"))
linkedLog.record(mapOf("command" to "combine_clicked: $keycodesText"))
executor.handleCombineClick(*keyCodes)
} finally {
@@ -202,7 +212,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
showToast("[$key$key]")
}
try {
MoFangAnalyticUtils.track(EVENT_INPUT, mutableMapOf(EVENT_INPUT_SUB_KEYCODE to keyCode.toString(), EVENT_INPUT_SUB_TYPE to "2"))
MoFangAnalyticUtils.track(EVENT_INPUT, mutableMapOf(EVENT_INPUT_PARAMS_KEYCODE to keyCode.toString(), EVENT_INPUT_PARAMS_TYPE to "2"))
linkedLog.record(mapOf("command" to "long_clicked: ${ KeyEvent.keyCodeToString(keyCode) }"))
executor.handleLongClick(keyCode)
} finally {
@@ -220,7 +230,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
showToast("[${keycodeText.replace("KEYCODE_", "", true)}]")
}
try {
MoFangAnalyticUtils.track(EVENT_INPUT, mutableMapOf(EVENT_INPUT_SUB_KEYCODE to keyCode.toString(), EVENT_INPUT_SUB_TYPE to "1"))
MoFangAnalyticUtils.track(EVENT_INPUT, mutableMapOf(EVENT_INPUT_PARAMS_KEYCODE to keyCode.toString(), EVENT_INPUT_PARAMS_TYPE to "1"))
linkedLog.record(mapOf("command" to "clicked: $keycodeText"))
executor.handleSingleClick(keyCode)
} finally {
@@ -269,7 +279,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
override fun onBluetoothKeyboardInputInvalid() {
CallerLogger.d(M_DEVA+TAG, "--- onBluetoothKeyboardInputInvalid ---")
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_IS_INVALID to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_IS_INVALID to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("callback" to "onBluetoothKeyboardInputInvalid"))
UiThreadHandler.post {
listeners.values.forEach {
@@ -280,25 +290,25 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
override fun onBluetoothKeyboardInputValid() {
CallerLogger.d(M_DEVA+TAG, "--- onBluetoothKeyboardInputValid ---")
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_IS_VALID to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_IS_VALID to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("callback" to "onBluetoothKeyboardInputValid"))
}
override fun onBluetoothOpenAgreed() {
CallerLogger.d(M_DEVA+TAG, "--- onBluetoothOpenAgreed ---")
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_BLUETOOTH_OPEN_AGREE to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_OPEN_AGREE to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("callback" to "onBluetoothOpenAgreed"))
}
override fun onBluetoothOpenDenied() {
CallerLogger.d(M_DEVA+TAG, "--- onBluetoothOpenDenied ---")
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_BLUETOOTH_OPEN_DENY to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_OPEN_DENY to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("callback" to "onBluetoothOpenDenied"))
}
override fun onBluetoothSettingRequest() {
CallerLogger.d(M_DEVA+TAG, "--- onBluetoothSettingRequest ---")
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_BLUETOOTH_SETTING_REQ to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_SETTING_REQ to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("callback" to "onBluetoothSettingRequest"))
UiThreadHandler.post {
Toast.makeText(Utils.getApp(), "检测到魔方未正确连接,请在系统蓝牙设置页面,找到魔方并配对连接...", Toast.LENGTH_SHORT).show()
@@ -307,7 +317,7 @@ internal class MoGoMoFangProviderImpl: IMoGoMoFangProvider, OnMoFangDeviceListen
override fun onBluetoothKeyboardAbnormalDisconnected(status: Int) {
CallerLogger.d(M_DEVA+TAG, "--- onBluetoothKeyboardAbnormalDisconnected(status: $status) ---")
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_SUB_DISCONNECT_SLEEP to "${System.currentTimeMillis()}"))
MoFangAnalyticUtils.track(EVENT_MOFANG_CONNECT, mutableMapOf(EVENT_MOFANG_CONNECT_PARAMS_DISCONNECT_SLEEP to "${System.currentTimeMillis()}"))
linkedLog.record(mapOf("callback" to "onBluetoothKeyboardAbnormalDisconnected:$status"))
}
}

View File

@@ -60,8 +60,10 @@ public class RemoteUserServiceImp extends Binder implements IUserInterface {
String _arg0;
_arg0 = data.readString();
String _result = this.exec(_arg0);
reply.writeNoException();
reply.writeString(_result);
if (reply != null) {
reply.writeNoException();
reply.writeString(_result);
}
return true;
default:
return super.onTransact(code, data, reply, flags);

View File

@@ -0,0 +1,116 @@
package com.zhjt.mogo_core_function_devatools.perf
import android.os.Debug
import android.os.Looper
import android.os.SystemClock
import com.mogo.eagle.core.function.api.devatools.perf.IMoGoCpuUsageProvider
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
internal class MoGoCpuUsageProviderImpl: IMoGoCpuUsageProvider {
private var processLaunchTime: Long = 0L
private var mainThreadStartTime : Long = 0L
private var mainThreadCpuUsage: Long = 0L
private val maxSize = 50 // 取top50的线程占用
private val map = LinkedHashMap<String, Long>(0, 0.75f, true)
private val lock = ReentrantLock()
private val builder = ThreadLocal<StringBuilder>()
private val otherThreadLaunchedTime = ThreadLocal<Long>()
private val mainLooper = Looper.getMainLooper()
override fun onProcessLaunched() {
processLaunchTime = SystemClock.elapsedRealtimeNanos()
}
override fun onMainThreadLaunched() {
mainThreadStartTime = Debug.threadCpuTimeNanos()
}
override fun updateMainThreadTime() {
if (Looper.myLooper() != mainLooper) {
return
}
if (mainThreadStartTime > 0) {
val dur = Debug.threadCpuTimeNanos() - mainThreadStartTime
if (dur > 0) {
mainThreadCpuUsage = dur
}
}
}
override fun updateOtherThreadTime() {
val last = otherThreadLaunchedTime.get()
val now = Debug.threadCpuTimeNanos()
var flag = true
try {
if (last == null) {
flag = false
otherThreadLaunchedTime.set(now)
return
}
val duration = now - last
if (duration < 1_000_000) {
//每1毫秒更新线程时间
flag = false
return
}
if (lock.isLocked) {
return
}
var builder = builder.get()
if (builder == null) {
builder = StringBuilder(128)
this.builder.set(builder)
}
if (builder.isNotEmpty()) {
builder.setLength(0)
}
builder.append(Thread.currentThread().name)
val isGetLock = lock.tryLock()
if (!isGetLock) {
return
}
try {
while (map.size >= maxSize) {
val toEvict = map.entries.iterator().next()
map.remove(toEvict.key)
}
val key = builder.toString()
map[key] = map.getOrPut(key) { 0L } + duration
} finally {
lock.unlock()
}
} finally {
if (flag) {
otherThreadLaunchedTime.set(now)
}
}
}
override fun dump(): LinkedHashMap<String, Long> {
return lock.withLock {
if (map.isNotEmpty()) {
val iterator = map.entries.iterator()
val rst = LinkedHashMap<String, Long>()
rst["MainThreadUsage"] = mainThreadCpuUsage
rst["ProcessUsage"] = SystemClock.elapsedRealtimeNanos() - processLaunchTime
while (iterator.hasNext()) {
val next = iterator.next()
rst[next.key] = next.value
}
rst
} else {
LinkedHashMap()
}
}
}
}

View File

@@ -49,7 +49,7 @@ class SceneManager {
//过滤所需条件
sceneModuleTAG.map[ADAS] = SceneModule(true, M_D_C)
sceneModuleTAG.map[DEVA] = SceneModule(true, M_DEVA)
sceneModuleTAG.map[HMI] = SceneModule(false, M_HMI)
sceneModuleTAG.map[HMI] = SceneModule(true, M_HMI)
sceneModuleTAG.map[OBU] = SceneModule(true, M_OBU)
sceneModuleTAG.map[V2X] = SceneModule(true, M_V2X)
sceneModuleTAG.map[MAP] = SceneModule(true, M_MAP)

View File

@@ -51,7 +51,7 @@ object SyncConfig {
}
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_INIT_STATUS,
linkChainLog = ChainConstant.CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_INIT,
nodeAliasCode = ChainConstant.CHAIN_CODE_APP_INFO_CONFIG_UPDATE,
paramIndexes = [0]

View File

@@ -3,7 +3,7 @@ package com.zhjt.mogo_core_function_devatools.trace
import android.content.Context
import android.os.Handler
import android.os.Looper
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.chain.ChainLogParam
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener
@@ -58,7 +58,7 @@ class TraceManager : IMoGoCloudListener, IMoGoAutopilotCarConfigListener {
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
// Trace过程中进行日志抓取对日志进行配置
fwBuildMap[ChainConstant.CHAIN_TYPE_INIT_STATUS] =
fwBuildMap[ChainConstant.CHAIN_TYPE_STATUS] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_INIT)
fwBuildMap[ChainConstant.CHAIN_TYPE_GNSS] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_GNSS)
@@ -72,47 +72,39 @@ class TraceManager : IMoGoCloudListener, IMoGoAutopilotCarConfigListener {
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_VEHICLE)
fwBuildMap[ChainConstant.CHAIN_TYPE_SOCKET_TRAFFIC_LIGHT] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_TRAFFIC_LIGHT)
fwBuildMap[ChainConstant.CHAIN_TYPE_HMI] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_HMI_ACTIONS)
fwBuildMap[ChainConstant.CHAIN_TYPE_ANR_LEAK] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_RECORD_ANR)
fwBuildMap[ChainConstant.CHAIN_TYPE_V2X] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_V2X)
fwBuildMap[ChainConstant.CHAIN_TYPE_HD_MAP] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_HD_MAP_BIZ)
fwBuildMap[ChainConstant.CHAIN_TYPE_WEAK_NETWORK] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_RECORD_WEAK_NETWORK)
fwBuildMap[ChainConstant.CHAIN_TYPE_OCH] =
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_OCH)
traceInfoCache[ChainConstant.CHAIN_TYPE_INIT_STATUS] =
ChainLogParam(true, "INIT状态")
traceInfoCache[ChainConstant.CHAIN_TYPE_STATUS] =
ChainLogParam(true, "BIZ")
traceInfoCache[ChainConstant.CHAIN_TYPE_GNSS] =
ChainLogParam(true, "ADAS自车定位")
traceInfoCache[ChainConstant.CHAIN_TYPE_SOCKET_AUTOPILOT] =
ChainLogParam(true, "ADAS自动驾驶链路(包含: 自动驾驶状态交互,全局路径,到站提醒,节点状态,异常上报,PNC)")
ChainLogParam(true, "ADAS自动驾驶链路(包含: 自动驾驶状态交互,全局路径,到站提醒,节点状态,异常上报,PNC,FM)")
traceInfoCache[ChainConstant.CHAIN_TYPE_SOCKET_DATA_TRACKED] =
ChainLogParam(true, "感知物体")
ChainLogParam(true, "感知物体")
traceInfoCache[ChainConstant.CHAIN_TYPE_SOCKET_TRAJECTORY] =
ChainLogParam(false, "ADAS车前引导线")
traceInfoCache[ChainConstant.CHAIN_TYPE_SOCKET_VEHICLE] =
ChainLogParam(false, "ADAS车辆底盘数据")
traceInfoCache[ChainConstant.CHAIN_TYPE_SOCKET_TRAFFIC_LIGHT] =
ChainLogParam(true, "红绿灯Union数据")
traceInfoCache[ChainConstant.CHAIN_TYPE_HMI] =
ChainLogParam(true, "人机交互行为")
traceInfoCache[ChainConstant.CHAIN_TYPE_ANR_LEAK] =
ChainLogParam(true, "ANR Record")
traceInfoCache[ChainConstant.CHAIN_TYPE_V2X] =
ChainLogParam(true, "V2X(V2N/V2I)")
traceInfoCache[ChainConstant.CHAIN_TYPE_HD_MAP] =
ChainLogParam(true, "HD Map Caller")
traceInfoCache[ChainConstant.CHAIN_TYPE_WEAK_NETWORK] =
ChainLogParam(true, "WeakNetWork Record")
FileWriteManager.getInstance()
.init(context, "", pkgName, fwBuildMap)
.init(context, "", DebugConfig.isDebug(), pkgName, fwBuildMap)
FileWriteManager.getInstance().registerListener { type ->
val param = traceInfoCache[type]
param?.let {
@@ -156,7 +148,7 @@ class TraceManager : IMoGoCloudListener, IMoGoAutopilotCarConfigListener {
fun refreshTraceInfo(map: HashMap<Int, ChainLogParam>) {
map.forEach { (type, param) ->
if (type != ChainConstant.CHAIN_TYPE_INIT_STATUS) {
if (type != ChainConstant.CHAIN_TYPE_STATUS) {
val fwBuild = this.fwBuildMap[type]
fwBuild?.let {
CallerLogger.d("$M_DEVA$TAG", "param : ${param.des} , record : ${param.record}")

View File

@@ -29,7 +29,6 @@ import kotlinx.coroutines.*
import java.io.IOException
import java.util.concurrent.ConcurrentHashMap
//todo emArrow trace
class UpgradeManager : IDownloadListener {
companion object {

View File

@@ -301,7 +301,7 @@ class MoGoUpgradeProviderImpl: IMoGoUpgradeProvider {
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_INIT_STATUS,
linkChainLog = ChainConstant.CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_CLOUD,
nodeAliasCode = ChainConstant.CHAIN_CODE_UPGRADE_APP,
paramIndexes = [0]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -5,5 +5,5 @@
android:endColor="#1B2966"
android:angle="0"
/>
<corners android:radius="40dp" />
<corners android:radius="@dimen/dp_36" />
</shape>

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/rbDataSelect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/sp_34"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
android:layout_margin="@dimen/dp_15"
>
</CheckBox>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<View
android:id="@+id/tvReasonTitleDivider"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toLeftOf="@id/tvReasonTitle"
android:background="#0176FF"
android:layout_margin="@dimen/dp_15"
/>
<TextView
android:id="@+id/tvReasonTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_32"
android:textColor="@color/white"
app:layout_constraintTop_toTopOf="@id/tvReasonTitleDivider"
app:layout_constraintBottom_toBottomOf="@id/tvReasonTitleDivider"
app:layout_constraintStart_toEndOf="@id/tvReasonTitleDivider"
android:layout_marginStart="@dimen/dp_15"
/>
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flReasonLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:alignContent="flex_start"
app:alignItems="center"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="flex_start"
app:layout_constraintTop_toBottomOf="@id/tvReasonTitleDivider"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="@dimen/dp_25"
android:layout_marginStart="@dimen/dp_15"
android:layout_marginEnd="@dimen/dp_15"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -23,7 +23,6 @@
android:textColor="#FFFFFFFF"
android:textSize="46dp"
android:gravity="center"
android:text="1"
/>
<TextView
@@ -33,120 +32,22 @@
app:layout_constraintLeft_toRightOf="@id/tvCollectNum"
app:layout_constraintTop_toTopOf="@id/tvCollectNum"
app:layout_constraintBottom_toBottomOf="@id/tvCollectNum"
android:text="时间14:23:10"
android:textColor="#FFFFFFFF"
android:textSize="38dp"
android:layout_marginStart="@dimen/dp_50"
/>
<RadioButton
android:id="@+id/rbLargeCar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="大型车:大货、大巴、特种车辆"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintLeft_toLeftOf="parent"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvCollectList"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
app:layout_constraintTop_toBottomOf="@id/tvCollectNum"
android:layout_marginStart="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_50"
android:checked="true"
/>
<RadioButton
android:id="@+id/rbTrafficLight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="交通灯:水平、箭头、雨天交通灯"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbLargeCar"
app:layout_constraintLeft_toLeftOf="@id/rbLargeCar"
android:layout_marginTop="@dimen/dp_30"
/>
<RadioButton
android:id="@+id/rbWater"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="积水距离10米内面积大于1平米"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbTrafficLight"
app:layout_constraintLeft_toLeftOf="@id/rbTrafficLight"
android:layout_marginTop="@dimen/dp_30"
/>
<RadioButton
android:id="@+id/rbConstruction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="施工:锥桶、路障"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbWater"
app:layout_constraintLeft_toLeftOf="@id/rbWater"
android:layout_marginTop="@dimen/dp_30"
/>
<RadioButton
android:id="@+id/rbAccident"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="车祸路段:有三角板"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toTopOf="@id/rbConstruction"
app:layout_constraintBottom_toBottomOf="@id/rbConstruction"
app:layout_constraintLeft_toRightOf="@id/rbConstruction"
android:layout_marginStart="@dimen/dp_50"
/>
<RadioButton
android:id="@+id/rbRain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="中雨交通流"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbConstruction"
app:layout_constraintLeft_toLeftOf="@id/rbConstruction"
android:layout_marginTop="@dimen/dp_30"
/>
<RadioButton
android:id="@+id/rbNightTraffic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="夜间交通流"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbAccident"
app:layout_constraintLeft_toLeftOf="@id/rbAccident"
android:layout_marginTop="@dimen/dp_30"
app:layout_constraintBottom_toTopOf="@id/tvCollectReport"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:layout_margin="@dimen/dp_25"
/>
<TextView

View File

@@ -2,26 +2,26 @@
<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="924dp"
android:layout_height="668dp"
app:roundLayoutRadius="40dp"
android:layout_width="@dimen/dp_859"
android:layout_height="@dimen/dp_850"
app:roundLayoutRadius="@dimen/dp_36"
android:background="#1B2966">
<View
android:layout_width="match_parent"
android:layout_height="113dp"
android:layout_height="@dimen/dp_102"
android:background="@drawable/ai_collect_title_bg"
/>
<TextView
android:id="@+id/tvInitiativeNum"
android:layout_width="120dp"
android:layout_height="113dp"
android:layout_width="@dimen/dp_108"
android:layout_height="@dimen/dp_102"
android:background="@drawable/icon_num_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:textColor="#FFFFFFFF"
android:textSize="46dp"
android:textSize="@dimen/sp_42"
android:gravity="center"
android:text="1"
/>
@@ -33,9 +33,8 @@
app:layout_constraintLeft_toRightOf="@id/tvInitiativeNum"
app:layout_constraintTop_toTopOf="@id/tvInitiativeNum"
app:layout_constraintBottom_toBottomOf="@id/tvInitiativeNum"
android:text="时间14:23:10"
android:textColor="#FFFFFFFF"
android:textSize="38dp"
android:textSize="@dimen/sp_34"
android:layout_marginStart="@dimen/dp_50"
/>
@@ -46,131 +45,49 @@
app:layout_constraintTop_toTopOf="@id/tvInitiativeNum"
app:layout_constraintBottom_toBottomOf="@id/tvInitiativeNum"
app:layout_constraintRight_toRightOf="parent"
android:text="身份QA"
android:textColor="#FFFFFFFF"
android:textSize="38dp"
android:textSize="@dimen/sp_34"
android:layout_marginEnd="@dimen/dp_50"
/>
<CheckBox
android:id="@+id/rbOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="严重画龙"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_10"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvInitiativeList"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvInitiativeNum"
android:layout_marginStart="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_40"
/>
<CheckBox
android:id="@+id/rbTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="速度过慢"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_10"
app:layout_constraintTop_toBottomOf="@id/tvInitiativeNum"
app:layout_constraintLeft_toRightOf="@id/rbOne"
android:layout_marginStart="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_40"
/>
<CheckBox
android:id="@+id/rbThree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="感知、定位、地图等其他"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/tvInitiativeNum"
app:layout_constraintLeft_toRightOf="@id/rbTwo"
android:layout_marginStart="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_40"
/>
<CheckBox
android:id="@+id/rbFour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="速度过快"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_10"
app:layout_constraintTop_toBottomOf="@id/rbOne"
app:layout_constraintLeft_toLeftOf="@id/rbOne"
android:layout_marginTop="@dimen/dp_40"
/>
<CheckBox
android:id="@+id/rbFive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="存在碰撞风险"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbTwo"
app:layout_constraintLeft_toLeftOf="@id/rbTwo"
android:layout_marginTop="@dimen/dp_40"
/>
<CheckBox
android:id="@+id/rbSix"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点刹、顿挫"
android:textColor="#FFFFFFFF"
android:textSize="34dp"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbOne"
app:layout_constraintLeft_toRightOf="@id/rbFive"
android:layout_marginTop="@dimen/dp_40"
android:layout_marginStart="@dimen/dp_30"
app:layout_constraintBottom_toTopOf="@id/viewAudioBg"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:layout_margin="@dimen/dp_20"
/>
<TextView
android:id="@+id/tvInitiativeReport"
android:layout_width="270dp"
android:layout_height="70dp"
android:layout_width="@dimen/dp_370"
android:layout_height="@dimen/dp_80"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/tvInitiativeCancel"
android:background="@drawable/report_button_bg"
android:text="上报"
android:textColor="#FFFFFF"
android:textSize="30dp"
android:textSize="@dimen/dp_27"
android:gravity="center"
android:layout_marginBottom="@dimen/dp_40"
/>
<TextView
android:id="@+id/tvInitiativeCancel"
android:layout_width="270dp"
android:layout_height="70dp"
android:layout_width="@dimen/dp_370"
android:layout_height="@dimen/dp_80"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@id/tvInitiativeReport"
android:text="取消"
android:textColor="#FFFFFF"
android:textSize="30dp"
android:textSize="@dimen/dp_27"
android:gravity="center"
android:background="@drawable/icon_cancel_bg"
android:layout_marginBottom="@dimen/dp_40"
@@ -178,8 +95,8 @@
<ImageView
android:id="@+id/viewAudioBg"
android:layout_width="824dp"
android:layout_height="174dp"
android:layout_width="@dimen/dp_768"
android:layout_height="@dimen/dp_122"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvInitiativeReport"
@@ -189,8 +106,8 @@
<ImageView
android:id="@+id/viewAudioButton"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_width="@dimen/dp_34"
android:layout_height="@dimen/dp_48"
app:layout_constraintLeft_toLeftOf="@id/viewAudioBg"
app:layout_constraintRight_toRightOf="@id/viewAudioBg"
app:layout_constraintTop_toTopOf="@id/viewAudioBg"
@@ -203,7 +120,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="30dp"
android:textSize="@dimen/dp_27"
app:layout_constraintTop_toTopOf="@id/viewAudioButton"
app:layout_constraintBottom_toBottomOf="@id/viewAudioButton"
app:layout_constraintLeft_toRightOf="@id/viewAudioButton"

View File

@@ -2,26 +2,26 @@
<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="924dp"
android:layout_height="668dp"
app:roundLayoutRadius="40dp"
android:layout_width="@dimen/dp_859"
android:layout_height="@dimen/dp_850"
app:roundLayoutRadius="@dimen/dp_36"
android:background="#1B2966">
<View
android:layout_width="match_parent"
android:layout_height="113dp"
android:layout_height="@dimen/dp_102"
android:background="@drawable/ai_collect_title_bg"
/>
<TextView
android:id="@+id/tvPassiveNum"
android:layout_width="120dp"
android:layout_height="113dp"
android:layout_width="@dimen/dp_108"
android:layout_height="@dimen/dp_102"
android:background="@drawable/icon_num_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:textColor="#FFFFFFFF"
android:textSize="46dp"
android:textSize="@dimen/sp_42"
android:gravity="center"
android:text="1"
/>
@@ -33,9 +33,8 @@
app:layout_constraintLeft_toRightOf="@id/tvPassiveNum"
app:layout_constraintTop_toTopOf="@id/tvPassiveNum"
app:layout_constraintBottom_toBottomOf="@id/tvPassiveNum"
android:text="时间14:23:10"
android:textColor="#FFFFFFFF"
android:textSize="38dp"
android:textSize="@dimen/sp_34"
android:layout_marginStart="@dimen/dp_50"
/>
@@ -46,37 +45,49 @@
app:layout_constraintTop_toTopOf="@id/tvPassiveNum"
app:layout_constraintBottom_toBottomOf="@id/tvPassiveNum"
app:layout_constraintRight_toRightOf="parent"
android:text="身份QA"
android:textColor="#FFFFFFFF"
android:textSize="38dp"
android:textSize="@dimen/sp_34"
android:layout_marginEnd="@dimen/dp_50"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvPassiveList"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvPassiveNum"
app:layout_constraintBottom_toTopOf="@id/viewAudioBg"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:layout_margin="@dimen/dp_20"
/>
<TextView
android:id="@+id/tvPassiveReport"
android:layout_width="270dp"
android:layout_height="70dp"
android:layout_width="@dimen/dp_370"
android:layout_height="@dimen/dp_80"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/tvPassiveCancel"
android:background="@drawable/report_button_bg"
android:text="上报"
android:textColor="#FFFFFF"
android:textSize="30dp"
android:textSize="@dimen/dp_27"
android:gravity="center"
android:layout_marginBottom="@dimen/dp_40"
/>
<TextView
android:id="@+id/tvPassiveCancel"
android:layout_width="270dp"
android:layout_height="70dp"
android:layout_width="@dimen/dp_370"
android:layout_height="@dimen/dp_80"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@id/tvPassiveReport"
android:text="取消"
android:textColor="#FFFFFF"
android:textSize="30dp"
android:textSize="@dimen/dp_27"
android:gravity="center"
android:background="@drawable/icon_cancel_bg"
android:layout_marginBottom="@dimen/dp_40"
@@ -84,8 +95,8 @@
<ImageView
android:id="@+id/viewAudioBg"
android:layout_width="824dp"
android:layout_height="174dp"
android:layout_width="@dimen/dp_768"
android:layout_height="@dimen/dp_122"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvPassiveReport"
@@ -95,8 +106,8 @@
<ImageView
android:id="@+id/viewAudioButton"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_width="@dimen/dp_34"
android:layout_height="@dimen/dp_48"
app:layout_constraintLeft_toLeftOf="@id/viewAudioBg"
app:layout_constraintRight_toRightOf="@id/viewAudioBg"
app:layout_constraintTop_toTopOf="@id/viewAudioBg"
@@ -109,35 +120,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="30dp"
android:textSize="@dimen/dp_27"
app:layout_constraintTop_toTopOf="@id/viewAudioButton"
app:layout_constraintBottom_toBottomOf="@id/viewAudioButton"
app:layout_constraintLeft_toRightOf="@id/viewAudioButton"
android:layout_marginStart="@dimen/dp_30"
/>
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvPassiveNum"
app:layout_constraintBottom_toTopOf="@id/viewAudioBg"
android:layout_margin="@dimen/dp_30"
>
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flReasonLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:alignContent="flex_start"
app:alignItems="center"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="flex_start"
/>
</ScrollView>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -75,6 +75,8 @@ dependencies {
implementation rootProject.ext.dependencies.koomjava
implementation rootProject.ext.dependencies.koomnative
implementation rootProject.ext.dependencies.koomxhook
implementation rootProject.ext.dependencies.thread_opt
api project(':test:crashreport-apmbyte')
compileOnly project(':core:function-impl:mogo-core-function-datacenter')
implementation project(':foudations:mogo-commons')

View File

@@ -54,14 +54,13 @@
-->
<activity
android:name="com.mogo.eagle.core.function.main.MainLauncherActivity"
android:clearTaskOnLaunch="${ACTIVITY_ROOT}"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"
android:enabled="true"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:resizeableActivity="false"
android:screenOrientation="landscape"
android:resumeWhilePausing="true"
android:screenOrientation="${SCREEN_ORIENTATION}"
android:stateNotNeeded="true"
android:theme="@style/Main"
android:windowSoftInputMode="adjustPan|stateHidden">
@@ -97,21 +96,6 @@
</activity>
<!-- <activity-->
<!-- android:name="com.mogo.eagle.core.function.main.VideoAdAtc"-->
<!-- android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize"-->
<!-- android:enabled="true"-->
<!-- android:exported="true"-->
<!-- android:process=":video_ad"-->
<!-- android:resizeableActivity="false"-->
<!-- android:resumeWhilePausing="true"-->
<!-- android:screenOrientation="landscape"-->
<!-- android:stateNotNeeded="true"-->
<!-- android:theme="@style/Main"-->
<!-- android:windowSoftInputMode="adjustPan|stateHidden">-->
<!-- </activity>-->
<activity
android:name="com.mogo.eagle.core.function.main.AppListActivity"
android:exported="true"
@@ -122,10 +106,6 @@
<!-- </intent-filter>-->
</activity>
<meta-data
android:name="MAP_SDK_VERSION111111"
android:value="${MAP_SDK_VERSION}" />
<receiver android:name="com.mogo.eagle.core.function.hmi.receiver.V2XWarningBroadcastReceiver">
<intent-filter>
<action android:name="com.hmi.v2x.notification" />

View File

@@ -3,11 +3,12 @@ package com.mogo.eagle.core.function.hmi.notification.anim
import android.animation.Animator
import android.animation.ValueAnimator
import android.graphics.Rect
import android.util.Log
import android.view.View
import android.view.WindowManager
import com.mogo.eagle.core.data.enums.SidePattern
import com.mogo.eagle.core.function.hmi.notification.interfaces.OnFloatAnimator
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.util.BarUtils
import kotlin.math.min
@@ -52,7 +53,7 @@ open class DefaultAnimator : OnFloatAnimator {
windowManager.updateViewLayout(view, params)
} catch (e: Exception) {
cancel()
Log.i("DebugViewSwitchLog", "执行动画异常,异常原因:"+e)
CallerLogger.i(M_HMI + "DebugViewSwitchLog", "执行动画异常,异常原因:$e")
}
}
}

View File

@@ -3,12 +3,9 @@ package com.mogo.eagle.core.function.hmi.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.biz.notice.NoticeNormalData
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.utilcode.util.SharedPrefs
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr
/**
* 用于普通云公告的测试
@@ -24,23 +21,25 @@ class NoticeNormalBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
try {
// 分发场景
dispatchShowWaring("11", "官方公告", "测试普通云公告普通云公告普通云公告普通云公告普通云公告普通云公告普通云公告哈哈哈哈哈哈好好",
"https://dataservice-1255510688.cos.ap-beijing.myqcloud.com/carImg/yycp_NoticeDETAIL_location.png",
"https://vd2.bdstatic.com/mda-mk1347dzxdmcre0y/sc/cae_h264/1635819498112313003/mda-mk1347dzxdmcre0y.mp4?v_from_s=hkapp-haokan-tucheng&auth_key=1635837585-0-0-5295f6658c7711ba7b4d3ef478a7fbaa&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest=",
2)
SharedPrefs.getInstance(context).putInt("videoType", 1)
dispatchShowWaring(
"11", "官方公告", "测试普通云公告普通云公告普通云公告普通云公告普通云公告普通云公告普通云公告哈哈哈哈哈哈好好",
"https://dataservice-1255510688.cos.ap-beijing.myqcloud.com/carImg/yycp_NoticeDETAIL_location.png",
"https://vd2.bdstatic.com/mda-mk1347dzxdmcre0y/sc/cae_h264/1635819498112313003/mda-mk1347dzxdmcre0y.mp4?v_from_s=hkapp-haokan-tucheng&auth_key=1635837585-0-0-5295f6658c7711ba7b4d3ef478a7fbaa&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest=",
2
)
SharedPrefsMgr.getInstance(context).putInt("videoType", 1)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun dispatchShowWaring(
id: String,
titleTv: String,
contentTv: String,
imageUrl: String,
videoUrl: String,
fileType: Int
id: String,
titleTv: String,
contentTv: String,
imageUrl: String,
videoUrl: String,
fileType: Int
) {
val data = NoticeNormalData()

View File

@@ -2,13 +2,11 @@ package com.mogo.eagle.core.function.hmi.ui
import android.content.Context
import android.text.TextUtils
import android.util.*
import android.view.*
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.commons.voice.AIAssist
import com.mogo.commons.voice.IMogoVoiceCmdCallBack
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_FRAGMENT_HMI
@@ -39,7 +37,6 @@ import com.mogo.eagle.core.function.hmi.ui.tools.ModifyBindingCarDialog
import com.mogo.eagle.core.function.hmi.ui.tools.ToBindingCarDialog
import com.mogo.eagle.core.function.hmi.ui.tools.UpgradeAppDialog
import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog
import com.mogo.eagle.core.function.hmi.ui.vehicle.TurnLightViewStatus
import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView
import com.mogo.eagle.core.utilcode.floating.*
import com.mogo.eagle.core.utilcode.kotlin.safeCancel
@@ -47,9 +44,10 @@ 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_HMI
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.tts.base.IMogoTTSCallback
import com.zhjt.service_biz.BizConfig
import kotlinx.coroutines.*
import kotlinx.coroutines.selects.*
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
/**
@@ -64,7 +62,6 @@ class MoGoHmiProvider : IMoGoHmiProvider {
private const val TAG = "MoGoHmiProvider"
}
private val lastSpeakJob by lazy { AtomicReference<Job>() }
private var lastShowV2XJob: Job? = null
private var context: Context? = null
@@ -73,7 +70,8 @@ class MoGoHmiProvider : IMoGoHmiProvider {
*/
private val lookAround by lazy { AtomicReference<MoGoPopWindow>() }
private val scope by lazy { CoroutineScope(Dispatchers.Default + SupervisorJob()) }
private val isPlayingTts by lazy { AtomicBoolean(false) }
override fun init(context: Context?) {
this.context = context
@@ -145,66 +143,27 @@ class MoGoHmiProvider : IMoGoHmiProvider {
}.invokeOnCompletion {
listener?.onDismiss()
}
Log.d("CODE", "---- 00 ------ tts_content: $ttsContent")
if (ttsContent != null && !TextUtils.isEmpty(ttsContent) && playTTS) {
val last = lastSpeakJob.get()
Log.d("CODE", "---- 0 ------: last: $last")
if (last != null && !last.isCompleted) {
Log.d("CODE", "---- 1 ------")
return
}
scope.launch {
Log.d("CODE", "---- 2 ------")
val d1 = async {
Log.d("CODE", "---- 2_1 start ------")
speak(it, ttsContent)
Log.d("CODE", "---- 2_1 end ------")
}
val d2 = async {
Log.d("CODE", "---- 2_2 start ------")
delay((305.75 * ttsContent.length).toLong())
Log.d("CODE", "---- 2_2 end ------")
}
val ret = select<Int> {
d1.onAwait { 1 }
d2.onAwait { 2 }
}
if (ret == 1) {
d2.cancel()
Log.d("CODE", "---- 3 ------")
} else {
d1.cancel()
Log.d("CODE", "---- 4 ------")
}
}.also { itx ->
lastSpeakJob.set(itx)
if (!isPlayingTts.get() && ttsContent != null && !TextUtils.isEmpty(ttsContent) && playTTS) {
context?.also {
AIAssist.getInstance(it).speakTTSVoiceWithLevel(ttsContent, AIAssist.LEVEL2, object : IMogoTTSCallback {
override fun onSpeakEnd(speakText: String?) {
super.onSpeakEnd(speakText)
isPlayingTts.set(false)
}
override fun onSpeakError(speakText: String?, errorMsg: String?) {
super.onSpeakError(speakText, errorMsg)
isPlayingTts.set(false)
}
})
isPlayingTts.set(true)
}
}
}
}
private suspend fun speak(ctx: Context, text: String) = suspendCancellableCoroutine<Unit> {
try {
val voiceCallback = object : IMogoVoiceCmdCallBack {
override fun onSpeakEnd(speakText: String?) {
super.onSpeakEnd(speakText)
it.resumeWith(Result.success(Unit))
}
override fun onSpeakError(speakText: String?, errorMsg: String?) {
super.onSpeakError(speakText, errorMsg)
it.resumeWith(Result.success(Unit))
}
}
it.invokeOnCancellation {
AIAssist.getInstance(ctx).stopSpeakTts(text)
}
AIAssist.getInstance(ctx).speakTTSVoiceWithLevel(text, AIAssist.LEVEL2, voiceCallback)
} catch (t: Throwable) {
it.resumeWith(Result.success(Unit))
CallerLogger.w("$M_HMI$TAG", t.message)
}
}
override fun showWarning(v2xType: String, direction: WarningDirectionEnum, expireTime: Long) {
//CallerV2XWarningListenerManager.show(v2xType, direction, expireTime)

View File

@@ -249,11 +249,7 @@ public class LogItemAdapter extends AbsRecyclerAdapter<AbsViewBinder<LogLine>, L
protected void publishResults(CharSequence constraint, FilterResults results) {
//noinspection unchecked
mList = (List<LogLine>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetChanged();
}
notifyDataSetChanged();
}
}
}

View File

@@ -25,6 +25,7 @@ public class LogLine {
"\\): ");
private static final String filterPattern = "ResourceType|memtrack|android.os.Debug|BufferItemConsumer|DPM.*|MDM.*|ChimeraUtils|BatteryExternalStats.*|chatty.*|DisplayPowerController|WidgetHelper|WearableService|DigitalWidget.*|^ANDR-PERF-.*";
private static final String failPattern = "(^maxLineHeight.*)|(Failed to read.*)";
private int logLevel;
private String tag;
private String logOutput;
@@ -57,7 +58,7 @@ public class LogLine {
char logLevelChar = matcher.group(1).charAt(0);
String logText = originalLine.substring(matcher.end());
if (logText.matches("^maxLineHeight.*|Failed to read.*")) {
if (logText.matches(failPattern)) {
logLine.setLogLevel(convertCharToLogLevel('V'));
} else {
logLine.setLogLevel(convertCharToLogLevel(logLevelChar));

View File

@@ -95,7 +95,6 @@ class M1LookAroundView: SurfaceView, SurfaceHolder.Callback, Runnable, IMoGoChas
handler.set(HandlerThread("look-around-drawer").let { it.start(); Handler(it.looper) })
}
handler.get()?.removeCallbacks(this)
handler.get()?.post(this)
isSurfaceValid = true
}
@@ -109,187 +108,171 @@ class M1LookAroundView: SurfaceView, SurfaceHolder.Callback, Runnable, IMoGoChas
}
override fun run() {
var isTimedBlock = false
if (!isSurfaceValid) {
return
}
if (this.surfaceWidth <= 0 || this.surfaceHeight <= 0) {
return
}
val data = this.data ?: return
val targetX = data.targetX
val targetY = data.targetY
val targetWidth = data.targetWidth
val targetHeight = data.targetHeight
val bitmapWidth = data.bitmapWidth
val bitmapHeight = data.bitmapHeight
val scaleX = this.surfaceWidth * 1.0f / bitmapWidth
val scaleY = this.surfaceHeight * 1.0f / bitmapHeight
val bytes = data.data ?: return
val canvas = holder.lockCanvas()
try {
if (!isSurfaceValid) {
isTimedBlock = true
if (canvas == null) {
return
}
if (this.surfaceWidth <= 0 || this.surfaceHeight <= 0) {
isTimedBlock = true
return
}
val data = this.data ?: return
val targetX = data.targetX
val targetY = data.targetY
val targetWidth = data.targetWidth
val targetHeight = data.targetHeight
val bitmapWidth = data.bitmapWidth
val bitmapHeight = data.bitmapHeight
val scaleX = this.surfaceWidth * 1.0f / bitmapWidth
val scaleY = this.surfaceHeight * 1.0f / bitmapHeight
val bytes = data.data
if (bytes == null) {
isTimedBlock = true
return
}
val canvas = holder.lockCanvas()
//1. 绘制图片
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) ?: return
try {
if (canvas == null) {
isTimedBlock = true
return
canvas.save()
canvas.scale(scaleX, scaleY)
canvas.drawBitmap(bitmap, 0f, 0f, bitmapPaint)
} finally {
canvas.restore()
if (!bitmap.isRecycled) {
bitmap.recycle()
}
//1. 绘制图片
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
if (bitmap == null) {
isTimedBlock = true
return
}
//2. 绘制车的信息
val newTargetX = targetX * scaleX
val newTargetY = targetY * scaleY
val newTargetWidth = targetWidth * scaleX
val newTargetHeight = targetHeight * scaleY
try {
//2.1 绘制车前的转向角
canvas.save()
var steering = this.steering
if (abs(steering) < 1) {
steering = 0f
}
try {
canvas.save()
canvas.scale(scaleX, scaleY)
canvas.drawBitmap(bitmap, 0f, 0f, bitmapPaint)
} finally {
canvas.restore()
if (!bitmap.isRecycled) {
bitmap.recycle()
}
}
//2. 绘制车的信息
val newTargetX = targetX * scaleX
val newTargetY = targetY * scaleY
val newTargetWidth = targetWidth * scaleX
val newTargetHeight = targetHeight * scaleY
try {
//2.1 绘制车前的转向角
canvas.save()
var steering = this.steering
if (abs(steering) < 1) {
steering = 0f
}
if (steering == 0f) {
canvas.translate(newTargetX + newTargetWidth * 0.5f, newTargetY)
routerPath.reset()
val halfX = newTargetWidth * 0.5f
var startX = - halfX
val startY= 0f
routerPath.moveTo(startX, startY)
var endX = startX
val endY = - newTargetY
routerPath.lineTo(endX, endY)
canvas.drawPath(routerPath, routerPaint)
startX += newTargetWidth
endX += newTargetWidth
routerPath.reset()
routerPath.moveTo(startX, startY)
routerPath.lineTo(endX, endY)
canvas.drawPath(routerPath, routerPaint)
} else {
val outerAngle = abs(steering * 1.0 / VEHICLE_STEERING_RATIO)
val radians = Math.toRadians(outerAngle)
val d = (newTargetHeight / tan(radians)).toFloat()
if (steering > 0) {
// 左打轮
// 将坐标原点平移到圆心
canvas.translate(newTargetX - (d - newTargetWidth), newTargetY + newTargetHeight)
//外圆半径
val outerR = (newTargetHeight / sin(radians)).toFloat()
//内圆半径
val innerR = sqrt((newTargetHeight * 1.0).pow(2.0) + ((d - newTargetWidth) * 1.0).pow(2.0)).toFloat()
val innerAngle = Math.toDegrees(asin(newTargetHeight / innerR) * 1.0)
outerRect.set(-outerR, -outerR, outerR, outerR)
innerRect.set(-innerR, -innerR, innerR, innerR)
canvas.drawArc(outerRect, -outerAngle.toFloat(), -60f, false, routerPaint)
canvas.drawArc(innerRect, -innerAngle.toFloat(), -60f, false, routerPaint)
}
if (steering < 0) {
//右打轮
// 将坐标原点平移到圆心
canvas.translate(newTargetX + d, newTargetY + newTargetHeight)
//外圆半径
val outerR = (newTargetHeight / sin(radians)).toFloat()
//内圆半径
val innerR = sqrt((newTargetHeight * 1.0).pow(2.0) + ((d - newTargetWidth) * 1.0).pow(2.0)).toFloat()
val innerAngle = Math.toDegrees(asin(newTargetHeight / innerR) * 1.0)
outerRect.set(-outerR, -outerR, outerR, outerR)
innerRect.set(-innerR, -innerR, innerR, innerR)
canvas.drawArc(outerRect, 180f + outerAngle.toFloat(), 60f, false, routerPaint)
canvas.drawArc(innerRect, 180f + innerAngle.toFloat(), 60f, false, routerPaint)
}
}
} finally {
canvas.restore()
}
try {
//2.2 绘制车周围盲区标定
canvas.save()
if (steering == 0f) {
canvas.translate(newTargetX + newTargetWidth * 0.5f, newTargetY)
val halfTargetWidth = newTargetWidth * 0.5f
var startX = -halfTargetWidth
var startY = BROKE_LINE_LENGTH
routerPath.reset()
val halfX = newTargetWidth * 0.5f
var startX = - halfX
val startY= 0f
routerPath.moveTo(startX, startY)
var endX = startX
var endY = 0f
// 绘制左上角
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endX += BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
val endY = - newTargetY
routerPath.lineTo(endX, endY)
canvas.drawPath(routerPath, routerPaint)
startX += newTargetWidth
endX += newTargetWidth
routerPath.reset()
routerPath.moveTo(startX, startY)
routerPath.lineTo(endX, endY)
canvas.drawPath(routerPath, routerPaint)
} else {
val outerAngle = abs(steering * 1.0 / VEHICLE_STEERING_RATIO)
val radians = Math.toRadians(outerAngle)
val d = (newTargetHeight / tan(radians)).toFloat()
if (steering > 0) {
// 左打轮
// 将坐标原点平移到圆心
canvas.translate(newTargetX - (d - newTargetWidth), newTargetY + newTargetHeight)
//外圆半径
val outerR = (newTargetHeight / sin(radians)).toFloat()
//内圆半径
val innerR = sqrt((newTargetHeight * 1.0).pow(2.0) + ((d - newTargetWidth) * 1.0).pow(2.0)).toFloat()
val innerAngle = Math.toDegrees(asin(newTargetHeight / innerR) * 1.0)
outerRect.set(-outerR, -outerR, outerR, outerR)
innerRect.set(-innerR, -innerR, innerR, innerR)
canvas.drawArc(outerRect, -outerAngle.toFloat(), -60f, false, routerPaint)
canvas.drawArc(innerRect, -innerAngle.toFloat(), -60f, false, routerPaint)
}
// 绘制右上角
startX = halfTargetWidth - BROKE_LINE_LENGTH
startY = 0f
endX = halfTargetWidth
endY = 0f
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endY += BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
//绘制左下角
startX = -halfTargetWidth
startY = newTargetHeight - BROKE_LINE_LENGTH
endX = startX
endY = newTargetHeight
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endX += BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
//绘制右下角
startX = halfTargetWidth - BROKE_LINE_LENGTH
startY = newTargetHeight
endX = halfTargetWidth
endY = startY
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endY -= BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
} finally {
canvas.restore()
if (steering < 0) {
//右打轮
// 将坐标原点平移到圆心
canvas.translate(newTargetX + d, newTargetY + newTargetHeight)
//外圆半径
val outerR = (newTargetHeight / sin(radians)).toFloat()
//内圆半径
val innerR = sqrt((newTargetHeight * 1.0).pow(2.0) + ((d - newTargetWidth) * 1.0).pow(2.0)).toFloat()
val innerAngle = Math.toDegrees(asin(newTargetHeight / innerR) * 1.0)
outerRect.set(-outerR, -outerR, outerR, outerR)
innerRect.set(-innerR, -innerR, innerR, innerR)
canvas.drawArc(outerRect, 180f + outerAngle.toFloat(), 60f, false, routerPaint)
canvas.drawArc(innerRect, 180f + innerAngle.toFloat(), 60f, false, routerPaint)
}
}
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas)
}
canvas.restore()
}
try {
//2.2 绘制车周围盲区标定
canvas.save()
canvas.translate(newTargetX + newTargetWidth * 0.5f, newTargetY)
val halfTargetWidth = newTargetWidth * 0.5f
var startX = -halfTargetWidth
var startY = BROKE_LINE_LENGTH
var endX = startX
var endY = 0f
// 绘制左上角
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endX += BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
// 绘制右上角
startX = halfTargetWidth - BROKE_LINE_LENGTH
startY = 0f
endX = halfTargetWidth
endY = 0f
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endY += BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
//绘制左下角
startX = -halfTargetWidth
startY = newTargetHeight - BROKE_LINE_LENGTH
endX = startX
endY = newTargetHeight
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endX += BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
//绘制右下角
startX = halfTargetWidth - BROKE_LINE_LENGTH
startY = newTargetHeight
endX = halfTargetWidth
endY = startY
brokePath.reset()
brokePath.moveTo(startX, startY)
brokePath.lineTo(endX, endY)
endY -= BROKE_LINE_LENGTH
brokePath.lineTo(endX, endY)
canvas.drawPath(brokePath, brokePaint)
} finally {
canvas.restore()
}
} finally {
if (isTimedBlock) {
try {
Thread.sleep(2000)
} catch (ignore: Exception) { }
try {
if (canvas != null && holder.surface.isValid) {
holder.unlockCanvasAndPost(canvas)
}
isSurfaceValid = holder.surface.isValid
} catch (t: Throwable) {
t.printStackTrace()
}
handler.get().post(this)
}
}
@@ -304,6 +287,8 @@ class M1LookAroundView: SurfaceView, SurfaceHolder.Callback, Runnable, IMoGoChas
Log.d(TAG, "-- onEach ---:$it")
if (it.isValid()) {
data = it
handler.get()?.removeCallbacks(this@M1LookAroundView)
handler.get()?.post(this@M1LookAroundView)
}
}.collect()
}

View File

@@ -9,6 +9,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.msgbox.FMInfoMsg
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxCountDownBean
import com.mogo.eagle.core.data.msgbox.MsgCategory
@@ -21,6 +22,7 @@ import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.msgbox.adapter.DriverMsgBoxBubbleAdapter
import com.mogo.eagle.core.function.msgbox.MsgBoxConfig
import com.mogo.eagle.core.utilcode.util.SoundPoolUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import kotlinx.android.synthetic.main.layout_driver_msg_box_bubble.view.*
@@ -96,6 +98,23 @@ class DriverMsgBoxBubbleView @JvmOverloads constructor(
} else if(category == MsgCategory.SYS_INFO){
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
//todo 过滤MAP系统异常报警
} else if(category == MsgCategory.FM_INFO){
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
//属于停车警示(包括择机靠边停车、立即舒适停车、就地紧急停车)时,需要弹出消息气泡并伴有提示音
val fmInfoMsg = msgBoxBean.bean as FMInfoMsg
if(fmInfoMsg.policyCode == "FM_DP_PNC_CHOOSE_STOP" //择机靠边停车
|| fmInfoMsg.policyCode == "FM_DP_COMFORTABLE_STOP" //立刻舒适停车
|| fmInfoMsg.policyCode == "FM_DP_EMERGENCY_STOP" //就地紧急停车
){
//语音提示
try {
SoundPoolUtils.getSoundPool().playSoundWithRedId(context,R.raw.weak_net_tips)
}catch (e: Exception){
e.printStackTrace()
}
//展示消息
showData(msgBoxBean)
}
} else{
if(msgBoxBean.sourceType == DataSourceType.SUMMARY){
//在一次订单中汇总消息只展示一次

View File

@@ -45,9 +45,10 @@ class DriverMsgBoxListView @JvmOverloads constructor(
initView()
}
private val TAG = "DriverMsgBoxListView"
private var noticeList: ArrayList<MsgBoxBean> ?= null
private var ipcReportList: ArrayList<MsgBoxBean> ?= null
private var badCaseList: ArrayList<MsgBoxBean> ?= null
private var noticeList: ArrayList<MsgBoxBean> ?= null //通知消息列表
private var fmList: ArrayList<MsgBoxBean> ?= ArrayList() //FM信息消息列表
private var ipcReportList: ArrayList<MsgBoxBean> ?= null //车辆系统信息消息列表
private var badCaseList: ArrayList<MsgBoxBean> ?= null//录包消息列表
private var driverMsgBoxListAdapter: DriverMsgBoxListAdapter ?=null
private var linearLayoutManager: LinearLayoutManager ?= null
@@ -71,9 +72,11 @@ class DriverMsgBoxListView @JvmOverloads constructor(
//通知
tvMsgNotice.setOnClickListener {
tvMsgNotice.setTextColor(resources.getColor(R.color.msg_box_title_color))
tvMsgFm.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgBadCase.setTextColor(resources.getColor(R.color.color_FFFFFF))
viewNoticeDivider.visibility = View.VISIBLE
viewFmDivider.visibility = View.GONE
viewIpcReportDivider.visibility = View.GONE
viewBadCaseDivider.visibility = View.GONE
MsgBoxConfig.setUserRecord(0)
@@ -86,15 +89,36 @@ class DriverMsgBoxListView @JvmOverloads constructor(
}
}
//FM信息
tvMsgFm.setOnClickListener {
tvMsgNotice.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgFm.setTextColor(resources.getColor(R.color.msg_box_title_color))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgBadCase.setTextColor(resources.getColor(R.color.color_FFFFFF))
viewNoticeDivider.visibility = View.GONE
viewFmDivider.visibility = View.VISIBLE
viewIpcReportDivider.visibility = View.GONE
viewBadCaseDivider.visibility = View.GONE
MsgBoxConfig.setUserRecord(1)
if(fmList == null){
rvMsgBoxList.visibility = View.GONE
}else{
driverMsgBoxListAdapter?.setData(fmList!!)
rvMsgBoxList.visibility = View.VISIBLE
rvMsgBoxList.scrollToPosition(0)
}
}
//车辆系统信息
tvMsgIpcReport.setOnClickListener {
tvMsgNotice.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgFm.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.msg_box_title_color))
tvMsgBadCase.setTextColor(resources.getColor(R.color.color_FFFFFF))
viewNoticeDivider.visibility = View.GONE
viewFmDivider.visibility = View.GONE
viewIpcReportDivider.visibility = View.VISIBLE
viewBadCaseDivider.visibility = View.GONE
MsgBoxConfig.setUserRecord(1)
MsgBoxConfig.setUserRecord(2)
if(ipcReportList == null){
rvMsgBoxList.visibility = View.GONE
}else{
@@ -107,12 +131,14 @@ class DriverMsgBoxListView @JvmOverloads constructor(
//录包
tvMsgBadCase.setOnClickListener {
tvMsgNotice.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgFm.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgBadCase.setTextColor(resources.getColor(R.color.msg_box_title_color))
viewNoticeDivider.visibility = View.GONE
viewFmDivider.visibility = View.GONE
viewIpcReportDivider.visibility = View.GONE
viewBadCaseDivider.visibility = View.VISIBLE
MsgBoxConfig.setUserRecord(2)
MsgBoxConfig.setUserRecord(3)
if(badCaseList == null){
rvMsgBoxList.visibility = View.GONE
}else{
@@ -127,11 +153,14 @@ class DriverMsgBoxListView @JvmOverloads constructor(
fun notifyData(){
//获取当前Tab选择
when(MsgBoxConfig.getUserRecord()){
//通知消息
0 ->{
tvMsgNotice.setTextColor(resources.getColor(R.color.msg_box_title_color))
tvMsgFm.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgBadCase.setTextColor(resources.getColor(R.color.color_FFFFFF))
viewNoticeDivider.visibility = View.VISIBLE
viewFmDivider.visibility = View.GONE
viewIpcReportDivider.visibility = View.GONE
viewBadCaseDivider.visibility = View.GONE
if(noticeList==null){
@@ -142,11 +171,32 @@ class DriverMsgBoxListView @JvmOverloads constructor(
rvMsgBoxList.scrollToPosition(0)
}
}
1 ->{
//FM消息
1->{
tvMsgNotice.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgFm.setTextColor(resources.getColor(R.color.msg_box_title_color))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgBadCase.setTextColor(resources.getColor(R.color.color_FFFFFF))
viewNoticeDivider.visibility = View.GONE
viewFmDivider.visibility = View.VISIBLE
viewIpcReportDivider.visibility = View.GONE
viewBadCaseDivider.visibility = View.GONE
if(fmList == null){
rvMsgBoxList.visibility = View.GONE
}else{
driverMsgBoxListAdapter?.setData(fmList!!)
rvMsgBoxList.visibility = View.VISIBLE
rvMsgBoxList.scrollToPosition(0)
}
}
//车辆系统信息消息
2 ->{
tvMsgNotice.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgFm.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.msg_box_title_color))
tvMsgBadCase.setTextColor(resources.getColor(R.color.color_FFFFFF))
viewNoticeDivider.visibility = View.GONE
viewFmDivider.visibility = View.GONE
viewIpcReportDivider.visibility = View.VISIBLE
viewBadCaseDivider.visibility = View.GONE
if(ipcReportList == null){
@@ -157,11 +207,14 @@ class DriverMsgBoxListView @JvmOverloads constructor(
rvMsgBoxList.scrollToPosition(0)
}
}
2 ->{
//录包消息
3 ->{
tvMsgNotice.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgFm.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgIpcReport.setTextColor(resources.getColor(R.color.color_FFFFFF))
tvMsgBadCase.setTextColor(resources.getColor(R.color.msg_box_title_color))
viewNoticeDivider.visibility = View.GONE
viewFmDivider.visibility = View.GONE
viewIpcReportDivider.visibility = View.GONE
viewBadCaseDivider.visibility = View.VISIBLE
if(badCaseList == null){
@@ -179,6 +232,7 @@ class DriverMsgBoxListView @JvmOverloads constructor(
override fun onDataChanged(category: MsgCategory, msgBoxList: MsgBoxBean) {
UiThreadHandler.post({
when (category) {
//通知
MsgCategory.NOTICE -> {
if(msgBoxList.sourceType == DataSourceType.SUMMARY){
//在一次订单中汇总消息只展示一次
@@ -196,18 +250,28 @@ class DriverMsgBoxListView @JvmOverloads constructor(
}
}
}
//FM信息
MsgCategory.FM_INFO -> {
fmList?.add(0,msgBoxList)
if(MsgBoxConfig.getUserRecord() == 1){
fmList?.let { driverMsgBoxListAdapter?.setData(it) }
}
}
//系统信息
MsgCategory.SYS_INFO -> {
ipcReportList?.add(0,msgBoxList)
if(MsgBoxConfig.getUserRecord() == 1){
if(MsgBoxConfig.getUserRecord() == 2){
ipcReportList?.let { driverMsgBoxListAdapter?.setData(it) }
}
}
//录包
MsgCategory.RECORD_BAG -> {
badCaseList?.add(0,msgBoxList)
if(MsgBoxConfig.getUserRecord() == 2){
if(MsgBoxConfig.getUserRecord() == 3){
badCaseList?.let { driverMsgBoxListAdapter?.setData(it) }
}
}
else -> {}
}
},UiThreadHandler.MODE.QUEUE)
}

View File

@@ -11,6 +11,8 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxCountDownBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.MsgCategory
import com.mogo.eagle.core.data.msgbox.VoiceMsg
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxEventListener
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxListener
import com.mogo.eagle.core.function.api.order.IOrderListener
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
@@ -19,6 +21,7 @@ import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.msgbox.adapter.PassengerMsgBoxBubbleAdapter
import com.mogo.eagle.core.function.msgbox.MsgBoxConfig
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import kotlinx.android.synthetic.main.layout_passenger_msg_box_bubble.view.*
@@ -31,13 +34,17 @@ class PassengerMsgBoxBubbleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMsgBoxListener, IOrderListener {
) : ConstraintLayout(context, attrs, defStyleAttr), IMsgBoxListener, IOrderListener,
IMsgBoxEventListener {
private val TAG = "PassengerMsgBoxBubbleView"
private val dataList :ArrayList<MsgBoxCountDownBean> = ArrayList()
private var passengerMsgBoxBubbleAdapter: PassengerMsgBoxBubbleAdapter ?= null
private var isShowData = true
private var isShowSummary = false //是否展示汇总消息
private var isCacheMsg = false //是否缓存消息
private var voiceIsShowing = false //小智语音消息是否正在展示
private var voiceMsgBean: MsgBoxCountDownBean ?= null //小智语音消息封装
init {
LayoutInflater.from(context).inflate(R.layout.layout_passenger_msg_box_bubble, this, true)
@@ -65,20 +72,96 @@ class PassengerMsgBoxBubbleView @JvmOverloads constructor(
if(category == MsgCategory.NOTICE){
if(msgBoxList.type == MsgBoxType.NOTICE || msgBoxList.type == MsgBoxType.V2X
|| msgBoxList.type == MsgBoxType.OBU){
if(msgBoxList.sourceType == DataSourceType.SUMMARY){
//在一次订单中汇总消息只展示一次
if(isShowSummary){
operationalData(msgBoxList)
isShowSummary = false
}
if(isCacheMsg){
//将消息缓存到未播放列表等待小智语音播放完成后取出播放
MsgBoxConfig.unPlayList.add(msgBoxList)
}else{
operationalData(msgBoxList)
//实时播放消息
notifyMsg(msgBoxList)
}
}
}
if(category == MsgCategory.VOICE_INFO){
if(msgBoxList.type == MsgBoxType.VOICE){
executeVoiceInfo(msgBoxList)
}
}
},UiThreadHandler.MODE.QUEUE)
}
/**
* 小智语音消息执行
*/
private fun executeVoiceInfo(msgBoxList: MsgBoxBean){
CallerLogger.d(TAG,"-----onStatusChange $msgBoxList")
val voiceMsg = msgBoxList.bean as VoiceMsg
if(!voiceMsg.isWakeUpEnd){
//有其他消息时,将其他消息缓存进未播放列表
voiceIsShowing = true
isCacheMsg = true
//开始展示消息
if(voiceMsgBean == null){
voiceMsgBean = MsgBoxCountDownBean(msgBoxList)
dataList.add(voiceMsgBean!!)
}else{
dataList.remove(voiceMsgBean)
voiceMsgBean!!.msgBoxBean = msgBoxList
dataList.add(voiceMsgBean!!)
}
passengerMsgBoxBubbleAdapter?.setData(dataList)
}
if(!voiceMsg.isWakeUp && voiceMsg.isWakeUpEnd){
//关闭消息展示
dataList.remove(voiceMsgBean)
passengerMsgBoxBubbleAdapter?.setData(dataList)
//如果未播放列表中有未播放的消息则陆续展示消息,新来的消息继续放到未播放列表中,
//如果未播放消息列表为空,则立刻改变状态,即使播放新消息
voiceIsShowing = false
handleCachedMsg()
}
}
/**
* 播放缓存消息
*/
private fun handleCachedMsg(){
if(MsgBoxConfig.unPlayList.isEmpty()){
isCacheMsg = false
}else{
//开始播放缓存未播放消息
val iterator = MsgBoxConfig.unPlayList.iterator()
while(iterator.hasNext()){
val msg = iterator.next()
if(passengerMsgBoxBubbleAdapter!!.getDataSize()<3){
notifyMsg(msg)
iterator.remove()
}
}
if(MsgBoxConfig.unPlayList.isEmpty()){
isCacheMsg = false
}
}
}
/**
* 通知新消息展示
*/
private fun notifyMsg(msgBoxList: MsgBoxBean){
if(msgBoxList.sourceType == DataSourceType.SUMMARY){
//在一次订单中汇总消息只展示一次
if(isShowSummary){
operationalData(msgBoxList)
isShowSummary = false
}
}else{
operationalData(msgBoxList)
}
}
/**
* 处理播放消息
*/
private fun operationalData(msgBoxList: MsgBoxBean){
MsgBoxConfig.noticeList.add(msgBoxList)
if(isShowData){
@@ -93,16 +176,28 @@ class PassengerMsgBoxBubbleView @JvmOverloads constructor(
super.onAttachedToWindow()
CallerMsgBoxListenerManager.addListener(TAG,this)
CallerOrderListenerManager.addListener(TAG,this)
CallerMsgBoxEventListenerManager.addListener(TAG,this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerMsgBoxListenerManager.removeListener(TAG)
CallerOrderListenerManager.removeListener(TAG)
CallerMsgBoxEventListenerManager.removeListener(TAG)
}
override fun onUpdateOrderStatus(inOrder: Boolean) {
isShowSummary = inOrder
}
/**
* 播放缓存消息
*/
override fun onHandleCachedMsg() {
if(voiceIsShowing){
return
}
handleCachedMsg()
}
}

View File

@@ -12,19 +12,18 @@ import androidx.annotation.Nullable;
public class SharpView extends View {
private int mWidth =0; //三角形的宽度
private int mHeight =0; //三角形的高度
private Context mContext;
private int mWidth = 0; //三角形的宽度
private int mHeight = 0; //三角形的高度
private final Paint paint = new Paint();
private final Path path = new Path();
public SharpView(Context context) {
super(context);
this.mContext=context;
initView();
}
public SharpView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.mContext=context;
initView();
}
@@ -32,28 +31,27 @@ public class SharpView extends View {
mWidth = 25;
mHeight = 25;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(mWidth,mHeight);
setMeasuredDimension(mWidth, mHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//创建画笔
Paint paint = new Paint();
paint.setColor(Color.parseColor("#FFFFFFFF"));
paint.setAntiAlias(true); //抗锯齿
paint.setStyle(Paint.Style.FILL);//实线
//创建路径
Path path = new Path();
path.moveTo(0,mHeight);
path.lineTo(mWidth,mHeight);
path.lineTo(mWidth/2,0);
path.moveTo(0, mHeight);
path.lineTo(mWidth, mHeight);
path.lineTo(mWidth / 2.0f, 0);
path.close();//闭合路径
//画在画布上
canvas.drawPath(path,paint);
canvas.drawPath(path, paint);
}
}

View File

@@ -19,6 +19,8 @@ import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.msgbox.MsgBoxConfig
import com.mogo.eagle.core.function.msgbox.MsgFmData
import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp
import com.mogo.eagle.core.utilcode.mogo.glide.transform.GlideRoundedCornersTransform
import com.mogo.eagle.core.utilcode.util.TimeUtils
@@ -42,6 +44,7 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
private val v2x: Int = 3
private val report: Int = 4
private val summary: Int = 5
private val fm: Int = 6
private var changeViewListener: ChangeViewListener?=null
@@ -86,6 +89,10 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_summary,parent,false)
return BubbleSummaryHolder(view)
}
fm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_fm,parent,false)
return BubbleFmHolder(view)
}
else -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_v2x,parent,false)
return BubbleV2XHolder(view)
@@ -133,6 +140,7 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
holder.tvOperationDoorContent.text = operationDoorMsg.content
}
}
//系统信息消息
is BubbleReportHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
@@ -149,6 +157,7 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
}
}
}
//云公告消息
is BubbleNoticeHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean.bean
@@ -188,6 +197,7 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
}
}
}
//V2X消息
is BubbleV2XHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
@@ -206,6 +216,7 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
}
}
}
//汇总消息
is BubbleSummaryHolder -> {
data?.let {
val summaryMsg = it[position].msgBoxBean.bean as V2XMsg
@@ -213,6 +224,41 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
holder.tvSummaryContent.text = summaryMsg.content
}
}
//FM信息
is BubbleFmHolder ->{
data?.let {
val fmMsg = it[position].msgBoxBean.bean as FMInfoMsg
holder.tvBubbleFmFault.text = MsgFmData.getFmPolicyName(fmMsg.policyCode)
if(fmMsg.policyTime == null){
holder.tvBubbleFmTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
}else{
holder.tvBubbleFmTime.text = TimeUtils.millis2String(fmMsg.policyTime!!,getHourMinFormat())
}
if(fmMsg.fmInfoList?.size == 0){
holder.tvBubbleFmFaultAction.text = "建议操作:暂无"
}else{
var curFaultLevel = 0 //默认级别遍历数组找出级别最高的level数越小大级别越高
fmMsg.fmInfoList?.forEach { faultInfo ->
if(faultInfo.faultActionCount>0){
faultInfo.faultActionList.forEach {actionCode ->
//获取建议操作级别,得到建议操作级别最高的操作
if(MsgFmData.FaultAction.getFaultLevel(actionCode) > curFaultLevel){
curFaultLevel = MsgFmData.FaultAction.getFaultLevel(actionCode)
}
}
}
}
val faultAction = MsgFmData.FaultAction.getFaultAction(curFaultLevel)
//当出现多个建议操作时,按照整车下电重启、请求人工驾驶接管、请求平行驾驶接管、系统重启、联系硬件工程师、
// 联系运维工程师、联系软件工程师优先级递减的顺序,只展示最高优先级的内容
if(curFaultLevel == 0){
holder.tvBubbleFmFaultAction.text = "建议操作:暂无"
}else{
holder.tvBubbleFmFaultAction.text = "${faultAction}(${MsgFmData.FaultAction.getFaultActionCode(curFaultLevel)})"
}
}
}
}
}
val msgBoxBean: MsgBoxCountDownBean = data!![position]
@@ -260,6 +306,8 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
notice
}else if(data!![position].msgBoxBean.type == MsgBoxType.V2X && data!![position].msgBoxBean.sourceType == DataSourceType.SUMMARY){
summary
}else if(data!![position].msgBoxBean.type == MsgBoxType.FMINFO){
fm
} else{
v2x
}
@@ -320,6 +368,13 @@ class DriverMsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.A
var tvSummaryTime: TextView = itemView.findViewById(R.id.tvSummaryTime)
}
//FM消息
class BubbleFmHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvBubbleFmFault: TextView = itemView.findViewById(R.id.tvBubbleFmFault)
var tvBubbleFmFaultAction: TextView = itemView.findViewById(R.id.tvBubbleFmFaultAction)
var tvBubbleFmTime: TextView = itemView.findViewById(R.id.tvBubbleFmTime)
}
fun setChangeListener(listener: ChangeViewListener){
changeViewListener = listener
}

View File

@@ -18,11 +18,13 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.msgbox.MsgFmData
import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp
import com.mogo.eagle.core.utilcode.mogo.glide.transform.GlideRoundedCornersTransform
import com.mogo.eagle.core.utilcode.util.ResourceUtils.getDrawable
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.getHourMinFormat
import com.mogo.eagle.core.utilcode.util.ToastUtils
/**
* @author XuXinChao
@@ -41,8 +43,9 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
private val operationDoorSwitchFail: Int = 13
private val notice: Int = 2
private val v2x: Int = 3
private val report: Int = 5
private val record: Int = 6
private val fm: Int = 4 //FM信息
private val report: Int = 5 //系统信息
private val record: Int = 6 //录包
private val summary: Int = 8
//Error
@@ -61,16 +64,24 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
//录包
record -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_bad_case, parent, false)
return BadCaseHolder(view)
}
//系统信息
report -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_box_ipc_report, parent, false)
return MsgBoxIpcReportHolder(view)
}
//FM信息
fm -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_box_fm,parent,false)
return FmInfoHolder(view)
}
operation -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_box_operation, parent, false)
@@ -112,6 +123,7 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
//录包
is BadCaseHolder -> {
data?.let {
holder.tvBagReceiveTime.text =
@@ -119,12 +131,237 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
holder.tvBagRecordTime.text =
"时间:${TimeUtils.millis2String(it[position].timestamp)}"
val msgBoxBean = it[position]
val recordBagMsg = msgBoxBean.bean as RecordBagMsg
holder.tvRecordCheck.setOnClickListener {
//打开被动录包弹窗
CallerDevaToolsManager.onReceiveBadCaseRecord(msgBoxBean, activity, false)
if(recordBagMsg.isShow){
ToastUtils.showShort("当前录包上报面板已打开,请勿重复操作")
}else{
//打开被动录包弹窗
CallerDevaToolsManager.onReceiveBadCaseRecord(msgBoxBean, activity, false)
recordBagMsg.isShow = true
}
}
}
}
//FM信息
is FmInfoHolder -> {
data?.let {
val fmInfoMsg = it[position].bean as FMInfoMsg
//时间显示
holder.tvFmTimeOpen.text =
"时间:${fmInfoMsg.policyTime?.let { it1 -> TimeUtils.millis2String(it1) }}"
holder.tvFmTimeNormal.text =
"时间:${fmInfoMsg.policyTime?.let { it1 -> TimeUtils.millis2String(it1) }}"
holder.tvFmTime.text =
fmInfoMsg.policyTime?.let { it1 -> TimeUtils.millis2String(it1,getHourMinFormat()) }
//不同级别的Icon显示
if(fmInfoMsg.policyCode == "FM_DP_ONLY_WARNING"){
//警示
holder.ivFmImageNormal.setImageDrawable(getDrawable(R.drawable.icon_fm_warning_normal))
holder.ivFmImageOpen.setImageDrawable(getDrawable(R.drawable.icon_fm_warning_open))
}else if(fmInfoMsg.policyCode == "FM_DP_SPEED_LIMIT1"
|| fmInfoMsg.policyCode == "FM_DP_SPEED_LIMIT2"
|| fmInfoMsg.policyCode == "FM_DP_SPEED_LIMIT3"){
//降速行驶
holder.ivFmImageNormal.setImageDrawable(getDrawable(R.drawable.icon_fm_reduce_normal))
holder.ivFmImageOpen.setImageDrawable(getDrawable(R.drawable.icon_fm_reduce_open))
}else if(fmInfoMsg.policyCode == "FM_DP_PNC_CHOOSE_STOP"
|| fmInfoMsg.policyCode == "FM_DP_COMFORTABLE_STOP"
|| fmInfoMsg.policyCode == "FM_DP_EMERGENCY_STOP"){
//安全停车
holder.ivFmImageNormal.setImageDrawable(getDrawable(R.drawable.icon_fm_stop_normal))
holder.ivFmImageOpen.setImageDrawable(getDrawable(R.drawable.icon_fm_stop_open))
}
//Title
holder.tvFmTitleNormal.text = MsgFmData.getFmPolicyName(fmInfoMsg.policyCode)
holder.tvFmTitleOpen.text = MsgFmData.getFmPolicyName(fmInfoMsg.policyCode)
//建议操作
if(fmInfoMsg.fmInfoList.isNullOrEmpty()){
//建议操作暂无
holder.tvFmActionOpen.text = "建议操作:暂无"
holder.tvFmActionNormal.text = "建议操作:暂无"
}else{
val receiveFaultLevel = ArrayList<Int>()
fmInfoMsg.fmInfoList!!.forEach { info ->
if(info.faultActionCount != 0){
info.faultActionList.forEach { action ->
//如果不包含此故障Level则进行添加
if(!receiveFaultLevel.contains(MsgFmData.FaultAction.getFaultLevel(action)) && MsgFmData.FaultAction.getFaultLevel(action)!=0){
receiveFaultLevel.add(MsgFmData.FaultAction.getFaultLevel(action))
}
}
}
}
//对faultLevel集合进行排序按照顺序输出建议操作
if(receiveFaultLevel.size > 0){
val faultActionStr: StringBuilder = StringBuilder()
faultActionStr.append("建议操作:")
receiveFaultLevel.sort()
receiveFaultLevel.reverse()
receiveFaultLevel.forEach {level->
if(MsgFmData.FaultAction.getFaultAction(level).isNotBlank()){
faultActionStr.append(MsgFmData.FaultAction.getFaultAction(level))
}
if(MsgFmData.FaultAction.getFaultActionCode(level).isNotBlank()){
faultActionStr.append("(")
faultActionStr.append(MsgFmData.FaultAction.getFaultActionCode(level))
faultActionStr.append(")")
}
if(MsgFmData.FaultAction.getFaultAction(level).isNotBlank() || MsgFmData.FaultAction.getFaultActionCode(level).isNotBlank()){
faultActionStr.append("/")
}
}
if(faultActionStr.length > 5){
if(faultActionStr.endsWith("/")){
faultActionStr.deleteCharAt(faultActionStr.lastIndex)
}
holder.tvFmActionOpen.text = faultActionStr.toString()
holder.tvFmActionNormal.text = faultActionStr.toString()
}else{
holder.tvFmActionOpen.text = "建议操作:暂无"
holder.tvFmActionNormal.text = "建议操作:暂无"
}
}else{
holder.tvFmActionOpen.text = "建议操作:暂无"
holder.tvFmActionNormal.text = "建议操作:暂无"
}
}
//故障策略
holder.tvFmFaultOpen.text = "故障策略:${MsgFmData.getFmPolicyName(fmInfoMsg.policyCode)}(${fmInfoMsg.policyCode})"
//故障原因
if(fmInfoMsg.fmInfoList.isNullOrEmpty()){
holder.tvFmReasonOpen.text = "故障原因:暂无"
}else{
val fmFaultReason = StringBuilder()
fmFaultReason.append("故障原因:")
for((index,info) in fmInfoMsg.fmInfoList!!.withIndex()){
fmFaultReason.append(info.faultName)
if(info.faultId.isNotBlank()){
fmFaultReason.append("(")
fmFaultReason.append(info.faultId)
fmFaultReason.append(")")
}
if(index!=(fmInfoMsg.fmInfoList!!.size-1)){
fmFaultReason.append("/")
}
}
holder.tvFmReasonOpen.text = fmFaultReason.toString()
}
//故障后果
if(fmInfoMsg.fmInfoList.isNullOrEmpty()){
holder.tvFmResultOpen.text = "故障后果:暂无"
}else{
val fmFaultResult = StringBuilder()
fmFaultResult.append("故障后果:")
fmInfoMsg.fmInfoList!!.forEach { info->
if(info.faultResultCount != 0){
info.faultResultList.forEach { result->
if(MsgFmData.FaultResult.getResultDefine(result).isNotBlank()){
fmFaultResult.append(MsgFmData.FaultResult.getResultDefine(result))
}
if(result.isNotBlank()){
fmFaultResult.append("(")
fmFaultResult.append(result)
fmFaultResult.append(")")
}
if(MsgFmData.FaultResult.getResultDefine(result).isNotBlank() || result.isNotBlank()){
fmFaultResult.append("/")
}
}
}
}
if(fmFaultResult.endsWith("/")){
holder.tvFmResultOpen.text = fmFaultResult.deleteCharAt(fmFaultResult.lastIndex).toString()
}else{
holder.tvFmResultOpen.text = "故障后果:暂无"
}
}
//对布局进行展开折叠操作
if(fmInfoMsg.isShow){
holder.tvFmStatusSelect.setCompoundDrawablesWithIntrinsicBounds(
getDrawable(R.drawable.icon_msg_close),
null,
null,
null
)
holder.tvFmStatusSelect.text = "折叠"
holder.ivFmImageNormal.visibility = View.GONE
holder.tvFmTitleNormal.visibility = View.GONE
holder.tvFmTimeNormal.visibility = View.GONE
holder.tvFmActionNormal.visibility = View.GONE
holder.ivFmImageOpen.visibility = View.VISIBLE
holder.tvFmTitleOpen.visibility = View.VISIBLE
holder.tvFmTimeOpen.visibility = View.VISIBLE
holder.tvFmActionOpen.visibility = View.VISIBLE
holder.tvFmFaultOpen.visibility = View.VISIBLE
holder.tvFmReasonOpen.visibility = View.VISIBLE
holder.tvFmResultOpen.visibility = View.VISIBLE
}else{
holder.tvFmStatusSelect.setCompoundDrawablesWithIntrinsicBounds(
getDrawable(R.drawable.icon_msg_open),
null,
null,
null
)
holder.tvFmStatusSelect.text = "展开"
holder.ivFmImageNormal.visibility = View.VISIBLE
holder.tvFmTitleNormal.visibility = View.VISIBLE
holder.tvFmTimeNormal.visibility = View.VISIBLE
holder.tvFmActionNormal.visibility = View.VISIBLE
holder.ivFmImageOpen.visibility = View.GONE
holder.tvFmTitleOpen.visibility = View.GONE
holder.tvFmTimeOpen.visibility = View.GONE
holder.tvFmActionOpen.visibility = View.GONE
holder.tvFmFaultOpen.visibility = View.GONE
holder.tvFmReasonOpen.visibility = View.GONE
holder.tvFmResultOpen.visibility = View.GONE
}
holder.tvFmStatusSelect.setOnClickListener{
if(!fmInfoMsg.isShow){
fmInfoMsg.isShow = true
holder.tvFmStatusSelect.setCompoundDrawablesWithIntrinsicBounds(
getDrawable(R.drawable.icon_msg_close),
null,
null,
null
)
holder.tvFmStatusSelect.text = "折叠"
holder.ivFmImageNormal.visibility = View.GONE
holder.tvFmTitleNormal.visibility = View.GONE
holder.tvFmTimeNormal.visibility = View.GONE
holder.tvFmActionNormal.visibility = View.GONE
holder.ivFmImageOpen.visibility = View.VISIBLE
holder.tvFmTitleOpen.visibility = View.VISIBLE
holder.tvFmTimeOpen.visibility = View.VISIBLE
holder.tvFmActionOpen.visibility = View.VISIBLE
holder.tvFmFaultOpen.visibility = View.VISIBLE
holder.tvFmReasonOpen.visibility = View.VISIBLE
holder.tvFmResultOpen.visibility = View.VISIBLE
}else{
fmInfoMsg.isShow = false
holder.tvFmStatusSelect.setCompoundDrawablesWithIntrinsicBounds(
getDrawable(R.drawable.icon_msg_open),
null,
null,
null
)
holder.tvFmStatusSelect.text = "展开"
holder.ivFmImageNormal.visibility = View.VISIBLE
holder.tvFmTitleNormal.visibility = View.VISIBLE
holder.tvFmTimeNormal.visibility = View.VISIBLE
holder.tvFmActionNormal.visibility = View.VISIBLE
holder.ivFmImageOpen.visibility = View.GONE
holder.tvFmTitleOpen.visibility = View.GONE
holder.tvFmTimeOpen.visibility = View.GONE
holder.tvFmActionOpen.visibility = View.GONE
holder.tvFmFaultOpen.visibility = View.GONE
holder.tvFmReasonOpen.visibility = View.GONE
holder.tvFmResultOpen.visibility = View.GONE
}
}
}
}
//系统信息
is MsgBoxIpcReportHolder -> {
data?.let { it ->
val reportMsgBox = it[position]
@@ -434,7 +671,10 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
report
} else if (data!![position].type == MsgBoxType.RECORD) {
record
} else {
} else if(data!![position].type == MsgBoxType.FMINFO){
fm
}
else {
v2x
}
}
@@ -446,6 +686,23 @@ class DriverMsgBoxListAdapter(private val activity: Activity) :
var tvRecordCheck: TextView = itemView.findViewById(R.id.tvRecordCheck)
}
//FM信息
class FmInfoHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var ivFmImageNormal: ImageView = itemView.findViewById(R.id.ivFmImageNormal) //故障级别图标
var tvFmTitleNormal: TextView = itemView.findViewById(R.id.tvFmTitleNormal) //标题展示故障策略
var tvFmTimeNormal: TextView = itemView.findViewById(R.id.tvFmTimeNormal) //时间
var tvFmStatusSelect: TextView = itemView.findViewById(R.id.tvFmStatusSelect) //展开折叠按钮
var tvFmActionNormal: TextView = itemView.findViewById(R.id.tvFmActionNormal) //建议操作
var tvFmTime: TextView = itemView.findViewById(R.id.tvFmTime) //时间
var ivFmImageOpen: ImageView = itemView.findViewById(R.id.ivFmImageOpen) //展开时图标
var tvFmTitleOpen: TextView = itemView.findViewById(R.id.tvFmTitleOpen) //标题文案为故障策略
var tvFmTimeOpen: TextView = itemView.findViewById(R.id.tvFmTimeOpen) //发生时间
var tvFmActionOpen: TextView = itemView.findViewById(R.id.tvFmActionOpen) //建议操作
var tvFmFaultOpen: TextView = itemView.findViewById(R.id.tvFmFaultOpen) //故障策略
var tvFmReasonOpen: TextView = itemView.findViewById(R.id.tvFmReasonOpen) //故障原因
var tvFmResultOpen: TextView = itemView.findViewById(R.id.tvFmResultOpen) //后果
}
//车辆系统信息
class MsgBoxIpcReportHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var ivReportImageNormal: ImageView = itemView.findViewById(R.id.ivReportImageNormal)

View File

@@ -12,14 +12,14 @@ import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.*
import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.glide.transform.GlideRoundedCornersTransform
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.getHourMinFormat
import com.mogo.eagle.core.widget.AlignTextView
import com.mogo.eagle.core.widget.AlignTwoTextView
import com.mogo.eagle.core.widget.RoundCanClickConstraintLayout
/**
@@ -34,6 +34,7 @@ class PassengerMsgBoxBubbleAdapter(private val activity: Activity): RecyclerView
private val notice: Int = 1
private val v2x: Int = 2
private val summary: Int = 3
private val voice: Int = 4
fun setData(data: ArrayList<MsgBoxCountDownBean>){
this.data = data
@@ -43,6 +44,17 @@ class PassengerMsgBoxBubbleAdapter(private val activity: Activity): RecyclerView
notifyDataSetChanged()
}
/**
* 获取列表数据个数
*/
fun getDataSize(): Int{
return if(data.isNullOrEmpty()){
0
}else{
data!!.size
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
notice -> {
@@ -53,6 +65,11 @@ class PassengerMsgBoxBubbleAdapter(private val activity: Activity): RecyclerView
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_passenger_msg_box_summary,parent,false)
BubbleSummaryHolder(view)
}
//小智语音
voice -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_passenger_msg_box_voice,parent,false)
BubbleVoiceHolder(view)
}
else -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_passenger_msg_box_v2x,parent,false)
BubbleV2XHolder(view)
@@ -108,23 +125,44 @@ class PassengerMsgBoxBubbleAdapter(private val activity: Activity): RecyclerView
}
}
}
//小智语音消息
is BubbleVoiceHolder -> {
data?.let {
val voiceMsg = it[position].msgBoxBean.bean as VoiceMsg
if(voiceMsg.isResp){
//小智说的
holder.tvVoiceRes.text = voiceMsg.msg
holder.tvVoiceRes.visibility = View.VISIBLE
holder.tvPassengerVoiceContent.visibility = View.GONE
}else{
//用户说的
holder.tvPassengerVoiceContent.text = voiceMsg.msg
holder.tvVoiceRes.visibility = View.GONE
holder.tvPassengerVoiceContent.visibility = View.VISIBLE
}
}
}
}
val msgBoxBean: MsgBoxCountDownBean = data!![position]
msgBoxBean.countDownTimer =object: CountDownTimer(CallerMsgBoxManager.getDismissTime(),1000){
override fun onTick(p0: Long) {
if(msgBoxBean.msgBoxBean.type != MsgBoxType.VOICE){
msgBoxBean.countDownTimer =object: CountDownTimer(CallerMsgBoxManager.getDismissTime(),CallerMsgBoxManager.getDismissTime()){
override fun onTick(p0: Long) {
}
}
override fun onFinish() {
data?.remove(msgBoxBean)
notifyDataSetChanged()
override fun onFinish() {
data?.remove(msgBoxBean)
notifyDataSetChanged()
// notifyItemRemoved(index)
// notifyItemRangeChanged(index,recordTypeEntity.size-index)
}
//通知消息盒子可以展示新的缓存消息
CallerMsgBoxEventListenerManager.invokeHandleCachedMsg()
}
}
msgBoxBean.countDownTimer?.start()
}
msgBoxBean.countDownTimer?.start()
}
override fun getItemCount() = data?.size ?: 0
@@ -134,7 +172,9 @@ class PassengerMsgBoxBubbleAdapter(private val activity: Activity): RecyclerView
notice
}else if(data!![position].msgBoxBean.type == MsgBoxType.V2X && data!![position].msgBoxBean.sourceType == DataSourceType.SUMMARY){
summary
} else{
}else if(data!![position].msgBoxBean.type == MsgBoxType.VOICE){
voice
}else{
v2x
}
}
@@ -160,4 +200,10 @@ class PassengerMsgBoxBubbleAdapter(private val activity: Activity): RecyclerView
var tvPassengerSummaryTime: TextView = itemView.findViewById(R.id.tvPassengerSummaryTime)
}
//小智语音消息
class BubbleVoiceHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvPassengerVoiceContent: AlignTextView = itemView.findViewById(R.id.tvPassengerVoiceContent)
var tvVoiceRes: AlignTwoTextView = itemView.findViewById(R.id.tvVoiceRes)
}
}

View File

@@ -5,6 +5,7 @@ import static com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocRece
import static com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBean.DISPATCH_TYPE_START;
import static com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBean.DISPATCH_TYPE_STOP;
import android.annotation.SuppressLint;
import android.content.Context;
import com.mogo.commons.voice.AIAssist;
@@ -12,6 +13,7 @@ import com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBea
public class DispatchDialogManager {
@SuppressLint("StaticFieldLeak")
private static volatile DispatchDialogManager manager;
private static final byte[] obj = new byte[0];
private final Context mContext;

View File

@@ -51,11 +51,15 @@ import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuConnectListener
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuInfoListener
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.hmi.view.IViewControlListener
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.FUNC_MODE_DEMO
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.FUNC_MODE_RAIN
import com.mogo.eagle.core.function.api.setting.ISopSettingListener
import com.mogo.eagle.core.function.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.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.call.obu.CallerObuApiManager
import com.mogo.eagle.core.function.call.obu.CallerObuConnectListenerManager
@@ -124,7 +128,7 @@ internal class DebugSettingView @JvmOverloads constructor(
IMoGoChassisThrottleStateListener,
IMoGoSweeperFutianCleanSystemListener,
IMoGoObuInfoListener,
ISopSettingListener {
ISopSettingListener, IViewControlListener {
private val TAG = "DebugSettingView"
@@ -708,6 +712,10 @@ internal class DebugSettingView @JvmOverloads constructor(
FunctionBuildConfig.isDemoMode = !FunctionBuildConfig.isDemoMode
CallerAutoPilotControlManager.setDemoMode(FunctionBuildConfig.isDemoMode)
CallerSopSettingManager.invokeDemoModeListener(isChecked)
CallerHmiViewControlListenerManager.invokeFuncMode(
FUNC_MODE_DEMO,
FunctionBuildConfig.isDemoMode
)
if (!FunctionBuildConfig.isDemoMode) {
//关闭美化模式时,通知工控机
CallerAutoPilotControlManager.setIPCDemoMode(FunctionBuildConfig.isDemoMode)
@@ -724,10 +732,10 @@ internal class DebugSettingView @JvmOverloads constructor(
}
tbIsStrictMode?.also {
it.isChecked = SharedPrefs.getInstance(Utils.getApp())
it.isChecked = SharedPrefsMgr.getInstance(Utils.getApp())
.getBoolean("MOGO_STRICT_MODE_ENABLED", false)
it.setOnCheckedChangeListener { _, isChecked ->
SharedPrefs.getInstance(Utils.getApp())
SharedPrefsMgr.getInstance(Utils.getApp())
.putBoolean("MOGO_STRICT_MODE_ENABLED", isChecked)
scope.launch {
ToastUtils.showShort("配置生效, 2秒后重启应用...")
@@ -1040,7 +1048,7 @@ internal class DebugSettingView @JvmOverloads constructor(
private fun setEagleEyeConfigListener() {
//初始化刹车加速度阈值信息
val brakeThreshold = SharedPrefsMgr.getInstance(context)
.getFloat(MoGoConfig.BRAKE_ACCELERATION_THRESHOLD, -2.5F)
.getFloat(MoGoConfig.BRAKE_ACCELERATION_THRESHOLD, FunctionBuildConfig.accThreshold)
etInputBrakeThreshold.setText(brakeThreshold.toString())
etInputBrakeThreshold.text?.let { etInputBrakeThreshold.setSelection(brakeThreshold.toString().length) }
//设置刹车加速度阈值信息
@@ -1054,6 +1062,7 @@ internal class DebugSettingView @JvmOverloads constructor(
if (thresholdStrFloat < 0) {
SharedPrefsMgr.getInstance(context)
.putFloat(MoGoConfig.BRAKE_ACCELERATION_THRESHOLD, thresholdStrFloat)
FunctionBuildConfig.accThreshold = thresholdStrFloat
ToastUtils.showShort("刹车阈值设置成功")
} else {
ToastUtils.showShort("刹车阈值加速度值应小于0")
@@ -1311,11 +1320,9 @@ internal class DebugSettingView @JvmOverloads constructor(
*/
tbSelfLog.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
LogUtils.getConfig().isLogSwitch = false
Logger.init(LogLevel.OFF)
MoGoAiCloudClient.getInstance().aiCloudClientConfig.isShowDebugLog = false
} else {
LogUtils.getConfig().isLogSwitch = true
Logger.init(LogLevel.DEBUG)
MoGoAiCloudClient.getInstance().aiCloudClientConfig.isShowDebugLog = true
}
@@ -1679,21 +1686,10 @@ internal class DebugSettingView @JvmOverloads constructor(
*/
tvServerEnvironment.text = "当前服务器环境:${AppConfigInfo.netMode} -- ${
when (AppConfigInfo.netMode) {
2 -> {
"测试环境"
}
3 -> {
"生产环境"
}
4 -> {
"演示环境"
}
else -> {
"未知环境"
}
2 -> "测试环境"
3 -> "生产环境"
4 -> "演示环境"
else -> "未知环境"
}
}"
@@ -1784,18 +1780,17 @@ internal class DebugSettingView @JvmOverloads constructor(
}
tvCmdbCarInfoContent.text =
SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.CAR_INFO) ?: ""
//APP升级功能
tvAppHost.text = "HOST地址" + SharedPrefsMgr.getInstance(context)
.getString(SharedPrefsConstants.HOST_ADDRESS) ?: ""
.getString(SharedPrefsConstants.HOST_ADDRESS)
tvAppContent.text = "APP升级数据" + SharedPrefsMgr.getInstance(context)
.getString(SharedPrefsConstants.APP_UPGRADE_CONTENT) ?: ""
.getString(SharedPrefsConstants.APP_UPGRADE_CONTENT)
tvCarInfo.text =
"GPS时间${(mGnssInfo?.satelliteTime?.times(1000))?.toLong()}\n" +
"GPS时间${(mGnssInfo?.satelliteTime?.times(1000))}\n" +
"自车经纬度:\n${mGnssInfo?.longitude}\n${mGnssInfo?.latitude}\n"
tvCarInfoCopy.text =
"GPS时间${(mGnssInfo?.satelliteTime?.times(1000))?.toLong()}\n" +
"GPS时间${(mGnssInfo?.satelliteTime?.times(1000))}\n" +
"自车经纬度:\n${mGnssInfo?.longitude}\n${mGnssInfo?.latitude}\n"
tvIdentifyInfo.text =
@@ -2305,4 +2300,14 @@ internal class DebugSettingView @JvmOverloads constructor(
tbCarAperture.isChecked = status
}
override fun updateFuncMode(tag: String, boolean: Boolean) {
super.updateFuncMode(tag, boolean)
if (tag == FUNC_MODE_DEMO) {
tbIsDemoMode.isChecked = FunctionBuildConfig.isDemoMode
}
if (tag == FUNC_MODE_RAIN) {
tbIsDemoMode.isChecked = FunctionBuildConfig.isRainMode
}
}
}

View File

@@ -33,6 +33,7 @@ import com.mogo.eagle.core.function.call.vehicle.CallerSweeperModeListenerManage
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.tools.DockerRebootDialog
import com.mogo.eagle.core.function.hmi.ui.tools.SweeperModeChangedConfirmDialog
import com.mogo.eagle.core.function.call.unmanned.CallerUnmannedListenerManager
import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog.Companion.hmiAction
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.vehicle.SweeperVehicleConfigUtils
@@ -123,24 +124,19 @@ internal class SOPSettingView @JvmOverloads constructor(
scV2XSwitch.setOnCheckedChangeListener { _, isChecked ->
FunctionBuildConfig.v2xMainSwitch = isChecked
hmiAction("SOP V2X总开关, ", isChecked)
Log.i(TAG, "SOP V2X总开关,$isChecked")
if (isChecked) {
//V2N总开关
scV2NSwitch.isChecked = FunctionBuildConfig.v2nMainSwitch
hmiAction("SOP V2N总开关, ", FunctionBuildConfig.v2nMainSwitch)
Log.i(TAG, "SOP V2N总开关, ${FunctionBuildConfig.v2nMainSwitch}")
//V2I总开关
scV2ISwitch.isChecked = HmiBuildConfig.isShowObuV2iView
hmiAction("SOP V2I总开关, ", HmiBuildConfig.isShowObuV2iView)
Log.i(TAG, "SOP V2I总开关, ${HmiBuildConfig.isShowObuV2iView}")
//V2V总开关
scObuV2vView.isChecked = HmiBuildConfig.isShowObuV2vView
hmiAction("SOP V2V总开关, ", HmiBuildConfig.isShowObuV2vView)
Log.i(TAG, "SOP V2V总开关, ${HmiBuildConfig.isShowObuV2vView}")
//obu总开关
scObu.isChecked = obuConnectStatus
hmiAction("SOP obu总开关, ", obuConnectStatus)
Log.i(TAG, "SOP obu总开关, $obuConnectStatus")
if (obuConnectStatus) {
CallerObuApiManager.resetObuIpAddress(MogoObuConst.OBU_DEFAULT_IP)
}
@@ -148,19 +144,15 @@ internal class SOPSettingView @JvmOverloads constructor(
//V2N总开关
scV2NSwitch.isChecked = false
hmiAction("SOP V2N总开关, ", false)
Log.i(TAG, "SOP V2N总开关, false")
//V2I总开关
scV2ISwitch.isChecked = false
hmiAction("SOP V2I总开关, ", false)
Log.i(TAG, "SOP V2I总开关, false")
//V2V总开关
scObuV2vView.isChecked = false
hmiAction("SOP V2V总开关, ", false)
Log.i(TAG, "SOP V2V总开关, false")
//obu总开关
scObu.isChecked = false
hmiAction("SOP OBU控制总开关, ", false)
Log.i(TAG, "SOP OBU控制总开关, false")
//断开链接
CallerObuApiManager.disConnectObu()
}
@@ -184,32 +176,32 @@ internal class SOPSettingView @JvmOverloads constructor(
//V2N新链路
scNewV2NData.isChecked = FunctionBuildConfig.isNewV2NData
hmiAction("SOP 是否是V2N新链路(云->工控机->App)", FunctionBuildConfig.isNewV2NData)
Log.i(TAG, "SOP 是否是V2N新链路(云->工控机->App), ${FunctionBuildConfig.isNewV2NData}")
//V2N场景进PNC
scV2nPnc.isChecked = FunctionBuildConfig.isV2NPnc
hmiAction("SOP V2N场景进PNC, ", FunctionBuildConfig.isV2NPnc)
Log.i(TAG, "SOP V2N场景进PNC, ${FunctionBuildConfig.isV2NPnc}")
CallerAutoPilotControlManager.sendV2nToPncCmd(FunctionBuildConfig.isV2NPnc)
//绿波通行
scGreenWaveSop.isChecked = HmiBuildConfig.isShowGreenWaveView
hmiAction("SOP obu绿波通行, ", HmiBuildConfig.isShowGreenWaveView)
Log.i(TAG, "SOP obu绿波通行, ${HmiBuildConfig.isShowGreenWaveView}")
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_GREENWAVE_WARNING, "1".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_GREENWAVE_WARNING,
"1".toByteArray()
)
} else {
//V2N新链路
scNewV2NData.isChecked = false
hmiAction("SOP 是否是V2N新链路(云->工控机->App)", false)
Log.i(TAG, "SOP 是否是V2N新链路(云->工控机->App), false")
//V2N场景进PNC
scV2nPnc.isChecked = false
hmiAction("SOP V2N场景进PNC, ", false)
Log.i(TAG, "SOP V2N场景进PNC, false")
CallerAutoPilotControlManager.sendV2nToPncCmd(false)
//绿波通行
scGreenWaveSop.isChecked = false
hmiAction("SOP obu绿波通行, ", false)
Log.i(TAG, "SOP obu绿波通行, false")
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_GREENWAVE_WARNING, "0".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_GREENWAVE_WARNING,
"0".toByteArray()
)
}
scNewV2NData.isEnabled = isChecked
scV2nPnc.isEnabled = isChecked
@@ -231,32 +223,32 @@ internal class SOPSettingView @JvmOverloads constructor(
//V2I场景进PNC
scV2iPnc.isChecked = FunctionBuildConfig.isV2IPnc
hmiAction("SOP V2I场景进PNC, ", FunctionBuildConfig.isV2IPnc)
Log.i(TAG, "SOP V2I场景进PNC,${FunctionBuildConfig.isV2IPnc}")
CallerAutoPilotControlManager.sendV2iToPncCmd(FunctionBuildConfig.isV2IPnc)
//闯红灯预警
scRunRedLightSop.isChecked = HmiBuildConfig.isShowRunRedLightView
hmiAction("SOP obu闯红灯预警, ", HmiBuildConfig.isShowRunRedLightView)
Log.i(TAG, "SOP obu闯红灯预警, ${HmiBuildConfig.isShowRunRedLightView}")
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_RUNREDLIGHT_WARNING, "1".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_RUNREDLIGHT_WARNING,
"1".toByteArray()
)
//路侧弱势交通参与者
scObuWeaknessTrafficSop.isChecked = HmiBuildConfig.isShowObuWeaknessTrafficView
hmiAction("SOP obu弱势交通控制, ", HmiBuildConfig.isShowObuWeaknessTrafficView)
Log.i(TAG, "SOP obu弱势交通控制, ${HmiBuildConfig.isShowObuWeaknessTrafficView}")
} else {
//V2I场景进PNC
scV2iPnc.isChecked = false
CallerAutoPilotControlManager.sendV2iToPncCmd(false)
hmiAction("SOP V2I场景进PNC, ", false)
Log.i(TAG, "SOP V2I场景进PNC, false")
//闯红灯预警
scRunRedLightSop.isChecked = false
hmiAction("SOP obu闯红灯预警, ", false)
Log.i(TAG, "SOP obu闯红灯预警, false")
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_RUNREDLIGHT_WARNING, "0".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_RUNREDLIGHT_WARNING,
"0".toByteArray()
)
//路侧弱势交通参与者
scObuWeaknessTrafficSop.isChecked = false
hmiAction("SOP obu弱势交通控制, ", false)
Log.i(TAG, "SOP obu弱势交通控制, false")
}
scV2iPnc.isEnabled = isChecked
scRunRedLightSop.isEnabled = isChecked
@@ -274,7 +266,6 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP 是否是V2N新链路(云->工控机->App)", isChecked)
Log.i(TAG, "SOP 是否是V2N新链路(云->工控机->App) ${isChecked}")
FunctionBuildConfig.isNewV2NData = isChecked
}
@@ -285,7 +276,6 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP V2N场景进PNC, ", isChecked)
Log.i(TAG, "SOP V2N场景进PNC, $isChecked")
CallerAutoPilotControlManager.sendV2nToPncCmd(isChecked)
FunctionBuildConfig.isV2NPnc = isChecked
}
@@ -297,12 +287,17 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP obu绿波通行, ", isChecked)
Log.i(TAG, "SOP obu绿波通行, $isChecked")
HmiBuildConfig.isShowGreenWaveView = isChecked
if (HmiBuildConfig.isShowGreenWaveView) {
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_GREENWAVE_WARNING, "1".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_GREENWAVE_WARNING,
"1".toByteArray()
)
} else {
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_GREENWAVE_WARNING, "0".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_GREENWAVE_WARNING,
"0".toByteArray()
)
}
}
@@ -313,7 +308,6 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP V2I场景进PNC, ", isChecked)
Log.i(TAG, "SOP V2I场景进PNC, $isChecked")
CallerAutoPilotControlManager.sendV2iToPncCmd(isChecked)
FunctionBuildConfig.isV2IPnc = isChecked
}
@@ -325,12 +319,17 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP obu闯红灯预警, ", isChecked)
Log.i(TAG, "SOP obu闯红灯预警, $isChecked")
HmiBuildConfig.isShowRunRedLightView = isChecked
if (HmiBuildConfig.isShowRunRedLightView) {
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_RUNREDLIGHT_WARNING, "1".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_RUNREDLIGHT_WARNING,
"1".toByteArray()
)
} else {
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.OBU_RUNREDLIGHT_WARNING, "0".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_RUNREDLIGHT_WARNING,
"0".toByteArray()
)
}
}
@@ -341,7 +340,6 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP obu弱势交通控制, ", isChecked)
Log.i(TAG, "SOP obu弱势交通控制, $isChecked")
HmiBuildConfig.isShowObuWeaknessTrafficView = isChecked
}
@@ -352,7 +350,6 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP obuV2V开关, ", isChecked)
Log.i(TAG, "SOP obuV2V开关, $isChecked")
HmiBuildConfig.isShowObuV2vView = isChecked
}
@@ -364,7 +361,6 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP OBU控制总开关, ", isChecked)
Log.i(TAG, "SOP OBU控制总开关, $isChecked")
if (isChecked) {
CallerObuApiManager.resetObuIpAddress(MogoObuConst.OBU_DEFAULT_IP)
} else {
@@ -383,7 +379,6 @@ internal class SOPSettingView @JvmOverloads constructor(
scMarkingObstacles.isChecked = FunctionBuildConfig.isPNCWarning
scMarkingObstacles.setOnCheckedChangeListener { _, isChecked ->
hmiAction("SOP 危险障碍物颜色标记开关, ", isChecked)
Log.i(TAG, "SOP 危险障碍物颜色标记开关, $isChecked")
FunctionBuildConfig.isPNCWarning = isChecked
}
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
@@ -394,7 +389,6 @@ internal class SOPSettingView @JvmOverloads constructor(
scRouteDynamicEffect.isChecked = HmiBuildConfig.isShowRouteStrategy
scRouteDynamicEffect.setOnCheckedChangeListener { _, isChecked ->
hmiAction("SOP 引导线动态效果, ", isChecked)
Log.i(TAG, "SOP 引导线动态效果, $isChecked")
HmiBuildConfig.isShowRouteStrategy = isChecked
}
@@ -417,7 +411,6 @@ internal class SOPSettingView @JvmOverloads constructor(
CallerMapUIServiceManager.getMapUIController()?.setIsDrawPointCloud(isChecked)
CallerSopSettingManager.invokePointCloudListener(isChecked)
hmiAction("SOP 是否渲染点云数据, ", isChecked)
Log.i(TAG, "SOP 是否渲染点云数据, $isChecked")
}
//自车光圈
@@ -427,7 +420,6 @@ internal class SOPSettingView @JvmOverloads constructor(
scCarAperture.isChecked = true
CallerMapUIServiceManager.getMapUIController()?.setDisplayAnimEnable(true)
hmiAction("SOP 是否展示自车光圈,", FunctionBuildConfig.isDisplayAnimEnable)
Log.i(TAG, "SOP 是否展示自车光圈,${FunctionBuildConfig.isDisplayAnimEnable}")
} else {
scCarAperture.isChecked = FunctionBuildConfig.isDisplayAnimEnable
}
@@ -435,7 +427,6 @@ internal class SOPSettingView @JvmOverloads constructor(
CallerMapUIServiceManager.getMapUIController()?.setDisplayAnimEnable(isChecked)
CallerSopSettingManager.invokeCarApertureListener(isChecked)
hmiAction("SOP 是否展示自车光圈,", isChecked)
Log.i(TAG, "SOP 是否展示自车光圈,$isChecked")
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
@@ -451,7 +442,6 @@ internal class SOPSettingView @JvmOverloads constructor(
scObstacleAvoidance.isChecked = FunctionBuildConfig.isDetouring
scObstacleAvoidance.setOnCheckedChangeListener { _, isChecked ->
hmiAction("SOP 绕障类功能开关, ", isChecked)
Log.i(TAG, "SOP 绕障类功能开关, $isChecked")
CallerAutoPilotControlManager.sendDetouring(isChecked)
FunctionBuildConfig.isDetouring = isChecked
}
@@ -463,10 +453,12 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP 演示模式开关, ", !FunctionBuildConfig.isDemoMode)
Log.i(TAG, "SOP 演示模式开关, ${!FunctionBuildConfig.isDemoMode}")
FunctionBuildConfig.isDemoMode = !FunctionBuildConfig.isDemoMode
CallerAutoPilotControlManager.setDemoMode(FunctionBuildConfig.isDemoMode)
CallerHmiViewControlListenerManager.invokeFuncMode(FUNC_MODE_DEMO, FunctionBuildConfig.isDemoMode)
CallerHmiViewControlListenerManager.invokeFuncMode(
FUNC_MODE_DEMO,
FunctionBuildConfig.isDemoMode
)
CallerSopSettingManager.invokeDemoModeListener(isChecked)
if (!FunctionBuildConfig.isDemoMode) {
//关闭美化模式时,通知工控机
@@ -485,7 +477,6 @@ internal class SOPSettingView @JvmOverloads constructor(
return@setOnCheckedChangeListener
}
hmiAction("SOP 雨天模式开关, ", isChecked)
Log.i(TAG, "SOP 雨天模式开关, $isChecked")
FunctionBuildConfig.isRainMode = isChecked
CallerAutoPilotControlManager.setRainMode(isChecked)
CallerHmiViewControlListenerManager.invokeFuncMode(FUNC_MODE_RAIN, isChecked)
@@ -502,7 +493,6 @@ internal class SOPSettingView @JvmOverloads constructor(
FunctionBuildConfig.isWeakNetSlowDown = isChecked
CallerAutoPilotControlManager.sendWeakNetSlowDown(isChecked)
hmiAction("SOP 弱网减速停车, ", isChecked)
Log.i(TAG, "SOP 弱网减速停车, $isChecked")
}
//故障减速停车
@@ -511,7 +501,6 @@ internal class SOPSettingView @JvmOverloads constructor(
FunctionBuildConfig.isFaultSlowDown = isChecked
CallerAutoPilotControlManager.sendBreakdownSlowDown(isChecked)
hmiAction("SOP 故障减速停车, ", isChecked)
Log.i(TAG, "SOP 故障减速停车, $isChecked")
}
//融合模式
rgFusionMode.setOnCheckedChangeListener { _, p1 ->
@@ -538,11 +527,13 @@ internal class SOPSettingView @JvmOverloads constructor(
}
}
hmiAction("SOP 融合模式, ", FunctionBuildConfig.fusionMode)
Log.i(TAG, "SOP 融合模式, ${FunctionBuildConfig.fusionMode}")
CallerAutoPilotControlManager.sendFusionMode(FunctionBuildConfig.fusionMode)
}
}
private var overTakeEditText: String = ""
private var overTakeEditDel = false
/**
* 其他类别开关设置
*/
@@ -551,7 +542,6 @@ internal class SOPSettingView @JvmOverloads constructor(
scTrafficLight.isChecked = !HmiBuildConfig.isShowTrafficLightView
scTrafficLight.setOnCheckedChangeListener { _, isChecked ->
hmiAction("SOP 红绿灯标识开关, ", isChecked)
Log.i(TAG, "SOP 红绿灯标识开关, $isChecked")
if (isChecked) {
CallerHmiManager.showTrafficLightView()
} else {
@@ -563,13 +553,18 @@ internal class SOPSettingView @JvmOverloads constructor(
scSpeedLimit.isChecked = HmiBuildConfig.isShowLimitingVelocityView
scSpeedLimit.setOnCheckedChangeListener { _, isChecked ->
hmiAction("SOP 限速标识开关, ", isChecked)
Log.i(TAG, "SOP 限速标识开关, $isChecked")
if (isChecked) {
HmiBuildConfig.isShowLimitingVelocityView = true
CallerHmiViewControlListenerManager.invokeVisible(IViewControlListener.LimitingVelocityView_TAG, View.VISIBLE)
CallerHmiViewControlListenerManager.invokeVisible(
IViewControlListener.LimitingVelocityView_TAG,
View.VISIBLE
)
} else {
HmiBuildConfig.isShowLimitingVelocityView = false
CallerHmiViewControlListenerManager.invokeVisible(IViewControlListener.LimitingVelocityView_TAG, View.GONE)
CallerHmiViewControlListenerManager.invokeVisible(
IViewControlListener.LimitingVelocityView_TAG,
View.GONE
)
}
}
@@ -577,7 +572,6 @@ internal class SOPSettingView @JvmOverloads constructor(
scIPCReport.isChecked = FunctionBuildConfig.isReportWarning
scIPCReport.setOnCheckedChangeListener { _, isChecked ->
hmiAction("SOP 是否开启异常上报, ", isChecked)
Log.i(TAG, "SOP 是否开启异常上报, $isChecked")
FunctionBuildConfig.isReportWarning = isChecked
}
@@ -603,7 +597,6 @@ internal class SOPSettingView @JvmOverloads constructor(
scShowBagRecordWindow.setOnCheckedChangeListener { _, isChecked ->
FunctionBuildConfig.isShowBagRecordWindow = isChecked
hmiAction("SOP 是否展示被动触发的录包弹窗, ", isChecked)
Log.i(TAG, "SOP 是否展示被动触发的录包弹窗, $isChecked")
}
// 清扫车业务模式切换
@@ -670,7 +663,7 @@ internal class SOPSettingView @JvmOverloads constructor(
}
btnSpeedSet.setOnClickListener {
val isSuccess =
CallerAutoPilotControlManager.sendDetouringSpeed(FunctionBuildConfig.detouringSpeed.toDouble())
CallerAutoPilotControlManager.sendDetouringSpeed(FunctionBuildConfig.detouringSpeed.toDouble())
if (isSuccess == true) {
ToastUtils.showShort("变道绕障的目标障碍物速度阈值设置成功")
hmiAction("SOP 变道绕障的目标障碍物速度阈值设置", "成功")
@@ -680,14 +673,77 @@ internal class SOPSettingView @JvmOverloads constructor(
}
}
ivSpeedOverTakeReduce.setOnClickListener {
if (FunctionBuildConfig.overTakeSpeed <= 3) {
ToastUtils.showShort("阈值最小可为3 m/s")
} else {
FunctionBuildConfig.overTakeSpeed -= 0.5f
tvOverTakeLimit.text = "${FunctionBuildConfig.overTakeSpeed} m/s"
}
hmiAction("SOP 超车目标障碍物速度阈值", FunctionBuildConfig.overTakeSpeed)
}
ivSpeedOverTakeAdd.setOnClickListener {
if (FunctionBuildConfig.overTakeSpeed >= 12.5) {
ToastUtils.showShort("阈值最大可为12.5 m/s")
} else {
FunctionBuildConfig.overTakeSpeed += 0.5f
tvOverTakeLimit.text = "${FunctionBuildConfig.overTakeSpeed} m/s"
}
hmiAction("SOP 超车目标障碍物速度阈值", FunctionBuildConfig.overTakeSpeed)
}
btnSpeedOverTakeSet.setOnClickListener {
val isSuccess =
CallerAutoPilotControlManager.sendOvertakeMaxSpeed(FunctionBuildConfig.overTakeSpeed.toDouble())
if (isSuccess == true) {
ToastUtils.showShort("SOP 超车目标障碍物速度阈值设置成功")
hmiAction("SOP 超车目标障碍物速度阈值设置", "成功")
} else {
ToastUtils.showShort("SOP 超车目标障碍物速度阈值设置失败")
hmiAction("SOP 超车目标障碍物速度阈值设置", "失败")
}
}
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
tvSpeedOverTakeLimit.visibility = View.GONE
ivSpeedOverTakeReduce.visibility = View.GONE
tvOverTakeLimit.visibility = View.GONE
ivSpeedOverTakeAdd.visibility = View.GONE
btnSpeedOverTakeSet.visibility = View.GONE
}
val virtualTaskPullTaskInterval = CallerUnmannedListenerManager.getVirtualTaskPullTaskInterval()
rbFive.isChecked = virtualTaskPullTaskInterval == 5
rbFifteen.isChecked = virtualTaskPullTaskInterval == 15
rbThirty.isChecked = virtualTaskPullTaskInterval == 30
rbFortyFive.isChecked = virtualTaskPullTaskInterval == 45
rgPullTime.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.rbFortyFive -> {
CallerUnmannedListenerManager.dispatchVirtualTaskPullTaskInterval(45)
}
R.id.rbThirty -> {
CallerUnmannedListenerManager.dispatchVirtualTaskPullTaskInterval(30)
}
R.id.rbFifteen -> {
CallerUnmannedListenerManager.dispatchVirtualTaskPullTaskInterval(15)
}
R.id.rbFive -> {
CallerUnmannedListenerManager.dispatchVirtualTaskPullTaskInterval(5)
}
}
}
rgPullTime.visibility =
if(AppIdentityModeUtils.isTaxiDriver(FunctionBuildConfig.appIdentityMode))
View.VISIBLE
else
View.GONE
/**
* 魔方sop运营相关配置
*/
@@ -695,7 +751,10 @@ internal class SOPSettingView @JvmOverloads constructor(
val mf = CallerDevaToolsManager.mofang()
if (mf != null) {
mfStatusLayout.setClickEnabled(true)
mfStatusLayout.setClickedTextAndTag(if (mf.isConnected()) "断开魔方连接" else "开始连接魔方", if (mf.isConnected()) 0 else 1)
mfStatusLayout.setClickedTextAndTag(
if (mf.isConnected()) "断开魔方连接" else "开始连接魔方",
if (mf.isConnected()) 0 else 1
)
mf.registerMoFangStatusListener(TAG, this)
mfStatusLayout.setOnClickCallback {
val tag = it.tag as? Int
@@ -735,17 +794,17 @@ internal class SOPSettingView @JvmOverloads constructor(
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
//添加 业务配置监听
CallerDevaToolsFuncConfigListenerManager.registerDevaToolsFuncConfigListener(
FuncBizConfig.FOUNDATION, TAG, true, this
FuncBizConfig.FOUNDATION, TAG, true, this
)
CallerHmiViewControlListenerManager.addListener(TAG, this)
CallerAutopilotGetParamResponseDispatcher.addListener(TAG, this)
//查询融合模式
CallerAutoPilotControlManager.sendGetParamReq(AdasConstants.MapSystemParamType.FUSION_MODE)
CallerAutoPilotControlManager.sendGetParamReq(AdasConstants.MapSystemParamType.OVERTAKE_MAX_SPEED)
//雨天、美化、点云设置同步
CallerSopSettingManager.addListener(TAG, this)
}
@@ -763,7 +822,10 @@ internal class SOPSettingView @JvmOverloads constructor(
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
// 移除 业务配置监听
CallerDevaToolsFuncConfigListenerManager.unRegisterDevaToolsFuncConfigListener(FuncBizConfig.FOUNDATION, TAG)
CallerDevaToolsFuncConfigListenerManager.unRegisterDevaToolsFuncConfigListener(
FuncBizConfig.FOUNDATION,
TAG
)
CallerHmiViewControlListenerManager.removeListener(TAG)
CallerAutopilotGetParamResponseDispatcher.removeListener(TAG)
CallerDevaToolsManager.mofang()?.unRegisterMoFangStatusListener(this)
@@ -862,9 +924,9 @@ internal class SOPSettingView @JvmOverloads constructor(
* 工控机配置参数获取
*/
override fun onGetParamResp(
header: MessagePad.Header,
getParamResp: MessagePad.SetParamReq,
adasParam: AdasParam
header: MessagePad.Header,
getParamResp: MessagePad.SetParamReq,
adasParam: AdasParam
) {
//融合模式
ThreadUtils.runOnUiThread {
@@ -874,27 +936,26 @@ internal class SOPSettingView @JvmOverloads constructor(
//全融合模式
rgFusionMode.check(R.id.rbFullIntegration)
}
2 -> {
//盲区模式
rgFusionMode.check(R.id.rbBlind)
}
3 -> {
//超视距模式
rgFusionMode.check(R.id.rbBeyondSight)
}
4 -> {
//透传模式
rgFusionMode.check(R.id.rbTransparent)
}
5 -> {
//纯路侧模式
rgFusionMode.check(R.id.rbPureRoad)
}
}
val overTakeSpeed = adasParam.overtakeMaxSpeed
tvOverTakeLimit.text = "$overTakeSpeed m/s"
}
}
}

View File

@@ -15,6 +15,7 @@ import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig
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.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager
@@ -251,6 +252,12 @@ internal class AutoPilotAndCheckView @JvmOverloads constructor(
private fun initOchView() {
actvLoginout.onClick {
if (CallerAutoPilotStatusListenerManager.getState() == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
|| CallerAutoPilotStatusListenerManager.getState() == IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING
) {
ToastUtils.showShort("请稍后退出")
return@onClick
}
EventBus.getDefault().post(EventLogout(EventLogout.LOGOUT_TYPE))
//将消息盒子操作记录还原
MsgBoxConfig.setUserRecord(0)

View File

@@ -10,7 +10,7 @@ import com.mogo.eagle.core.data.temp.EventLogout
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.SharedPrefs
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.StringUtils
import kotlinx.android.synthetic.main.view_och_bus_operation.view.*
import org.greenrobot.eventbus.EventBus
@@ -28,7 +28,7 @@ class BusOperationView @JvmOverloads constructor(
init {
LayoutInflater.from(context).inflate(R.layout.view_och_bus_operation,this,true)
context?.let {
actvAccountPhone.text = phoneMask(SharedPrefs.getInstance(it).getString("och_account",""))
actvAccountPhone.text = phoneMask(SharedPrefsMgr.getInstance(it).getString("och_account",""))
}
clickPersonalRightView()
clickQRBtn()
@@ -69,7 +69,7 @@ class BusOperationView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
context?.let {
actvAccountPhone.text = phoneMask(SharedPrefs.getInstance(it).getString("och_account",""))
actvAccountPhone.text = phoneMask(SharedPrefsMgr.getInstance(it).getString("och_account",""))
}
}

View File

@@ -1,6 +1,8 @@
package com.mogo.eagle.core.function.hmi.ui.utils
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.zhjt.service.chain.ChainLog
class HmiActionLog {
@@ -8,12 +10,13 @@ class HmiActionLog {
companion object {
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_HMI,
linkChainLog = ChainConstant.CHAIN_TYPE_STATUS,
linkCode = ChainConstant.CHAIN_SOURCE_HMI,
nodeAliasCode = ChainConstant.CHAIN_CODE_HMI_ACTIONS,
paramIndexes = [0, 1]
)
fun hmiAction(data: Any, data1: Any) {
CallerLogger.d(M_HMI + data.toString(), data1)
}
}

View File

@@ -103,7 +103,7 @@ class PncActionsView @JvmOverloads constructor(
it.drivingAction.number
)
&& mTrafficLightResult != null
&& getWaitTrafficLightTime().isNotBlank()
&& hasRedLight()
) {
actions += ",预计${getWaitTrafficLightTime()}秒后通过"
} else {
@@ -133,11 +133,15 @@ class PncActionsView @JvmOverloads constructor(
mTrafficLightResult = trafficLightResult
}
private fun hasRedLight(): Boolean {
return mTrafficLightResult != null
&& mTrafficLightResult!!.currentRoadTrafficLight() != null
&& mTrafficLightResult!!.currentRoadTrafficLight()!!.isRed()
&& mTrafficLightResult!!.currentRoadTrafficLight()!!.time() > 0
}
private fun getWaitTrafficLightTime(): String {
return if (mTrafficLightResult != null
&& mTrafficLightResult!!.currentRoadTrafficLight() != null
&& mTrafficLightResult!!.currentRoadTrafficLight()!!.isRed()
) {
return if (hasRedLight()) {
mTrafficLightResult!!.currentRoadTrafficLight()!!.time().toString()
} else {
""

View File

@@ -46,7 +46,7 @@ class SteeringBrakeView(context: Context, attrs: AttributeSet?) : ConstraintLayo
}
override fun onChassisLocationWGS84(gnssInfo: MogoLocation) {
//设置刹车信息,小于默认认为是刹车 //todo 优化sp获取不要每次回调都去调用sp
//设置刹车信息,小于默认认为是刹车 //todo emArrow 优化sp获取不要每次回调都去调用sp
brakeLight =
if (gnssInfo.acceleration < SharedPrefsMgr.getInstance(Utils.getApp()).getFloat(
MoGoConfig.BRAKE_ACCELERATION_THRESHOLD, -2.5f
@@ -61,7 +61,7 @@ class SteeringBrakeView(context: Context, attrs: AttributeSet?) : ConstraintLayo
"---onAutopilotLightSwitchData ---Acceleration = " + gnssInfo.acceleration + "-- brakeLight = " + brakeLight
)
ThreadUtils.runOnUiThread {
if (!isShowTurnLight) { //在不展示转向灯的情况下,展示车辆刹车的动效
if (!isShowTurnLight) { //在不展示转向灯的情况下,展示车辆刹车的动效 todo emArrow 逻辑放入地图
brakeView.visibility = View.VISIBLE
brakeView.setBrakeLight(brakeLight)
} else {

View File

@@ -3,7 +3,6 @@ package com.mogo.eagle.core.function.hmi.ui.vehicle
import android.content.Context
import android.os.CountDownTimer
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
@@ -21,6 +20,8 @@ import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.function.hmi.R
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_HMI
import com.mogo.eagle.core.utilcode.util.SoundPoolUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.zhjt.mogo.adas.data.bean.MogoReport
@@ -55,13 +56,10 @@ class TakeOverView @JvmOverloads constructor(
}
override fun onAutopilotStatusResponse(state: Int) {
Log.i(TAG, "onAutopilotStatusResponse state=$state")
if(state == 7){
isParallel = true
Log.i(TAG, "onAutopilotStatusResponse isParallel status=true")
}else if(state == 0 || state == 1){
isParallel = false
Log.i(TAG, "onAutopilotStatusResponse isParallel status=false")
}
}
@@ -119,10 +117,10 @@ class TakeOverView @JvmOverloads constructor(
//弱网
MogoReport.Code.Error.EPARALLEL.AICLOUD_NETWORK_WEAK,
MogoReport.Code.Error.EPARALLEL.AICLOUD_CONNECTION_ERROR -> {
Log.i(TAG, "收到弱网上报,当前自驾状态=$isParallel")
CallerLogger.i(M_HMI + TAG, "收到弱网上报,当前自驾状态=$isParallel")
//如果是平行驾驶状态下,提示弱网接管
if(isParallel){
Log.i(TAG,"是平行驾驶状态下,提示弱网接管")
CallerLogger.i(M_HMI + TAG,"是平行驾驶状态下,提示弱网接管")
if(AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)){
//M1仅做提示音和消息盒子无语音播报和提示接管动画
showM1ParallelDrivingWarning(EventTypeEnumNew.NETWORK_WEAK_EVENT.poiType,

View File

@@ -53,7 +53,6 @@ class BatteryView : View , IMoGoSkinModeChangeListener {
) : super(context, attrs, defStyleAttr) {
}
@SuppressLint("NewApi")
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(width.toInt(), height.toInt())

View File

@@ -3,6 +3,7 @@ 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 androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.commons.module.status.MogoStatusManager
@@ -76,6 +77,16 @@ class RomaBusView @JvmOverloads constructor(
}
}
override fun romaViewStatus(status: Boolean) {
ThreadUtils.runOnUiThread {
if(status){
this.visibility = View.VISIBLE
} else {
this.visibility = View.GONE
}
}
}
override fun romaStatus(status: Boolean) {
ThreadUtils.runOnUiThread {
click = true

View File

@@ -6,7 +6,6 @@ import android.os.Looper
import android.os.Message
import android.text.Html
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
@@ -91,7 +90,6 @@ class RomaDistanceView @JvmOverloads constructor(
override fun romaDistance(distance: String) {
super.romaDistance(distance)
dis = distance.toDouble().toInt()
Log.i(TAG, "romaDistance:$dis")
}
override fun onDetachedFromWindow() {

View File

@@ -3,6 +3,7 @@ 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 androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.eagle.core.function.api.map.roma.IMoGoRomaListener
@@ -67,6 +68,29 @@ class RomaPassengerView @JvmOverloads constructor(
}
}
override fun romaViewStatus(status: Boolean) {
ThreadUtils.runOnUiThread {
if(status){
this.visibility = View.VISIBLE
} else {
this.visibility = View.GONE
}
}
}
/**
* 外部调用visible时进行判断
*/
fun updateVisible(visible: Boolean){
if(visible){
if(CallerMapRomaListener.isRange()){
this.visibility = View.VISIBLE
}
}else{
this.visibility = View.GONE
}
}
override fun romaStatus(status: Boolean) {
ThreadUtils.runOnUiThread {
click = true

View File

@@ -3,6 +3,7 @@ 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 androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.commons.module.status.MogoStatusManager
@@ -76,6 +77,16 @@ class RomaTaxiView @JvmOverloads constructor(
}
}
override fun romaViewStatus(status: Boolean) {
ThreadUtils.runOnUiThread {
if(status){
this.visibility = View.VISIBLE
} else {
this.visibility = View.GONE
}
}
}
override fun romaStatus(status: Boolean) {
ThreadUtils.runOnUiThread {
click = true

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