Merge remote-tracking branch 'origin/dev_robotaxi-d-app-module_290_220715_2.9.0' into dev_robotaxi-d-app-module_290_220715_2.9.0

This commit is contained in:
donghongyu
2022-07-25 18:11:03 +08:00
46 changed files with 1239 additions and 367 deletions

View File

@@ -248,9 +248,9 @@ public abstract class BaseBusTabFragment<V extends IView, P extends Presenter<V>
@Override
public void onAutopilotRecordResult(@Nullable RecordPanelOuterClass.RecordPanel recordPanel) {
if (!HmiBuildConfig.isShowBadCaseView && recordPanel != null && recordPanel.getType() == 1 && recordPanel.getStat() == 100) {
CallerDevaToolsManager.INSTANCE.onReceiveBadCaseRecord(recordPanel);
}
// if (!HmiBuildConfig.isShowBadCaseView && recordPanel != null && recordPanel.getType() == 1 && recordPanel.getStat() == 100) {
// CallerDevaToolsManager.INSTANCE.onReceiveBadCaseRecord(recordPanel);
// }
}
@Override

View File

@@ -64,6 +64,10 @@ public class BusLinePresenter extends Presenter<BusSwitchLineView> implements IB
BusLineModel.getInstance().commitSwitchLineId(lineId);
}
public void removeListener(){
BusLineModel.getInstance().setBusLinesCallback(null);
}
public void queryBusRoutes(){
BusOrderModel.getInstance().queryBusRoutes();
}
@@ -71,6 +75,5 @@ public class BusLinePresenter extends Presenter<BusSwitchLineView> implements IB
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
super.onDestroy(owner);
BusLineModel.getInstance().setBusLinesCallback(null);
}
}

View File

@@ -79,7 +79,7 @@ public class BusSwitchLineActivity extends MvpActivity<BusSwitchLineView, BusLin
mLinesListView = findViewById(R.id.switch_line_rv);
mLinesListView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new SwitchLineAdapter(this,mData);
mAdapter = new SwitchLineAdapter(getApplicationContext(),mData);
mLinesListView.setAdapter(mAdapter);
//设置item 点击事件
mAdapter.setOnLineItemClickListener(new LineItemClickListener() {
@@ -158,6 +158,10 @@ public class BusSwitchLineActivity extends MvpActivity<BusSwitchLineView, BusLin
public void onChangeLineIdSuccess(){
ToastUtils.showLong(getResources().getString(R.string.bus_change_line_commit_tip_s));
mPresenter.queryBusRoutes();
if (mAdapter != null){
mAdapter.setOnLineItemClickListener(null);
}
mPresenter.removeListener();
finish();
}
@@ -198,9 +202,6 @@ public class BusSwitchLineActivity extends MvpActivity<BusSwitchLineView, BusLin
@Override
protected void onDestroy() {
super.onDestroy();
if (mAdapter != null){
mAdapter.setOnLineItemClickListener(null);
}
}
/**
@@ -255,6 +256,9 @@ public class BusSwitchLineActivity extends MvpActivity<BusSwitchLineView, BusLin
}
}else {
if (line.choose == 1){//1:绑定 2:未绑定 默认绑定
if (mItemClickListener != null) {
mItemClickListener.onItemClick(position);
}
holder.selectIv.setImageResource(R.drawable.bus_selected_btn);
}else {
holder.selectIv.setImageResource(R.drawable.bus_unselect_btn);

View File

@@ -5,7 +5,9 @@ import android.text.TextUtils;
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.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.analytics.AnalyticsManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.constant.BusConst;
@@ -35,7 +37,9 @@ public class BusAnalyticsManager {
private Runnable startAutopilotRunnable = () -> {
// 15s内未开启上报失败埋点
mStartAutopilotParams.put(BusConst.EVENT_PARAM_START_RESULT, false);
mStartAutopilotParams.put(BusConst.EVENT_PARAM_START_RESULT
, CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState() ==
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING);
AnalyticsManager.INSTANCE.track(mStartAutopilotKey, mStartAutopilotParams);
};

View File

@@ -149,8 +149,10 @@ public abstract class BaseSurfaceView extends SurfaceView implements SurfaceHold
getHolder().unlockCanvasAndPost(canvas);
onFrameDrawFinish();
}
handler.postDelayed(this, frameDuration);
if (handler != null){
handler.postDelayed(this, frameDuration);
}
}
}

View File

@@ -872,9 +872,8 @@ public class TaxiPassengerModel implements IOCHTaxiPassengerNaviChangedCallback
return;
}
if (mCurrentOCHOrder.orderStatus != TaxiPassengerOrderStatusEnum.UserArriveAtStart.getCode()) {
ToastUtils.showShort("当前订单状态异常!");
return;
if (mCurrentOCHOrder.orderStatus == TaxiPassengerOrderStatusEnum.UserArriveAtStart.getCode()){
startServicePilotDone();
}
double startWgsLon = mCurrentOCHOrder.startSitePoint.get(0);
@@ -906,6 +905,7 @@ public class TaxiPassengerModel implements IOCHTaxiPassengerNaviChangedCallback
+ " ,startSiteName=" + mCurrentOCHOrder.startSiteAddr
+ " ,endSiteName=" + mCurrentOCHOrder.endSiteAddr);
TaxiPassengerAnalyticsManager.getInstance().triggerStartAutopilotEvent(false, false,
mCurrentOCHOrder.startSiteAddr, mCurrentOCHOrder.endSiteAddr, mCurrentOCHOrder.orderNo);
}

View File

@@ -48,7 +48,7 @@ public class TaxiPassengerV2XNotificationView extends IViewNotification {
// 设置View的出场位置
setSidePattern(SidePattern.LEFT);
setLayoutGravity(Gravity.LEFT);
setLayoutGravity(Gravity.LEFT | Gravity.TOP);
// 设置View的停留位置相对屏幕左上角的位置
// setOffsetX(getResources().
// getDimensionPixelSize(R.dimen.taxi_p_v2x_notification_view_margin_left));

View File

@@ -115,6 +115,8 @@ public class TaxiModel {
private ITaxiControllerStatusCallback mControllerStatusCallback; //Model->PresenterVR mode等
private ITaxiOrderStatusCallback mOrderStatusCallback; //Model->Presenter订单变更
private volatile boolean isRestartAutopilot = false;
private List<LatLng> mRoutePoints = new ArrayList<>();
private double mLongitude, mLatitude;
@@ -787,7 +789,7 @@ public class TaxiModel {
new TaxiServiceCallback<TaxiDataBaseRespBean>() {
@Override
public void onSuccess(TaxiDataBaseRespBean data) {
if (data != null && data.code == 0 && data.data.equals(true))
if (data != null && data.code == 0)
updateAutopilotStatus(data.data.equals(true));
}
@@ -840,6 +842,7 @@ public class TaxiModel {
mCurrentOCHOrder = null;
TaxiTrajectoryManager.getInstance().syncTrajectoryInfo();
SharedPrefsMgr.getInstance(mContext).remove(TaxiConst.SP_KEY_OCH_TAXI_ORDER);
isRestartAutopilot = false;
if (FunctionBuildConfig.isDemoMode) {
// 当美化模式(演示模式)开启时: 取消或订单已完成时置false
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false;
@@ -860,9 +863,7 @@ public class TaxiModel {
/**
* 以当前订单为基础,开启自动驾驶
*
* @param isRestart 开启自动驾驶
*/
**/
@ChainLog(
linkChainLog = CHAIN_LINK_LOG_WEB_SOCKET_AUTOPILOT,
linkCode = CHAIN_LINK_ADAS,
@@ -871,20 +872,27 @@ public class TaxiModel {
paramIndexes = {-1}, //
clientPkFileName = "sn"
)
public void startAutoPilot(boolean isRestart) {
public void startAutoPilot() {
if (!checkCurrentOCHOrder()) {
CallerLogger.INSTANCE.e(M_TAXI + TAG, "no order or order is empty.");
ToastUtils.showShort("当前订单不存在或异常!");
return;
}
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
== CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState()) {
// TODO: 2021/11/28 工控机存在刚开始状态为0但是可以开启变为2工控机解决前不显示此toast
// ToastUtils.showShort("自动驾驶状态为不可用!");
}
//点击开始自动驾驶按钮订单状态去流转, 不再与自动驾驶是否启动成功挂钩
if (mCurrentOCHOrder.orderStatus == TaxiOrderStatusEnum.UserArriveAtStart.getCode()){
startServicePilotDone();
isRestartAutopilot = false;
}else {
isRestartAutopilot = true;
}
double startWgsLon = mCurrentOCHOrder.startSitePoint.get(0);
double startWgsLat = mCurrentOCHOrder.startSitePoint.get(1);
double endWgsLon = mCurrentOCHOrder.endSitePoint.get(0);
@@ -910,13 +918,9 @@ public class TaxiModel {
CallerLogger.INSTANCE.d(M_TAXI + TAG, "start autopilot with parameter: %s", GsonUtil.jsonFromObject(parameters)
+ " ,startSiteName=" + mCurrentOCHOrder.startSiteAddr + " ,endSiteName=" + mCurrentOCHOrder.endSiteAddr);
TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent(isRestart, false,
TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent(isRestartAutopilot, false,
mCurrentOCHOrder.startSiteAddr, mCurrentOCHOrder.endSiteAddr, mCurrentOCHOrder.orderNo);
if (DebugConfig.isDebug()) {
// ToastUtils.showShort("Start autopilot!");
}
// TODO: 2021/8/20 无工控机环境, 手动调起自动驾驶开启返回结果,有工控机环境要删除
// OCHTaxiUiController.getInstance().onAutoPilotStatusChanged( IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING, "开启自动驾驶" );
}
@@ -1014,7 +1018,12 @@ public class TaxiModel {
if (getCurOrderStatus() == TaxiOrderStatusEnum.OnTheWayToStart) {
judgeStartStation(location);
}
if (getCurOrderStatus() == TaxiOrderStatusEnum.OnTheWayToEnd &&
mPrevAPStatus != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING){
judgeEndStation(location);
}
}
mLongitude = location.getLongitude();
mLatitude = location.getLatitude();
if (mControllerStatusCallback != null) {
@@ -1023,6 +1032,37 @@ public class TaxiModel {
}
};
private void judgeEndStation(Location location) {
if (mCurrentOCHOrder == null || mCurrentOCHOrder.endSiteGcjPoint == null
|| mCurrentOCHOrder.endSiteGcjPoint.size() < 2) {
return;
}
double startLon = mCurrentOCHOrder.endSiteGcjPoint.get(0);
double startLat = mCurrentOCHOrder.endSiteGcjPoint.get(1);
double distance = CoordinateUtils.calculateLineDistance(
startLon, startLat,
location.getLongitude(), location.getLatitude());
CallerLogger.INSTANCE.i(M_TAXI + TAG, "judgeEndStation() distance = " + distance);
if (distance > TaxiConst.ARRIVE_AT_START_STATION_DISTANCE) {
distance = CoordinateUtils.calculateLineDistance(startLon, startLat,
CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon(),
CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat());
}
if (distance <= TaxiConst.ARRIVE_AT_START_STATION_DISTANCE) {
if (!checkCurrentOCHOrder()
|| (getCurOrderStatus() == TaxiOrderStatusEnum.ArriveAtEnd)) {
CallerLogger.INSTANCE.i(M_TAXI + TAG, "order exception or order ArriveAtEnd");
return;
}
arriveTerminal();
return;
}
}
/**
* 订单流转debug START
*/
@@ -1085,29 +1125,21 @@ public class TaxiModel {
mADASStatusCallback.onAutopilotRunning();
}
if (mCurrentOCHOrder != null
&& getCurOrderStatus() == TaxiOrderStatusEnum.UserArriveAtStart
&& state != mPrevAPStatus) {
// 当高频返回autopilot 2时不重复调用订单状态变更
mPrevAPStatus = state; // 每个状态单独赋值解决无订单时已经是2的状态导致的新订单来时无法进入此逻辑更新状态
&& TaxiOrderStatusEnum.OnTheWayToEnd.getCode() == mCurrentOCHOrder.orderStatus){
if (state != mPrevAPStatus) {
// 当高频返回autopilot 2时不重复调用订单状态变更
mPrevAPStatus = state; // 每个状态单独赋值解决无订单时已经是2的状态导致的新订单来时无法进入此逻辑更新状态
startServicePilotDone();
TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent(isRestartAutopilot, true,
mCurrentOCHOrder.startSiteAddr, mCurrentOCHOrder.endSiteAddr, mCurrentOCHOrder.orderNo);
TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent(false, true,
mCurrentOCHOrder.startSiteAddr, mCurrentOCHOrder.endSiteAddr, mCurrentOCHOrder.orderNo);
if (FunctionBuildConfig.isDemoMode) {
// 当美化模式(演示模式)开启时: 订单对应自动驾驶开启后置true
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true;
CallerAutoPilotManager.INSTANCE.setDemoMode(true);
CallerLogger.INSTANCE.d(M_TAXI + TAG, "美化模式-ignore置为true到达出发点且已开启自动驾驶");
if (FunctionBuildConfig.isDemoMode) {
// 当美化模式(演示模式)开启时: 订单对应自动驾驶开启后置true
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true;
CallerAutoPilotManager.INSTANCE.setDemoMode(true);
CallerLogger.INSTANCE.d(M_TAXI + TAG, "美化模式-ignore置为true到达出发点且已开启自动驾驶");
}
}
} else if (mCurrentOCHOrder != null
&& getCurOrderStatus() == TaxiOrderStatusEnum.OnTheWayToEnd
&& state != mPrevAPStatus) {
mPrevAPStatus = state;
// 接管后再次启动成功埋点
TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent(true, true,
mCurrentOCHOrder.startSiteAddr, mCurrentOCHOrder.endSiteAddr, mCurrentOCHOrder.orderNo);
}
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) {
if (state != mPrevAPStatus && mADASStatusCallback != null){
@@ -1154,10 +1186,8 @@ public class TaxiModel {
|| (getCurOrderStatus() == TaxiOrderStatusEnum.ArriveAtEnd)) {
return;
}
if (DebugConfig.isDebug()) {
// ToastUtils.showShort("到达目的地");
}
arriveTerminal();
if (FunctionBuildConfig.isDemoMode) {
// 当美化模式(演示模式)开启时: 到达目的地置false
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false;

View File

@@ -88,10 +88,9 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
/**
* 开启自动驾驶
* @param isRestart 是否是接管后重启自动驾驶
*/
public void startAutoPilot(boolean isRestart) {
TaxiModel.getInstance().startAutoPilot(isRestart);
public void startAutoPilot() {
TaxiModel.getInstance().startAutoPilot();
}
/**

View File

@@ -319,9 +319,9 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
@Override
public void onAutopilotRecordResult(@Nullable RecordPanelOuterClass.RecordPanel recordPanel) {
if (!HmiBuildConfig.isShowBadCaseView && recordPanel != null && recordPanel.getType() == 1 && recordPanel.getStat() == 100) {
CallerDevaToolsManager.INSTANCE.onReceiveBadCaseRecord(recordPanel);
}
// if (!HmiBuildConfig.isShowBadCaseView && recordPanel != null && recordPanel.getType() == 1 && recordPanel.getStat() == 100) {
// CallerDevaToolsManager.INSTANCE.onReceiveBadCaseRecord(recordPanel);
// }
}
@Override

View File

@@ -63,7 +63,7 @@ public class TaxiFragment extends BaseTaxiTabFragment<TaxiFragment, TaxiPresente
mPresenter.getCurOrderStatus() == TaxiOrderStatusEnum.UserArriveAtStart)
&& !isStarting) {
CallerLogger.INSTANCE.d(M_TAXI + TAG, "restartAutopilot");
mPresenter.startAutoPilot(true);
mPresenter.startAutoPilot();
startOrStopLoadingAnim(true);
}
}
@@ -215,7 +215,7 @@ public class TaxiFragment extends BaseTaxiTabFragment<TaxiFragment, TaxiPresente
public void startAutoPilot() {
if (!isStarting){
mPresenter.startAutoPilot(false);
mPresenter.startAutoPilot();
startOrStopLoadingAnim(true);
}
}
@@ -362,7 +362,7 @@ public class TaxiFragment extends BaseTaxiTabFragment<TaxiFragment, TaxiPresente
});
findViewById(R.id.test_bar_on_the_way_to_end).setOnClickListener(v -> {
if (!isStarting){
mPresenter.startAutoPilot(false);
mPresenter.startAutoPilot();
startOrStopLoadingAnim(true);
}
TaxiModel.getInstance().setOnTheWayToEndStation();

View File

@@ -1,17 +1,19 @@
package com.mogo.och.taxi.utils;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI;
import android.text.TextUtils;
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.function.call.analytics.AnalyticsManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.taxi.constant.TaxiConst;
import java.util.HashMap;
import java.util.Map;
/**
* OCH Taxi埋点工具
@@ -63,6 +65,8 @@ public class TaxiAnalyticsManager {
mStartAutopilotParams.put(TaxiConst.EVENT_PARAM_END_NAME, endName);
mStartAutopilotParams.put(TaxiConst.EVENT_PARAM_ORDER_NUMBER, orderNo);
// CallerLogger.INSTANCE.d(M_TAXI + "埋点==","restart = "+restart+", send= "+send);
if (send) {
// 开启成功,上报埋点
if (startAutopilotRunnable != null &&

View File

@@ -16,13 +16,23 @@ import mogo_msg.MogoReportMsg
*/
class IPCReportManager : IMoGoAutopilotStatusListener {
private var ipcReportList = arrayListOf<ReportEntity>()
private var ipcErrorReportList = arrayListOf<ReportEntity>() //错误上报列表
private var ipcWarningReportList = arrayListOf<ReportEntity>() //警告上报列表
companion object{
const val TAG ="IPCReportManager"
val INSTANCE: IPCReportManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
IPCReportManager()
}
//Warning
const val RESULT_AUTOPILOT_INFERIOR = "RESULT_AUTOPILOT_INFERIOR"
const val RESULT_SHOW_WARNING = "RESULT_SHOW_WARNING"
const val RESULT_REMOTEPILOT_INFERIOR = "RESULT_REMOTEPILOT_INFERIOR"
//Error
const val RESULT_AUTOPILOT_DISABLE = "RESULT_AUTOPILOT_DISABLE"
const val RESULT_AUTOPILOT_SYSTEM_UNSTARTED = "RESULT_AUTOPILOT_SYSTEM_UNSTARTED"
const val RESULT_REMOTEPILOT_DISABLE = "RESULT_REMOTEPILOT_DISABLE"
}
fun initServer(){
@@ -38,17 +48,38 @@ class IPCReportManager : IMoGoAutopilotStatusListener {
*/
override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
guardianInfo?.let{
if(it.level=="error"){
if(ipcReportList.size>19){
ipcReportList.removeLast()
//Error 弹窗并有提示音
if(it.resultList.contains(RESULT_AUTOPILOT_DISABLE)
|| it.resultList.contains(RESULT_AUTOPILOT_SYSTEM_UNSTARTED)
|| it.resultList.contains(RESULT_REMOTEPILOT_DISABLE)){
if(ipcErrorReportList.size>19){
ipcErrorReportList.removeLast()
}
ipcReportList.add(0,
ipcErrorReportList.add(0,
ReportEntity(TimeUtils.millis2String(System.currentTimeMillis()),
it.src,it.level,it.msg,it.code,it.resultList,it.actionsList))
//当前不处于美化模式时,展示监控节点上报
if(!FunctionBuildConfig.isDemoMode){
if(FunctionBuildConfig.isReportWarning){
CallerHmiManager.showIPCReportWindow(ipcReportList)
CallerHmiManager.showIPCReportWindow(ipcErrorReportList,ipcWarningReportList,1)
}
}
}
//Warning 不弹窗也不会有提示音
else if(it.resultList.contains(RESULT_AUTOPILOT_INFERIOR)
|| it.resultList.contains(RESULT_SHOW_WARNING)
|| it.resultList.contains(RESULT_REMOTEPILOT_INFERIOR)){
if(ipcWarningReportList.size>19){
ipcWarningReportList.removeLast()
}
ipcWarningReportList.add(0,
ReportEntity(TimeUtils.millis2String(System.currentTimeMillis()),
it.src,it.level,it.msg,it.code,it.resultList,it.actionsList))
//当前不处于美化模式时,展示监控节点上报
if(!FunctionBuildConfig.isDemoMode){
if(FunctionBuildConfig.isReportWarning){
CallerHmiManager.showIPCReportWindow(ipcErrorReportList,ipcWarningReportList,2)
}
}
}

View File

@@ -1,6 +1,7 @@
package com.zhjt.mogo_core_function_devatools
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.view.View
import com.alibaba.android.arouter.facade.annotation.Route
@@ -86,8 +87,8 @@ class DevaToolsProvider : IDevaToolsProvider {
BadCaseManager.initAiCollect(view)
}
override fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel) {
BadCaseManager.onReceiveBadCaseRecord(record)
override fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel,activity: Activity) {
BadCaseManager.onReceiveBadCaseRecord(record,activity)
}
override fun showFeedbackWindow(ctx: Context) {

View File

@@ -1,6 +1,7 @@
package com.zhjt.mogo_core_function_devatools.badcase
import android.app.Activity
import android.content.Context
import android.view.View
import android.view.WindowManager
@@ -23,8 +24,11 @@ import com.mogo.eagle.core.utilcode.reminder.Reminder
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
import com.mogo.eagle.core.utilcode.reminder.api.IReminder.IGlobalStateChangeListener
import com.mogo.eagle.core.utilcode.util.ClickUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
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.badcase.repository.net.api.entity.BadCaseResponse.Reason
import com.zhjt.mogo_core_function_devatools.ext.enqueuePop
@@ -56,9 +60,6 @@ internal object BadCaseManager : LifecycleEventObserver {
@Volatile
private var dismissJob: Job? = null
@Volatile
private var feedbackFloatShow = false
@OptIn(ExperimentalCoroutinesApi::class)
private var channel: Channel<AutoPilotRecord> = Channel(Channel.RENDEZVOUS)
get() = if (field.isClosedForReceive || field.isClosedForSend) {
@@ -104,14 +105,21 @@ internal object BadCaseManager : LifecycleEventObserver {
val activity = view.context as? FragmentActivity ?: throw IllegalStateException("please ensure context is FragmentActivity.")
view.setOnClickListener {
if(ClickUtils.isFastClick()){
val initiativeBadCaseWindow = InitiativeBadCaseWindow(activity)
initiativeBadCaseWindow.setClickListener(object: InitiativeBadCaseWindow.ClickListener{
override fun closeWindow() {
initiativeBadCaseWindow.hideFloatWindow()
if(NetworkUtils.isConnected()){
if(BadCaseConfig.dockerVersion!=null){
val initiativeBadCaseWindow = InitiativeBadCaseWindow(activity)
initiativeBadCaseWindow.setClickListener(object: InitiativeBadCaseWindow.ClickListener{
override fun closeWindow() {
initiativeBadCaseWindow.hideFloatWindow()
}
})
initiativeBadCaseWindow.showFloatWindow()
}else{
ToastUtils.showShort("工控机连接状态异常")
}
})
initiativeBadCaseWindow.showFloatWindow()
}else{
ToastUtils.showShort("网络异常,请检查网络")
}
}else{
ToastUtils.showShort("请勿连续点击,稍后再试")
}
@@ -126,13 +134,21 @@ internal object BadCaseManager : LifecycleEventObserver {
val activity = view.context as? FragmentActivity ?: throw IllegalStateException("please ensure context is FragmentActivity.")
view.setOnClickListener {
if(ClickUtils.isFastClick()){
val aiDataCollectWindow = AIDataCollectWindow(activity)
aiDataCollectWindow.setClickListener(object: AIDataCollectWindow.ClickListener{
override fun closeWindow() {
aiDataCollectWindow.hideFloatWindow()
if(NetworkUtils.isConnected()){
if(BadCaseConfig.dockerVersion!=null){
val aiDataCollectWindow = AIDataCollectWindow(activity)
aiDataCollectWindow.setClickListener(object: AIDataCollectWindow.ClickListener{
override fun closeWindow() {
aiDataCollectWindow.hideFloatWindow()
}
})
aiDataCollectWindow.showFloatWindow()
}else{
ToastUtils.showShort("工控机连接状态异常")
}
})
aiDataCollectWindow.showFloatWindow()
}else{
ToastUtils.showShort("网络异常,请检查网络")
}
}else{
ToastUtils.showShort("请勿连续点击,稍后再试")
}
@@ -219,16 +235,19 @@ internal object BadCaseManager : LifecycleEventObserver {
return oldT == 0L || newT == 0L || (newT - oldT >= 0 && (newT - oldT) < CASE_EXPIRE_DURATION)
}
fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel) {
if (feedbackFloatShow) {
return
}
scope?.launch {
val newRecord = record.toRecord()
withContext(Dispatchers.IO) {
presenter.insertRecord(newRecord)
channel.send(newRecord)
}
fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel,activity: Activity) {
CallerLogger.d("$M_DEVA$TAG", "收到录包结果回调${record}")
CallerLogger.d("$M_DEVA$TAG", "开始创建被动录包弹窗,window num=${BadCaseConfig.windowNum}")
CallerLogger.d("$M_DEVA$TAG","key=${record.key};filename${record.filename}")
ThreadUtils.runOnUiThread {
val passiveBadCaseWindow = PassiveBadCaseWindow(activity)
passiveBadCaseWindow.setRecord(record.key.toString(),record.filename)
passiveBadCaseWindow.setClickListener(object: PassiveBadCaseWindow.ClickListener{
override fun closeWindow() {
passiveBadCaseWindow.hideFloatWindow()
}
})
passiveBadCaseWindow.showFloatWindow()
}
}
@@ -294,31 +313,10 @@ internal object BadCaseManager : LifecycleEventObserver {
}
}
private val listener = object : IGlobalStateChangeListener {
override fun onShow(reminder: IReminder) {
if (reminder.key().startsWith("FeedBackFloatWindow_")) {
feedbackFloatShow = true
}
}
override fun onHide(reminder: IReminder) {
if (reminder.key().startsWith("FeedBackFloatWindow_")) {
feedbackFloatShow = false
}
}
}
override fun onStateChanged(source: LifecycleOwner, event: Event) {
if (event == ON_CREATE) {
Reminder.registerGlobalStateChangeListener(listener)
}
if (event == ON_DESTROY) {
Reminder.unRegisterGlobalStateChangeListener(listener)
dismissJob?.takeIf { it.isActive }?.cancel()
hideFloat = null
}
}
}

View File

@@ -9,18 +9,24 @@ import android.view.*
import android.widget.RadioButton
import android.widget.TextView
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
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.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.badcase.toRecord
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import mogo.telematics.pad.MessagePad
import record_cache.RecordPanelOuterClass
import java.lang.reflect.Field
import java.util.*
@@ -31,7 +37,7 @@ import java.util.*
* @since: 2022/7/12
*/
class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener,
IMoGoAutopilotRecordListener {
IMoGoAutopilotRecordListener , IMoGoAutopilotCarStateListener {
companion object {
const val TAG = "AIDataCollectWindow"
@@ -56,6 +62,12 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
private lateinit var tvCollectCancel: TextView //取消按钮
private var collectReason: String = "大型车:大货、大巴、特种车辆"
@Volatile
private var recordKey: String?=null //录制bag包key
@Volatile
private var recordFileName: String?=null //录制文件包名
private var longitude: Double?=null
private var latitude: Double?=null
private lateinit var mFloatLayout: View
private var mInViewX = 0f
@@ -92,18 +104,23 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
tvCollectReport = mFloatLayout.findViewById(R.id.tvCollectReport)
tvCollectCancel = mFloatLayout.findViewById(R.id.tvCollectCancel)
if(BadCaseConfig.windowNum<1){
BadCaseConfig.windowNum = 1
}
tvCollectNum.text = BadCaseConfig.windowNum.toString()
BadCaseConfig.windowNum++
tvCollectTime.text ="时间:${millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat())}"
//采集结果回调监听
CallerAutopilotRecordListenerManager.addListener(this.hashCode().toString(),this)
// 添加 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.addListener(this.hashCode().toString(), this)
//开始录制AI数据采集Bag包
CallerAutoPilotManager.recordPackage(
99,
Random(SystemClock.elapsedRealtime()).nextInt(),
20,
12
)
//大型车
rbLargeCar.setOnClickListener{
setRadioButtonStatus(
@@ -200,26 +217,28 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
tvCollectReport.setOnClickListener {
GlobalScope.launch{
val uploadResult = presenter.upload(mutableMapOf<String, String>().also { itx ->
itx["carLicense"] = "DFD02313"
itx["filename"] = "/home/mogo/data/bags/badcase/20220706145143/20220706145143-265939904-rosmaster-XXXX000000.bag"
itx["filesize"] = "0"
itx["key"] = "265939904"
itx["reason"] = collectReason
itx["duration"] = "16"
itx["startTime"] = "20220706145203"
itx["channel"] = "AI"
itx["carSn"] = MoGoAiCloudClientConfig.getInstance().sn
itx["userRole"] = "安全员"
itx["audioUrl"] = "http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/CarPad/mogopadlog/deviceId/2022-07-07/AUDIO_myTest.wav"
itx["mapVersion"] = "MAP-taxi-hq_RoboTaxi_hq_H9_2.3.0.5_20220410"
itx["eyeVersion"] = "2.8.0"
itx["coordinate"] = ""
itx["carLicense"] = AppConfigInfo.plateNumber?:"" //车牌号
itx["filename"] = recordFileName?:"" //bag包文件地址
itx["filesize"] = "0" //bag包文件大小
itx["key"] = recordKey?:"" //key
itx["reason"] = collectReason //采集原因
itx["duration"] = "20" //采集时长固定为20S
itx["startTime"] = System.currentTimeMillis().toString() //上报时间(时间戳格式)
itx["channel"] = "AI" //渠道
itx["carSn"] = MoGoAiCloudClientConfig.getInstance().sn //SN
itx["userRole"] = "" //采集者角色
itx["audioUrl"] = "" //音频COS地址
itx["mapVersion"] = BadCaseConfig.dockerVersion ?:"" //工控机版本
itx["eyeVersion"] = AppUtils.getAppVersionName() //鹰眼版本
itx["coordinate"] = "latitude:${latitude};longitude:${longitude}" //坐标
})
if (uploadResult == null || uploadResult.code != 200) {
TipToast.shortTip("上报失败")
} else {
TipToast.shortTip("上报成功")
BadCaseConfig.windowNum--
clickListener?.closeWindow()
}
}
@@ -241,27 +260,24 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
it.gravity = Gravity.START or Gravity.TOP
it.width = 924
it.height = 668
it.alpha = 0.9f
it.alpha = 1.0f
}
}
override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) {
CallerLogger.d("${M_DEVA}${TAG}", "-- 收到工控机录制任务回调 -- $recordPanel")
when(recordPanel.toRecord().stat){
100, 101 ->{
//成功结束录制
TipToast.shortTip("bag录制成功")
ThreadUtils.runOnUiThread{
if(recordKey==null){
recordKey = recordPanel.key.toString()
BadCaseConfig.recordKeyList.add(recordPanel.key)
}
300 ->{
//开始录制
}
200 ->{
//录制失败
TipToast.shortTip("bag录制失败")
if(recordFileName==null){
recordFileName = recordPanel.filename
}
}
}
private fun setRadioButtonStatus(largeCarStatus: Boolean,trafficLightStatus: Boolean,waterStatus: Boolean,
@@ -296,9 +312,6 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
// 手指移动的时候更新小悬浮窗的位置
mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
}
// MotionEvent.ACTION_UP -> // 如果手指离开屏幕时xDownInScreen和xInScreen相等且yDownInScreen和yInScreen相等则视为触发了单击事件。
// if (mDownInScreenX === mInScreenX && mDownInScreenY === mInScreenY) {
// }
}
return true
}
@@ -309,12 +322,16 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)-350
mWindowManager!!.addView(mFloatLayout, mWindowParams)
}
}
fun hideFloatWindow() {
//注销采集结果回调监听
CallerAutopilotRecordListenerManager.removeListener(this.hashCode().toString())
// 移除 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.removeListener(this.hashCode().toString())
if (mFloatLayout.parent != null) mWindowManager!!.removeView(mFloatLayout)
}
@@ -345,4 +362,9 @@ class AIDataCollectWindow constructor(activity: Activity) : View.OnTouchListener
fun closeWindow()
}
override fun onAutopilotCarStateData(gnssInfo: MessagePad.GnssInfo?) {
latitude = gnssInfo?.latitude
longitude = gnssInfo?.longitude
}
}

View File

@@ -37,9 +37,9 @@ defStyleAttr: Int = 0
}
private var clickListener: ClickListener? = null
private var mIdentity = "安全员"
private var mPreviousDuration = 12
private var mBackDuration = 8
private var mIdentity = BadCaseConfig.identity
private var mPreviousDuration = BadCaseConfig.previousDuration
private var mBackDuration = BadCaseConfig.backDuration
private var mType = 1
init{
@@ -80,30 +80,30 @@ defStyleAttr: Int = 0
try {
if(preTimeStr.isEmpty()){
mPreviousDuration = 12
mPreviousDuration = BadCaseConfig.previousDuration
}else{
mPreviousDuration = preTimeStr.toInt()
}
if(afterTimeStr.isEmpty()){
mBackDuration = 8
mBackDuration = BadCaseConfig.backDuration
}else{
mBackDuration = afterTimeStr.toInt()
}
if(mPreviousDuration<0 || mPreviousDuration>300){
ToastUtils.showLong("采集时长最长300S")
if(mPreviousDuration<0 || mPreviousDuration>30){
ToastUtils.showLong("前溯采集时长最长30S")
return@setOnClickListener
}
if(mBackDuration<0 || mBackDuration>300){
ToastUtils.showLong("采集时长最长300S")
ToastUtils.showLong("采集时长最长300S")
return@setOnClickListener
}
if((mPreviousDuration+mBackDuration)<5){
ToastUtils.showLong("采集时长最短5S")
ToastUtils.showLong("采集时长最短5S")
return@setOnClickListener
}
if((mPreviousDuration+mBackDuration)>300){
ToastUtils.showLong("采集时长最长300S")
ToastUtils.showLong("采集时长最长300S")
return@setOnClickListener
}
BadCaseConfig.previousDuration = mPreviousDuration
@@ -125,6 +125,22 @@ defStyleAttr: Int = 0
clickListener?.onClose()
}
//现场恢复
when(BadCaseConfig.identity){
"安全员"->{
rbSafetyOfficer.isChecked = true
}
"QA、研发"->{
rbDeveloper.isChecked = true
}
"产品、运营、演示"->{
rbProduct.isChecked = true
}
}
etInitiativePreTime.hint = "${BadCaseConfig.previousDuration}S"
etInitiativeAfterTime.hint = "${BadCaseConfig.backDuration}S"
// val test1 = TestBean(1,"人工接管自动录制")
// val test2 = TestBean(2,"地图采集")
// val test3 = TestBean(3,"画龙问题排查")
@@ -172,7 +188,7 @@ defStyleAttr: Int = 0
// )
// radioButton.textSize = SizeUtils.sp2px(9f).toFloat()
// radioButton.id = it.id
// radioButton.isChecked = it.id == 1
// radioButton.isChecked = it.id == BadCaseConfig.type
// //设置文字
// radioButton.text = it.src
// //将radioButton添加到radioGroup中
@@ -218,7 +234,7 @@ defStyleAttr: Int = 0
)
radioButton.textSize = SizeUtils.sp2px(9f).toFloat()
radioButton.id = it.id
radioButton.isChecked = it.id == 1
radioButton.isChecked = it.id == BadCaseConfig.type
//设置文字
radioButton.text = it.desc
//将radioButton添加到radioGroup中

View File

@@ -3,25 +3,54 @@ package com.zhjt.mogo_core_function_devatools.badcase.biz
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.PixelFormat
import android.os.CountDownTimer
import android.os.Handler
import android.os.SystemClock
import android.util.DisplayMetrics
import android.view.*
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
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.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.zhidao.loglib.call.LogInfoManagerFactory
import com.zhidao.loglib.upload.OnUploadListener
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.badcase.record.RecordManager
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import mogo.telematics.pad.MessagePad
import record_cache.RecordPanelOuterClass
import java.io.File
import java.lang.StringBuilder
import java.lang.reflect.Field
import java.util.*
/**
* @author XuXinChao
* @description BadCase主动录包
* @since: 2022/7/13
*/
class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchListener{
class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchListener,
IMoGoAutopilotRecordListener, IMoGoAutopilotCarStateListener {
companion object {
const val TAG = "InitiativeBadCaseWindow"
}
private var mActivity: Activity = activity
private var mWindowParams: WindowManager.LayoutParams? = null
@@ -33,12 +62,29 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
private lateinit var tvInitiativeTime: TextView
private lateinit var tvInitiativeIdentity: TextView
private lateinit var viewAudioButton: View
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 viewAudioButton: ImageView
private lateinit var tvAudioCountDown: TextView
private lateinit var tvInitiativeReport: TextView
private lateinit var tvInitiativeCancel: TextView
private var audioStatus = false
private var audioFileName:String?=null //录音文件名称
private var uploadReason: StringBuilder = StringBuilder() //上报原因,标签
@Volatile
private var recordKey: String?=null //录制bag包key
@Volatile
private var recordFileName: String?=null //录制文件包名
private var longitude: Double?=null
private var latitude: Double?=null
private var mInViewX = 0f
private var mInViewY = 0f
@@ -66,36 +112,77 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
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)
viewAudioButton = mFloatLayout.findViewById(R.id.viewAudioButton)
tvAudioCountDown = mFloatLayout.findViewById(R.id.tvAudioCountDown)
tvInitiativeReport = mFloatLayout.findViewById(R.id.tvInitiativeReport)
tvInitiativeCancel = mFloatLayout.findViewById(R.id.tvInitiativeCancel)
if(BadCaseConfig.windowNum<1){
BadCaseConfig.windowNum = 1
}
tvInitiativeNum.text = BadCaseConfig.windowNum.toString()
BadCaseConfig.windowNum++
tvInitiativeTime.text = "时间:${millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat())}"
tvInitiativeIdentity.text = "身份:${BadCaseConfig.identity}"
viewAudioButton.setOnClickListener {
audioStatus = !audioStatus
if(audioStatus){
viewAudioButton.background = mActivity.getDrawable(R.drawable.bad_case_audio_select)
//开始录音
RecordManager.getInstance().start("audio_test")
}else{
viewAudioButton.background = mActivity.getDrawable(R.drawable.bad_case_audio_normal)
//结束录音
RecordManager.getInstance().stop()
}
}
tvInitiativeReport.setOnClickListener {
CallerAutoPilotManager.recordPackage(BadCaseConfig.type,
//采集结果回调监听
CallerAutopilotRecordListenerManager.addListener(this.hashCode().toString(),this)
// 添加 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.addListener(this.hashCode().toString(), this)
//开启录包
CallerAutoPilotManager.recordPackage(BadCaseConfig.type,
Random(SystemClock.elapsedRealtime()).nextInt(),
BadCaseConfig.totalDuration,
BadCaseConfig.previousDuration
)
viewAudioButton.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
}
tvInitiativeReport.setOnClickListener {
if(!rbOne.isChecked && !rbTwo.isChecked && !rbThree.isChecked &&
!rbFour.isChecked && !rbFive.isChecked && !rbSix.isChecked){
TipToast.shortTip("请选择至少一个Case")
return@setOnClickListener
}
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("点刹、顿挫")
}
if(audioStatus){
audioStatus = !audioStatus
setAudio(audioStatus)
Handler().postDelayed({
uploadAudio()
},1000)
}else{
uploadAudio()
}
}
tvInitiativeCancel.setOnClickListener {
BadCaseConfig.windowNum--
clickListener?.closeWindow()
@@ -110,7 +197,100 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
it.gravity = Gravity.START or Gravity.TOP
it.width = 924
it.height = 668
it.alpha = 0.9f
it.alpha = 1.0f
}
}
var countDownTimer: CountDownTimer?=null
private fun setAudio(status: Boolean){
if(status){
//开始录音
audioFileName = "Audio_${System.currentTimeMillis()}_BadCase"
RecordManager.getInstance().start(audioFileName)
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_select)
tvAudioCountDown.visibility = View.VISIBLE
//开始倒计时
if(countDownTimer==null){
countDownTimer = object : CountDownTimer(60000, 1000) {
override fun onTick(millisUntilFinished: Long) {
tvAudioCountDown.text = "${millisUntilFinished/1000}S"
}
override fun onFinish() {
tvAudioCountDown.visibility = View.GONE
//结束录音
RecordManager.getInstance().stop()
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_normal)
}
}
countDownTimer?.start()
}
}else{
//结束倒计时
countDownTimer?.cancel()
countDownTimer?.onFinish()
//将倒计时置空
countDownTimer = null
}
}
private fun uploadAudio(){
val singlePath = "/mnt/sdcard/mogo/DataCollection/${audioFileName}.wav"
val file = File(singlePath)
if(file.exists()){
LogInfoManagerFactory.createAudioUpload(mActivity.applicationContext,"Audio",singlePath,
object : OnUploadListener {
override fun onUploadSuccess(filePath: String, downloadUrl: String) {
CallerLogger.d("$M_DEVA$TAG", "语音文件上传成功downloadUrl=$downloadUrl")
//上传到服务器
upload(downloadUrl)
}
override fun onUploadFail(filePath: String) {
TipToast.shortTip("上传语音文件失败")
}
})
}else{
//上传到服务器
upload(null)
}
}
/**
* 将记录上传到服务器
* @param downloadUrl 语音文件下载地址
*/
private fun upload(downloadUrl: String?){
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"] = uploadReason.toString()?:"" //采集原因
itx["duration"] = BadCaseConfig.totalDuration.toString() //采集时长固定为20S
itx["startTime"] = System.currentTimeMillis().toString() //上报时间(时间戳格式)
itx["channel"] = "1" //渠道
itx["carSn"] = MoGoAiCloudClientConfig.getInstance().sn //SN
itx["userRole"] = BadCaseConfig.identity //采集者角色
itx["audioUrl"] = downloadUrl?:"" //音频COS地址
itx["mapVersion"] = BadCaseConfig.dockerVersion ?:"" //工控机版本
itx["eyeVersion"] = AppUtils.getAppVersionName() //鹰眼版本
itx["coordinate"] = "latitude:${latitude};longitude:${longitude}" //坐标
})
if (uploadResult == null || uploadResult.code != 200) {
TipToast.shortTip("上报失败")
} else {
TipToast.shortTip("上报成功")
BadCaseConfig.windowNum--
clickListener?.closeWindow()
}
}
}
@@ -135,9 +315,6 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
// 手指移动的时候更新小悬浮窗的位置
mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
}
// MotionEvent.ACTION_UP -> // 如果手指离开屏幕时xDownInScreen和xInScreen相等且yDownInScreen和yInScreen相等则视为触发了单击事件。
// if (mDownInScreenX === mInScreenX && mDownInScreenY === mInScreenY) {
// }
}
return true
}
@@ -148,12 +325,16 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)-350
mWindowManager!!.addView(mFloatLayout, mWindowParams)
}
}
fun hideFloatWindow() {
//注销采集结果回调监听
CallerAutopilotRecordListenerManager.removeListener(this.hashCode().toString())
// 移除 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.removeListener(this.hashCode().toString())
if (mFloatLayout.parent != null) mWindowManager!!.removeView(mFloatLayout)
}
@@ -176,6 +357,20 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
return sbar
}
override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) {
CallerLogger.d("${M_DEVA}${TAG}", "-- 收到工控机录制任务回调 -- $recordPanel")
ThreadUtils.runOnUiThread {
if(recordKey==null){
recordKey = recordPanel.key.toString()
BadCaseConfig.recordKeyList.add(recordPanel.key)
}
if(recordFileName==null){
recordFileName = recordPanel.filename
}
}
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
@@ -184,4 +379,9 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
fun closeWindow()
}
override fun onAutopilotCarStateData(gnssInfo: MessagePad.GnssInfo?) {
latitude = gnssInfo?.latitude
longitude = gnssInfo?.longitude
}
}

View File

@@ -0,0 +1,369 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.CountDownTimer
import android.os.Handler
import android.util.DisplayMetrics
import android.util.Log
import android.view.*
import android.widget.CheckBox
import android.widget.CompoundButton
import android.widget.ImageView
import android.widget.TextView
import com.google.android.flexbox.FlexboxLayout
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener
import androidx.lifecycle.lifecycleScope
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarStatusListenerManager
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.SizeUtils
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.zhidao.loglib.call.LogInfoManagerFactory
import com.zhidao.loglib.upload.OnUploadListener
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.badcase.record.RecordManager
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import mogo.telematics.pad.MessagePad
import com.mogo.eagle.core.utilcode.kotlin.*
import java.io.File
import java.lang.reflect.Field
/**
* @author XuXinChao
* @description BadCase被动录包
* @since: 2022/7/17
*/
class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListener,
IMoGoAutopilotCarStateListener, CompoundButton.OnCheckedChangeListener {
companion object {
const val TAG = "PassiveBadCaseWindow"
}
private var mActivity: Activity = activity
private var mWindowParams: WindowManager.LayoutParams? = null
private var mWindowManager: WindowManager? = null
private lateinit var mFloatLayout: View
private var audioStatus = false
private var audioFileName:String?=null //录音文件名称
private var uploadReason: String = String() //上报原因,标签
private var recordKey: String?=null //录制bag包key
private var recordFileName: String?=null //录制文件包名
private var longitude: Double?=null
private var latitude: Double?=null
private var mInViewX = 0f
private var mInViewY = 0f
private var mDownInScreenX = 0f
private var mDownInScreenY = 0f
private var mInScreenX = 0f
private var mInScreenY = 0f
private var clickListener: ClickListener? = null
var countDownTimer: CountDownTimer?=null
private lateinit var tvPassiveNum: TextView
private lateinit var tvPassiveTime: TextView
private lateinit var tvPassiveIdentity: TextView
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
init {
initFloatWindow();
}
private val presenter by lazy {
BadCasePresenter()
}
@SuppressLint("SetTextI18n")
private fun initFloatWindow(){
mFloatLayout = LayoutInflater.from(mActivity).inflate(R.layout.view_passive_bad_case, null) as View
mFloatLayout.setOnTouchListener(this)
tvPassiveNum = mFloatLayout.findViewById(R.id.tvPassiveNum)
tvPassiveTime = mFloatLayout.findViewById(R.id.tvPassiveTime)
tvPassiveIdentity = mFloatLayout.findViewById(R.id.tvPassiveIdentity)
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)
if(BadCaseConfig.windowNum<1){
BadCaseConfig.windowNum = 1
}
tvPassiveNum.text = BadCaseConfig.windowNum.toString()
BadCaseConfig.windowNum++
tvPassiveTime.text = "时间:${millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat())}"
tvPassiveIdentity.text = "身份:${BadCaseConfig.identity}"
// 添加 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.addListener(TAG, this)
viewAudioButton.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
}
tvPassiveReport.setOnClickListener {
if(uploadReason.isEmpty()){
TipToast.shortTip("请选择至少一个Case")
return@setOnClickListener
}
if(audioStatus){
audioStatus = !audioStatus
setAudio(audioStatus)
Handler().postDelayed({
uploadAudio()
},1000)
}else{
uploadAudio()
}
}
tvPassiveCancel.setOnClickListener {
BadCaseConfig.windowNum--
clickListener?.closeWindow()
}
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 = 924
it.height = 668
it.alpha = 1.0f
}
}
private fun setAudio(status: Boolean){
if(status){
//开始录音
audioFileName = "Audio_${System.currentTimeMillis()}_BadCase"
RecordManager.getInstance().start(audioFileName)
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_select)
tvAudioCountDown.visibility = View.VISIBLE
//开始倒计时
if(countDownTimer==null){
countDownTimer = object : CountDownTimer(60000, 1000) {
override fun onTick(millisUntilFinished: Long) {
tvAudioCountDown.text = "${millisUntilFinished/1000}S"
}
override fun onFinish() {
tvAudioCountDown.visibility = View.GONE
//结束录音
RecordManager.getInstance().stop()
//更改录音按钮背景
viewAudioButton.setImageResource(R.drawable.icon_bad_case_audio_normal)
}
}
countDownTimer?.start()
}
}else{
//结束倒计时
countDownTimer?.cancel()
countDownTimer?.onFinish()
//将倒计时置空
countDownTimer = null
}
}
private fun uploadAudio(){
val singlePath = "/mnt/sdcard/mogo/DataCollection/${audioFileName}.wav"
val file = File(singlePath)
if(file.exists()){
LogInfoManagerFactory.createAudioUpload(mActivity.applicationContext,"Audio",singlePath,
object : OnUploadListener {
override fun onUploadSuccess(filePath: String, downloadUrl: String) {
CallerLogger.d("$M_DEVA$TAG", "语音文件上传成功downloadUrl=$downloadUrl")
//上传到服务器
upload(downloadUrl)
}
override fun onUploadFail(filePath: String) {
TipToast.shortTip("上传语音文件失败")
}
})
}else{
//上传到服务器
upload(null)
}
}
/**
* 将记录上传到服务器
* @param downloadUrl 语音文件下载地址
*/
private fun upload(downloadUrl: String?){
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"] = uploadReason //采集原因
itx["duration"] = BadCaseConfig.totalDuration.toString() //采集时长固定为20S
itx["startTime"] = System.currentTimeMillis().toString() //上报时间(时间戳格式)
itx["channel"] = "0" //渠道
itx["carSn"] = MoGoAiCloudClientConfig.getInstance().sn //SN
itx["userRole"] = BadCaseConfig.identity //采集者角色
itx["audioUrl"] = downloadUrl?:"" //音频COS地址
itx["mapVersion"] = BadCaseConfig.dockerVersion ?:"" //工控机版本
itx["eyeVersion"] = AppUtils.getAppVersionName() //鹰眼版本
itx["coordinate"] = "latitude:${latitude};longitude:${longitude}" //坐标
})
if (uploadResult == null || uploadResult.code != 200) {
TipToast.shortTip("上报失败")
} else {
TipToast.shortTip("上报成功")
BadCaseConfig.windowNum--
clickListener?.closeWindow()
}
}
}
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)
}
}
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)-350
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 = SizeUtils.sp2px(9f).toFloat()
checkBox.text = it.reason
checkBox.isChecked = it.isChecked
checkBox.setOnCheckedChangeListener(this@PassiveBadCaseWindow)
flReasonLayout.addView(checkBox,lp)
}
}
}
}
}
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
Log.i("onCheckedChanged","buttonView"+buttonView)
Log.i("onCheckedChanged","isChecked"+isChecked)
buttonView?.text?.let {
if(isChecked){
if(!uploadReason.contains(it)){
uploadReason += it
}
}else{
if(uploadReason.contains(it)){
uploadReason = uploadReason.replace(it.toString(),"")
}
}
}
}
fun hideFloatWindow() {
// 移除 ADAS车辆状态&定位 监听
CallerAutopilotCarStatusListenerManager.removeListener(TAG)
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
}
fun setRecord(key:String,fileName:String){
recordKey = key
recordFileName = fileName
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
interface ClickListener {
fun closeWindow()
}
override fun onAutopilotCarStateData(gnssInfo: MessagePad.GnssInfo?) {
latitude = gnssInfo?.latitude
longitude = gnssInfo?.longitude
}
}

View File

@@ -1,13 +0,0 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz
/**
* @author xuxinchao
* @description
* @since: 2022/7/11
*/
data class TestBean(
var id: Int,
var src: String
) {
}

View File

@@ -24,5 +24,10 @@ object BadCaseConfig {
//BadCase采集和AI数据采集弹窗数量
@JvmField
var windowNum = 1
//工控机版本
@JvmField
var dockerVersion:String ?= null
var recordKeyList:ArrayList<Long> = ArrayList()
}

View File

@@ -4,8 +4,8 @@ import com.mogo.commons.debug.DebugConfig
internal object BadCaseHost {
private const val HOST_DEV = "http://dzt.zhidaozhixing.com/"
private const val HOST_RELEASE = "https://dzt-test.zhidaozhixing.com/"
private const val HOST_DEV = "http://dzt-test.zhidaozhixing.com/"
private const val HOST_RELEASE = "http://dzt.zhidaozhixing.com/"
fun getHost(): String{
return when (DebugConfig.getNetMode()) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -2,7 +2,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#3A57C5"
android:endColor="#323C6F"
android:endColor="#1B2966"
android:angle="0"
/>
<corners android:radius="40px" />

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false">
<solid android:color="#6D7BAF" />
<stroke android:width="5px" android:color="#FFCCCCCC" />
<size
android:width="105px"
android:height="105px" />
</shape>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false">
<gradient
android:startColor="#029DFF"
android:endColor="#0056FF"
android:angle="145"
/>
<stroke android:width="5px" android:color="#FFA7B6F0" />
<size
android:width="105px"
android:height="105px" />
</shape>

View File

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

View File

@@ -92,7 +92,6 @@
android:textColor="#FFFFFFFF"
android:textSize="38px"
android:button="@null"
android:checked="true"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="30px"
android:paddingTop="@dimen/dp_30"
@@ -146,7 +145,7 @@
android:textSize="38px"
app:layout_constraintTop_toBottomOf="@id/rbProduct"
app:layout_constraintLeft_toLeftOf="@id/rbProduct"
android:layout_marginTop="@dimen/dp_80"
android:layout_marginTop="@dimen/dp_50"
/>
<TextView
@@ -291,7 +290,7 @@
android:layout_height="15px"
android:src="@drawable/icon_expand"
app:layout_constraintLeft_toLeftOf="@id/tvInitiativeAfter"
app:layout_constraintTop_toBottomOf="@id/tvInitiativeAfter"
app:layout_constraintTop_toBottomOf="@id/etInitiativeAfterTime"
android:layout_marginTop="@dimen/dp_80"
/>

View File

@@ -5,7 +5,7 @@
android:layout_width="924px"
android:layout_height="668px"
app:roundLayoutRadius="40px"
android:background="@color/module_switch_map_bg">
android:background="#1B2966">
<View
android:layout_width="match_parent"
@@ -175,7 +175,7 @@
android:textColor="#FFFFFF"
android:textSize="30px"
android:gravity="center"
android:background="@drawable/cancel_button_bg"
android:background="@drawable/icon_cancel_bg"
android:layout_marginBottom="@dimen/dp_40"
/>

View File

@@ -5,7 +5,7 @@
android:layout_width="924px"
android:layout_height="668px"
app:roundLayoutRadius="40px"
android:background="@color/module_switch_map_bg">
android:background="#1B2966">
<View
android:layout_width="match_parent"
@@ -52,7 +52,7 @@
android:layout_marginEnd="@dimen/dp_50"
/>
<RadioButton
<CheckBox
android:id="@+id/rbOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -61,46 +61,46 @@
android:textSize="34px"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
android:drawablePadding="@dimen/dp_10"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvInitiativeNum"
android:layout_marginStart="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginStart="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_40"
/>
<RadioButton
<CheckBox
android:id="@+id/rbTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点刹、顿挫"
android:textColor="#FFFFFFFF"
android:textSize="34px"
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/rbOne"
android:layout_marginStart="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_50"
/>
<RadioButton
android:id="@+id/rbThree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="速度过慢"
android:textColor="#FFFFFFFF"
android:textSize="34px"
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="34px"
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_50"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginStart="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_40"
/>
<RadioButton
<CheckBox
android:id="@+id/rbFour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -109,13 +109,13 @@
android:textSize="34px"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
android:drawablePadding="@dimen/dp_10"
app:layout_constraintTop_toBottomOf="@id/rbOne"
app:layout_constraintLeft_toLeftOf="@id/rbOne"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_40"
/>
<RadioButton
<CheckBox
android:id="@+id/rbFive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -127,22 +127,23 @@
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbTwo"
app:layout_constraintLeft_toLeftOf="@id/rbTwo"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_40"
/>
<RadioButton
<CheckBox
android:id="@+id/rbSix"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="感知、定位、地图等其他"
android:text="点刹、顿挫"
android:textColor="#FFFFFFFF"
android:textSize="34px"
android:button="@null"
android:drawableLeft="@drawable/badcase_radio_button_style"
android:drawablePadding="@dimen/dp_20"
app:layout_constraintTop_toBottomOf="@id/rbThree"
app:layout_constraintLeft_toLeftOf="@id/rbThree"
android:layout_marginTop="@dimen/dp_50"
app:layout_constraintTop_toBottomOf="@id/rbOne"
app:layout_constraintLeft_toRightOf="@id/rbFive"
android:layout_marginTop="@dimen/dp_40"
android:layout_marginStart="@dimen/dp_30"
/>
<TextView
@@ -171,40 +172,42 @@
android:textColor="#FFFFFF"
android:textSize="30px"
android:gravity="center"
android:background="@drawable/cancel_button_bg"
android:background="@drawable/icon_cancel_bg"
android:layout_marginBottom="@dimen/dp_40"
/>
<View
<ImageView
android:id="@+id/viewAudioBg"
android:layout_width="824px"
android:layout_height="174px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvInitiativeReport"
android:background="@drawable/bad_case_audio_bg"
android:background="@drawable/icon_audio_bg"
android:layout_marginBottom="@dimen/dp_40"
/>
<View
<ImageView
android:id="@+id/viewAudioButton"
android:layout_width="105px"
android:layout_height="105px"
android:layout_width="120px"
android:layout_height="120px"
app:layout_constraintLeft_toLeftOf="@id/viewAudioBg"
app:layout_constraintRight_toRightOf="@id/viewAudioBg"
app:layout_constraintTop_toTopOf="@id/viewAudioBg"
app:layout_constraintBottom_toBottomOf="@id/viewAudioBg"
android:background="@drawable/bad_case_audio_normal"
android:background="@drawable/icon_bad_case_audio_normal"
/>
<ImageView
android:layout_width="40px"
android:layout_height="55px"
android:src="@drawable/icon_audio"
app:layout_constraintLeft_toLeftOf="@id/viewAudioButton"
app:layout_constraintRight_toRightOf="@id/viewAudioButton"
<TextView
android:id="@+id/tvAudioCountDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="30px"
app:layout_constraintTop_toTopOf="@id/viewAudioButton"
app:layout_constraintBottom_toBottomOf="@id/viewAudioButton"
app:layout_constraintLeft_toRightOf="@id/viewAudioButton"
android:layout_marginStart="@dimen/dp_30"
/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.RoundConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="924px"
android:layout_height="668px"
app:roundLayoutRadius="40px"
android:background="#1B2966">
<View
android:layout_width="match_parent"
android:layout_height="113px"
android:background="@drawable/ai_collect_title_bg"
/>
<TextView
android:id="@+id/tvPassiveNum"
android:layout_width="120px"
android:layout_height="113px"
android:background="@drawable/icon_num_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:textColor="#FFFFFFFF"
android:textSize="46px"
android:gravity="center"
android:text="1"
/>
<TextView
android:id="@+id/tvPassiveTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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="38px"
android:layout_marginStart="@dimen/dp_50"
/>
<TextView
android:id="@+id/tvPassiveIdentity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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="38px"
android:layout_marginEnd="@dimen/dp_50"
/>
<TextView
android:id="@+id/tvPassiveReport"
android:layout_width="270px"
android:layout_height="70px"
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="30px"
android:gravity="center"
android:layout_marginBottom="@dimen/dp_40"
/>
<TextView
android:id="@+id/tvPassiveCancel"
android:layout_width="270px"
android:layout_height="70px"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@id/tvPassiveReport"
android:text="取消"
android:textColor="#FFFFFF"
android:textSize="30px"
android:gravity="center"
android:background="@drawable/icon_cancel_bg"
android:layout_marginBottom="@dimen/dp_40"
/>
<ImageView
android:id="@+id/viewAudioBg"
android:layout_width="824px"
android:layout_height="174px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvPassiveReport"
android:background="@drawable/icon_audio_bg"
android:layout_marginBottom="@dimen/dp_40"
/>
<ImageView
android:id="@+id/viewAudioButton"
android:layout_width="120px"
android:layout_height="120px"
app:layout_constraintLeft_toLeftOf="@id/viewAudioBg"
app:layout_constraintRight_toRightOf="@id/viewAudioBg"
app:layout_constraintTop_toTopOf="@id/viewAudioBg"
app:layout_constraintBottom_toBottomOf="@id/viewAudioBg"
android:background="@drawable/icon_bad_case_audio_normal"
/>
<TextView
android:id="@+id/tvAudioCountDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="30px"
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

@@ -30,6 +30,7 @@ import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.data.constants.MoGoFragmentPaths
import com.mogo.eagle.core.data.enums.SidePattern
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
@@ -72,6 +73,8 @@ import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_V2X
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
import com.mogo.eagle.core.utilcode.reminder.*
import com.mogo.eagle.core.utilcode.reminder.api.*
import com.mogo.eagle.core.utilcode.reminder.api.IReminder.IStateChangeListener
@@ -79,8 +82,10 @@ import com.mogo.eagle.core.utilcode.reminder.api.impl.*
import com.mogo.eagle.core.utilcode.util.SoundUtils
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.module.common.enums.*
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.fragment_hmi.*
import kotlinx.coroutines.*
import mogo_msg.MogoReportMsg
@@ -140,6 +145,7 @@ import java.util.*
private var speakJob: Job? = null
private var showingV2XTip: IReminder? = null
private var roadVideoDialog: RoadVideoDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
@@ -209,10 +215,26 @@ import java.util.*
override fun getNotificationView(): IViewNotification? = context?.let { V2XNotificationView(it) }
override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) {
if (HmiBuildConfig.isShowBadCaseView && recordPanel.type == 1 && recordPanel.stat == 100) {
CallerDevaToolsManager.onReceiveBadCaseRecord(recordPanel)
CallerLogger.d("$M_HMI$TAG", "recordKey=${recordPanel.key},stat=${recordPanel.stat}")
if(BadCaseConfig.recordKeyList.contains(recordPanel.key)){
if(recordPanel.stat == 100 || recordPanel.stat == 101){
//成功结束录制
TipToast.shortTip("${millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat())} bag录制成功")
}
if(recordPanel.stat == 200){
//录制失败
TipToast.shortTip("${millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat())} bag录制失败")
}
return
}
if (recordPanel.type == 2 && (
//处于非美化模式下弹窗
if (!FunctionBuildConfig.isDemoMode && (recordPanel.stat == 100 || recordPanel.stat == 101)) {
//只在司机屏生效,乘客屏不生效
if(AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)){
activity?.let { CallerDevaToolsManager.onReceiveBadCaseRecord(recordPanel, it) }
}
}
if (!FunctionBuildConfig.isDemoMode && recordPanel.type == 2 && (
recordPanel.stat == 101 || //工控机采集完成-被动完成
recordPanel.stat == 100 || //工控机采集完成-主动完成
recordPanel.stat == 102 || //工控机达到最大采集时长
@@ -259,24 +281,28 @@ import java.util.*
/**
* 展示工控机监控上报数据
* @param reportList 上报数据列表
* @param errorReportList 错误级别上报数据列表
* @param warningReportList 提醒级别上报数据列表
* @param reportLevel 1:error级别 2:warning级别
*/
override fun showIPCReportWindow(reportList: ArrayList<ReportEntity>) {
override fun showIPCReportWindow(errorReportList: ArrayList<ReportEntity>,warningReportList: ArrayList<ReportEntity>,reportLevel: Int) {
ThreadUtils.runOnUiThread{
if(ipcReportWindow==null){
ipcReportWindow= activity?.let { IPCReportWindow(it) }
ipcReportWindow?.setClickListener(object: IPCReportWindow.ClickListener{
override fun closeWindow() {
ipcReportWindow?.hideFloatWindow()
ipcReportWindow =null
if(reportLevel == 1){
if(ipcReportWindow==null){
ipcReportWindow= activity?.let { IPCReportWindow(it) }
ipcReportWindow?.setClickListener(object: IPCReportWindow.ClickListener{
override fun closeWindow() {
ipcReportWindow?.hideFloatWindow()
ipcReportWindow =null
}
})
ipcReportWindow?.let {
SoundUtils.playRing(requireContext())
}
})
ipcReportWindow?.let {
SoundUtils.playRing(requireContext())
}
ipcReportWindow?.showFloatWindow()
}
ipcReportWindow?.showFloatWindow()
ipcReportWindow?.refreshData(reportList)
ipcReportWindow?.refreshData(errorReportList,warningReportList,reportLevel)
}
}
@@ -578,12 +604,19 @@ import java.util.*
content.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType))
content.setWarningContent(warningContent)
var reminder: IReminder? = null
Log.d("$M_HMI$TAG", "--- show v2x dialog 1 ---: info -> v2x-type: $v2xType : expireTime: $expireTime")
Reminder.enqueue(this@MoGoHmiFragment, object : PopupWindowReminder(PopupWindow(content, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).also { itx ->
itx.isTouchable = false
itx.isFocusable = false
itx.isClippingEnabled = false
itx.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val transition = Slide(Gravity.TOP).also { t ->
val transition = Slide(when(content.sidePattern) {
LEFT, RESULT_LEFT-> Gravity.LEFT
RIGHT, RESULT_RIGHT -> Gravity.RIGHT
TOP, RESULT_TOP -> Gravity.TOP
BOTTOM, RESULT_BOTTOM -> Gravity.BOTTOM
else -> Gravity.TOP
}).also { t ->
t.interpolator = AccelerateDecelerateInterpolator()
t.duration = 200
}
@@ -595,7 +628,8 @@ import java.util.*
override fun show() {
val parent = it.window.decorView
parent.doOnAttach {
popupWindow.showAtLocation(parent, Gravity.TOP, 0, 0)
Log.d("$M_HMI$TAG", "--- show v2x dialog 2 ---: info -> v2x-type: $v2xType : expireTime: $expireTime")
popupWindow.showAtLocation(parent, content.layoutGravity, 0, 0)
}
}
@@ -607,7 +641,6 @@ import java.util.*
override fun onShow(reminder: IReminder) {
listener?.onShow()
if (ttsContent != null && !TextUtils.isEmpty(ttsContent) && playTTS) {
CallerLogger.d("$M_HMI$TAG", "---> ttsContent = $ttsContent")
lifecycleScope.launch {
speak(it, ttsContent)
}.also {
@@ -625,6 +658,7 @@ import java.util.*
if (reminder == null) {
return
}
showingV2XTip = reminder
lifecycleScope.launch {
delay(expireTime)
reminder?.hide()
@@ -663,6 +697,8 @@ import java.util.*
activity?.let {
WarningFloat.dismiss(tag)
}
Log.d("$M_HMI$TAG", "--- disableWarningV2X ---")
showingV2XTip?.takeIf { it.isShowing() }?.also { it.hide() }
}
/**

View File

@@ -5,6 +5,7 @@ import android.graphics.PixelFormat
import android.util.DisplayMetrics
import android.view.*
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.report.ReportEntity
@@ -23,6 +24,8 @@ class IPCReportWindow constructor(activity: Activity) : View.OnTouchListener{
private var mWindowManager: WindowManager? = null
private lateinit var rvIPCReport: RecyclerView
private lateinit var ivIpcClose: ImageView
private lateinit var tvIpcErrorTab: TextView
private lateinit var tvIpcWarningTab: TextView
private var ipcReportAdapter: IPCReportAdapter?=null
private lateinit var mFloatLayout: View
@@ -35,6 +38,9 @@ class IPCReportWindow constructor(activity: Activity) : View.OnTouchListener{
private var clickListener: ClickListener? = null
private var ipcErrorReportList: List<ReportEntity>? = null //错误上报列表
private var ipcWarningReportList: List<ReportEntity>? = null//警告上报列表
init {
initFloatWindow();
}
@@ -44,28 +50,47 @@ class IPCReportWindow constructor(activity: Activity) : View.OnTouchListener{
mFloatLayout.setOnTouchListener(this)
rvIPCReport= mFloatLayout.findViewById(R.id.rv_ipc_report)
ivIpcClose = mFloatLayout.findViewById(R.id.iv_ipc_close)
tvIpcErrorTab = mFloatLayout.findViewById(R.id.tv_ipc_error_tab)
tvIpcWarningTab = mFloatLayout.findViewById(R.id.tv_ipc_warning_tab)
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 = 600
it.height = 800
it.alpha = 0.9f
it.width = 924
it.height = 444
it.alpha = 1.0f
}
ipcReportAdapter = IPCReportAdapter()
rvIPCReport.layoutManager = WrapContentLinearLayoutManager(mActivity,
LinearLayoutManager.VERTICAL,false)
rvIPCReport.adapter = ipcReportAdapter
//关闭按钮
ivIpcClose.setOnClickListener {
clickListener?.closeWindow()
}
//错误列表
tvIpcErrorTab.setOnClickListener {
ipcReportAdapter?.setData(ipcErrorReportList)
ipcReportAdapter?.notifyDataSetChanged()
}
//预警列表
tvIpcWarningTab.setOnClickListener {
ipcReportAdapter?.setData(ipcWarningReportList)
ipcReportAdapter?.notifyDataSetChanged()
}
}
fun refreshData(data:List<ReportEntity>){
ipcReportAdapter?.setData(data)
fun refreshData(errorReportList:List<ReportEntity>,warningReportList:List<ReportEntity>,reportLevel: Int){
if(reportLevel == 1){
ipcReportAdapter?.setData(errorReportList)
ipcErrorReportList = errorReportList
}else{
ipcReportAdapter?.setData(warningReportList)
ipcWarningReportList = warningReportList
}
ipcReportAdapter?.notifyDataSetChanged()
}
@@ -103,7 +128,8 @@ class IPCReportWindow constructor(activity: Activity) : View.OnTouchListener{
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)
// mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)
mWindowParams!!.y = metrics.heightPixels - getSysBarHeight(mActivity)-100
mWindowManager!!.addView(mFloatLayout, mWindowParams)
}
}

View File

@@ -30,7 +30,7 @@ class V2XNotificationView @JvmOverloads constructor(
LayoutInflater.from(context).inflate(R.layout.notification_v2x_msg_vr, this, true)
// 设置View的出场位置
sidePattern = SidePattern.RESULT_TOP
layoutGravity = Gravity.CENTER_HORIZONTAL
layoutGravity = Gravity.CENTER_HORIZONTAL or Gravity.TOP
// 设置View的停留位置
setPadding(0, 110, 0, 0)
}

View File

@@ -13,6 +13,7 @@ import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.view_version_name.view.*
/**
@@ -88,6 +89,8 @@ class VersionNameView @JvmOverloads constructor(
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
dockerVersion = autoPilotStatusInfo.dockVersion
showCurrentMapVersion()
//将工控机版本赋值给BadCase配置常量
BadCaseConfig.dockerVersion = autoPilotStatusInfo.dockVersion
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#3A57C5"
android:endColor="#1E2E87"
android:startColor="#029DFF"
android:endColor="#0056FF"
android:angle="0"
/>
<corners android:radius="8px" />
<corners android:topLeftRadius="40px" />
</shape>

View File

@@ -11,7 +11,7 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
android:textSize="16sp"
android:text="@string/ipc_report_time"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
@@ -24,7 +24,7 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/tvReportTimeTitle"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
android:textSize="16sp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
/>
@@ -36,7 +36,7 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvReportTimeTitle"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
android:textSize="16sp"
android:text="@string/ipc_report_type"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
@@ -49,8 +49,8 @@
app:layout_constraintTop_toTopOf="@id/tvReportResultTitle"
app:layout_constraintLeft_toRightOf="@id/tvReportResultTitle"
app:layout_constraintRight_toRightOf="parent"
android:textColor="@color/color_FF0006"
android:textSize="14sp"
android:textColor="@color/color_FFFFFF"
android:textSize="16sp"
android:minLines="1"
android:layout_marginEnd="10dp"
/>
@@ -62,7 +62,7 @@
app:layout_constraintTop_toBottomOf="@id/tvReportResultContent"
app:layout_constraintLeft_toLeftOf="parent"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
android:textSize="16sp"
android:text="@string/ipc_report_msg"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
@@ -76,8 +76,8 @@
app:layout_constraintLeft_toRightOf="@id/tvReportMsgTitle"
app:layout_constraintRight_toRightOf="parent"
android:minLines="1"
android:textColor="@color/color_FF0006"
android:textSize="14sp"
android:textColor="@color/color_FFFFFF"
android:textSize="16sp"
android:layout_marginEnd="10dp"
/>
@@ -88,7 +88,7 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvReportMsgContent"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
android:textSize="16sp"
android:text="@string/ipc_report_action"
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
@@ -103,7 +103,7 @@
app:layout_constraintRight_toRightOf="parent"
android:minLines="1"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
android:textSize="16sp"
android:layout_marginEnd="10dp"
/>
@@ -113,8 +113,10 @@
android:background="#F0F0F0"
app:layout_constraintTop_toBottomOf="@id/tvReportActionContent"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
android:textSize="16sp"
android:layout_marginTop="5dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,49 +1,57 @@
<?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="500px"
android:layout_height="350px"
android:layout_width="924px"
android:layout_height="444px"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_ipc_drag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_drag"
android:padding="10dp"
android:layout_gravity="center_horizontal"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<ImageView
android:id="@+id/iv_ipc_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_report_close"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/iv_ipc_drag"
app:layout_constraintBottom_toBottomOf="@id/iv_ipc_drag"
android:padding="10dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<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">
app:roundLayoutRadius="40px">
<TextView
android:id="@+id/tv_ipc_error_tab"
android:layout_width="412px"
android:layout_height="90px"
android:text="Error"
android:textColor="#FFFFFFFF"
android:textSize="38px"
android:gravity="center"
android:background="@drawable/ipc_error_tab_bg"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/tv_ipc_warning_tab"
android:layout_width="412px"
android:layout_height="90px"
android:text="Warning"
android:textColor="#FFFFFFFF"
android:textSize="38px"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/tv_ipc_error_tab"
android:background="#3A57C5"
/>
<ImageView
android:id="@+id/iv_ipc_close"
android:layout_width="100px"
android:layout_height="90px"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:src="@drawable/icon_ipc_close"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_ipc_report"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/tv_ipc_error_tab"
app:layout_constraintBottom_toBottomOf="parent"
/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -1,5 +1,6 @@
package com.mogo.eagle.core.function.api.devatools
import android.app.Activity
import android.content.Context
import android.view.View
import com.alibaba.android.arouter.facade.template.IProvider
@@ -86,7 +87,7 @@ interface IDevaToolsProvider : IProvider {
/**
* 当工控机回调时调用
*/
fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel)
fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel,activity: Activity)
/**
* 展示录包配置

View File

@@ -243,9 +243,11 @@ interface IMoGoWaringProvider : IMoGoHmiViewProxy {
/**
* 展示工控机监控上报数据
* @param reportList 上报数据列表
* @param errorReportList 错误级别上报数据列表
* @param warningReportList 提醒级别上报数据列表
* @param reportLevel 1:error级别 2:warning级别
*/
fun showIPCReportWindow(reportList: ArrayList<ReportEntity>)
fun showIPCReportWindow(errorReportList: ArrayList<ReportEntity>,warningReportList: ArrayList<ReportEntity>,reportLevel: Int)
fun showVideoDialog(url: String, isFlvUrl: Boolean)
}

View File

@@ -1,5 +1,6 @@
package com.mogo.eagle.core.function.call.devatools
import android.app.Activity
import android.content.Context
import android.view.View
import com.mogo.eagle.core.data.constants.MogoServicePaths
@@ -119,8 +120,8 @@ object CallerDevaToolsManager {
/**
* 收到工控机回调时触发
*/
fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel) {
devaToolsProviderApi?.onReceiveBadCaseRecord(record)
fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel,activity: Activity) {
devaToolsProviderApi?.onReceiveBadCaseRecord(record,activity)
}
/**

View File

@@ -352,10 +352,12 @@ object CallerHmiManager : CallerBase() {
/**
* 展示工控机监控上报数据
* @param reportList 上报数据列表
* @param errorReportList 错误级别上报数据列表
* @param warningReportList 提醒级别上报数据列表
* @param reportLevel 1:error级别 2:warning级别
*/
fun showIPCReportWindow(reportList: ArrayList<ReportEntity>){
waringProviderApi?.showIPCReportWindow(reportList)
fun showIPCReportWindow(errorReportList: ArrayList<ReportEntity>,warningReportList: ArrayList<ReportEntity>,reportLevel: Int){
waringProviderApi?.showIPCReportWindow(errorReportList,warningReportList,reportLevel)
}
@JvmOverloads