Merge branch 'dev_robotaxi-d_240912_6.7.0' of gitlab.zhidaoauto.com:SCA/L4HA/AndroidApp/MoGoEagleEye into dev_robotaxi-d_240912_6.7.0

This commit is contained in:
aibingbing
2024-09-26 17:54:58 +08:00
37 changed files with 1113 additions and 147 deletions

View File

@@ -33,6 +33,11 @@ class OchCustomViewProvider : IOchCustomViewProvider {
if(temp is FacadeProvider){
commonService = temp.commonService
}
}else{
val temp = ARouter.getInstance().build(FacadeConst.PASSENGER_PATH).navigation(context)
if(temp is FacadeProvider){
commonService = temp.commonService
}
}
}

View File

@@ -61,6 +61,7 @@ dependencies {
implementation rootProject.ext.dependencies.roomRxjava
implementation rootProject.ext.dependencies.androidxrecyclerview
kapt rootProject.ext.dependencies.recyclerviewadapterhelper
implementation rootProject.ext.dependencies.lottie
implementation rootProject.ext.dependencies.androidxroomruntime
kapt rootProject.ext.dependencies.androidxroomcompiler

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

View File

@@ -71,10 +71,12 @@ class SwitchLineTaskAdapter(
if(checkTask!!.taskId==task.taskId){
checkTask = null
mTaskItemClickListener?.onItemClick(currentPosition,false)
notifyItemChanged(currentPosition)
}else {
resetOther()
checkTask = task
mTaskItemClickListener?.onItemClick(currentPosition,true)
notifyItemChanged(currentPosition)
}
}
@@ -88,6 +90,7 @@ class SwitchLineTaskAdapter(
if(checkTask!=null && result.taskId==checkTask!!.taskId){
checkTask = null
notifyItemChanged(index)
return
}
}
}

View File

@@ -9,8 +9,11 @@ import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.utils.RxUtils
import com.mogo.och.shuttle.weaknet.R
import kotlinx.android.synthetic.main.shuttle_weak_task_leave_station_view.view.actv_draggable
import kotlinx.android.synthetic.main.shuttle_weak_task_leave_station_view.view.lottie_bg
class BizLeaveStationView @JvmOverloads constructor(
context: Context,
@@ -38,6 +41,7 @@ class BizLeaveStationView @JvmOverloads constructor(
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_task_leave_station_view, this, true)
draggableButton = findViewById(R.id.actv_draggable)
lottie_bg.setImageAssetsFolder("images")
}
override fun onAttachedToWindow() {
@@ -87,7 +91,12 @@ class BizLeaveStationView @JvmOverloads constructor(
duration = 100
}.start()
}else if (draggableButton.translationX>=(width-draggableButton.width)){
slideListener?.slideEnd()
lottie_bg.setAnimation("data.json")
lottie_bg.playAnimation()
actv_draggable.setTextColor(ResourcesUtils.getColor(R.color.shuttle_driver_80FFFFFF))
RxUtils.createSubscribe(1_000) {
slideListener?.slideEnd()
}
}else{
ObjectAnimator.ofFloat(
draggableButton, "translationX", draggableButton.translationX,
@@ -106,6 +115,9 @@ class BizLeaveStationView @JvmOverloads constructor(
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
lottie_bg.setAnimation("slide.json")
lottie_bg.playAnimation()
actv_draggable.setTextColor(ResourcesUtils.getColor(R.color.white))
ObjectAnimator.ofFloat(
draggableButton, "translationX", draggableButton.translationX,
0f

View File

@@ -2,5 +2,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_30"/>
<solid android:color="@color/bus_color_4dffffff"/>
<solid android:color="@color/bus_color_4D000000"/>
</shape>

View File

@@ -7,14 +7,24 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/aciv_task_leave_station_slide_bg"
app:layout_constraintBottom_toBottomOf="parent"
<!-- <androidx.appcompat.widget.AppCompatImageView-->
<!-- android:id="@+id/aciv_task_leave_station_slide_bg"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- android:src="@drawable/bus_task_leave_station_slide_bg"-->
<!-- android:layout_width="@dimen/dp_774"-->
<!-- android:layout_height="@dimen/dp_120"/>-->
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_bg"
android:layout_width="774px"
android:layout_height="120px"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/bus_task_leave_station_slide_bg"
android:layout_width="@dimen/dp_774"
android:layout_height="@dimen/dp_120"/>
app:layout_constraintTop_toTopOf="parent"
app:lottie_fileName="slide.json"
app:lottie_loop="true"
app:lottie_autoPlay="true"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_draggable"

View File

@@ -74,4 +74,5 @@
<color name="shuttle_driver_bf0e3dbc">#BF0E3DBC</color>
<color name="shuttle_driver_bf1e2e89">#BF1E2E89</color>
<color name="shuttle_driver_D4D4D4">#D4D4D4</color>
<color name="shuttle_driver_80FFFFFF">#80FFFFFF</color>
</resources>

View File

@@ -17,8 +17,8 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Group;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentTransaction;
import com.mogo.commons.mvp.IView;
@@ -29,7 +29,6 @@ import com.mogo.eagle.core.function.api.och.toolkit.IToolKitItemClickListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager;
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager;
import com.mogo.eagle.core.function.hmi.map.MapContainerLayout;
import com.mogo.eagle.core.function.view.MapRoamView;
@@ -46,9 +45,6 @@ import com.mogo.och.taxi.R;
import java.lang.ref.WeakReference;
import me.jessyan.autosize.utils.AutoSizeUtils;
/**
* 网约车基础Fragment主要负责布局通用界面处理站点面板和通话面板互斥情况
* <p>
@@ -56,7 +52,7 @@ import me.jessyan.autosize.utils.AutoSizeUtils;
*
* @author tongchenfei
*/
public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> implements IMogoMapListener{
public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> implements IMogoMapListener {
private static final String TAG = "BaseOchFragment";
private RelativeLayout ctvAutopilotStatusRL;
@@ -66,7 +62,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
private FrameLayout flNaviPanelContainer;
private MapRoamView mapRoamView;
private Group groupTestPanel;
// private FrameLayout mSpeedView;
// private FrameLayout mSpeedView;
private ImageView mAutopilotImage;
private TextView mAutopilotTv;
private ImageView mCloseNaviIcon;
@@ -75,7 +71,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
protected TaxiAmapNaviFragment ochAmapNaviFragment = null;
protected TaxiRottingNaviFragment taxiRottingNaviFragment = null;
// protected AppCompatImageView acivShowGuid;
// protected AppCompatImageView acivShowGuid;
private MapContainerLayout mapContainerLayout;
private OverMapDialog overMapDialog;
private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -147,24 +143,24 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
// 模拟 不可自动驾驶目前场景是刚开机adas还未和工控机连接
findViewById(R.id.btnAutopilotDisable).setOnClickListener(view ->
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE,true)
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE, true)
);
// 模拟 可自动驾驶,工控机连接正常,且处于人工干预状态
findViewById(R.id.btnAutopilotEnable).setOnClickListener(view ->
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE,true)
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE, true)
);
// 模拟 自动驾驶能力,自动驾驶中,可能是停车,可能是行进,但是是机器在处理车的前进后退,不是人
findViewById(R.id.btnAutopilotRunning).setOnClickListener(view ->
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING,true)
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING, true)
);
findViewById(R.id.btnAutopilotmanco).setOnClickListener(view ->
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING,true));
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING, true));
tvOperationStatus.setOnClickListener(new OnPreventFastClickListener() {
@Override
@@ -190,16 +186,19 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
// }
// });
if(getContext()!=null){
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addSingleToolKitDefaultItem(runningTaskGateWay,"运营面板", R.drawable.common_biz_operation,4);
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addToolKitDefaultItemClickListener(runningTaskGateWay,new IToolKitItemClickListener() {
if (getContext() != null) {
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addSingleToolKitDefaultItem(runningTaskGateWay, "运营面板", R.drawable.common_biz_operation, 4);
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addToolKitDefaultItemClickListener(runningTaskGateWay, new IToolKitItemClickListener() {
@Override
public void onItemClick(@NonNull String toolTag, @Nullable Context ctx) {
personalDialogFragment = new WeakReference<>(new TaxiPersonalDialogFragment());
personalDialogFragment.get().show(getActivity().getSupportFragmentManager(), "service_data");
FragmentActivity activity = getActivity();
if (activity != null) {
personalDialogFragment.get().show(activity.getSupportFragmentManager(), "service_data");
}
}
});
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addSingleToolKitCustomItem(lineView, new LineView(getContext()),10);
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addSingleToolKitCustomItem(lineView, new LineView(getContext()), 10);
}
}
@@ -245,7 +244,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
public void onDestroyView() {
mapContainerLayout.onDestroy();
mapRoamView.onDestroy();
if(overMapDialog!=null) {
if (overMapDialog != null) {
overMapDialog.hideDialog();
overMapDialog.destory();
overMapDialog = null;
@@ -272,7 +271,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
super.onDestroy();
}
public void onAutopilotStatusChanged(int status,boolean canStart) {
public void onAutopilotStatusChanged(int status, boolean canStart) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
@@ -287,9 +286,9 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
}
// 3. 其他过程直接更新
startOrStopLoadingAnim(false);
autopilotStatusAnimchanged(status,canStart);
autopilotStatusAnimchanged(status, canStart);
}
},UiThreadHandler.MODE.QUEUE);
}, UiThreadHandler.MODE.QUEUE);
}
public void stopAnimAndUpdateBtnStatus() {
@@ -297,8 +296,8 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
startAutopilotDone(false);
}
public void onManMachineCoDriving(int manMachineCoDriving,boolean canStartAuto) {
autopilotStatusAnimchanged(manMachineCoDriving,canStartAuto);
public void onManMachineCoDriving(int manMachineCoDriving, boolean canStartAuto) {
autopilotStatusAnimchanged(manMachineCoDriving, canStartAuto);
}
public void updateCtvAutopilotStatusTag(boolean tag) {
@@ -312,7 +311,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
protected abstract void updateOrderBottomBtnUI();
public void autopilotStatusAnimchanged(int status,boolean canStart) {
public void autopilotStatusAnimchanged(int status, boolean canStart) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status) {
mAutopilotTv.setText("自动驾驶");
mAutopilotTv.setTextColor(ResourcesUtils.getColor(R.color.taxi_autopilot_text_color_normal));
@@ -320,11 +319,11 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
ctvAutopilotStatusRL.setBackgroundResource(R.drawable.common_autopilot_in_autopilot);
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == status) {
mAutopilotTv.setText("自动驾驶");
if(canStart){
if (canStart) {
mAutopilotTv.setTextColor(ResourcesUtils.getColor(R.color.taxi_autopilot_text_color_normal));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot);
ctvAutopilotStatusRL.setBackgroundResource(R.drawable.common_autopilot_press);
}else {
} else {
mAutopilotTv.setTextColor(ResourcesUtils.getColor(R.color.taxi_autopilot_text_color_disable));
mAutopilotImage.setImageResource(R.drawable.taxi_ic_autopilot_disable);
ctvAutopilotStatusRL.setBackgroundResource(R.drawable.common_autopilot_press);
@@ -345,7 +344,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
}
private void startAutopilotDone(boolean success) {
if(mAutopilotImage==null){
if (mAutopilotImage == null) {
return;
}
if (autopilotLoadingAnimator != null) {
@@ -366,7 +365,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
@Override
public void run() {
startOrStopLoadingAnim(false);
onAutopilotStatusChanged(CallerAutoPilotStatusListenerManager.INSTANCE.getState(),CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false, 0));
onAutopilotStatusChanged(CallerAutoPilotStatusListenerManager.INSTANCE.getState(), CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false, 0));
}
}, 1000L);
}
@@ -424,7 +423,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
if(flStationPanelContainer!=null) {
if (flStationPanelContainer != null) {
flStationPanelContainer.setVisibility(View.GONE);
// ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) visualViewDirver.getLayoutParams();
// layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
@@ -435,14 +434,14 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
// visualViewDirver.setLayoutParams(layoutParams);
}
}
},UiThreadHandler.MODE.QUEUE);
}, UiThreadHandler.MODE.QUEUE);
}
public void showPanel() {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
if(flStationPanelContainer!=null) {
if (flStationPanelContainer != null) {
flStationPanelContainer.setVisibility(View.VISIBLE);
// ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) visualViewDirver.getLayoutParams();
// layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
@@ -453,7 +452,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
// visualViewDirver.setLayoutParams(layoutParams);
}
}
},UiThreadHandler.MODE.QUEUE);
}, UiThreadHandler.MODE.QUEUE);
}
/**
@@ -478,7 +477,7 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
}
tvOperationStatus.setVisibility(visible);
}
},UiThreadHandler.MODE.QUEUE);
}, UiThreadHandler.MODE.QUEUE);
}
protected void showAmapNaviToStationFragment(boolean isShow) {
@@ -549,7 +548,8 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
public void setGuidShow() {
// acivShowGuid.setVisibility(View.VISIBLE);
}
public void setGuidHide(){
public void setGuidHide() {
// acivShowGuid.setVisibility(View.GONE);
}
}

View File

@@ -8,7 +8,7 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
//apply from: rootProject.file('gradle/bytex/bytex.gradle')
apply from: rootProject.file('gradle/bytex/bytex.gradle')
Properties properties = new Properties()
properties.load(project.rootProject.file("gradle.properties").newDataInputStream())

View File

@@ -20,6 +20,7 @@ ext {
localbroadcastmanager : "androidx.localbroadcastmanager:localbroadcastmanager:1.0.0",
// flexbox
flexbox : 'com.google.android.flexbox:flexbox:3.0.0',
lottie :'com.airbnb.android:lottie:5.2.0',
guava :'com.google.guava:guava:29.0-android',
// 测试
junit : "junit:junit:4.12",

View File

@@ -610,25 +610,25 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
override fun onAutopilotStatistics(statistics: AutopilotStatistics?) {
statistics?.let {
Log.i(TAG,"onAutopilotStatistics status = "+ it.status)
if(it.status == AutopilotStatistics.AUTOPILOT_START_STATUS.FAILED){
// if(it.status == AutopilotStatistics.AUTOPILOT_START_STATUS.FAILED){
//触发一键上报
ThreadUtils.runOnUiThread{
val activity = AppStateManager.currentActivity()
if (activity !is AppCompatActivity) {
return@runOnUiThread
}
if(reportTypeWindow == null){
reportTypeWindow = ReportTypeWindow(activity)
reportTypeWindow?.setClickListener(object: ReportTypeWindow.ClickListener{
override fun closeWindow() {
reportTypeWindow?.hideFloatWindow()
reportTypeWindow = null
}
})
}
reportTypeWindow?.showOneClickReportWindow(xPosition,yPosition)
}
}
// ThreadUtils.runOnUiThread{
// val activity = AppStateManager.currentActivity()
// if (activity !is AppCompatActivity) {
// return@runOnUiThread
// }
// if(reportTypeWindow == null){
// reportTypeWindow = ReportTypeWindow(activity)
// reportTypeWindow?.setClickListener(object: ReportTypeWindow.ClickListener{
// override fun closeWindow() {
// reportTypeWindow?.hideFloatWindow()
// reportTypeWindow = null
// }
// })
// }
// reportTypeWindow?.showOneClickReportWindow(xPosition,yPosition)
// }
// }
}
}

View File

@@ -417,25 +417,25 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
when (motionEvent?.action) {
MotionEvent.ACTION_DOWN -> {
// 获取相对View的坐标即以此View左上角为原点
mInViewX = motionEvent.x
mInViewY = motionEvent.y
// 获取相对屏幕的坐标,即以屏幕左上角为原点
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY
}
MotionEvent.ACTION_MOVE -> {
// 更新浮动窗口位置参数
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY
mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
// 手指移动的时候更新小悬浮窗的位置
mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
}
}
// when (motionEvent?.action) {
// MotionEvent.ACTION_DOWN -> {
// // 获取相对View的坐标即以此View左上角为原点
// mInViewX = motionEvent.x
// mInViewY = motionEvent.y
// // 获取相对屏幕的坐标,即以屏幕左上角为原点
// mInScreenX = motionEvent.rawX
// mInScreenY = motionEvent.rawY
// }
// MotionEvent.ACTION_MOVE -> {
// // 更新浮动窗口位置参数
// mInScreenX = motionEvent.rawX
// mInScreenY = motionEvent.rawY
// mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
// mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
// // 手指移动的时候更新小悬浮窗的位置
// mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
// }
// }
return true
}

View File

@@ -3,7 +3,7 @@
<item>
<shape>
<!-- 边框颜色 -->
<solid android:color="#8996C7"/>
<solid android:color="#A3A3A3"/>
<corners
android:bottomLeftRadius="@dimen/dp_8"
android:bottomRightRadius="@dimen/dp_8"
@@ -20,7 +20,7 @@
android:right="@dimen/dp_1" >
<shape>
<!-- View填充颜色 -->
<solid android:color="#F2161927" />
<solid android:color="#2E323A" />
<corners
android:bottomLeftRadius="@dimen/dp_8"
android:bottomRightRadius="@dimen/dp_8"

View File

@@ -6,5 +6,5 @@
android:angle="270"
/>
<corners
android:radius="@dimen/dp_0"/>
android:radius="@dimen/dp_10"/>
</shape>

View File

@@ -191,6 +191,8 @@
android:visibility="gone"
android:layout_marginTop="@dimen/dp_m_5"
android:paddingTop="@dimen/dp_5"
android:layout_marginStart="@dimen/dp_m_1"
android:layout_marginEnd="@dimen/dp_m_1"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -8,7 +8,9 @@ import com.mogo.eagle.core.data.enums.Carmodel
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxEventListener
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.bone.tab.FaultReasonView
import com.mogo.eagle.core.function.hmi.bone.tab.ReportTypeView
import com.mogo.eagle.core.function.hmi.bone.tab.WorkOrderView
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.UiThreadHandler
@@ -94,8 +96,23 @@ class BoneTabLayout @JvmOverloads constructor(
override fun openWorkOrderView() {
workOrderView.visibility = VISIBLE
}
override fun closeReportView() {
updateTabType(TabType.REPORT_INFO)
}
})
faultReasonView.setClickListener(object: FaultReasonView.ClickListener{
override fun closeFaultReasonView() {
updateTabType(TabType.REPORT_INFO)
}
})
workOrderView.setClickListener(object: WorkOrderView.ClickListener{
override fun closeWorkOrderView() {
updateTabType(TabType.REPORT_INFO)
}
})
}
fun setCarNo(carNo: String?) {

View File

@@ -325,6 +325,7 @@ class FaultReasonView @JvmOverloads constructor(
//取消
tvFaultCancel.setOnClickListener {
this@FaultReasonView.visibility = View.GONE
clickListener?.closeFaultReasonView()
}
}
@@ -430,7 +431,7 @@ class FaultReasonView @JvmOverloads constructor(
}
interface ClickListener {
fun closeWindow()
fun closeFaultReasonView()
}
/**
@@ -448,6 +449,7 @@ class FaultReasonView @JvmOverloads constructor(
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@FaultReasonView.visibility = View.GONE
clickListener?.closeFaultReasonView()
},1500)
}
}

View File

@@ -120,8 +120,7 @@ class ReportTypeView @JvmOverloads constructor(
//故障类
tvReportTypeFault.setOnClickListener {
//TODO 更改!
if(!ProjectUtils.isSaas()){
if(ProjectUtils.isSaas()){
clickListener?.openFaultReasonView()
}else{
//展示工单上报弹窗
@@ -144,10 +143,12 @@ class ReportTypeView @JvmOverloads constructor(
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@ReportTypeView.visibility = View.GONE
clickListener?.closeReportView()
},1500)
}else{
ToastUtils.showShort("主动录包命令下发失败")
this@ReportTypeView.visibility = View.GONE
clickListener?.closeReportView()
}
}
}
@@ -172,6 +173,7 @@ class ReportTypeView @JvmOverloads constructor(
if(!hasReportOperate){
ThreadUtils.runOnUiThread {
this@ReportTypeView.visibility = View.GONE
clickListener?.closeReportView()
}
}
}
@@ -201,6 +203,7 @@ class ReportTypeView @JvmOverloads constructor(
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this.visibility = View.GONE
clickListener?.closeReportView()
},1500)
}
}
@@ -210,6 +213,7 @@ class ReportTypeView @JvmOverloads constructor(
ToastUtils.showShort("故障原因上报失败$msg")
ThreadUtils.runOnUiThread {
this.visibility = View.GONE
clickListener?.closeReportView()
}
}
@@ -252,6 +256,8 @@ class ReportTypeView @JvmOverloads constructor(
interface ClickListener {
fun openFaultReasonView()
fun openWorkOrderView()
fun closeReportView()
}
fun setClickListener(clickListener: ClickListener) {

View File

@@ -73,6 +73,8 @@ class WorkOrderView @JvmOverloads constructor(
var ret = 0 // 函数调用返回值
private var audioStatus = false
private var clickListener: ClickListener? = null
init {
LayoutInflater.from(context).inflate(R.layout.view_work_order, this, true)
initView()
@@ -90,7 +92,7 @@ class WorkOrderView @JvmOverloads constructor(
private fun initEvent(){
CallerDevaToolsListenerManager.addListener(TAG, this)
//弹窗展示时间
tv_work_order_time.text = resources.getString(R.string.work_order_time) +
tv_work_order_time.text =
millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
wrap_radio_group.setOnCheckedChangeListener{_, checkedId ->
@@ -197,6 +199,7 @@ class WorkOrderView @JvmOverloads constructor(
//取消
tv_work_order_cancel.setOnClickListener {
this@WorkOrderView.visibility = View.GONE
clickListener?.closeWorkOrderView()
}
}
@@ -302,6 +305,7 @@ class WorkOrderView @JvmOverloads constructor(
ToastUtils.showShort("工单上报成功")
ThreadUtils.runOnUiThread {
this@WorkOrderView.visibility = View.GONE
clickListener?.closeWorkOrderView()
}
}
@@ -309,4 +313,12 @@ class WorkOrderView @JvmOverloads constructor(
ToastUtils.showShort("工单上报失败")
}
interface ClickListener{
fun closeWorkOrderView()
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
}

View File

@@ -0,0 +1,206 @@
package com.mogo.eagle.core.function.hmi.ui.msgbox
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.deva.report.ReportEntity
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.msgbox.FMInfoMsg
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxCountDownBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.MsgCategory
import com.mogo.eagle.core.data.msgbox.MsgFmData
import com.mogo.eagle.core.function.api.autopilot.IMoGoNodeStateListener
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxListener
import com.mogo.eagle.core.function.api.order.IOrderListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerNodeStateListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxListenerManager
import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.msgbox.adapter.MsgBoxBubbleAdapter
import com.mogo.eagle.core.function.msgbox.MsgBoxConfig
import com.mogo.eagle.core.utilcode.util.SoundPoolUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.mogo.adas.data.bean.NodeStateInfo
import kotlinx.android.synthetic.main.layout_driver_msg_box_bubble.view.clMsgBubbleLayout
import kotlinx.android.synthetic.main.layout_msg_box_bubble.view.llMsgBubbleLayout
import kotlinx.android.synthetic.main.layout_msg_box_bubble.view.rvBubbleList
/**
* 司机端消息盒子气泡视图改版视图
*/
class MsgBoxBubbleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMsgBoxListener, IOrderListener{
init {
LayoutInflater.from(context).inflate(R.layout.layout_msg_box_bubble, this, true)
initView()
}
var msgBoxBubbleAdapter: MsgBoxBubbleAdapter ?= null
private val TAG = "DriverMsgBoxBubbleView"
private val dataList :ArrayList<MsgBoxCountDownBean> = ArrayList()
private var isShowData = true
private var isShowSummary = false //是否展示汇总消息
private fun initView(){
val linearLayoutManager = LinearLayoutManager(context)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
linearLayoutManager.stackFromEnd = true
linearLayoutManager.reverseLayout = true
msgBoxBubbleAdapter = MsgBoxBubbleAdapter(context as Activity)
msgBoxBubbleAdapter?.setChangeListener(object : MsgBoxBubbleAdapter.ChangeViewListener{
override fun notifyView() {
if(dataList.isEmpty()){
llMsgBubbleLayout.visibility = View.GONE
}
}
})
rvBubbleList.adapter = msgBoxBubbleAdapter
rvBubbleList.layoutManager = linearLayoutManager
}
/**
* 是否展示接收消息,消息盒子打开状态下不再展示气泡消息
* @param show true 展示false 不展示
*/
fun isShowData(show: Boolean){
isShowData = show
}
override fun onDataChanged(category: MsgCategory, msgBoxBean: MsgBoxBean) {
UiThreadHandler.post({
when (category) {
MsgCategory.NOTICE -> {
MsgBoxConfig.noticeList.add(msgBoxBean)
}
MsgCategory.SYS_INFO -> {
MsgBoxConfig.systemInfoList.add(msgBoxBean)
}
MsgCategory.RECORD_BAG -> {
MsgBoxConfig.recordBagList.add(msgBoxBean)
}
else -> {}
}
if(isShowData){
if(category == MsgCategory.RECORD_BAG){
if(!FunctionBuildConfig.isDemoMode && FunctionBuildConfig.isShowBagRecordWindow){
//弹出被动录包弹窗
CallerDevaToolsManager.onReceiveBadCaseRecord(msgBoxBean,context as Activity,true)
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
}
} else if(category == MsgCategory.SYS_INFO){
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
if(msgBoxBean.type == MsgBoxType.REPORT){
val reportMsg = msgBoxBean.bean as ReportEntity
//P8-P1均只收在消息盒子里P0消息盒子弹出其中P0弹出时需要判断驾驶状态非自动驾驶、非平行驾驶状态不弹出其余状态弹出
var isShowReport = false
for(action in reportMsg.actionsList){
if("ACTION_MANUAL_HANDLE_IMMEDIATELY" == action){
if(CallerAutoPilotStatusListenerManager.getState() == 2
|| CallerAutoPilotStatusListenerManager.getState() == 7){
isShowReport = true
}
}
}
if(isShowReport){
//展示消息
showData(msgBoxBean)
}
}
} else if(category == MsgCategory.FM_INFO){
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
if(FunctionBuildConfig.isTakeoverRemind){
//属于停车警示(包括择机靠边停车、立即舒适停车、就地紧急停车)时,需要弹出消息气泡并伴有提示音
val fmInfoMsg = msgBoxBean.bean as FMInfoMsg
var curFaultLevel = 5 //默认级别遍历数组找出级别最高的level数越小级别越高
fmInfoMsg.fmInfoList?.forEach { faultInfo ->
if(faultInfo.faultActionCount>0){
faultInfo.faultActionList.forEach {actionCode ->
//获取建议操作级别,得到建议操作级别最高的操作
if(MsgFmData.FaultAction.getFaultLevel(actionCode) < curFaultLevel){
curFaultLevel = MsgFmData.FaultAction.getFaultLevel(actionCode)
}
}
}
}
//P0级消息弹出时需要判断驾驶状态非自动驾驶、非平行驾驶状态不弹出其余状态弹出
if(curFaultLevel == 0){
//自动驾驶状态 0是不可用 1是ready 2是自动驾驶中 7:平行驾驶中
if(CallerAutoPilotStatusListenerManager.getState() == 2
|| CallerAutoPilotStatusListenerManager.getState() == 7){
// 6.6.0 ,因为 FSM 模块也会弹修改为只有没有 FSM 模块才弹
// 6.6.0 20240823 考虑到 FSM 初期消息不一定全,先不加限制,产品先观察功能后再考虑是否过滤
// if (hasNoneFSMNode()) {
//语音提示
try {
SoundPoolUtils.getSoundPool().playSoundWithRedId(context,R.raw.weak_net_tips)
}catch (e: Exception){
e.printStackTrace()
}
//展示消息
showData(msgBoxBean)
//}
}
}
}
} else{
if(msgBoxBean.sourceType == DataSourceType.SUMMARY){
//在一次订单中汇总消息只展示一次
if(isShowSummary){
showData(msgBoxBean)
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
isShowSummary = false
}
}else{
if(msgBoxBean.type == MsgBoxType.V2X){
//鹰眼650需求不再展示气泡态V2X消息
return@post
}
showData(msgBoxBean)
CallerMsgBoxEventListenerManager.invokeUpdateTipListener(true)
}
}
}
}, UiThreadHandler.MODE.QUEUE)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerMsgBoxListenerManager.addListener(TAG,this)
CallerOrderListenerManager.addListener(TAG,this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerMsgBoxListenerManager.removeListener(TAG)
CallerOrderListenerManager.removeListener(TAG)
}
override fun onUpdateOrderStatus(inOrder: Boolean) {
isShowSummary = inOrder
}
private fun showData(msgBoxBean: MsgBoxBean){
clMsgBubbleLayout.visibility = View.VISIBLE
val msgBoxCountDownBean = MsgBoxCountDownBean(msgBoxBean)
dataList.add(msgBoxCountDownBean)
msgBoxBubbleAdapter?.setData(dataList)
}
}

View File

@@ -0,0 +1,484 @@
package com.mogo.eagle.core.function.hmi.ui.msgbox.adapter
import android.app.Activity
import android.os.CountDownTimer
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.deva.report.ReportEntity
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.AutopilotMsg
import com.mogo.eagle.core.data.msgbox.FMInfoMsg
import com.mogo.eagle.core.data.msgbox.FSMMsg
import com.mogo.eagle.core.data.msgbox.MsgBoxCountDownBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.MsgFmData
import com.mogo.eagle.core.data.msgbox.NoticeFrCloudMsg
import com.mogo.eagle.core.data.msgbox.OperationMsg
import com.mogo.eagle.core.data.msgbox.SSMMsg
import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp
import com.mogo.eagle.core.utilcode.mogo.glide.transform.GlideRoundedCornersTransform
import com.mogo.eagle.core.utilcode.util.ResourceUtils.getDrawable
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.getHourMinFormat
import com.mogo.eagle.core.widget.RoundCanClickConstraintLayout
class MsgBoxBubbleAdapter(private val activity: Activity) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var data: ArrayList<MsgBoxCountDownBean> ?= null
private var changeViewListener: ChangeViewListener?=null
private val operation: Int = 1
private val operationReturn: Int = 10
private val operationStop: Int = 11
private val operationDoorSwitchFail: Int = 13 //车门开启、关闭失败
private val notice: Int = 2
private val v2x: Int = 3
private val report: Int = 4
private val summary: Int = 5
private val fm: Int = 6
private val ssm: Int = 7
private val autopilot: Int = 8
private val fsm: Int = 9
private val none: Int = 10
fun setData(data: ArrayList<MsgBoxCountDownBean>){
this.data = data
if(data.size>4){
data.removeAt(0)
}
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
operation -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_operation,parent,false)
return BubbleOperationHolder(view)
}
operationReturn -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_bubble_operation_return, parent, false)
return BubbleOperationReturnHolder(view)
}
operationStop -> {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_bubble_operation_stop, parent, false)
return BubbleOperationStopHolder(view)
}
operationDoorSwitchFail ->{
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_msg_bubble_operation_door, parent, false)
return BubbleOperationDoorFailHolder(view)
}
report -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_report,parent,false)
return BubbleReportHolder(view)
}
notice -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_notice,parent,false)
return BubbleNoticeHolder(view)
}
summary -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_summary,parent,false)
return BubbleSummaryHolder(view)
}
fm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_fm,parent,false)
return BubbleFmHolder(view)
}
ssm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_ssm,parent,false)
return BubbleSsmHolder(view)
}
autopilot -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_autopilot,parent,false)
return BubbleAutopilotHolder(view)
}
fsm -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_fsm,parent,false)
return BubbleFSMHolder(view)
}
else -> {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_msg_bubble_v2x,parent,false)
return BubbleV2XHolder(view)
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is BubbleOperationHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
val operationMsg = msgBoxBean.bean as OperationMsg
holder.tvBubbleOperationTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvBubbleOperationContent.text = operationMsg.content
holder.clBubbleOperationLayout.setOnClickListener {
CallerMsgBoxEventListenerManager.invokeBubbleOperationListener(msgBoxBean)
}
}
}
//运营平台还车通知
is BubbleOperationReturnHolder -> {
data?.let {
val operationReturnMsg = it[position].msgBoxBean.bean as OperationMsg
holder.tvOperationReturnContent.text = operationReturnMsg.content
holder.tvOperationReturnTime.text =
TimeUtils.millis2String(operationReturnMsg.timestamp, getHourMinFormat())
}
}
//运营平台靠边停车
is BubbleOperationStopHolder -> {
data?.let {
val operationStopMsg = it[position].msgBoxBean.bean as OperationMsg
holder.tvOperationStopTime.text =
TimeUtils.millis2String(operationStopMsg.timestamp, getHourMinFormat())
holder.tvOperationStopContent.text = operationStopMsg.content
}
}
//车门开启关闭失败
is BubbleOperationDoorFailHolder -> {
data?.let{
val operationDoorMsg = it[position].msgBoxBean.bean as OperationMsg
holder.tvOperationDoorTime.text =
TimeUtils.millis2String(operationDoorMsg.timestamp, getHourMinFormat())
holder.tvOperationDoorContent.text = operationDoorMsg.content
}
}
//系统信息消息
is BubbleReportHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
val reportEntity = msgBoxBean.bean as ReportEntity
holder.tvBubbleReportTime.text = "时间:${TimeUtils.millis2String(it[position].msgBoxBean.timestamp)}"
holder.tvBubbleReceiveTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
var resultStr = "类型:"
for (result in reportEntity.resultList){
resultStr = "${resultStr}${CallerAutoPilotControlManager.getReportResultDesc(result)}"
}
holder.tvBubbleReportType.text = resultStr
holder.clReportLayout.setOnClickListener {
CallerMsgBoxEventListenerManager.invokeBubbleReportListener(msgBoxBean)
}
}
}
//云公告消息
is BubbleNoticeHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean.bean
val noticeFrCloudMsg = msgBoxBean as NoticeFrCloudMsg
if(noticeFrCloudMsg.type == 0){
val noticeNormalData = noticeFrCloudMsg.noticeNormalData
holder.tvNoticeTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvNoticeContent.text = noticeNormalData?.content
GlideApp.with(activity).load(noticeNormalData?.imageUrl).optionalTransform(
GlideRoundedCornersTransform(
20f,
GlideRoundedCornersTransform.CornerType.ALL
)
).into(holder.ivNoticeImage)
holder.tvNoticeCheck.setOnClickListener {
//云公告
if (noticeNormalData != null) {
CallerHmiManager.showNoticeNormalData(noticeNormalData)
}
}
}else if(noticeFrCloudMsg.type == 1){
val noticeTrafficStylePushData = noticeFrCloudMsg.trafficPushData
holder.tvNoticeTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvNoticeContent.text = noticeTrafficStylePushData?.content
GlideApp.with(activity).load(noticeTrafficStylePushData?.poiImgUrl).optionalTransform(
GlideRoundedCornersTransform(
20f,
GlideRoundedCornersTransform.CornerType.ALL
)
).into(holder.ivNoticeImage)
holder.tvNoticeCheck.setOnClickListener {
//云公告
if (noticeTrafficStylePushData != null) {
CallerHmiManager.showTrafficBanner(noticeTrafficStylePushData)
}
}
}
}
}
//V2X消息
is BubbleV2XHolder -> {
data?.let {
val msgBoxBean = it[position].msgBoxBean
val v2XMsg = msgBoxBean.bean as V2XMsg
holder.tvV2XTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvV2XContent.text = v2XMsg.content
holder.ivV2XImage.setImageDrawable(ResourcesCompat.getDrawable(activity.resources,EventTypeEnumNew.getUpdateIconRes(v2XMsg.type),null))
holder.clV2XLayout.setOnClickListener {
CallerMsgBoxEventListenerManager.invokeBubbleV2XListener(msgBoxBean)
}
if(v2XMsg.type== EventTypeEnumNew.TYPE_VERIFICATION_SUCCESSFUL.poiType||v2XMsg.type == EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.poiType){
holder.itemView.setBackgroundResource(R.drawable.bg_temp_v2x_success)
}else{
holder.itemView.setBackgroundResource(R.drawable.bg_msg_box_v2x)
}
if(v2XMsg.communicationType.isNullOrEmpty()){
holder.tvV2XTitle.text = EventTypeEnumNew.getEventTitle(v2XMsg.type)
}else{
holder.tvV2XTitle.text = String.format(activity.resources.getString(R.string.v2x_title_content),
v2XMsg.communicationType, EventTypeEnumNew.getEventTitle(v2XMsg.type))
}
}
}
//汇总消息
is BubbleSummaryHolder -> {
data?.let {
val summaryMsg = it[position].msgBoxBean.bean as V2XMsg
holder.tvSummaryTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
holder.tvSummaryContent.text = summaryMsg.content
}
}
//FM信息
is BubbleFmHolder ->{
data?.let {
val fmMsg = it[position].msgBoxBean.bean as FMInfoMsg
if(fmMsg.policyTime == null){
holder.tvBubbleFmTime.text = TimeUtils.millis2String(it[position].msgBoxBean.timestamp,getHourMinFormat())
}else{
holder.tvBubbleFmTime.text = TimeUtils.millis2String(fmMsg.policyTime!!,getHourMinFormat())
}
if(fmMsg.fmInfoList?.size == 0){
holder.tvBubbleFmFaultAction.text = "建议操作:暂无"
holder.tvBubbleFmFault.text = MsgFmData.getFmPolicyName(fmMsg.policyCode)
}else{
var curFaultLevel = 5 //默认级别遍历数组找出级别最高的level数越小级别越高
fmMsg.fmInfoList?.forEach { faultInfo ->
if(faultInfo.faultActionCount>0){
faultInfo.faultActionList.forEach {actionCode ->
//获取建议操作级别,得到建议操作级别最高的操作
if(MsgFmData.FaultAction.getFaultLevel(actionCode) < curFaultLevel){
curFaultLevel = MsgFmData.FaultAction.getFaultLevel(actionCode)
}
}
}
}
val faultAction = MsgFmData.FaultAction.getFaultAction(curFaultLevel)
holder.tvBubbleFmFault.text = faultAction
//当出现多个建议操作时,按照整车下电重启、请求人工驾驶接管、请求平行驾驶接管、系统重启、联系硬件工程师、
// 联系运维工程师、联系软件工程师优先级递减的顺序,只展示最高优先级的内容
if(curFaultLevel == 5){
holder.tvBubbleFmFaultAction.text = "建议操作:暂无"
}else{
holder.tvBubbleFmFaultAction.text = "${faultAction}(${MsgFmData.FaultAction.getFaultActionCode(curFaultLevel)})"
}
//不同级别的Icon显示
when(curFaultLevel){
0->{
//重度预警样式
holder.ivBubbleFmImage.setImageDrawable(getDrawable(R.drawable.icon_fm_stop_normal))
}
1,2,3->{
//中度预警样式
holder.ivBubbleFmImage.setImageDrawable(getDrawable(R.drawable.icon_fm_reduce_normal))
}
4,5->{
//轻度预警样式
holder.ivBubbleFmImage.setImageDrawable(getDrawable(R.drawable.icon_fm_warning_normal))
}
}
}
}
}
//SSM连接消息
is BubbleSsmHolder ->{
data?.let {
val ssmMsg = it[position].msgBoxBean.bean as SSMMsg
holder.tvSsmTitle.text = ssmMsg.title
holder.tvSsmContent.text= ssmMsg.content
holder.tvSsmTime.text = TimeUtils.millis2String(ssmMsg.timestamp,getHourMinFormat())
}
}
//域控制器连接消息
is BubbleAutopilotHolder ->{
data?.let {
val autopilotMsg = it[position].msgBoxBean.bean as AutopilotMsg
holder.tvAutopilotTitle.text = autopilotMsg.title
holder.tvAutopilotContent.text = autopilotMsg.content
holder.tvAutopilotTime.text = TimeUtils.millis2String(autopilotMsg.timestamp,getHourMinFormat())
}
}
//FSM消息
is BubbleFSMHolder ->{
data?.let {
val fsmMsg = it[position].msgBoxBean.bean as FSMMsg
holder.tvFSMTitle.text = fsmMsg.title
holder.tvFSMContent.text = fsmMsg.content
holder.tvFSMTime.text = TimeUtils.millis2String(fsmMsg.timestamp,getHourMinFormat())
}
}
}
val msgBoxBean: MsgBoxCountDownBean = data!![position]
msgBoxBean.countDownTimer =object: CountDownTimer(CallerMsgBoxManager.getDismissTime(),1000){
override fun onTick(p0: Long) {
}
override fun onFinish() {
data?.remove(msgBoxBean)
changeViewListener?.notifyView()
notifyDataSetChanged()
}
}
msgBoxBean.countDownTimer?.start()
}
override fun getItemCount() = data?.size ?: 0
override fun getItemViewType(position: Int): Int {
return if(data!![position].msgBoxBean.type == MsgBoxType.OPERATION){
when ((data!![position].msgBoxBean.bean as OperationMsg).type) {
0 -> {
//运营平台还车通知
operationReturn
}
1 -> {
//运营平台靠边停车
operationStop
}
3 -> {
//车门开启关闭失败
operationDoorSwitchFail
}
else -> {
//普通运营平台
operation
}
}
}else if(data!![position].msgBoxBean.type == MsgBoxType.REPORT){
report
}else if(data!![position].msgBoxBean.type == MsgBoxType.NOTICE){
notice
}else if(data!![position].msgBoxBean.type == MsgBoxType.V2X && data!![position].msgBoxBean.sourceType == DataSourceType.SUMMARY){
summary
}else if(data!![position].msgBoxBean.type == MsgBoxType.FMINFO){
fm
}else if(data!![position].msgBoxBean.type == MsgBoxType.SSMINFO){
ssm
}else if(data!![position].msgBoxBean.type == MsgBoxType.AUTOPILOT){
autopilot
}else if(data!![position].msgBoxBean.type == MsgBoxType.FSM){
fsm
} else {
v2x
}
}
fun setChangeListener(listener: ChangeViewListener){
changeViewListener = listener
}
interface ChangeViewListener{
fun notifyView()
}
//车辆系统信息
class BubbleReportHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvBubbleReportTime: TextView = itemView.findViewById(R.id.tvBubbleReportTime)
var tvBubbleReportType: TextView = itemView.findViewById(R.id.tvBubbleReportType)
var tvBubbleReceiveTime: TextView = itemView.findViewById(R.id.tvBubbleReceiveTime)
var clReportLayout: RoundCanClickConstraintLayout = itemView.findViewById(R.id.clReportLayout)
}
//运营平台
class BubbleOperationHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvBubbleOperationTime: TextView = itemView.findViewById(R.id.tvBubbleOperationTime)
var tvBubbleOperationContent: TextView = itemView.findViewById(R.id.tvBubbleOperationContent)
var clBubbleOperationLayout: RoundCanClickConstraintLayout = itemView.findViewById(R.id.clBubbleOperationLayout)
}
//运营平台还车通知
class BubbleOperationReturnHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvOperationReturnTime: TextView = itemView.findViewById(R.id.tvOperationReturnTime)
var tvOperationReturnContent: TextView = itemView.findViewById(R.id.tvOperationReturnContent)
}
//运营平台靠边停车通知
class BubbleOperationStopHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvOperationStopTime: TextView = itemView.findViewById(R.id.tvOperationStopTime)
var tvOperationStopContent: TextView = itemView.findViewById(R.id.tvOperationStopContent)
}
//车门开启关闭失败
class BubbleOperationDoorFailHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvOperationDoorTime: TextView = itemView.findViewById(R.id.tvOperationDoorTime)
var tvOperationDoorContent: TextView = itemView.findViewById(R.id.tvOperationDoorContent)
}
//Notice
class BubbleNoticeHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivNoticeImage: ImageView = itemView.findViewById(R.id.ivNoticeImage)
// var tvNoticeTitle: TextView = itemView.findViewById(R.id.tvNoticeTitle)
var tvNoticeTime: TextView = itemView.findViewById(R.id.tvNoticeTime)
var tvNoticeCheck: TextView = itemView.findViewById(R.id.tvNoticeCheck)
var tvNoticeContent: TextView = itemView.findViewById(R.id.tvNoticeContent)
}
//V2X
class BubbleV2XHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivV2XImage: ImageView = itemView.findViewById(R.id.ivV2XImage)
var tvV2XTime: TextView = itemView.findViewById(R.id.tvV2XTime)
var tvV2XContent: TextView = itemView.findViewById(R.id.tvV2XContent)
var clV2XLayout: ConstraintLayout = itemView.findViewById(R.id.clV2XLayout)
var tvV2XTitle: TextView = itemView.findViewById(R.id.tvV2XTitle)
}
//汇总消息
class BubbleSummaryHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvSummaryContent: TextView = itemView.findViewById(R.id.tvSummaryContent)
var tvSummaryTime: TextView = itemView.findViewById(R.id.tvSummaryTime)
}
//FM消息
class BubbleFmHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var tvBubbleFmFault: TextView = itemView.findViewById(R.id.tvBubbleFmFault)
var tvBubbleFmFaultAction: TextView = itemView.findViewById(R.id.tvBubbleFmFaultAction)
var tvBubbleFmTime: TextView = itemView.findViewById(R.id.tvBubbleFmTime)
var ivBubbleFmImage: ImageView = itemView.findViewById(R.id.ivBubbleFmImage)
}
//SSM连接消息
class BubbleSsmHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivSsmImage: ImageView = itemView.findViewById(R.id.ivSsmImage)
var tvSsmTitle: TextView = itemView.findViewById(R.id.tvSsmTitle)
var tvSsmTime: TextView = itemView.findViewById(R.id.tvSsmTime)
var tvSsmContent: TextView = itemView.findViewById(R.id.tvSsmContent)
}
//域控制器连接状态消息
class BubbleAutopilotHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivAutopilotImage: ImageView = itemView.findViewById(R.id.ivAutopilotImage)
var tvAutopilotTitle: TextView = itemView.findViewById(R.id.tvAutopilotTitle)
var tvAutopilotTime: TextView = itemView.findViewById(R.id.tvAutopilotTime)
var tvAutopilotContent: TextView = itemView.findViewById(R.id.tvAutopilotContent)
}
//FSM状态消息(现阶段提示启动自驾失败消息过渡阶段提示未来展示fsm消息提醒)
class BubbleFSMHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var ivFSMImage: ImageView = itemView.findViewById(R.id.ivFSMImage)
var tvFSMTitle: TextView = itemView.findViewById(R.id.tvFSMTitle)
var tvFSMTime: TextView = itemView.findViewById(R.id.tvFSMTime)
var tvFSMContent: TextView = itemView.findViewById(R.id.tvFSMContent)
}
}

View File

@@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.annotation.CallSuper
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceGroup
@@ -22,11 +23,14 @@ import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.data.multidisplay.TelematicConstant
import com.mogo.eagle.core.data.obu.MogoObuConst
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener
import com.mogo.eagle.core.function.api.devatools.mofang.IMoGoMoFangProvider
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.FUNC_MODE_DEMO
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener.Companion.FUNC_MODE_RAIN
import com.mogo.eagle.core.function.api.setting.ISopSettingListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarConfigListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
@@ -35,20 +39,26 @@ import com.mogo.eagle.core.function.call.obu.CallerObuApiManager
import com.mogo.eagle.core.function.call.setting.CallerSopSettingManager
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.eagle.core.function.call.unmanned.CallerUnmannedListenerManager
import com.mogo.eagle.core.function.call.vehicle.CallerSweeperModeListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.operate.preferences.PreferenceWithMoFang
import com.mogo.eagle.core.function.hmi.ui.operate.preferences.PreferenceWithSpeedSetting
import com.mogo.eagle.core.function.hmi.ui.operate.preferences.PreferenceWithUnmanInterval
import com.mogo.eagle.core.function.hmi.ui.operate.preferences.PreferenceWithWelcomeWords
import com.mogo.eagle.core.function.hmi.ui.tools.SweeperModeChangedConfirmDialog
import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog.Companion.hmiAction
import com.mogo.eagle.core.function.hmi.ui.utils.SOPAnalyticsManager.clickEventAnalytics
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.vehicle.SweeperVehicleConfigUtils
import com.mogo.eagle.core.utilcode.rv.divider.CommonDividerItemDecoration
import com.mogo.eagle.core.utilcode.util.AppStateManager
import com.mogo.eagle.core.utilcode.util.ToastUtils
import kotlinx.android.synthetic.main.layout_operate_panel.view.iv_operate_panel_close
import kotlinx.coroutines.launch
import me.jessyan.autosize.utils.AutoSizeUtils
import mogo.telematics.pad.MessagePad
class OperatePanelLayout : LinearLayout {
@@ -397,14 +407,35 @@ class OperatePanelLayout : LinearLayout {
}
}
class DemoPreferenceFragmentCompat : OperatePanelDetailBase() {
class DemoPreferenceFragmentCompat : OperatePanelDetailBase(), IViewControlListener {
companion object {
private const val TAG = "DemoPreferenceFragmentCompat"
private const val KEY_DEMO_SWITCH = "demo_switch"
private const val KEY_RECORD_BAG_DIALOG = "record_bag_dialog"
private const val KEY_TAKE_OVER_WAKE = "take_over_wake"
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
CallerHmiViewControlListenerManager.addListener(TAG, this)
}
override fun updateFuncMode(tag: String, checked: Boolean) {
super.updateFuncMode(tag, checked)
if (tag == FUNC_MODE_DEMO) {
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_DEMO_SWITCH)?.also {
it.extras.putBoolean("is_pressed", false)
changeValue(it, checked)
}
}
}
override fun onDestroyView() {
super.onDestroyView()
CallerHmiViewControlListenerManager.removeListener(TAG)
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.operate_panel_preference_details_demo, rootKey)
}
@@ -427,13 +458,17 @@ class OperatePanelLayout : LinearLayout {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
when (preference.key) {
KEY_DEMO_SWITCH -> {
val isPressed = preference.extras.getBoolean("is_pressed", true)
if (!isPressed) {
preference.extras.remove("is_pressed")
return true
}
val isChecked = newValue as? Boolean ?: false
hmiAction("SOP 演示模式开关, ", !FunctionBuildConfig.isDemoMode)
clickEventAnalytics("美化模式", isChecked)
FunctionBuildConfig.isDemoMode = !FunctionBuildConfig.isDemoMode
CallerAutoPilotControlManager.setDemoMode(FunctionBuildConfig.isDemoMode)
CallerHmiViewControlListenerManager.invokeFuncMode(FUNC_MODE_DEMO, FunctionBuildConfig.isDemoMode)
CallerSopSettingManager.invokeDemoModeListener(isChecked)
if (!FunctionBuildConfig.isDemoMode) { //关闭美化模式时,通知工控机
CallerAutoPilotControlManager.setIPCDemoMode(FunctionBuildConfig.isDemoMode)
}
@@ -455,14 +490,35 @@ class OperatePanelLayout : LinearLayout {
}
}
class HdMapPreferenceFragmentCompat : OperatePanelDetailBase() {
class HdMapPreferenceFragmentCompat : OperatePanelDetailBase(), ISopSettingListener {
companion object {
private const val TAG = "HdMapPreferenceFragmentCompat"
private const val KEY_DANGER_OBSTACLES_COLOR_MARK = "danger_obstacles_color_mark"
private const val KEY_ROUTE_GUIDE_LINE_DYNAMIC_EFFECT = "route_guide_line_dynamic_effect"
private const val KEY_POINT_CLOUD_EFFECT = "point_cloud_effect"
private const val KEY_SELF_CAR_APERTURE = "self_car_aperture"
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
CallerSopSettingManager.addListener(TAG, this)
}
override fun onDestroyView() {
super.onDestroyView()
CallerSopSettingManager.removeListener(TAG)
}
override fun onPointCloudClickEvent(status: Boolean) {
super.onPointCloudClickEvent(status)
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_POINT_CLOUD_EFFECT)?.also { changeValue(it, status) }
}
override fun onCarApertureClickEvent(status: Boolean) {
super.onCarApertureClickEvent(status)
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_SELF_CAR_APERTURE)?.also { changeValue(it, status) }
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.operate_panel_preference_details_hdmap, rootKey)
}
@@ -539,11 +595,12 @@ class OperatePanelLayout : LinearLayout {
private const val KEY_RED_OR_GREEN_LIGHT_MERGE_MARKER = "red_or_green_light_merge_marker"
private const val KEY_FAULT_REPORT_TIP = "fault_report_tip"
private const val KEY_LIMIT_SPEED_MARKER = "limit_speed_marker"
private const val KEY_SELF_ROUTING_VERIFY_MODE = "self_routing_verify_mode"
private const val KEY_LOOK_AROUND_360 = "look_around_360"
private const val KEY_WEATHER_EFFECT_SWITCH = "weather_effect_switch"
private const val KEY_SYSTEM_BOOT_STATUS_SHOW = "system_boot_status_show"
private const val KEY_SELF_ROUTING_VERIFY_MODE = "self_routing_verify_mode"
private const val KEY_UNMANNED_DEMO_PULL_INTERVAL = "unmanned_demo_pull_interval"
private const val KEY_SWEEPER_CLOUD_CONTROL = "sweeper_cloud_control"
private const val KEY_LOOK_AROUND_360 = "look_around_360"
}
override fun getDefaultVal(pref: Preference): Any? {
@@ -575,6 +632,16 @@ class OperatePanelLayout : LinearLayout {
KEY_UNMANNED_DEMO_PULL_INTERVAL -> {
return CallerUnmannedListenerManager.getVirtualTaskPullTaskIntervalF()
}
KEY_SWEEPER_CLOUD_CONTROL -> {
if (!isEnabled(pref)) {
return false
}
return if (SweeperVehicleConfigUtils.isSPExistCurrentSweeperModeConfig()) {
SweeperVehicleConfigUtils.isSPCurrentSweeperCloudMode()
} else {
SweeperVehicleConfigUtils.isDefaultSweeperCloudMode(FunctionBuildConfig.sweeperDefaultMode)
}
}
}
return super.getDefaultVal(pref)
}
@@ -590,6 +657,9 @@ class OperatePanelLayout : LinearLayout {
KEY_WEATHER_EFFECT_SWITCH -> {
AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)
}
KEY_SWEEPER_CLOUD_CONTROL -> {
return AppIdentityModeUtils.isSweeper(FunctionBuildConfig.appIdentityMode) && (SweeperVehicleConfigUtils.isDefaultSweeperCanSwitchMode(FunctionBuildConfig.sweeperCanSwitchMode))
}
else -> super.isEnabled(pref)
}
}
@@ -606,7 +676,7 @@ class OperatePanelLayout : LinearLayout {
PreferenceWithUnmanInterval.Interval.FORTY_FIVE_SECOND -> CallerUnmannedListenerManager.dispatchVirtualTaskPullTaskInterval(45)
PreferenceWithUnmanInterval.Interval.NEVER -> CallerUnmannedListenerManager.dispatchVirtualTaskPullTaskInterval(-1)
}
clickEventAnalytics("Taxi无人化演练任务拉取时间间隔",true)
clickEventAnalytics("Taxi无人化演练任务拉取时间间隔", true)
}
}
return super.onPreferenceClick(preference)
@@ -701,6 +771,27 @@ class OperatePanelLayout : LinearLayout {
HmiBuildConfig.isShowConnectionProgressView = isChecked
CallerHmiViewControlListenerManager.updateConnectionProgressView(isChecked)
}
KEY_SWEEPER_CLOUD_CONTROL -> {
val isChecked = newValue as? Boolean ?: false
val activity = AppStateManager.currentActivity()
if (activity != null) {
val confirmDialog = SweeperModeChangedConfirmDialog(activity)
confirmDialog.setClickListener(object: SweeperModeChangedConfirmDialog.ClickListener {
override fun confirm() {
CallerSweeperModeListenerManager.invokeSweeperModeListeners(
if (isChecked) SweeperVehicleConfigUtils.BUSINESS_MODE_CLOUD
else SweeperVehicleConfigUtils.BUSINESS_MODE_OPERATE
)
}
override fun cancel() {
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_WEATHER_EFFECT_SWITCH)?.also { changeValue(it, !isChecked) }
}
})
confirmDialog.showSweeperModeChangeConfirmDialog()
}
clickEventAnalytics("清扫云控业务",isChecked)
}
}
return super.onPreferenceChange(preference, newValue)
}
@@ -788,8 +879,9 @@ class OperatePanelLayout : LinearLayout {
}
}
class VehiclesPreferenceFragmentCompat : OperatePanelDetailBase() {
class VehiclesPreferenceFragmentCompat : OperatePanelDetailBase(), IMoGoAutopilotCarConfigListener, ISopSettingListener, IViewControlListener {
companion object {
private const val TAG = "VehiclesPreferenceFragmentCompat"
private const val KEY_PNC_PARK_INTERSECTION_CAR = "pnc_park_intersection_car"
private const val KEY_PNC_PARK_OVERTAKE_CAR = "pnc_park_overtake_car"
private const val KEY_DETOUR_RETARD_PARK = "detour_retard_park"
@@ -807,10 +899,52 @@ class OperatePanelLayout : LinearLayout {
private const val KEY_OVERTAKE_SPEED_THRESHOLDSS = "overtake_speed_thresholds"
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
CallerSopSettingManager.addListener(TAG, this)
CallerHmiViewControlListenerManager.addListener(TAG, this)
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun updateFuncMode(tag: String, checked: Boolean) {
super.updateFuncMode(tag, checked)
if (tag == FUNC_MODE_RAIN) {
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_RAIN_DAY)?.also {
it.extras.putBoolean("is_pressed", false)
changeValue(it, checked)
}
}
}
override fun onDestroyView() {
CallerAutopilotCarConfigListenerManager.removeListener(TAG)
CallerSopSettingManager.removeListener(TAG)
CallerHmiViewControlListenerManager.removeListener(TAG)
super.onDestroyView()
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.operate_panel_preference_details_vehicles, rootKey)
}
override fun onExamControlClickEvent(status: Boolean) {
super.onExamControlClickEvent(status)
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_EXAM_FUNCTION_PANEL)?.also { changeValue(it, status) }
}
override fun onRainModeClickEvent(status: Boolean) {
super.onRainModeClickEvent(status)
preferenceScreen.findPreferenceReal<SwitchPreferenceCompat>(KEY_RAIN_DAY)?.also { changeValue(it, status) }
}
override fun onAutopilotCarConfig(carConfigResp: MessagePad.CarConfigResp) {
super.onAutopilotCarConfig(carConfigResp)
lifecycleScope.launch {
val max = carConfigResp.speedLimit * 3.6
preferenceScreen.findPreferenceReal<PreferenceWithSpeedSetting>(KEY_AUTO_PILOT_SPEED_THRESHOLDS)?.update(listOf("0", "$max", "$max", "5"))
}
}
override fun isEnabled(pref: Preference): Boolean {
when (pref.key) {
KEY_AUTO_PILOT_SPEED_THRESHOLDS, KEY_OVERTAKE_SPEED_THRESHOLDSS -> {
@@ -855,13 +989,14 @@ class OperatePanelLayout : LinearLayout {
KEY_PURE_OBU_MODE -> {
return FunctionBuildConfig.fusionMode == 5
}
KEY_AUTO_PILOT_SPEED_THRESHOLDS -> {
return listOf("0.0", "${FunctionBuildConfig.maxSpeedLimit}", "${FunctionBuildConfig.maxSpeedLimit}", "5.0")
}
KEY_CHANGE_LANE_SPEED_THRESHOLDS -> {
return setOf("3.0", "7.0", "${FunctionBuildConfig.detouringSpeed}", "0.5")
return listOf("3.0", "7.0", "${FunctionBuildConfig.detouringSpeed}", "0.5")
}
KEY_OVERTAKE_SPEED_THRESHOLDSS -> {
return setOf("3.0", "12.5", "${FunctionBuildConfig.overTakeSpeed}", "0.5")
}
KEY_AUTO_PILOT_SPEED_THRESHOLDS -> { //TODO renwj 自动驾驶速度阈值,旧版本没有看到
return listOf("3.0", "12.5", "${FunctionBuildConfig.overTakeSpeed}", "0.5")
}
}
return super.getDefaultVal(pref)
@@ -871,7 +1006,20 @@ class OperatePanelLayout : LinearLayout {
Log.d(TAG, "-- onPreferenceClick --:pref -> $preference")
when (preference.key) {
KEY_AUTO_PILOT_SPEED_THRESHOLDS -> {
FunctionBuildConfig.detouringSpeed = preference.extras.getFloat(PreferenceWithSpeedSetting.KEY_BUNDLE_CURRENT_VALUE, FunctionBuildConfig.detouringSpeed.toFloat()).toInt()
FunctionBuildConfig.maxSpeedLimit = preference.extras.getDouble(PreferenceWithSpeedSetting.KEY_BUNDLE_CURRENT_VALUE, FunctionBuildConfig.maxSpeedLimit)
val isSuccess = CallerAutoPilotControlManager.setAutoPilotSpeed(FunctionBuildConfig.maxSpeedLimit.toInt())
when {
isSuccess -> {
ToastUtils.showShort("车速设置成功,立即生效")
}
else -> {
ToastUtils.showShort("设置车速失败,请启动域控制器")
}
}
return true
}
KEY_CHANGE_LANE_SPEED_THRESHOLDS -> {
FunctionBuildConfig.detouringSpeed = preference.extras.getDouble(PreferenceWithSpeedSetting.KEY_BUNDLE_CURRENT_VALUE, FunctionBuildConfig.detouringSpeed.toDouble()).toInt()
hmiAction("SOP 变道绕障的目标障碍物速度阈值", FunctionBuildConfig.detouringSpeed)
val isSuccess = CallerAutoPilotControlManager.sendDetouringSpeed(FunctionBuildConfig.detouringSpeed.toDouble())
if (isSuccess == true) {
@@ -882,9 +1030,10 @@ class OperatePanelLayout : LinearLayout {
hmiAction("SOP 变道绕障的目标障碍物速度阈值设置", "失败")
}
clickEventAnalytics("变道速度阈值", true)
return true
}
KEY_OVERTAKE_SPEED_THRESHOLDSS -> {
FunctionBuildConfig.overTakeSpeed = preference.extras.getFloat(PreferenceWithSpeedSetting.KEY_BUNDLE_CURRENT_VALUE, FunctionBuildConfig.overTakeSpeed)
FunctionBuildConfig.overTakeSpeed = preference.extras.getDouble(PreferenceWithSpeedSetting.KEY_BUNDLE_CURRENT_VALUE, FunctionBuildConfig.overTakeSpeed.toDouble()).toFloat()
val isSuccess = CallerAutoPilotControlManager.sendOvertakeMaxSpeed(FunctionBuildConfig.overTakeSpeed.toDouble())
if (isSuccess == true) {
ToastUtils.showShort("SOP 超车目标障碍物速度阈值设置成功")
@@ -894,6 +1043,7 @@ class OperatePanelLayout : LinearLayout {
hmiAction("SOP 超车目标障碍物速度阈值设置", "失败")
}
clickEventAnalytics("超车速度阈值", true)
return true
}
}
return super.onPreferenceClick(preference)
@@ -906,12 +1056,14 @@ class OperatePanelLayout : LinearLayout {
hmiAction("SOP PNC-park-会车, ", isChecked)
CallerAutoPilotControlManager.sendParkVehCross(isChecked)
FunctionBuildConfig.isOpenParkVehCross = isChecked
return true
}
KEY_PNC_PARK_OVERTAKE_CAR -> {
val isChecked = newValue as? Boolean ?: false
hmiAction("SOP PNC-park-超车, ", isChecked)
CallerAutoPilotControlManager.sendParkVehOvertake(isChecked)
FunctionBuildConfig.isOpenOvertake = isChecked
return true
}
KEY_DETOUR_RETARD_PARK -> {
val isChecked = newValue as? Boolean ?: false
@@ -919,8 +1071,14 @@ class OperatePanelLayout : LinearLayout {
CallerAutoPilotControlManager.sendDetouring(isChecked)
FunctionBuildConfig.isDetouring = isChecked
clickEventAnalytics("绕障类功能", isChecked)
return true
}
KEY_RAIN_DAY -> {
val isPressed = preference.extras.getBoolean("is_pressed", true)
if (!isPressed) {
preference.extras.remove("is_pressed")
return true
}
val isChecked = newValue as? Boolean ?: false
hmiAction("SOP 雨天模式开关, ", isChecked)
clickEventAnalytics("雨天模式", isChecked)
@@ -928,6 +1086,7 @@ class OperatePanelLayout : LinearLayout {
CallerAutoPilotControlManager.setRainMode(isChecked)
CallerHmiViewControlListenerManager.invokeFuncMode(FUNC_MODE_RAIN, isChecked)
CallerSopSettingManager.invokeRainModeListener(isChecked)
return true
}
KEY_WEAK_NET_DECELERATION_PARK -> {
val isChecked = newValue as? Boolean ?: false
@@ -935,6 +1094,7 @@ class OperatePanelLayout : LinearLayout {
CallerAutoPilotControlManager.sendWeakNetSlowDown(isChecked)
hmiAction("SOP 弱网减速停车, ", isChecked)
clickEventAnalytics("弱网减速停车", isChecked)
return true
}
KEY_FAULT_DECELERATION_PARK -> {
val isChecked = newValue as? Boolean ?: false
@@ -942,6 +1102,7 @@ class OperatePanelLayout : LinearLayout {
CallerAutoPilotControlManager.sendBreakdownSlowDown(isChecked)
hmiAction("SOP 故障减速停车, ", isChecked)
clickEventAnalytics("故障减速停车", isChecked)
return true
}
KEY_EXAM_FUNCTION_PANEL -> {
val isChecked = newValue as? Boolean ?: false
@@ -949,36 +1110,42 @@ class OperatePanelLayout : LinearLayout {
CallerDevaToolsManager.showExamControlWindow(isChecked)
hmiAction("SOP 考试功能面板, ", isChecked)
clickEventAnalytics("考试功能面板", isChecked)
return true
}
KEY_ALL_MERGE_MODE -> {
FunctionBuildConfig.fusionMode = 1
hmiAction("SOP 融合模式, ", FunctionBuildConfig.fusionMode)
clickEventAnalytics("融合模式", true)
CallerAutoPilotControlManager.sendFusionMode(FunctionBuildConfig.fusionMode)
return true
}
KEY_BLIND_AREA_MODE -> {
FunctionBuildConfig.fusionMode = 2
hmiAction("SOP 融合模式, ", FunctionBuildConfig.fusionMode)
clickEventAnalytics("融合模式", true)
CallerAutoPilotControlManager.sendFusionMode(FunctionBuildConfig.fusionMode)
return true
}
KEY_BEYOND_VISUAL_RANGE_MODE -> {
FunctionBuildConfig.fusionMode = 3
hmiAction("SOP 融合模式, ", FunctionBuildConfig.fusionMode)
clickEventAnalytics("融合模式", true)
CallerAutoPilotControlManager.sendFusionMode(FunctionBuildConfig.fusionMode)
return true
}
KEY_TRANSPARENT_TRANSFER_MODE -> {
FunctionBuildConfig.fusionMode = 4
hmiAction("SOP 融合模式, ", FunctionBuildConfig.fusionMode)
clickEventAnalytics("融合模式", true)
CallerAutoPilotControlManager.sendFusionMode(FunctionBuildConfig.fusionMode)
return true
}
KEY_PURE_OBU_MODE -> {
FunctionBuildConfig.fusionMode = 5
hmiAction("SOP 融合模式, ", FunctionBuildConfig.fusionMode)
clickEventAnalytics("融合模式", true)
CallerAutoPilotControlManager.sendFusionMode(FunctionBuildConfig.fusionMode)
return true
}
}
return super.onPreferenceChange(preference, newValue)

View File

@@ -21,24 +21,34 @@ class PreferenceWithSpeedSetting : Preference {
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context) : super(context)
private var mDefaultValueSet: Any? = null
private var mSpeedData: Any? = null
private var mFlag = true
override fun setDefaultValue(defaultValue: Any?) {
super.setDefaultValue(defaultValue)
mDefaultValueSet = defaultValue
mSpeedData = defaultValue
notifyChanged()
}
fun update(data: List<String>) {
mSpeedData = data
notifyChanged()
}
override fun onSetInitialValue(defaultValue: Any?) {
super.onSetInitialValue(defaultValue)
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val defaultSet = mDefaultValueSet ?: return
if (defaultSet !is Set<*> || defaultSet.size != 4) {
val speedData = mSpeedData ?: return
if (speedData !is List<*> || speedData.size != 4) {
throw AssertionError()
}
val min = (defaultSet.elementAt(0) as String).toFloat()
val max = (defaultSet.elementAt(1) as String).toFloat()
var cur = (defaultSet.elementAt(2) as String).toFloat()
val step = (defaultSet.elementAt(3) as String).toFloat()
val min = (speedData.elementAt(0) as String).toDouble()
val max = (speedData.elementAt(1) as String).toDouble()
var cur = (speedData.elementAt(2) as String).toDouble()
val step = (speedData.elementAt(3) as String).toDouble()
if (min > max) {
throw AssertionError()
}
@@ -52,7 +62,7 @@ class PreferenceWithSpeedSetting : Preference {
val btnOk = holder.findViewById(R.id.bt_ok)
val speedLimit = holder.findViewById(R.id.tv_speed_limit) as? TextView
if (speedLimit?.tag != null && speedLimit.tag is Float) {
cur = max(cur, speedLimit.tag as Float)
cur = max(cur, speedLimit.tag as Double)
}
speedLimit?.text = cur.toString()
val minus = holder.findViewById(R.id.iv_speed_minus)
@@ -83,11 +93,14 @@ class PreferenceWithSpeedSetting : Preference {
speedLimit?.tag = addAfter
speedLimit?.text = addAfter.toString()
}
btnOk.isEnabled = false
if (mFlag) {
mFlag = false
btnOk.isEnabled = false
}
btnOk.setOnClickListener(null)
btnOk.onClick {
onPreferenceClickListener?.also {
extras.putFloat(KEY_BUNDLE_CURRENT_VALUE, cur)
extras.putDouble(KEY_BUNDLE_CURRENT_VALUE, cur)
it.onPreferenceClick(this)
}
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/llMsgBubbleLayout"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvBubbleList"
android:layout_width="@dimen/dp_654"
android:layout_height="wrap_content"
/>
</LinearLayout>

View File

@@ -11,7 +11,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/dp_86"
android:layout_marginStart="@dimen/dp_60"
android:layout_marginTop="@dimen/dp_112"
android:layout_marginTop="@dimen/dp_56"
android:orientation="horizontal">
<ImageView

View File

@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_view"
android:paddingTop="0dip"
app:pressed_enabled="false"
android:paddingBottom="@dimen/dp_20" />

View File

@@ -2,6 +2,7 @@
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -11,6 +12,7 @@
android:paddingBottom="@dimen/dp_25"
android:paddingStart="@dimen/dp_30"
android:layout_marginEnd="@dimen/dp_30"
app:pressed_enabled="false"
android:background="@drawable/bg_operate_panel_preference_header"
tools:text="地图效果"
android:gravity="start"

View File

@@ -41,8 +41,8 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="@dimen/dp_280"
android:layout_marginBottom="@dimen/dp_180"
android:layout_marginStart="@dimen/dp_270"
android:layout_marginBottom="@dimen/dp_170"
/>
<com.mogo.eagle.core.function.hmi.bone.tab.FaultReasonView

View File

@@ -23,7 +23,7 @@
android:layout_height="wrap_content"
android:text="@string/fault_reason"
android:textSize="@dimen/sp_40"
android:textColor="@color/white"
android:textColor="#CCFFFFFF"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_title_bg"
app:layout_constraintBottom_toBottomOf="@id/view_title_bg"
@@ -41,7 +41,7 @@
app:layout_constraintTop_toTopOf="@id/view_title_bg"
app:layout_constraintBottom_toBottomOf="@id/view_title_bg"
app:layout_constraintEnd_toEndOf="@id/view_title_bg"
android:layout_marginEnd="@dimen/dp_30"
android:layout_marginEnd="@dimen/dp_53"
/>
<View
@@ -60,7 +60,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/work_order_type"
android:textSize="@dimen/sp_32"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/view_type_label"
@@ -74,9 +74,9 @@
android:layout_width="@dimen/dp_779"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/view_type_label"
app:layout_constraintTop_toBottomOf="@id/tv_type_title"
app:layout_constraintLeft_toLeftOf="@id/view_type_label"
android:layout_marginTop="@dimen/dp_18"
android:layout_marginTop="@dimen/dp_15"
>
<RadioButton
@@ -144,7 +144,7 @@
app:layout_constraintTop_toBottomOf="@id/wrap_radio_group"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_40"
/>
<TextView
@@ -215,7 +215,7 @@
app:layout_constraintTop_toBottomOf="@id/iv_time_reduce"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_103"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginTop="@dimen/dp_40"
/>
<TextView
@@ -232,17 +232,6 @@
android:layout_marginStart="@dimen/dp_13"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tv_describe_title"
app:layout_constraintBottom_toBottomOf="@id/tv_describe_title"
app:layout_constraintLeft_toRightOf="@id/tv_describe_title"
android:textSize="@dimen/sp_32"
android:textColor="#CCCCCC"
android:text="@string/fault_note_supplement"
/>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_describe_input"
android:layout_width="@dimen/dp_779"
@@ -287,7 +276,7 @@
android:textSize="@dimen/sp_36"
android:textStyle="bold"
android:gravity="center"
android:layout_marginTop="@dimen/dp_97"
android:layout_marginTop="@dimen/dp_90"
/>
<TextView
@@ -302,7 +291,7 @@
android:textStyle="bold"
android:gravity="center"
android:background="@drawable/bg_fault_cancel"
android:layout_marginTop="@dimen/dp_97"
android:layout_marginTop="@dimen/dp_90"
/>

View File

@@ -27,18 +27,6 @@
android:title="限速标识"
android:persistent="false"
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
<SwitchPreferenceCompat
android:key="self_routing_verify_mode"
android:layout="@layout/layout_operate_panel_preference_switch_compat"
android:title="自主算路验证模式"
android:persistent="false"
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
<SwitchPreferenceCompat
android:key="look_around_360"
android:layout="@layout/layout_operate_panel_preference_switch_compat"
android:title="360环视"
android:persistent="false"
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
<SwitchPreferenceCompat
android:key="weather_effect_switch"
android:layout="@layout/layout_operate_panel_preference_switch_compat"
@@ -57,5 +45,23 @@
android:title="无人化演练任务拉取时间间隔"
android:persistent="false"
android:widgetLayout="@layout/layout_operate_panel_preference_widget_radio_group_custom" />
<SwitchPreferenceCompat
android:key="self_routing_verify_mode"
android:layout="@layout/layout_operate_panel_preference_switch_compat"
android:title="自主算路验证模式"
android:persistent="false"
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
<SwitchPreferenceCompat
android:key="sweeper_cloud_control"
android:layout="@layout/layout_operate_panel_preference_switch_compat"
android:title="清扫车云控业务"
android:persistent="false"
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
<SwitchPreferenceCompat
android:key="look_around_360"
android:layout="@layout/layout_operate_panel_preference_switch_compat"
android:title="360环视"
android:persistent="false"
android:widgetLayout="@layout/layout_operate_panel_preference_widget_switch_compat" />
</PreferenceCategory>
</androidx.preference.PreferenceScreen>

View File

@@ -441,4 +441,11 @@ object FunctionBuildConfig {
@Volatile
@JvmField
var welcomeWords: String? = null
/**
* 最大限速值
*/
@Volatile
@JvmField
var maxSpeedLimit: Double = 0.0
}

View File

@@ -1,5 +1,6 @@
package com.mogo.eagle.core.function.call.autopilot
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarConfigListener
import com.mogo.eagle.core.function.call.base.CallerBase
import mogo.telematics.pad.MessagePad
@@ -28,6 +29,7 @@ object CallerAutopilotCarConfigListenerManager : CallerBase<IMoGoAutopilotCarCon
@Synchronized
fun invokeAutopilotCarConfigData(carConfigResp: MessagePad.CarConfigResp) {
mCarConfigResp = carConfigResp
FunctionBuildConfig.maxSpeedLimit = carConfigResp.maxSpeedLimit
M_LISTENERS.forEach {
val listener = it.value
try {