工控机升级和异常上报

1、工控机异常上报弹窗提示
2、修改调试窗
3、工控机升级长链接监听
This commit is contained in:
xuxinchao
2022-05-13 17:38:58 +08:00
parent 36be0a8574
commit b8576667cf
17 changed files with 504 additions and 166 deletions

View File

@@ -1,7 +1,6 @@
package com.mogo.eagle.core.function.bindingcar;
import android.content.Context;
import android.util.Log;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
@@ -10,6 +9,7 @@ import com.mogo.eagle.core.data.constants.MogoServicePaths;
import com.mogo.eagle.core.function.api.bindingcar.BindingcarCallBack;
import com.mogo.eagle.core.function.api.bindingcar.IMoGoBindingcarProvider;
import com.mogo.eagle.core.function.bindingcar.network.BindingcarNetWorkManager;
import com.mogo.eagle.core.function.ipcupgrade.IPCUpgradeManager;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import org.jetbrains.annotations.NotNull;
@@ -34,12 +34,13 @@ public class BindingcarProvider implements IMoGoBindingcarProvider {
@Override
public void onDestroy() {
IPCUpgradeManager.Companion.getINSTANCE().destroy();
}
@Override
public void init(Context context) {
mContext = context;
IPCUpgradeManager.Companion.getINSTANCE().initServer(context);
}
/**

View File

@@ -0,0 +1,64 @@
package com.mogo.eagle.core.function.ipcupgrade
import android.content.Context
import android.util.Log
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo
import com.mogo.eagle.core.data.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
/**
* @author XuXinChao
* @description 工控机镜像版本升级管理
* @since: 2022/5/12
*/
class IPCUpgradeManager: IMogoOnMessageListener<IPCUpgradeStateInfo> ,
IMoGoAutopilotStatusListener {
companion object{
const val TAG ="IPCUpgradeManager"
const val IPC_UPGRADE_MSG_TYPE = 50000
val INSTANCE: IPCUpgradeManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
IPCUpgradeManager()
}
}
private var mContext: Context? = null
fun initServer(context: Context){
mContext = context
//添加长链接监听
MogoAiCloudSocketManager.getInstance(context)
.registerOnMessageListener(IPC_UPGRADE_MSG_TYPE, this)
// 添加 ADAS状态 监听
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
}
override fun target(): Class<IPCUpgradeStateInfo> {
return IPCUpgradeStateInfo::class.java
}
override fun onMsgReceived(obj: IPCUpgradeStateInfo?) {
}
/**
* 自动驾驶状态信息
* @param autoPilotStatusInfo 状态信息
*/
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
}
fun destroy(){
//注销长链接监听
MogoAiCloudSocketManager.getInstance(mContext)
.unregisterLifecycleListener(IPC_UPGRADE_MSG_TYPE)
// 移除 ADAS状态 监听
CallerAutoPilotStatusListenerManager.removeListener(TAG)
mContext = null
}
}

View File

@@ -11,6 +11,7 @@ import com.mogo.eagle.core.function.check.net.CheckNetWork.checkNetWork
import com.mogo.eagle.core.function.check.net.CheckResultData
import com.mogo.eagle.core.function.check.view.CheckActivity
import com.mogo.eagle.core.function.check.view.CheckDialog
import com.mogo.eagle.core.function.report.IPCReportManager
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.module.common.MogoApisHandler
import com.mogo.service.statusmanager.IMogoStatusChangedListener
@@ -31,6 +32,10 @@ class VehicleMonitoringManager : ICheckProvider, IMogoStatusChangedListener {
private val mListeners: ConcurrentHashMap<String, IMogoCheckListener> = ConcurrentHashMap()
private var hasTipShow = false //是否已经弹框提示
var dialog: CheckDialog? = null
override val functionName: String
get() = "VehicleMonitoringManager"
override fun init(context: Context) {
mContext = context
MogoApisHandler.getInstance().apis.statusManagerApi.registerStatusChangedListener(
@@ -38,6 +43,8 @@ class VehicleMonitoringManager : ICheckProvider, IMogoStatusChangedListener {
StatusDescriptor.MAIN_PAGE_RESUME,
this
)
//开启工控机监控节点上报服务
IPCReportManager.INSTANCE.initServer()
}
override fun registerVehicleMonitoringListener(module: String, listener: IMogoCheckListener) {
@@ -113,4 +120,10 @@ class VehicleMonitoringManager : ICheckProvider, IMogoStatusChangedListener {
}
}
}
override fun onDestroy() {
//停止工控机监控节点上报服务
IPCReportManager.INSTANCE.destroy()
}
}

View File

@@ -0,0 +1,58 @@
package com.mogo.eagle.core.function.report
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.report.ReportEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import mogo_msg.MogoReportMsg
/**
* @author XuXinChao
* @description 工控机监控节点信息上报管理
* @since: 2022/5/12
*/
class IPCReportManager : IMoGoAutopilotStatusListener {
private var ipcReportList = arrayListOf<ReportEntity>()
companion object{
const val TAG ="IPCReportManager"
val INSTANCE: IPCReportManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
IPCReportManager()
}
}
fun initServer(){
// 添加 ADAS状态 监听
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
}
/**
*工控机监控节点上报
*/
override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
guardianInfo?.let{
if(it.level=="error"){
if(ipcReportList.size>20){
ipcReportList.removeLast()
}
ipcReportList.add(0,
ReportEntity(TimeUtils.millis2String(System.currentTimeMillis()),
it.src,it.level,it.msg,it.code,it.resultList,it.actionsList))
//当前不处于美化模式时,展示监控节点上报
if(!FunctionBuildConfig.isDemoMode){
CallerHmiManager.showIPCReportWindow(ipcReportList)
}
}
}
}
fun destroy(){
// 移除 ADAS状态 监听
CallerAutoPilotStatusListenerManager.removeListener(TAG)
}
}

View File

@@ -11,9 +11,9 @@ import android.view.WindowManager.LayoutParams
import android.view.animation.*
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.autopilot.AdUpgradeStateHelper
import com.mogo.eagle.core.data.camera.CameraEntity
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
@@ -47,6 +47,7 @@ import com.mogo.eagle.core.function.hmi.ui.camera.CameraListView
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeBannerView
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeNormalBannerView
import com.mogo.eagle.core.function.hmi.ui.setting.DebugSettingView
import com.mogo.eagle.core.function.hmi.ui.setting.IPCReportWindow
import com.mogo.eagle.core.function.hmi.ui.setting.ReportListFloatWindow
import com.mogo.eagle.core.function.hmi.ui.tools.AutoPilotAndCheckView
import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView
@@ -62,6 +63,7 @@ import kotlinx.coroutines.*
import mogo_msg.MogoReportMsg
import record_cache.RecordPanelOuterClass
import java.util.*
import kotlin.collections.ArrayList
/**
@@ -112,6 +114,8 @@ class MoGoHmiFragment : MvpFragment<MoGoHmiContract.View?, HmiPresenter?>(),
private var reportList = arrayListOf<ReportEntity>()
//工控机上报列表悬浮窗
private var reportListFloatWindow: ReportListFloatWindow?=null
private var ipcReportWindow: IPCReportWindow?=null
override fun vipIdentification(visible: Boolean) {
ThreadUtils.runOnUiThread {
@@ -210,13 +214,28 @@ class MoGoHmiFragment : MvpFragment<MoGoHmiContract.View?, HmiPresenter?>(),
ToastUtils.showShort("重启成功")
} else {
//重启失败
msg?.let {
msg.let {
ToastUtils.showShort(it)
}
}
}
}
/**
* 展示工控机监控上报数据
* @param reportList 上报数据列表
*/
override fun showIPCReportWindow(reportList: ArrayList<ReportEntity>) {
ThreadUtils.runOnUiThread{
if(ipcReportWindow==null){
ipcReportWindow= activity?.let { IPCReportWindow(it) }
ipcReportWindow?.showFloatWindow()
AIAssist.getInstance(AbsMogoApplication.getApp()).speakTTSVoice("")
}
ipcReportWindow?.refreshData(reportList)
}
}
/**
* 设置 V2X 通知 代理View
*/

View File

@@ -731,114 +731,7 @@ class DebugSettingView @JvmOverloads constructor(
CallerAutoPilotManager.recordPackage()
}
}
/**
* 工控机升级
*/
btnSystemUpgrade.onClick {
if (AppConfigInfo.isConnectAutopilot) {
Logger.i(
TAG,
"upgradeMode=" + upgradeMode + " downloadStatus=" + downloadStatus + " upgradeStatus=" + upgradeStatus
)
if (AdUpgradeStateHelper.isDownloading(downloadStatus)) {
//点击Toast提示下载剩余时间
ToastUtils.showShort(
"预计" + AdUpgradeStateHelper.getRemainingTime(
totalProgress,
previousProgress,
currentProgress
) + "下载完成"
)
} else if (AdUpgradeStateHelper.getUpgradeStatus()) {
//工控机状态为“升级中”
ToastUtils.showShort("新版本升级中预计5分钟升级完成")
} else if (AdUpgradeStateHelper.isUpgradeFailed(upgradeStatus)) {
//如果升级失败则Toast提示升级失败请联系运维人员
ToastUtils.showShort("升级失败,请联系运维人员")
} else if (AdUpgradeStateHelper.isHintUpgradeMode(upgradeMode) && AdUpgradeStateHelper.isDownloadFinish(
downloadStatus,
upgradeStatus
)
) {
//如果升级模式为“提示升级”,并且下载状态为已经下载完成,点击弹出升级确认弹窗
if (adUpgradeDialog == null) {
adUpgradeDialog = AdUpgradeDialog(context)
adUpgradeDialog?.setClickListener(object : AdUpgradeDialog.ClickListener {
override fun confirm() {
if (mAutoPilotStatusInfo?.state == 2) {
//当前处于自动驾驶状态不可进行升级Toast提示
ToastUtils.showShort("升级前请先退出自动驾驶模式")
} else {
//确认升级
Logger.i(TAG, "upgrade confirm")
//设置当前状态为“升级中”
AdUpgradeStateHelper.setUpgradeStatus(true)
CallerAutoPilotManager.setIPCUpgradeAffirm()
}
}
override fun cancel() {
//取消升级
Logger.i(TAG, "upgrade cancel")
//取消升级命令不下发
// CallerAutoPilotManager.setIPCUpgradeCancel()
}
})
}
adUpgradeDialog?.showUpgradeDialog()
} else {
ToastUtils.showShort("当前工控机处于最新版本状态,不可升级")
}
} else {
ToastUtils.showShort("域控制器未连接")
}
}
/**
* 重启系统
*/
btnSystemRestart.onClick {
if (AppConfigInfo.isConnectAutopilot) {
if (dockerRebootDialog == null) {
dockerRebootDialog = DockerRebootDialog(context)
dockerRebootDialog?.setClickListener(object : DockerRebootDialog.ClickListener {
override fun confirm() {
if (mAutoPilotStatusInfo?.state == 2) {
//当前处于自动驾驶状态不可进行重启Toast提示
ToastUtils.showShort("请先退出自动驾驶状态")
} else if (AdUpgradeStateHelper.showCannotReboot(
downloadStatus,
upgradeStatus
)
) {
//当工控机处于下载或者升级状态,需要先进行升级
ToastUtils.showShort("请先完成新自动驾驶系统的下载/升级")
} else {
//确认重启
Logger.i(TAG, "reboot confirm")
CallerAutoPilotManager.setIPCReboot()
}
}
override fun cancel() {
//取消重启
Logger.i(TAG, "reboot cancel")
}
})
}
dockerRebootDialog?.showUpgradeDialog()
} else {
ToastUtils.showShort("域控制器未连接")
}
}
}
/**
@@ -857,27 +750,6 @@ class DebugSettingView @JvmOverloads constructor(
}
}
/**
* 设置工控机下载、升级状态信息
* @param upgradeMode 升级模式(提示升级、静默升级)
* @param downloadStatus 下载状态
* @param currentProgress 当前已经下载包体大小
* @param totalProgress 下载包体总大小
* @param downloadVersion 下载版本
* @param upgradeStatus 升级状态
*/
fun setAdUpgradeInfo(
upgradeMode: Int, downloadStatus: Int, currentProgress: Int, totalProgress: Int,
downloadVersion: String, upgradeStatus: Int
) {
this.upgradeMode = upgradeMode
this.downloadStatus = downloadStatus
this.previousProgress = this.currentProgress
this.currentProgress = currentProgress
this.totalProgress = totalProgress
this.downloadVersion = downloadVersion
this.upgradeStatus = upgradeStatus
}
/**
* 设置Hmi点击监听

View File

@@ -0,0 +1,60 @@
package com.mogo.eagle.core.function.hmi.ui.setting
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.report.ReportEntity
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.hmi.R
/**
* @author XuXinChao
* @description 工控机异常节点上报适配器
* @since: 2022/5/12
*/
class IPCReportAdapter: RecyclerView.Adapter<IPCReportAdapter.IPCReportHolder>(){
private var data:List<ReportEntity>? = null
fun setData( data: List<ReportEntity>?){
this.data = data
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IPCReportHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_ipc_report, parent, false)
return IPCReportHolder(view)
}
override fun onBindViewHolder(holder: IPCReportHolder, position: Int) {
data?.let {it ->
val reportEntity = it[position]
reportEntity.let {
holder.tvReportTimeContent.text = it.time
var resultStr = "发生异常"
for (result in it.resultList){
resultStr = "${resultStr}-${CallerAutoPilotManager.getReportResultDesc(result)}"
}
holder.tvReportResultContent.text = resultStr
holder.tvReportMsgContent.text = it.msg
var actionStr = ""
for (action in it.actionsList){
actionStr = "${actionStr}-${CallerAutoPilotManager.getReportActionDesc(action)}"
}
holder.tvReportActionContent.text = actionStr
}
}
}
override fun getItemCount() = data?.size ?: 0
class IPCReportHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var tvReportTimeContent: TextView = itemView.findViewById(R.id.tvReportTimeContent)
var tvReportResultContent: TextView = itemView.findViewById(R.id.tvReportResultContent)
var tvReportMsgContent: TextView = itemView.findViewById(R.id.tvReportMsgContent)
var tvReportActionContent: TextView = itemView.findViewById(R.id.tvReportActionContent)
}
}

View File

@@ -0,0 +1,126 @@
package com.mogo.eagle.core.function.hmi.ui.setting
import android.app.Activity
import android.graphics.PixelFormat
import android.util.DisplayMetrics
import android.view.*
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.report.ReportEntity
import com.mogo.eagle.core.function.hmi.R
import java.lang.reflect.Field
/**
* @author XuXinChao
* @description 工控机异常节点上报
* @since: 2022/5/12
*/
class IPCReportWindow constructor(activity: Activity) : View.OnTouchListener{
private var mActivity: Activity = activity
private var mWindowParams: WindowManager.LayoutParams? = null
private var mWindowManager: WindowManager? = null
private lateinit var rvIPCReport: RecyclerView
private var ipcReportAdapter: IPCReportAdapter?=null
private lateinit var mFloatLayout: View
private var mInViewX = 0f
private var mInViewY = 0f
private var mDownInScreenX = 0f
private var mDownInScreenY = 0f
private var mInScreenX = 0f
private var mInScreenY = 0f
init {
initFloatWindow();
}
private fun initFloatWindow(){
mFloatLayout = LayoutInflater.from(mActivity).inflate(R.layout.view_ipc_report, null) as View
mFloatLayout.setOnTouchListener(this)
rvIPCReport= mFloatLayout.findViewById(R.id.rv_ipc_report)
mWindowParams = WindowManager.LayoutParams()
mWindowManager = mActivity.windowManager
mWindowParams?.let {
it.format = PixelFormat.RGBA_8888
it.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
it.gravity = Gravity.START or Gravity.TOP
it.width = 800
it.height = 1000
it.alpha = 0.9f
}
ipcReportAdapter = IPCReportAdapter()
rvIPCReport.layoutManager = LinearLayoutManager(mActivity,
LinearLayoutManager.VERTICAL,false)
rvIPCReport.adapter = ipcReportAdapter
}
fun refreshData(data:List<ReportEntity>){
ipcReportAdapter?.setData(data)
ipcReportAdapter?.notifyDataSetChanged()
}
override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
when (motionEvent?.action) {
MotionEvent.ACTION_DOWN -> {
// 获取相对View的坐标即以此View左上角为原点
mInViewX = motionEvent.x
mInViewY = motionEvent.y
// 获取相对屏幕的坐标,即以屏幕左上角为原点
mDownInScreenX = motionEvent.rawX
mDownInScreenY = motionEvent.rawY - getSysBarHeight(mActivity)
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY - getSysBarHeight(mActivity)
}
MotionEvent.ACTION_MOVE -> {
// 更新浮动窗口位置参数
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY - getSysBarHeight(mActivity)
mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
// 手指移动的时候更新小悬浮窗的位置
mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
}
// MotionEvent.ACTION_UP -> // 如果手指离开屏幕时xDownInScreen和xInScreen相等且yDownInScreen和yInScreen相等则视为触发了单击事件。
// if (mDownInScreenX === mInScreenX && mDownInScreenY === mInScreenY) {
// }
}
return true
}
fun showFloatWindow() {
if (mFloatLayout.parent == null) {
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)
mWindowManager!!.addView(mFloatLayout, mWindowParams)
}
}
fun hideFloatWindow() {
if (mFloatLayout.parent != null) mWindowManager!!.removeView(mFloatLayout)
}
// 获取系统状态栏高度
private fun getSysBarHeight(activity: Activity): Int {
val c: Class<*>
val obj: Any
val field: Field
val x: Int
var sbar = 0
try {
c = Class.forName("com.android.internal.R\$dimen")
obj = c.newInstance()
field = c.getField("status_bar_height")
x = field.get(obj).toString().toInt()
sbar = activity.resources.getDimensionPixelSize(x)
} catch (e1: Exception) {
e1.printStackTrace()
}
return sbar
}
}

View File

@@ -104,6 +104,7 @@ class SystemVersionView @JvmOverloads constructor(
CallerLogger.i("$M_HMI$$TAG", "upgrade confirm")
//设置当前状态为“升级中”
AdUpgradeStateHelper.setUpgradeStatus(true)
//TODO
CallerAutoPilotManager.setIPCUpgradeAffirm()
//将角标设为升级中
ivAdStatus?.setImageResource(R.drawable.icon_upgrading)

View File

@@ -0,0 +1,81 @@
<?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">
<TextView
android:id="@+id/tvReportTimeTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:id="@+id/tvReportTimeContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/tvReportTimeTitle"
/>
<TextView
android:id="@+id/tvReportResultTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvReportTimeTitle"
/>
<TextView
android:id="@+id/tvReportResultContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvReportResultTitle"
app:layout_constraintLeft_toRightOf="@id/tvReportResultTitle"
android:minLines="1"
/>
<TextView
android:id="@+id/tvReportMsgTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvReportResultContent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:id="@+id/tvReportMsgContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvReportMsgTitle"
app:layout_constraintLeft_toRightOf="@id/tvReportMsgTitle"
android:minLines="1"
/>
<TextView
android:id="@+id/tvReportActionTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvReportMsgContent"
/>
<TextView
android:id="@+id/tvReportActionContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tvReportActionTitle"
app:layout_constraintLeft_toRightOf="@id/tvReportActionTitle"
android:minLines="1"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F0F0F0"
app:layout_constraintTop_toBottomOf="@id/tvReportActionContent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -636,36 +636,13 @@
android:layout_height="1dp"
android:background="#F0F0F0"
app:layout_constraintTop_toBottomOf="@id/btnRecordPackage" />
<Button
android:id="@+id/btnSystemUpgrade"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="升级系统"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/btnSystemRestart"
app:layout_constraintTop_toBottomOf="@id/recordPackageDivider"
tools:visibility="visible" />
<Button
android:id="@+id/btnSystemRestart"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="重启系统"
android:visibility="gone"
app:layout_constraintLeft_toRightOf="@id/btnSystemUpgrade"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/recordPackageDivider"
tools:visibility="visible" />
<TextView
android:id="@+id/tvCarInfo"
style="@style/DebugSettingText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/btnSystemUpgrade" />
app:layout_constraintTop_toBottomOf="@id/recordPackageDivider" />
<TextView
android:id="@+id/tvIdentifyInfo"

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="840px"
android:layout_height="584px"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/icon_drag"
android:padding="15dp"
android:layout_gravity="center_horizontal"
/>
<com.mogo.eagle.core.widget.RoundConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dialog_bg_color"
app:roundLayoutRadius="10dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_ipc_report"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>
</LinearLayout>

View File

@@ -37,7 +37,7 @@
<string name="application_upgrade_confirm">是否将应用升级至最新版本?</string>
<string name="application_upgrade_tips">注意!升级时需退出自动驾驶,支持在人工驾驶时升级,升级时不可中途断电。</string>
<string name="confirm">确认</string>
<string name="cancel">取消</string>
<string name="cancel">稍后升级</string>
<!--绑定车机-->
<string name="bindingcar_title">绑定车机</string>