diff --git a/app_ipc_monitoring/build.gradle b/app_ipc_monitoring/build.gradle
index 3690d79c72..775aab3f0a 100644
--- a/app_ipc_monitoring/build.gradle
+++ b/app_ipc_monitoring/build.gradle
@@ -1,3 +1,5 @@
+import java.text.SimpleDateFormat
+
apply plugin: 'com.android.application'
android {
@@ -24,6 +26,15 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+ //插入构建时间
+ buildTypes.each {
+ //设置时间格式
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd.HHmmss", Locale.getDefault())
+ //获取当前时间
+ Date curDate = new Date(System.currentTimeMillis())
+ String buildTime = formatter.format(curDate)
+ it.buildConfigField 'String', 'BUILD_TIME', "\"${buildTime}\""
+ }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
@@ -44,13 +55,14 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.3.1'
- implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
+ implementation rootProject.ext.dependencies.material
+ implementation rootProject.ext.dependencies.androidxconstraintlayout
+ implementation rootProject.ext.dependencies.androidxappcompat
implementation 'androidx.recyclerview:recyclerview:1.2.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
- implementation "com.google.code.gson:gson:2.8.9"
+ implementation rootProject.ext.dependencies.gson
implementation project(':libraries:mogo-adas')
implementation project(':core:mogo-core-data')
implementation project(':core:mogo-core-utils')
diff --git a/app_ipc_monitoring/src/main/AndroidManifest.xml b/app_ipc_monitoring/src/main/AndroidManifest.xml
index 7b879c95e6..68c61efc7b 100644
--- a/app_ipc_monitoring/src/main/AndroidManifest.xml
+++ b/app_ipc_monitoring/src/main/AndroidManifest.xml
@@ -29,6 +29,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java
index 4a2eb6705f..aefb5ed711 100644
--- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java
@@ -10,6 +10,7 @@ import com.zhidao.adas.client.bean.GlobalPathResp;
import com.zhidao.adas.client.bean.GnssInfo;
import com.zhidao.adas.client.bean.MogoReportMessage;
import com.zhidao.adas.client.bean.PerceptionTrafficLight;
+import com.zhidao.adas.client.bean.PredictionObstacleTrajectory;
import com.zhidao.adas.client.bean.RecordPanel;
import com.zhidao.adas.client.bean.TrackedObjects;
import com.zhidao.adas.client.bean.Trajectory;
@@ -98,6 +99,7 @@ public class DataDistribution {
public final List listAutopilotState = new ArrayList<>();
public final List listMogoReportMessage = new ArrayList<>();
public final List listPerceptionTrafficLight = new ArrayList<>();
+ public final List listPredictionObstacleTrajectory = new ArrayList<>();
public final List listBasicInfoReq = new ArrayList<>();
public final List listRecordPanel = new ArrayList<>();
public final List listGlobalPathResp = new ArrayList<>();
@@ -114,7 +116,8 @@ public class DataDistribution {
}
private String onTransmit(String time, BaseInfo data) {
- String str = cutDown(data.toString());
+ String temp = data.toString();
+ String str = cutDown(temp);
if (data instanceof Trajectory) {
listTrajectory.add(0, time + str);
if (listTrajectory.size() > LIST_SIZE) {
@@ -205,6 +208,19 @@ public class DataDistribution {
// for (OnAdasClientListener listener : listeners) {
// listener.onPerceptionTrafficLight((PerceptionTrafficLight) data);
// }
+// }
+ } else if (data instanceof PredictionObstacleTrajectory) {
+ listPredictionObstacleTrajectory.add(0, time + str);
+ if (listPredictionObstacleTrajectory.size() > LIST_SIZE) {
+ listPredictionObstacleTrajectory.remove(listPredictionObstacleTrajectory.size() - 1);
+ }
+ if (listener != null) {
+ listener.onRefresh();
+ }
+// if (!listeners.isEmpty()) {
+// for (OnAdasClientListener listener : listeners) {
+// listener.onRefresh();
+// }
// }
} else if (data instanceof BasicInfoReq) {
listBasicInfoReq.add(0, time + str);
@@ -295,7 +311,7 @@ public class DataDistribution {
// }
}
- return str;
+ return temp;
}
private class WriteThread implements Runnable {
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/ConnectStatusAdapter.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/ConnectStatusAdapter.java
new file mode 100644
index 0000000000..5c6cd96285
--- /dev/null
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/ConnectStatusAdapter.java
@@ -0,0 +1,67 @@
+package com.zhidao.adas.client.adapter;
+
+import android.annotation.SuppressLint;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.zhidao.adas.client.R;
+import com.zhidao.adas.client.base.BaseAdapter;
+import com.zhidao.adas.client.base.BaseViewHolder;
+import com.zhidao.adas.client.bean.IPCConnectState;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+
+/**
+ * 连接状态
+ */
+public class ConnectStatusAdapter extends BaseAdapter {
+ private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ", Locale.getDefault());
+ private static final String POS = "%03d. ";
+
+ public void refreshView() {
+// notifyItemChanged(mDatas.size()-1,0);
+ notifyItemRangeChanged(0, getItemCount());
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @SuppressLint("SetTextI18n")
+ @Override
+ protected void onBindDataToItem(ViewHolder viewHolder, IPCConnectState data, int position) {
+ viewHolder.id.setText(String.format(Locale.getDefault(), POS, getItemCount() - position));
+ viewHolder.editText.setText(sdf.format(new Date(data.time)) + "\n" + data.status);
+ viewHolder.editText.setTextColor(mContext.getResources().getColor(data.color));
+ }
+
+ @Override
+ protected View getItemViewResource(ViewGroup viewGroup) {
+ return LayoutInflater.from(mContext).inflate(R.layout.item_status, viewGroup, false);
+ }
+
+
+ @Override
+ protected ViewHolder getViewHolder(View view) {
+ return new ViewHolder(view, this);
+ }
+
+
+ class ViewHolder extends BaseViewHolder {
+ EditText editText;
+ TextView id;
+
+ public ViewHolder(View itemView, ConnectStatusAdapter adapter) {
+ super(itemView, adapter);
+ editText = itemView.findViewById(R.id.log);
+ id = itemView.findViewById(R.id.id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseActivity.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseActivity.java
index b04a20f511..b89e5feca2 100644
--- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseActivity.java
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseActivity.java
@@ -2,14 +2,38 @@ package com.zhidao.adas.client.base;
import android.os.Handler;
import android.os.Message;
+import android.view.Gravity;
+import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
+import com.zhidao.adas.client.ui.MainActivity;
+
import java.lang.ref.WeakReference;
public abstract class BaseActivity extends AppCompatActivity {
private BaseHandler mBaseHandler;
+ private Toast toast;
+ protected void showToastCenter(String msg) {
+ showToastCenter(msg, Toast.LENGTH_SHORT);
+ }
+
+ protected void showToastCenter(String msg, int duration) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (toast != null) {
+ toast.cancel();
+ toast = null;
+ }
+ toast = Toast.makeText(BaseActivity.this, "", duration); //如果有居中显示需求
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ toast.setText(msg);
+ toast.show();
+ }
+ });
+ }
@Override
protected void onDestroy() {
super.onDestroy();
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/IPCConnectState.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/IPCConnectState.java
index d5ee3b31e3..cc1ca7c09b 100644
--- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/IPCConnectState.java
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/IPCConnectState.java
@@ -3,6 +3,7 @@ package com.zhidao.adas.client.bean;
import androidx.annotation.ColorRes;
public class IPCConnectState {
+ public final long time;
public final String status;
@ColorRes
public final int color;
@@ -10,5 +11,6 @@ public class IPCConnectState {
public IPCConnectState(String status, @ColorRes int color) {
this.status = status;
this.color = color;
+ time = System.currentTimeMillis();
}
}
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/PredictionObstacleTrajectory.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/PredictionObstacleTrajectory.java
new file mode 100644
index 0000000000..5ea6472a70
--- /dev/null
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/PredictionObstacleTrajectory.java
@@ -0,0 +1,22 @@
+package com.zhidao.adas.client.bean;
+
+import com.google.protobuf.TextFormat;
+
+import mogo.telematics.pad.MessagePad;
+import prediction.Prediction;
+
+public class PredictionObstacleTrajectory extends BaseInfo {
+ public final Prediction.mPredictionObjects bean;
+
+ public PredictionObstacleTrajectory(MessagePad.Header header, Prediction.mPredictionObjects bean) {
+ super("接收", bean.getSerializedSize(), header);
+ this.bean = bean;
+ }
+
+
+ @Override
+ public String toString() {
+ return super.toString() + TextFormat.printer().escapingNonAscii(false).printToString(bean);
+ }
+
+}
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/FloatWindow.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/FloatWindow.java
new file mode 100644
index 0000000000..67a7a2ce87
--- /dev/null
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/FloatWindow.java
@@ -0,0 +1,181 @@
+package com.zhidao.adas.client.ui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.zhidao.adas.client.R;
+import com.zhidao.adas.client.adapter.ConnectStatusAdapter;
+import com.zhidao.adas.client.adapter.DataShowAdapter;
+import com.zhidao.adas.client.bean.IPCConnectState;
+import com.zhidao.adas.client.utils.MyLinearLayoutManager;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+/**
+ * @author xuxinchao
+ * @description
+ * @since: 2022/4/20
+ */
+public class FloatWindow implements View.OnTouchListener {
+
+ private final Activity mContext;
+ private WindowManager.LayoutParams mWindowParams;
+ private WindowManager mWindowManager;
+
+ private View mFloatLayout;
+ private float mInViewX;
+ private float mInViewY;
+ private float mDownInScreenX;
+ private float mDownInScreenY;
+ private float mInScreenX;
+ private float mInScreenY;
+ private RecyclerView rv_status;
+ private ConnectStatusAdapter adapter;
+ private List list;
+
+ public FloatWindow(Activity context, List list) {
+ this.mContext = context;
+ this.list = list;
+ initFloatWindow();
+ }
+ public void refreshView(){
+ if (adapter!=null){
+ adapter.refreshView();
+ }
+ }
+
+ private void initRV() {
+ //创建默认的线性LayoutManager 横向的GridLayoutManager
+ MyLinearLayoutManager linearLayoutManager = new MyLinearLayoutManager(mContext);
+// linearLayoutManager.setStackFromEnd(true);//列表再底部开始展示,反转后由上面开始展示
+// linearLayoutManager.setReverseLayout(true);//列表翻转
+ rv_status.setLayoutManager(linearLayoutManager);
+ //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
+ rv_status.setHasFixedSize(false);
+ rv_status.setNestedScrollingEnabled(false);
+ adapter = new ConnectStatusAdapter();
+ adapter.setHasStableIds(true);
+ rv_status.setAdapter(adapter);
+ adapter.setData(list);
+ }
+
+ private void initFloatWindow() {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ if (inflater == null)
+ return;
+ mFloatLayout = (View) inflater.inflate(R.layout.layout_float, null);
+ rv_status = mFloatLayout.findViewById(R.id.rv_status);
+ mFloatLayout.setOnTouchListener(this);
+ initRV();
+ mWindowParams = new WindowManager.LayoutParams();
+// mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+// if (Build.VERSION.SDK_INT >= 26) {//8.0新特性
+// mWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+// }else{
+// mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+// }
+
+ mWindowManager = mContext.getWindowManager();
+
+ mWindowParams.format = PixelFormat.RGBA_8888;
+ mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ mWindowParams.gravity = Gravity.START | Gravity.TOP;
+ mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
+ mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ mWindowParams.alpha = 0.9F;
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ return floatLayoutTouch(motionEvent);
+ }
+
+ private boolean floatLayoutTouch(MotionEvent motionEvent) {
+ switch (motionEvent.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ // 获取相对View的坐标,即以此View左上角为原点
+ mInViewX = motionEvent.getX();
+ mInViewY = motionEvent.getY();
+ // 获取相对屏幕的坐标,即以屏幕左上角为原点
+ mDownInScreenX = motionEvent.getRawX();
+ mDownInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
+ mInScreenX = motionEvent.getRawX();
+ mInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ // 更新浮动窗口位置参数
+ mInScreenX = motionEvent.getRawX();
+ mInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
+ mWindowParams.x = (int) (mInScreenX - mInViewX);
+ mWindowParams.y = (int) (mInScreenY - mInViewY);
+ // 手指移动的时候更新小悬浮窗的位置
+ mWindowManager.updateViewLayout(mFloatLayout, mWindowParams);
+ break;
+ case MotionEvent.ACTION_UP:
+ // 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
+ if (mDownInScreenX == mInScreenX && mDownInScreenY == mInScreenY) {
+
+ }
+ break;
+ }
+ return true;
+ }
+
+ public void showFloatWindow(float y) {
+ if (mFloatLayout.getParent() == null) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ // 默认固定位置,靠屏幕右边缘的中间
+ mWindowManager.getDefaultDisplay().getMetrics(metrics);
+ mWindowParams.x = metrics.widthPixels;
+ mWindowParams.y = (int) (y);
+ mWindowManager.addView(mFloatLayout, mWindowParams);
+ }
+ }
+
+
+ public void hideFloatWindow() {
+ if (mFloatLayout.getParent() != null)
+ mWindowManager.removeView(mFloatLayout);
+ }
+
+ public void setFloatLayoutAlpha(boolean alpha) {
+ if (alpha)
+ mFloatLayout.setAlpha((float) 0.5);
+ else
+ mFloatLayout.setAlpha(1);
+ }
+
+ private int sbar = -1;
+
+ // 获取系统状态栏高度
+ public int getSysBarHeight(Context contex) {
+ if (sbar == -1) {
+ Class> c;
+ Object obj;
+ Field field;
+ int x;
+ sbar = 0;
+ try {
+ c = Class.forName("com.android.internal.R$dimen");
+ obj = c.newInstance();
+ field = c.getField("status_bar_height");
+ x = Integer.parseInt(field.get(obj).toString());
+ sbar = contex.getResources().getDimensionPixelSize(x);
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ }
+ }
+ return sbar;
+ }
+
+}
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/HelpActivity.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/HelpActivity.java
new file mode 100644
index 0000000000..e9c5cf6607
--- /dev/null
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/HelpActivity.java
@@ -0,0 +1,22 @@
+package com.zhidao.adas.client.ui;
+
+import android.os.Bundle;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.zhidao.adas.client.R;
+import com.zhidao.adas.client.base.BaseActivity;
+
+public class HelpActivity extends BaseActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_help);
+ showToastCenter("点击屏幕任意位置,退出帮助页面");
+ }
+
+ public void onBack(View view) {
+ finish();
+ }
+}
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java
index 0efabf141b..4ea018b8ea 100644
--- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java
@@ -146,6 +146,9 @@ public class InfoFragment extends BaseFragment {
case Constants.TITLE.RECEIVE_PERCEPTION_TRAFFIC_LIGHT:
adapter.setData(DataDistribution.getInstance().listPerceptionTrafficLight);
break;
+ case Constants.TITLE.RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY:
+ adapter.setData(DataDistribution.getInstance().listPredictionObstacleTrajectory);
+ break;
case Constants.TITLE.RECEIVE_ERROR:
adapter.setData(DataDistribution.getInstance().listErrorData);
break;
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java
index c44ba91b5e..c74df8e22b 100644
--- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java
@@ -4,6 +4,7 @@ import static com.mogo.telematic.MogoProtocolMsg.NORMAL_DATA;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Message;
@@ -57,6 +58,7 @@ import com.zhidao.adas.client.bean.IPCConnectState;
import com.zhidao.adas.client.bean.MogoReportMessage;
import com.zhidao.adas.client.bean.MySSHResult;
import com.zhidao.adas.client.bean.PerceptionTrafficLight;
+import com.zhidao.adas.client.bean.PredictionObstacleTrajectory;
import com.zhidao.adas.client.bean.RecordPanel;
import com.zhidao.adas.client.bean.TrackedObjects;
import com.zhidao.adas.client.bean.Trajectory;
@@ -76,7 +78,6 @@ import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
-import com.zhidao.support.recorder.RecordDataManager;
import java.net.Inet4Address;
import java.net.InetAddress;
@@ -92,13 +93,14 @@ import io.netty.channel.Channel;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
import perception.TrafficLightOuterClass;
+import prediction.Prediction;
import record_cache.RecordPanelOuterClass;
public class MainActivity extends BaseActivity implements OnAdasListener, OnAdasConnectStatusListener, BaseAdapter.OnItemClickListener {
private final static String TAG = MainActivity.class.getSimpleName();
private static final int WHAT_IPC_IP = 0x00;
private static final int WHAT_DRIVER_IP = 0x01;
- private static final int WHATIPC_CONNECT_STATE = 0x02;
+ private static final int WHAT_IPC_CONNECT_STATE = 0x02;
private EditText etIp;
private ImageView role;
private ImageView tvIp;
@@ -124,7 +126,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
private final List titleFragmentData = new ArrayList<>();
private final List titleBtnData = new ArrayList<>();
-
+ private final List connectStatusList = new ArrayList<>();
private InfoTitleAdapter btnAdapter;
private InfoTitleAdapter fragmentAdapter;
@@ -141,6 +143,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
private InfoFragment errorFragment;
private InfoFragment reportMessageFragment;
private InfoFragment perceptionTrafficLightFragment;
+ private InfoFragment predictionObstacleTrajectoryFragment;
private VersionFragment versionFragment;
private FragmentManager manager;
private FragmentTransaction transaction;
@@ -151,7 +154,8 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
private int connectStatus;
private AutoPilotModeDialog autoPilotModeDialog;
private ListPopupWindow listPopupWindow;
-
+ private FloatWindow floatWindow;
+ private View include_title;
// @Override
// protected void onStart() {
// super.onStart();
@@ -207,6 +211,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
private void initView() {
+ include_title = findViewById(R.id.include_title);
etIp = findViewById(R.id.et_ip);
role = findViewById(R.id.role);
line = findViewById(R.id.line);
@@ -278,7 +283,6 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
etIp.setSelection(ip.length());
}
-// infoTitleList.add("录音测试");
//初始化fragment
manager = getSupportFragmentManager();
transaction = manager.beginTransaction();
@@ -379,6 +383,13 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
showLocalIP();
}
});
+ title.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ startActivity(new Intent(MainActivity.this, HelpActivity.class));
+ return true;
+ }
+ });
tvIp.setOnClickListener(new View.OnClickListener() {
@Override
@@ -393,6 +404,18 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
}
});
+ tvConnectState.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (floatWindow == null) {
+ floatWindow = new FloatWindow(MainActivity.this, connectStatusList);
+ floatWindow.showFloatWindow(include_title.getY() + include_title.getHeight());
+ } else {
+ floatWindow.hideFloatWindow();
+ floatWindow = null;
+ }
+ }
+ });
}
private void showListPopupWindow() {
@@ -431,6 +454,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
titleFragmentData.add(Constants.TITLE.RECEIVE_AUTOPILOT_STATE);
titleFragmentData.add(Constants.TITLE.RECEIVE_REPORT_MESSAGE);
titleFragmentData.add(Constants.TITLE.RECEIVE_PERCEPTION_TRAFFIC_LIGHT);
+ titleFragmentData.add(Constants.TITLE.RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY);
titleFragmentData.add(Constants.TITLE.RECEIVE_CAR_CONFIG_RESP);
titleFragmentData.add(Constants.TITLE.RECEIVE_RECORD_RESULT);
titleFragmentData.add(Constants.TITLE.RECEIVE_GLOBAL_PATH_RESP);
@@ -446,7 +470,6 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
titleBtnData.add("数据采集5秒");
titleBtnData.add("数据采集start");
titleBtnData.add("数据采集end");
- titleBtnData.add("录音测试");
titleBtnData.add("发送信号灯");
titleBtnData.add("自动驾驶限速");
titleBtnData.add("重启Docker");
@@ -588,6 +611,14 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
transaction.commit();
}
break;
+ case Constants.TITLE.RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY:
+ if (predictionObstacleTrajectoryFragment == null)
+ predictionObstacleTrajectoryFragment = new InfoFragment(data);
+ if (!predictionObstacleTrajectoryFragment.isVisible()) {
+ transaction.replace(R.id.fl_info, predictionObstacleTrajectoryFragment);
+ transaction.commit();
+ }
+ break;
case Constants.TITLE.RECEIVE_CAR_CONFIG_RESP:
AdasManager.getInstance().sendCarConfigReq();
if (versionFragment == null)
@@ -630,36 +661,52 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
}
-
- private String onUpdateConnectStateView() {
- String status;
+ private int getStatusColor(int connectStatus) {
int color;
switch (connectStatus) {
case IPC_CONNECTION_STATUS.CONNECTED:
- status = "已连接";
color = R.color.connect_status_connected;
break;
default:
case IPC_CONNECTION_STATUS.DISCONNECTED:
- status = "未连接";
color = R.color.connect_status_disconnected;
break;
case IPC_CONNECTION_STATUS.CONNECTING:
- status = "连接中";
color = R.color.connect_status_connecting;
break;
case IPC_CONNECTION_STATUS.SEARCH_ADDRESS:
- status = "搜索IP";
color = R.color.connect_status_search_address;
break;
case IPC_CONNECTION_STATUS.NOT_FOUND_ADDRESS:
- status = "未找到";
color = R.color.connect_status_disconnecting;
break;
}
+ return color;
+ }
+
+ private String onUpdateConnectStateView() {
+ String status;
+ switch (connectStatus) {
+ case IPC_CONNECTION_STATUS.CONNECTED:
+ status = "已连接";
+ break;
+ default:
+ case IPC_CONNECTION_STATUS.DISCONNECTED:
+ status = "未连接";
+ break;
+ case IPC_CONNECTION_STATUS.CONNECTING:
+ status = "连接中";
+ break;
+ case IPC_CONNECTION_STATUS.SEARCH_ADDRESS:
+ status = "搜索IP";
+ break;
+ case IPC_CONNECTION_STATUS.NOT_FOUND_ADDRESS:
+ status = "未找到";
+ break;
+ }
Message msg = Message.obtain();
- msg.obj = new IPCConnectState(status, color);
- msg.what = WHATIPC_CONNECT_STATE;
+ msg.obj = new IPCConnectState(status, getStatusColor(connectStatus));
+ msg.what = WHAT_IPC_CONNECT_STATE;
getHandler().sendMessage(msg);
return status;
}
@@ -720,6 +767,12 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
DataDistribution.getInstance().addData(base);
}
+ @Override
+ public void onPredictionObstacleTrajectory(MessagePad.Header header, Prediction.mPredictionObjects predictionObjects) {
+ PredictionObstacleTrajectory base = new PredictionObstacleTrajectory(header, predictionObjects);
+ DataDistribution.getInstance().addData(base);
+ }
+
@Override
public void onBasicInfoReq(MessagePad.Header header, MessagePad.BasicInfoReq basicInfoReq) {
BasicInfoReq info = new BasicInfoReq(header, basicInfoReq);
@@ -766,27 +819,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
- private Toast toast;
- public void showToastCenter(String msg) {
- showToastCenter(msg, Toast.LENGTH_SHORT);
- }
-
- public void showToastCenter(String msg, int duration) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (toast != null) {
- toast.cancel();
- toast = null;
- }
- toast = Toast.makeText(MainActivity.this, "", duration); //如果有居中显示需求
- toast.setGravity(Gravity.CENTER, 0, 0);
- toast.setText(msg);
- toast.show();
- }
- });
- }
private void initAdas() {
@@ -857,7 +890,6 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
AdasManager.getInstance().create(options, this);
AdasManager.getInstance().setOnAdasListener(this);
-// AdasManager.getInstance().setOnAdasConnectStatusListener(this);
if (BuildConfig.IS_CLIENT) {
/*—————————————作为乘客端———————————*/
@@ -881,18 +913,6 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
- @Override
- protected void onPause() {
- super.onPause();
-// AdasManager.getInstance().pause();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-// AdasManager.getInstance().resume();
- }
-
@Override
protected void onDestroy() {
super.onDestroy();
@@ -906,7 +926,12 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
- public void onConnectionIPCStatus(int ipcConnectionStatus, String failedMsg) {
+ public void onConnectionIPCStatus(int ipcConnectionStatus, String reason) {
+ Log.i(TAG, "连接状态=" + (reason == null ? "主动断开连接" : reason));
+ connectStatusList.add(0, new IPCConnectState(reason == null ? "主动断开连接" : reason, getStatusColor(ipcConnectionStatus)));
+ if (connectStatusList.size() > 100) {
+ connectStatusList.remove(connectStatusList.size() - 1);
+ }
connectStatus = ipcConnectionStatus;
String status = onUpdateConnectStateView();
if (connectStatus == IPC_CONNECTION_STATUS.CONNECTED) {
@@ -917,10 +942,6 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
Constants.addIpcUsedIps(this, ips, tem);
}
} else if (connectStatus == IPC_CONNECTION_STATUS.DISCONNECTED) {
- if (!TextUtils.isEmpty(failedMsg)) {
- status += " failedMsg=" + failedMsg;
- showToastCenter("连接失败:" + failedMsg);
- }
getHandler().sendEmptyMessage(WHAT_IPC_IP);
}
// LogSave.getInstance().saveLog("连接状态", status);
@@ -1012,12 +1033,6 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
CupidLogUtils.w(TAG, "AutopilotRecord===>send:" + bEnd);
break;
case 6:
- //录音测试
- CupidLogUtils.w(TAG, "录音测试");
- RecordDataManager.getInstance().init(MainActivity.this, "1234567", "", 22, "", "");
- RecordDataManager.getInstance().record();
- break;
- case 7:
//发送信号灯
MessagePad.TrafficLightStatus left = MessagePad.TrafficLightStatus.newBuilder()
.setPhaseNo("1")
@@ -1041,7 +1056,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
.build();
AdasManager.getInstance().sendTrafficLightData("10038", 26.848153, 112.574883, "180.0", "SN", 100413, -4, 201, 0, detail);
break;
- case 8:
+ case 7:
//速度设置
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("自动驾驶限速");
@@ -1068,27 +1083,27 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
builder.show();//显示Dialog对话框
break;
- case 9:
+ case 8:
//重启Docker
AdasManager.getInstance().rebootAPDocker();
break;
- case 10:
+ case 9:
//重启IPC
AdasManager.getInstance().rebootIPC();
break;
- case 11:
+ case 10:
//关机
AdasManager.getInstance().shutdownIPC();
break;
- case 12:
+ case 11:
//采集类型
AdasManager.getInstance().sendRecordCause(recordKey, recordFileName, "1", "变道有干扰");
break;
- case 13:
+ case 12:
//打开演示模式
AdasManager.getInstance().sendDemoModeReq(1);
break;
- case 14:
+ case 13:
//关闭演示模式
AdasManager.getInstance().sendDemoModeReq(0);
break;
@@ -1107,7 +1122,10 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
ipcIp.setVisibility(View.VISIBLE);
ipcIp.setText("司机IP:" + NSDNettyManager.getInstance().getConnServerIp());
break;
- case WHATIPC_CONNECT_STATE:
+ case WHAT_IPC_CONNECT_STATE:
+ if (floatWindow != null) {
+ floatWindow.refreshView();
+ }
IPCConnectState status = (IPCConnectState) msg.obj;
tvConnectState.setText(status.status);
tvConnectState.setTextColor(getResources().getColor(status.color));
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java
index 9eb89345e7..ff7f719b48 100644
--- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java
@@ -167,10 +167,11 @@ public class VersionFragment extends BaseFragment {
list.add(new Config("最大自动驾驶限速:", adasConfig == null ? null : adasConfig.getMaxSpeedLimit() + "m/s"));
list.add(new Config("最小加速度:", adasConfig == null ? null : adasConfig.getMinAcceleration() + "m/s²"));
list.add(new Config("最大加速度:", adasConfig == null ? null : adasConfig.getMaxAcceleration() + "m/s²"));
- list.add(new Config("IPC通信协议版本:", adasConfig == null ? null : String.valueOf(adasConfig.getProtocolVersion().getNumber())));
+ list.add(new Config("IPC通信协议版本:", adasConfig == null ? null : String.valueOf(adasConfig.getProtocolVersionValue())));
list.add(new Config("APP通信协议版本:", String.valueOf(AdasManager.getInstance().getProtocolVersion())));
}
list.add(new Config("ADAS LIB版本:", AdasManager.getInstance().getAdasVersion()));
+ list.add(new Config("APP构建时间:", BuildConfig.BUILD_TIME));
adapter.setData(list);
}
diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java
index cc1308c998..2b4d91388a 100644
--- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java
+++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java
@@ -150,6 +150,7 @@ public class Constants {
String RECEIVE_AUTOPILOT_STATE = "自动驾驶状态";
String RECEIVE_REPORT_MESSAGE = "监控事件";
String RECEIVE_PERCEPTION_TRAFFIC_LIGHT = "感知红绿灯";
+ String RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY = "他车轨迹预测";
// String RECEIVE_BASIC_INFO_REQ = "自动驾驶设备基础信息请求";
String RECEIVE_CAR_CONFIG_RESP = "信息与配置";
diff --git a/app_ipc_monitoring/src/main/res/drawable/bg_float.xml b/app_ipc_monitoring/src/main/res/drawable/bg_float.xml
new file mode 100644
index 0000000000..eeb2ab95b9
--- /dev/null
+++ b/app_ipc_monitoring/src/main/res/drawable/bg_float.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/app_ipc_monitoring/src/main/res/drawable/help.png b/app_ipc_monitoring/src/main/res/drawable/help.png
new file mode 100644
index 0000000000..7c4f62166e
Binary files /dev/null and b/app_ipc_monitoring/src/main/res/drawable/help.png differ
diff --git a/app_ipc_monitoring/src/main/res/layout/activity_help.xml b/app_ipc_monitoring/src/main/res/layout/activity_help.xml
new file mode 100644
index 0000000000..76bfacd070
--- /dev/null
+++ b/app_ipc_monitoring/src/main/res/layout/activity_help.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app_ipc_monitoring/src/main/res/layout/item_status.xml b/app_ipc_monitoring/src/main/res/layout/item_status.xml
new file mode 100644
index 0000000000..a4cfdf3b81
--- /dev/null
+++ b/app_ipc_monitoring/src/main/res/layout/item_status.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app_ipc_monitoring/src/main/res/layout/layout_float.xml b/app_ipc_monitoring/src/main/res/layout/layout_float.xml
new file mode 100644
index 0000000000..9cbebe07f8
--- /dev/null
+++ b/app_ipc_monitoring/src/main/res/layout/layout_float.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app_ipc_monitoring/src/main/res/values/styles.xml b/app_ipc_monitoring/src/main/res/values/styles.xml
index 725f5b6689..71a18efd24 100644
--- a/app_ipc_monitoring/src/main/res/values/styles.xml
+++ b/app_ipc_monitoring/src/main/res/values/styles.xml
@@ -28,4 +28,7 @@
- true
+
+
+
diff --git a/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.kt b/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.kt
index c414762e87..ee736d0533 100644
--- a/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.kt
+++ b/core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.kt
@@ -47,6 +47,7 @@ import mogo.telematics.pad.MessagePad
import mogo.telematics.pad.MessagePad.TrackedObject
import mogo_msg.MogoReportMsg
import perception.TrafficLightOuterClass
+import prediction.Prediction
import record_cache.RecordPanelOuterClass
/**
@@ -214,6 +215,13 @@ class MoGoAdasListenerImpl : OnAdasListener {
}
+ override fun onPredictionObstacleTrajectory(
+ header: MessagePad.Header?,
+ predictionObjects: Prediction.mPredictionObjects?
+ ) {
+ //他车轨迹预测
+ }
+
override fun onBasicInfoReq(
header: MessagePad.Header,
basicInfoReq: MessagePad.BasicInfoReq?
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt
index 62fe6d6e0d..335fd64ee9 100644
--- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt
+++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt
@@ -22,13 +22,16 @@ import com.mogo.eagle.core.data.enums.SidePattern
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.notice.NoticeNormalData
import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData
+import com.mogo.eagle.core.data.report.ReportEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
+import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.hmi.IMoGoHmiViewProxy
import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity
import com.mogo.eagle.core.function.api.hmi.view.IViewNotification
import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWaringProvider
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
+import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.check.CallerCheckManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
@@ -44,16 +47,19 @@ 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.ReportListFloatWindow
import com.mogo.eagle.core.function.hmi.ui.tools.AutoPilotAndCheckView
import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView
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.ThreadUtils
+import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.module.common.enums.EventTypeEnum
import kotlinx.android.synthetic.main.fragment_hmi.*
import kotlinx.coroutines.*
+import mogo_msg.MogoReportMsg
import record_cache.RecordPanelOuterClass
import java.util.*
@@ -68,7 +74,8 @@ class MoGoHmiFragment : MvpFragment(),
IMoGoWaringProvider,
IMoGoHmiViewProxy,
MoGoHmiContract.View,
- IMoGoAutopilotRecordListener {
+ IMoGoAutopilotRecordListener,
+ IMoGoAutopilotStatusListener {
private val TAG = "MoGoHmiFragment"
// DebugSettingView
@@ -101,6 +108,10 @@ class MoGoHmiFragment : MvpFragment(),
// V2X预警弹窗 View 代理
private var mViewNotification: IViewNotification? = null
+ //工控机节点上报列表
+ private var reportList = arrayListOf()
+ //工控机上报列表悬浮窗
+ private var reportListFloatWindow: ReportListFloatWindow?=null
override fun vipIdentification(visible: Boolean) {
ThreadUtils.runOnUiThread {
@@ -143,6 +154,7 @@ class MoGoHmiFragment : MvpFragment(),
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
CallerAutopilotRecordListenerManager.addListener(TAG, this)
+ CallerAutoPilotStatusListenerManager.addListener(TAG, this)
/*// TODO 这里后面需要改成独立进程通讯后台获取YUV
view.postDelayed({
@@ -174,6 +186,7 @@ class MoGoHmiFragment : MvpFragment(),
override fun onDestroyView() {
super.onDestroyView()
CallerAutopilotRecordListenerManager.removeListener(TAG)
+ CallerAutoPilotStatusListenerManager.removeListener(TAG)
}
@@ -386,7 +399,7 @@ class MoGoHmiFragment : MvpFragment(),
*/
override fun toggleDebugView() {
CallerLogger.d("$M_HMI$TAG", "长按显示状态工具栏")
- context?.let {
+ activity?.let {
if (mDebugSettingViewFloat != null) {
WarningFloat.dismiss(mDebugSettingViewFloat!!.config.floatTag, false)
mDebugSettingViewFloat = null
@@ -394,6 +407,18 @@ class MoGoHmiFragment : MvpFragment(),
} else {
if (mDebugSettingView == null) {
mDebugSettingView = DebugSettingView(it)
+ mDebugSettingView?.setClickListener(object: DebugSettingView.ClickListener{
+ override fun showReportListWindow(show: Boolean) {
+ if(show){
+ //打开工控机上报列表
+ reportListFloatWindow = ReportListFloatWindow(it)
+ reportListFloatWindow?.showFloatWindow()
+ }else{
+ //关闭工控机上报列表
+ reportListFloatWindow?.hideFloatWindow()
+ }
+ }
+ })
}
var side = SidePattern.RIGHT
var gravity = Gravity.RIGHT
@@ -979,6 +1004,23 @@ class MoGoHmiFragment : MvpFragment(),
}
+ /**
+ * 工控机监控节点上报
+ */
+ override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
+ ThreadUtils.runOnUiThread{
+ guardianInfo?.let {
+ if(reportList.size>20){
+ reportList.removeLast()
+ }
+ reportList.add(0,
+ ReportEntity(TimeUtils.millis2String(System.currentTimeMillis()),
+ it.src,it.level,it.msg,it.code,it.resultList,it.actionsList))
+ reportListFloatWindow?.refreshData(reportList)
+ }
+ }
+ }
+
override fun onDestroy() {
super.onDestroy()
CallerLogger.d("$M_HMI$TAG", "onDestroy")
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/AccelerationFloatWindow.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/AccelerationFloatWindow.kt
new file mode 100644
index 0000000000..7632315dcb
--- /dev/null
+++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/AccelerationFloatWindow.kt
@@ -0,0 +1,133 @@
+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.gnss.AccelerationEntity
+import com.mogo.eagle.core.function.hmi.R
+import java.lang.reflect.Field
+
+/**
+ * @author XuXinChao
+ * @description 可拖拽实时加速度面板
+ * @since: 2022/4/21
+ */
+class AccelerationFloatWindow constructor(activity: Activity) : View.OnTouchListener{
+
+ private var mActivity: Activity = activity
+ private var mWindowParams: WindowManager.LayoutParams? = null
+ private var mWindowManager: WindowManager? = null
+ private lateinit var rvAccelerationList: RecyclerView
+ private var accelerationListAdapter: AccelerationListAdapter?=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_acceleration_float, null) as View
+ mFloatLayout.setOnTouchListener(this)
+ rvAccelerationList= mFloatLayout.findViewById(R.id.rvAccelerationList)
+ mWindowParams = WindowManager.LayoutParams()
+// mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+// if (Build.VERSION.SDK_INT >= 26) {//8.0新特性
+// mWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+// }else{
+// mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+// }
+ 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 = 600
+ it.height = WindowManager.LayoutParams.WRAP_CONTENT
+ it.alpha = 0.8f
+ }
+ accelerationListAdapter= AccelerationListAdapter(mActivity)
+ rvAccelerationList.layoutManager = LinearLayoutManager(mActivity,
+ LinearLayoutManager.VERTICAL,false)
+ rvAccelerationList.adapter = accelerationListAdapter
+ rvAccelerationList.isNestedScrollingEnabled = false
+ }
+
+ fun refreshData(data:List){
+ accelerationListAdapter?.setDada(data)
+ accelerationListAdapter?.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
+ }
+
+}
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/AccelerationListAdapter.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/AccelerationListAdapter.kt
new file mode 100644
index 0000000000..3b7bb5c873
--- /dev/null
+++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/AccelerationListAdapter.kt
@@ -0,0 +1,48 @@
+package com.mogo.eagle.core.function.hmi.ui.setting
+
+import android.content.Context
+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.gnss.AccelerationEntity
+import com.mogo.eagle.core.function.hmi.R
+
+/**
+ * @author XuXinChao
+ * @description 实时加速度列表适配器
+ * @since: 2022/4/20
+ */
+class AccelerationListAdapter(context: Context) :
+ RecyclerView.Adapter() {
+
+ private var context: Context? = context
+ private var data:List? = null
+
+ fun setDada( data: List?){
+ this.data = data
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccelerationListHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_acceleration_detail, parent, false)
+ return AccelerationListHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: AccelerationListHolder, position: Int) {
+ data?.let { it ->
+ val accelerationEntity = it[position]
+ holder.tvMoment.text = accelerationEntity.moment
+ holder.tvAcceleration.text = accelerationEntity.acceleration
+ }
+ }
+
+ override fun getItemCount() = data?.size ?: 0
+
+ class AccelerationListHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
+ var tvMoment: TextView = itemView.findViewById(R.id.tvMoment)
+ var tvAcceleration: TextView = itemView.findViewById(R.id.tvAcceleration)
+ }
+
+}
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt
index 9207392d7d..2a13769282 100644
--- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt
+++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/DebugSettingView.kt
@@ -1,6 +1,7 @@
package com.mogo.eagle.core.function.hmi.ui.setting
import android.annotation.SuppressLint
+import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.os.Build
@@ -24,6 +25,7 @@ import com.mogo.eagle.core.data.constants.MoGoConfig
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.scene.SceneModule
import com.mogo.eagle.core.data.enums.TrafficTypeEnum
+import com.mogo.eagle.core.data.gnss.AccelerationEntity
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.data.obu.ObuStatusInfo
import com.mogo.eagle.core.data.upgrade.UpgradeVersionEntity
@@ -66,6 +68,7 @@ import mogo.telematics.pad.MessagePad
import mogo_msg.MogoReportMsg
import java.util.*
import kotlin.collections.ArrayList
+import kotlin.math.abs
/**
* @author xiaoyuzhou
@@ -91,6 +94,11 @@ class DebugSettingView @JvmOverloads constructor(
private var mAutoPilotStatusInfo: AutopilotStatusInfo? = null
private var mGnssInfo: MessagePad.GnssInfo? = null
+ private var accelerationFloatWindow: AccelerationFloatWindow?=null
+ private var accelerationList = arrayListOf()
+ private var accelerationIsShow: Boolean = false //实时加速度面板是否展示
+ private var accelerationThresholdNum: Double = 0.0
+
// 感知识别「已知类型」数据个数
private var mIdentifyDataSize = 0
@@ -141,6 +149,8 @@ class DebugSettingView @JvmOverloads constructor(
private var lastVisualAngleMode: VisualAngleMode? = null
+ private var clickListener: ClickListener? = null
+
init {
LayoutInflater.from(context).inflate(R.layout.view_debug_setting, this, true)
initView()
@@ -604,6 +614,11 @@ class DebugSettingView @JvmOverloads constructor(
//初始化ADAS日志开关状态
tbADASLog.isChecked = CallerAutoPilotManager.isEnableLog()
+ //查看上报历史列表
+ tbReportMore.setOnCheckedChangeListener { _, isChecked ->
+ clickListener?.showReportListWindow(isChecked)
+ }
+
}
/**
@@ -966,6 +981,33 @@ class DebugSettingView @JvmOverloads constructor(
}
}
+ /**
+ * 实时加速度面板控制
+ */
+ tbOpenAcceleration.setOnCheckedChangeListener { _, isChecked ->
+ if(isChecked){
+ //打开实时加速度面板
+ accelerationFloatWindow = context?.let { AccelerationFloatWindow(it as Activity) }
+ accelerationFloatWindow?.showFloatWindow()
+ etThreshold.visibility = View.VISIBLE
+ btnThresholdDefine.visibility = View.VISIBLE
+ }else{
+ //关闭实时加速度面板
+ accelerationFloatWindow?.hideFloatWindow()
+ etThreshold.visibility = View.GONE
+ btnThresholdDefine.visibility = View.GONE
+ }
+ accelerationIsShow = isChecked
+ }
+
+ btnThresholdDefine.setOnClickListener {
+ try{
+ accelerationThresholdNum = etThreshold.text.toString().toDouble()
+ }catch(e:java.lang.Exception){
+ ToastUtils.showShort("请输入正确的阈值")
+ }
+ }
+
}
/**
@@ -1599,6 +1641,26 @@ class DebugSettingView @JvmOverloads constructor(
override fun onAutopilotCarStateData(gnssInfo: MessagePad.GnssInfo?) {
mGnssInfo = gnssInfo
+ //实时加速度列表
+ ThreadUtils.runOnUiThread{
+ if(accelerationIsShow){
+ if(accelerationList.size > 9){
+ accelerationList.removeLast()
+ }
+ gnssInfo?.acceleration?.let {
+ if(accelerationList.isEmpty()){
+ accelerationList.add(AccelerationEntity(TimeUtils.millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat()),it.toString()))
+ }
+ if(abs(it.minus(accelerationList.first().acceleration.toDouble())) > abs(accelerationThresholdNum)){
+ accelerationList.add(0, AccelerationEntity(TimeUtils.millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat()),it.toString()))
+ }
+
+ accelerationFloatWindow?.refreshData(accelerationList)
+ }
+
+ }
+ }
+
}
@RequiresApi(Build.VERSION_CODES.N)
@@ -1746,4 +1808,12 @@ class DebugSettingView @JvmOverloads constructor(
}
}
+ fun setClickListener(clickListener: ClickListener) {
+ this.clickListener = clickListener
+ }
+
+ interface ClickListener{
+ fun showReportListWindow(show: Boolean)
+ }
+
}
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/ReportListAdapter.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/ReportListAdapter.kt
new file mode 100644
index 0000000000..c10403b348
--- /dev/null
+++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/ReportListAdapter.kt
@@ -0,0 +1,90 @@
+package com.mogo.eagle.core.function.hmi.ui.setting
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Color
+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/4/13
+ */
+class ReportListAdapter(context: Context) :
+ RecyclerView.Adapter() {
+
+ private var context: Context? = context
+ private var data:List? = null
+
+ public fun setDada( data: List?){
+ this.data = data
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReportListHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_report_detail, parent, false)
+ return ReportListHolder(view)
+ }
+
+ @SuppressLint("SetTextI18n")
+ override fun onBindViewHolder(holder: ReportListHolder, position: Int) {
+ data?.let { it ->
+ val reportEntity = it[position]
+ reportEntity.let {
+ holder.tvReportTime.text = it.time
+ holder.tvReportSrc.text = "src:${it.src}"
+ holder.tvReportLevel.text = "level:${it.level}"
+ holder.tvReportMsg.text = "msg:${it.msg}"
+ holder.tvReportCode.text = "code:${it.code}"
+ var resultStr = "result:"
+ for (result in it.resultList) {
+ resultStr = "$resultStr$result${CallerAutoPilotManager.getReportResultDesc(result)} "
+ }
+ holder.tvReportResult.text = resultStr
+ var actionStr = "action:"
+ for (action in it.actionsList) {
+ actionStr = "$actionStr$action${CallerAutoPilotManager.getReportActionDesc(action)} "
+ }
+ holder.tvReportActions.text = actionStr
+
+ if ("error" == it.level) {
+ //字体为红色,吐司提示
+ holder.tvReportSrc.setTextColor(Color.RED)
+ holder.tvReportLevel.setTextColor(Color.RED)
+ holder.tvReportMsg.setTextColor(Color.RED)
+ holder.tvReportCode.setTextColor(Color.RED)
+ holder.tvReportResult.setTextColor(Color.RED)
+ holder.tvReportActions.setTextColor(Color.RED)
+ } else {
+ holder.tvReportSrc.setTextColor(Color.WHITE)
+ holder.tvReportLevel.setTextColor(Color.WHITE)
+ holder.tvReportMsg.setTextColor(Color.WHITE)
+ holder.tvReportCode.setTextColor(Color.WHITE)
+ holder.tvReportResult.setTextColor(Color.WHITE)
+ holder.tvReportActions.setTextColor(Color.WHITE)
+ }
+ }
+ }
+
+ }
+
+ override fun getItemCount() = data?.size ?: 0
+
+ class ReportListHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
+ var tvReportTime: TextView = itemView.findViewById(R.id.tvReportTime)
+ var tvReportSrc: TextView = itemView.findViewById(R.id.tvReportSrc)
+ var tvReportLevel: TextView = itemView.findViewById(R.id.tvReportLevel)
+ var tvReportMsg: TextView = itemView.findViewById(R.id.tvReportMsg)
+ var tvReportCode: TextView = itemView.findViewById(R.id.tvReportCode)
+ var tvReportResult: TextView = itemView.findViewById(R.id.tvReportResult)
+ var tvReportActions: TextView = itemView.findViewById(R.id.tvReportActions)
+ }
+
+}
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/ReportListFloatWindow.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/ReportListFloatWindow.kt
new file mode 100644
index 0000000000..f14472f33c
--- /dev/null
+++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/setting/ReportListFloatWindow.kt
@@ -0,0 +1,125 @@
+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/4/13
+ */
+class ReportListFloatWindow constructor(activity: Activity) : View.OnTouchListener{
+
+ private var mActivity: Activity = activity
+ private var mWindowParams: WindowManager.LayoutParams? = null
+ private var mWindowManager: WindowManager? = null
+ private lateinit var rvReportList: RecyclerView
+ private var reportListAdapter: ReportListAdapter?=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_report_list, null) as View
+ mFloatLayout.setOnTouchListener(this)
+ rvReportList= mFloatLayout.findViewById(R.id.rv_report_list)
+ 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
+ }
+ reportListAdapter= ReportListAdapter(mActivity)
+ rvReportList.layoutManager = LinearLayoutManager(mActivity,
+ LinearLayoutManager.VERTICAL,false)
+ rvReportList.adapter = reportListAdapter
+ }
+
+ fun refreshData(data:List){
+ reportListAdapter?.setDada(data)
+ reportListAdapter?.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
+ }
+
+}
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/drawable-xxhdpi/icon_drag.png b/core/function-impl/mogo-core-function-hmi/src/main/res/drawable-xxhdpi/icon_drag.png
new file mode 100644
index 0000000000..305f239505
Binary files /dev/null and b/core/function-impl/mogo-core-function-hmi/src/main/res/drawable-xxhdpi/icon_drag.png differ
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_acceleration_detail.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_acceleration_detail.xml
new file mode 100644
index 0000000000..cc2a41a71f
--- /dev/null
+++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_acceleration_detail.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_report_detail.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_report_detail.xml
new file mode 100644
index 0000000000..767163596a
--- /dev/null
+++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_report_detail.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_acceleration_float.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_acceleration_float.xml
new file mode 100644
index 0000000000..8629837b9f
--- /dev/null
+++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_acceleration_float.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml
index afaac05e7f..e6ad801c09 100644
--- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml
+++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_debug_setting.xml
@@ -12,109 +12,145 @@
android:layout_width="match_parent"
android:layout_height="@dimen/dp_350"
android:visibility="gone"
- app:layout_constraintBottom_toBottomOf="parent">
+ app:layout_constraintBottom_toBottomOf="parent"
+ tools:visibility="visible">
-
+ android:layout_height="match_parent">
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toTopOf="parent" />
+
+
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toBottomOf="@id/tbReportMore"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintRight_toLeftOf="@id/tbReportMore"
+ app:layout_constraintTop_toBottomOf="@id/vReportLine"
+ app:layout_constraintTop_toTopOf="@id/tbReportMore" />
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toBottomOf="@id/tbReportMore" />
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/vReportSrcLine" />
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toBottomOf="@id/tvReportLevel" />
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/vReportLevelLine" />
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toBottomOf="@id/tvReportMsg" />
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/vReportMsgLine" />
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toBottomOf="@id/tvReportCode" />
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/vReportCodeLine" />
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toBottomOf="@id/tvReportResult" />
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/vReportResultLine" />
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toBottomOf="@id/tvReportActions" />
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/vReportActionsLine" />
+ android:background="#F0F0F0"
+ app:layout_constraintTop_toBottomOf="@id/tvReportSec" />
-
-
-
-
-
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/vReportSecLine" />
+
@@ -221,7 +257,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:visibility="gone">
+ android:visibility="gone"
+ tools:visibility="visible">
+ android:visibility="gone"
+ tools:visibility="visible">
+ android:visibility="gone"
+ tools:visibility="visible">
+ android:visibility="gone"
+ tools:visibility="visible">
+ app:layout_constraintTop_toBottomOf="@id/recordPackageDivider"
+ tools:visibility="visible" />
+ app:layout_constraintTop_toBottomOf="@id/recordPackageDivider"
+ tools:visibility="visible" />
+ android:visibility="gone"
+ tools:visibility="visible">
+ android:visibility="gone"
+ tools:visibility="visible">