diff --git a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerBaseFragment.java b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerBaseFragment.java index 945a3d7aa7..07c9eaad40 100644 --- a/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerBaseFragment.java +++ b/OCH/mogo-och-taxi-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerBaseFragment.java @@ -1,6 +1,5 @@ package com.mogo.och.taxi.passenger.ui; -import android.os.Build; import android.os.Handler; import android.os.Looper; import android.view.View; @@ -13,6 +12,8 @@ import androidx.fragment.app.FragmentTransaction; import com.mogo.commons.AbsMogoApplication; import com.mogo.commons.mvp.MvpFragment; import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener; +import com.mogo.eagle.core.function.api.hmi.IMoGoHmiViewProxy; +import com.mogo.eagle.core.function.api.hmi.view.IViewNotification; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager; import com.mogo.eagle.core.function.call.hmi.CallerHmiManager; import com.mogo.eagle.core.function.call.map.CallerSmpManager; @@ -41,7 +42,7 @@ import java.lang.ref.WeakReference; * @author tongchenfei */ public class TaxiPassengerBaseFragment extends MvpFragment - implements IMogoMapListener, TaxiPassengerTaxiView, ITPClickStartAutopilotCallback { + implements IMogoMapListener, TaxiPassengerTaxiView, ITPClickStartAutopilotCallback, IMoGoHmiViewProxy.IViewNotificationProvider { static final String TAG = "TaxiPassengerBaseFragment"; @@ -49,7 +50,6 @@ public class TaxiPassengerBaseFragment extends MvpFragment mArrivedEndView; private WeakReference mArrivedCheckView; @@ -82,8 +82,7 @@ public class TaxiPassengerBaseFragment extends MvpFragment() @@ -123,6 +135,8 @@ import kotlin.collections.ArrayList private var adUpgradeDialog: AdUpgradeDialog?=null + private var speakJob: Job? = null + override fun vipIdentification(visible: Boolean) { ThreadUtils.runOnUiThread { if (visible) { @@ -174,7 +188,7 @@ import kotlin.collections.ArrayList // 首次初始化使用默认视图 setProxyTrafficLightView(viewTrafficLightVr) setProxyLimitingSpeedView(viewLimitingVelocity) - setProxyNotificationView(V2XNotificationView(view.context)) + setViewNotificationProvider(this) context?.also { if (!AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { @@ -183,7 +197,8 @@ import kotlin.collections.ArrayList } } - @OptIn(ExperimentalCoroutinesApi::class) + 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) @@ -256,11 +271,8 @@ import kotlin.collections.ArrayList } } - /** - * 设置 V2X 通知 代理View - */ - override fun setProxyNotificationView(view: IViewNotification) { - mViewNotification = view + override fun setViewNotificationProvider(provider: IViewNotificationProvider) { + mViewNotificationProvider = provider } /** @@ -525,88 +537,97 @@ import kotlin.collections.ArrayList alertContent: CharSequence?, ttsContent: String?, tag: String?, - listenerIMoGo: IMoGoWarningStatusListener?, + listener: IMoGoWarningStatusListener?, playTts: Boolean, expireTime: Long ) { val playTTS = playTts && !AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode) - lifecycleScope.launchWhenResumed { - activity?.let { - val floatWindow = mWarningFloat - val showTag = floatWindow?.config?.floatTag - if (floatWindow == null || TextUtils.isEmpty(showTag) || !floatWindow.isShow() || floatWindow.config.floatTag != tag) { - // 代理View初始化了才可以弹窗 - mViewNotification?.let { notificationView -> - notificationView.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType)) - val warningContent = alertContent - ?: EventTypeEnum.getWarningContent(v2xType) - if (warningContent.isEmpty()) { - CallerLogger.e("$M_HMI$TAG", "Show warningContent is null or empty!") - return@launchWhenResumed - } else { - notificationView.setWarningContent(warningContent) - } - if (floatWindow != null && floatWindow.isShow()) { - showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - WarningFloat.dismiss(floatWindow.config.floatTag, true) - } - mWarningFloat = WarningFloat.with(it) - .setTag(tag) - .setLayout(notificationView) - .setSidePattern(notificationView.sidePattern) - .setCountDownTime(expireTime) - .setGravity(notificationView.layoutGravity, offsetX = notificationView.offsetX, offsetY = notificationView.offsetY) - .setImmersionStatusBar(true) - .isEnqueue(true) - .addWarningStatusListener(listenerIMoGo) - .addWarningStatusListener(object : IMoGoWarningStatusListener { - override fun onShow() { - // 创建弹窗成功才进行TTS播报 - CallerLogger.d( - "$M_HMI$TAG", - "mWarningFloat = $mWarningFloat---ttsContent = $ttsContent" - ) - if (mWarningFloat != null && !TextUtils.isEmpty(ttsContent) && playTTS) { - CallerLogger.d("$M_HMI$TAG", "---> ttsContent = $ttsContent") - AIAssist.getInstance(activity) - .speakTTSVoice(ttsContent) - } - } - - override fun onDismiss() { - showWarning(WarningDirectionEnum.ALERT_WARNING_NON) - } - }) - .setAnimator(object : DefaultAnimator() { - override fun enterAnim( - view: View, - params: LayoutParams, - windowManager: WindowManager, - sidePattern: SidePattern - ): Animator? = - super.enterAnim(view, params, windowManager, sidePattern)?.apply { - interpolator = OvershootInterpolator() - } - - override fun exitAnim( - view: View, - params: LayoutParams, - windowManager: WindowManager, - sidePattern: SidePattern - ): Animator? = - super.exitAnim(view, params, windowManager, sidePattern) - ?.setDuration(200) - }) - .show() - } - } else { - val notification = floatWindow.config.layoutView as? V2XNotificationView - if (alertContent?.isNotEmpty() == true) { - notification?.setWarningContent(alertContent) - floatWindow.resetExpireTime(expireTime) + activity?.let { + val warningContent = alertContent + ?: EventTypeEnum.getWarningContent(v2xType) + if (warningContent.isEmpty()) { + CallerLogger.e("$M_HMI$TAG", "Show warningContent is null or empty!") + return + } + speakJob?.safeCancel() + val content = mViewNotificationProvider?.getNotificationView() ?: return + content.setWarningIcon(EventTypeEnum.getWarningIcon(v2xType)) + content.setWarningContent(warningContent) + var reminder: IReminder? = null + 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 -> + t.interpolator = AccelerateDecelerateInterpolator() + t.duration = 200 + } + if (VERSION.SDK_INT >= VERSION_CODES.M) { + itx.enterTransition = transition + itx.exitTransition = transition + } + }) { + override fun show() { + val parent = it.window.decorView + parent.doOnAttach { + popupWindow.showAtLocation(parent, Gravity.TOP, 0, 0) } } + + override fun isOverride(): Boolean { + return true + } + }.also { itx -> reminder = itx }, object : IStateChangeListener { + + 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 { + speakJob = it + } + } + } + + override fun onHide(reminder: IReminder) { + listener?.onDismiss() + showWarning(WarningDirectionEnum.ALERT_WARNING_NON) + } + }) + + if (reminder == null) { + return } + lifecycleScope.launch { + delay(expireTime) + reminder?.hide() + } + } + } + + private suspend fun speak(ctx: Context, text: String) = suspendCancellableCoroutine { + try { + val voiceCallback = object : IMogoVoiceCmdCallBack { + override fun onSpeakEnd(speakText: String?) { + super.onSpeakEnd(speakText) + it.resumeWith(Result.success(Unit)) + } + + override fun onSpeakError(speakText: String?, errorMsg: String?) { + super.onSpeakError(speakText, errorMsg) + it.resumeWith(Result.success(Unit)) + } + } + it.invokeOnCancellation { + AIAssist.getInstance(ctx).stopSpeakTts(text) + } + AIAssist.getInstance(ctx).speakTTSVoice(text, voiceCallback) + } catch (t: Throwable) { + it.resumeWith(Result.success(Unit)) + Logger.e(TAG, t.message) } } diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/V2XNotificationView.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/V2XNotificationView.kt index 7cb59295d2..104aed541a 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/V2XNotificationView.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/V2XNotificationView.kt @@ -32,8 +32,7 @@ class V2XNotificationView @JvmOverloads constructor( sidePattern = SidePattern.RESULT_TOP layoutGravity = Gravity.CENTER_HORIZONTAL // 设置View的停留位置 - offsetX = 0 - offsetY = 110 + setPadding(0, 110, 0, 0) } override fun setWarningIcon(@DrawableRes warningIcon: Int) { diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/receiver/TestPanelBroadcastReceiver.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/receiver/TestPanelBroadcastReceiver.java index c46a63790a..de171cf38c 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/receiver/TestPanelBroadcastReceiver.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/receiver/TestPanelBroadcastReceiver.java @@ -63,6 +63,16 @@ public class TestPanelBroadcastReceiver extends BroadcastReceiver { intent.putExtra(V2XConst.BROADCAST_SCENE_EXTRA_KEY, v2XMessageEntity); LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); + // 存储本地,出行动态作展示 + saveLocalStory(V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING, + v2XMessageEntity.getContent().getNoveltyInfo()); + } if (sceneType == 2) {// 触发AI道路施工事件 + V2XMessageEntity v2XMessageEntity = + TestOnLineCarUtils.getV2XScenarioAIRoadEventData(); + Intent intent = new Intent(V2XConst.BROADCAST_SCENE_HANDLER_ACTION); + intent.putExtra(V2XConst.BROADCAST_SCENE_EXTRA_KEY, v2XMessageEntity); + LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); + // 存储本地,出行动态作展示 saveLocalStory(V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING, v2XMessageEntity.getContent().getNoveltyInfo()); diff --git a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TestOnLineCarUtils.java b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TestOnLineCarUtils.java index 5d24b5e4d8..1dbffa8b64 100644 --- a/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TestOnLineCarUtils.java +++ b/core/function-impl/mogo-core-function-v2x/src/main/java/com/mogo/eagle/core/function/v2x/events/utils/TestOnLineCarUtils.java @@ -1,5 +1,7 @@ package com.mogo.eagle.core.function.v2x.events.utils; +import static com.mogo.module.common.entity.V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING; + import com.mogo.eagle.core.data.map.MogoLatLng; import com.mogo.eagle.core.function.v2x.R; import com.mogo.eagle.core.function.v2x.events.entity.net.V2XOptimalRouteDataRes; @@ -7,10 +9,12 @@ import com.mogo.eagle.core.function.v2x.events.entity.net.V2XSpecialCarRes; import com.mogo.eagle.core.network.utils.GsonUtil; import com.mogo.eagle.core.utilcode.util.Utils; import com.mogo.module.common.entity.MarkerExploreWay; +import com.mogo.module.common.entity.MarkerLocation; import com.mogo.module.common.entity.MarkerResponse; import com.mogo.module.common.entity.V2XMessageEntity; import com.mogo.module.common.entity.V2XRoadEventEntity; import com.mogo.module.common.entity.V2XWarningEntity; +import com.mogo.v2x.event.V2XEvent; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -80,7 +84,7 @@ public class TestOnLineCarUtils { V2XMessageEntity v2xMessageEntity = new V2XMessageEntity<>(); // 控制类型 - v2xMessageEntity.setType(V2XMessageEntity.V2XTypeEnum.ALERT_ROAD_WARNING); + v2xMessageEntity.setType(ALERT_ROAD_WARNING); // 设置数据 v2xMessageEntity.setContent(v2xRoadEventEntity); // 控制展示状态 @@ -92,7 +96,22 @@ public class TestOnLineCarUtils { return null; } - + /** + * 模拟道路事件测试数据 + */ + public static V2XMessageEntity getV2XScenarioAIRoadEventData() { + V2XRoadEventEntity entity = new V2XRoadEventEntity(); + entity.setLocation(new MarkerLocation()); + entity.setShowEventButton(false); + entity.setPoiType("100061"); + entity.setExpireTime(20000); + V2XMessageEntity body = new V2XMessageEntity<>(); + body.setOnlyShow(false); + body.setShowState(true); + body.setContent(entity); + body.setType(ALERT_ROAD_WARNING); + return body; + } /** * 模拟道路事件UGC测试数据 */ diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt index f07cdfe6df..f6378350aa 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/IMoGoHmiViewProxy.kt @@ -14,7 +14,7 @@ interface IMoGoHmiViewProxy { * 设置 V2X预警 代理View * @param view */ - fun setProxyNotificationView(view: IViewNotification) + fun setViewNotificationProvider(provider: IViewNotificationProvider) /** * 设置 红绿灯 代理View @@ -27,4 +27,10 @@ interface IMoGoHmiViewProxy { * @param view */ fun setProxyLimitingSpeedView(view: IViewLimitingVelocity) + + + interface IViewNotificationProvider { + + fun getNotificationView() : IViewNotification? + } } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewNotification.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewNotification.kt index 9c9e1ff864..e3842ae9e3 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewNotification.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/view/IViewNotification.kt @@ -38,15 +38,6 @@ abstract class IViewNotification(context: Context?, attrs: AttributeSet?, defSty */ open var sidePattern: SidePattern = SidePattern.RESULT_TOP - /** - * 距离屏幕左上角 0,0点 X 轴距离,单位:px - */ - open var offsetX: Int = 0 - - /** - * 距离屏幕左上角 0,0点 Y 轴距离,单位:px - */ - open var offsetY: Int = 0 open fun setWarningIcon(@DrawableRes warningIcon: Int) {} diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt index 5488945771..813e37f9f5 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/hmi/warning/IMoGoWaringProvider.kt @@ -74,7 +74,7 @@ interface IMoGoWaringProvider : IMoGoHmiViewProxy { * @param ttsContent tts语音播报消息 * @param tag tag绑定弹窗的标志 */ - fun showWarningV2X(v2xType: String, alertContent: CharSequence?, ttsContent: String?, tag: String?, listenerIMoGo: IMoGoWarningStatusListener?, playTts: Boolean, expireTime: Long) + fun showWarningV2X(v2xType: String, alertContent: CharSequence?, ttsContent: String?, tag: String?, listener: IMoGoWarningStatusListener?, playTts: Boolean, expireTime: Long) /** * 关闭指定floatTag 的 VR下V2X预警弹窗 diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt index 5335ce979e..174886a8ea 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/hmi/CallerHmiManager.kt @@ -8,6 +8,7 @@ import com.mogo.eagle.core.data.enums.WarningDirectionEnum import com.mogo.eagle.core.data.notice.NoticeNormalData import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData import com.mogo.eagle.core.data.report.ReportEntity +import com.mogo.eagle.core.function.api.hmi.IMoGoHmiViewProxy.IViewNotificationProvider import com.mogo.eagle.core.function.api.hmi.view.IViewLimitingVelocity import com.mogo.eagle.core.function.api.hmi.view.IViewNotification import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight @@ -337,8 +338,8 @@ object CallerHmiManager : CallerBase() { * 设置 V2X弹窗预警 代理View * @param view */ - fun setProxyNotificationView(view: IViewNotification) { - waringProviderApi?.setProxyNotificationView(view) + fun setNotificationViewProvider(provider: IViewNotificationProvider) { + waringProviderApi?.setViewNotificationProvider(provider) } /** diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/Extensions.kt b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/Extensions.kt index d1d75f6b85..1029ae55f7 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/Extensions.kt +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/Extensions.kt @@ -9,8 +9,7 @@ import android.text.* import android.text.style.ForegroundColorSpan import android.util.TypedValue import android.view.* -import android.widget.EditText -import android.widget.TextView +import android.widget.* import androidx.annotation.ColorInt import androidx.annotation.IntRange import androidx.core.view.ViewCompat diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt index fe0e586a0e..7e1045088c 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/reminder/api/impl/PopupWindowReminder.kt @@ -4,7 +4,7 @@ import android.widget.PopupWindow import androidx.lifecycle.LifecycleOwner import com.mogo.eagle.core.utilcode.reminder.api.IReminder -abstract class PopupWindowReminder(private val popupWindow: PopupWindow): IReminder { +abstract class PopupWindowReminder(val popupWindow: PopupWindow): IReminder { override fun lifecycleOwner(): LifecycleOwner = popupWindow.lifecycleOwner