package com.mogo.functions.test import android.animation.Animator import android.app.Activity import android.content.Context import android.content.Intent import android.graphics.Color import android.view.Gravity import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.view.animation.OvershootInterpolator import android.widget.PopupWindow import androidx.core.view.ViewCompat import androidx.lifecycle.lifecycleScope import androidx.test.core.app.ActivityScenario import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener import com.mogo.eagle.core.function.hmi.notification.WarningFloat import com.mogo.eagle.core.function.hmi.notification.anim.DefaultAnimator import com.mogo.eagle.core.data.enums.SidePattern import com.mogo.eagle.core.function.hmi.ui.* import com.mogo.eagle.core.function.main.MainLauncherActivity import com.mogo.eagle.core.utilcode.kotlin.shape import com.mogo.eagle.core.utilcode.reminder.Reminder import com.mogo.eagle.core.utilcode.reminder.api.impl.ActivityReminder import com.mogo.eagle.core.utilcode.reminder.api.impl.PopupWindowReminder import com.mogo.eagle.core.utilcode.reminder.api.impl.ViewReminder import com.mogo.eagle.core.utilcode.util.AppStateManager import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import java.lang.Integer.min import java.util.concurrent.* import java.util.concurrent.TimeUnit.MILLISECONDS @RunWith(AndroidJUnit4::class) @LargeTest class ReminderTest { lateinit var launch: ActivityScenario @Before fun before() { launch = ActivityScenario.launch(MainLauncherActivity::class.java) } @Test fun testViewReminderNotOverride() = runBlocking(Dispatchers.Main) { launch.onActivity { it.lifecycleScope.launchWhenResumed { for (i in 1..10) { val reminder = WindowManagerViewUnOverrideReminder(View(it).also { itx -> itx.background = shape(solid = color(i)) }, 300, 300) Reminder.enqueue(it, reminder) delay(TimeUnit.SECONDS.toMillis(3)) reminder.hide() } } } delay(TimeUnit.SECONDS.toMillis(100)) return@runBlocking } @Test fun testShowWarningV2x() = runBlocking { val f = ensureMoGoHmiFragmentShow() delay(5000) (1 until 20).map { it }.asFlow() .onEach { f.showWarningV2X("10006", "test", "测试$it", "$it", null, true, 5000) } .flowOn(Dispatchers.Default) .collect() delay(3000000) } private suspend fun ensureMoGoHmiFragmentShow(): MoGoHmiFragment = suspendCancellableCoroutine { launch.onActivity { itx -> val executor = Executors.newSingleThreadScheduledExecutor() executor.scheduleAtFixedRate({ var find = itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment while (find == null) { find = itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment } while (!find.isResumed) { Thread.sleep(500) } it.resumeWith(Result.success(find)) try { Thread.sleep(500) executor.shutdownNow() } catch (e: Throwable) { e.printStackTrace() } }, 50, 500, MILLISECONDS) } } @Test fun testViewReminderOverride() = runBlocking(Dispatchers.Main) { launch.onActivity { it.lifecycleScope.launchWhenCreated { for (i in 1..10) { val reminder = WindowManagerViewOverrideReminder(View(it).also { itx -> itx.background = shape(solid = color(i)) }, 300, 300) Reminder.enqueue(it, reminder) delay(TimeUnit.SECONDS.toMillis(3)) } } } delay(TimeUnit.SECONDS.toMillis(100)) return@runBlocking } @Test fun testViewReminderWhenActivityDestroyed() = runBlocking(Dispatchers.Main) { launch.onActivity { it.lifecycleScope.launchWhenCreated { for (i in 1..10) { val reminder = WindowManagerViewOverrideReminder(View(it).also { itx -> itx.background = shape(solid = color(i)) }, 300, 300) Reminder.enqueue(it, reminder) delay(TimeUnit.SECONDS.toMillis(3)) if (i == 8) { it.finish() } } } } delay(TimeUnit.SECONDS.toMillis(100)) } @Test fun testWarningFloat() = runBlocking(Dispatchers.Main) { launch.onActivity { it.lifecycleScope.launchWhenCreated { for (i in 1..10) { val v = View(it).also { it.background = shape(solid = color(i)) it.layoutParams = WindowManager.LayoutParams().also { itx -> itx.width = 300 itx.height = 400 } } val builder = WarningFloat.with(it).setTag("test${i}").setLayout(v).setSidePattern(SidePattern.RESULT_TOP).setCountDownTime(TimeUnit.SECONDS.toMillis(10)).setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110).setImmersionStatusBar(true).addWarningStatusListener(object : IMoGoWarningStatusListener { override fun onShow() { } }).setAnimator(object : DefaultAnimator() { override fun enterAnim(view: View, params: WindowManager.LayoutParams, windowManager: WindowManager, sidePattern: SidePattern): Animator? = super.enterAnim(view, params, windowManager, sidePattern)?.apply { interpolator = OvershootInterpolator() } override fun exitAnim(view: View, params: WindowManager.LayoutParams, windowManager: WindowManager, sidePattern: SidePattern): Animator? = super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200) }) Reminder.enqueue(it, WarningFloatReminder(builder)) delay(TimeUnit.SECONDS.toMillis(3)) } } } delay(TimeUnit.SECONDS.toMillis(100)) } @Test fun testActivityReminder() = runBlocking(Dispatchers.Main) { launch.onActivity { it.lifecycleScope.launchWhenResumed { for (i in 1..10) { val reminder = ActivityNameReminder(it, "com.mogo.launcher.TestActivity") Reminder.enqueue(it, reminder) delay(TimeUnit.SECONDS.toMillis(6)) reminder.hide() } } } delay(TimeUnit.SECONDS.toMillis(100)) } @Test fun testActivityReminderOverride() = runBlocking(Dispatchers.Main) { launch.onActivity { it.lifecycleScope.launchWhenResumed { for (i in 1..10) { val reminder = ActivityNameOverrideReminder(it, "com.mogo.launcher.TestActivity") Reminder.enqueue(it, reminder) delay(TimeUnit.SECONDS.toMillis(6)) } } } delay(TimeUnit.SECONDS.toMillis(100)) } @Test fun testPopupWindowReminder() = runBlocking { launch.onActivity { it.lifecycleScope.launchWhenResumed { for (i in 1..10) { val reminder = TestPopupWindowReminder(it.findViewById(android.R.id.content), PopupWindow(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT).also { itx -> itx.contentView = View(it).also { xx -> xx.background = shape(solid = color(i)) xx.layoutParams = ViewGroup.LayoutParams(300, 400) } }) Reminder.enqueue(it, reminder) delay(TimeUnit.SECONDS.toMillis(3)) reminder.hide() } } } delay(TimeUnit.SECONDS.toMillis(100)) } @Test fun testPopupWindowReminderOverride() = runBlocking { launch.onActivity { it.lifecycleScope.launchWhenResumed { for (i in 1..10) { val reminder = TestPopupWindowReminderOverride(it.findViewById(android.R.id.content), PopupWindow(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT).also { itx -> itx.contentView = View(it).also { xx -> xx.background = shape(solid = color(i)) xx.layoutParams = ViewGroup.LayoutParams(300, 400) } }) Reminder.enqueue(it, reminder) delay(TimeUnit.SECONDS.toMillis(3)) } } } delay(TimeUnit.SECONDS.toMillis(100)) } @Test fun testWarningFloatForProject() = runBlocking { // launch.onActivity { // it.lifecycleScope.launchWhenResumed { // for (i in 1..10) { // val notificationView = V2XNotificationView(it) // notificationView.setWarningIcon(EventTypeEnum.getWarningIcon("10003")) // notificationView.setWarningContent("XXXXXX${i}") // WarningFloat.with(it) // .setTag("tag") // .setLayout(notificationView) // .setSidePattern(SidePattern.RESULT_TOP) // .setCountDownTime(5000) // .setGravity(Gravity.CENTER_HORIZONTAL, offsetY = 110) // .setImmersionStatusBar(true) // .addWarningStatusListener(object : IMoGoWarningStatusListener { // override fun onShow() { // } // }) // .setAnimator(object : DefaultAnimator() { // override fun enterAnim( // view: View, // params: WindowManager.LayoutParams, // windowManager: WindowManager, // sidePattern: SidePattern // ): Animator? = // super.enterAnim(view, params, windowManager, sidePattern)?.apply { // interpolator = OvershootInterpolator() // } // // override fun exitAnim( // view: View, // params: WindowManager.LayoutParams, // windowManager: WindowManager, // sidePattern: SidePattern // ): Animator? = // super.exitAnim(view, params, windowManager, sidePattern)?.setDuration(200) // }) // .show() // delay(2000) // } // } // } // delay(TimeUnit.SECONDS.toMillis(100)) } class WarningFloatReminder(private val builder: WarningFloat.Builder) : ViewReminder(builder.config.layoutView!!) { override fun show() { builder.show() } override fun hide() { WarningFloat.dismiss(builder.config.floatTag, false) } override fun isOverride(): Boolean { return true } } class WindowManagerViewUnOverrideReminder(private val content: View, private val width: Int, private val height: Int) : ViewReminder(content) { private val wm by lazy { content.context.getSystemService(Activity.WINDOW_SERVICE) as WindowManager } private var isAdd = false override fun show() { if (!isAdd) { val params = WindowManager.LayoutParams().also { it.width = width it.height = height } params.gravity = Gravity.CENTER wm.addView(content, params) isAdd = true } } override fun hide() { if (isAdd && ViewCompat.isAttachedToWindow(content)) { wm.removeView(content) isAdd = false } } } class WindowManagerViewOverrideReminder(private val content: View, private val width: Int, private val height: Int) : ViewReminder(content) { private val wm by lazy { content.context.getSystemService(Activity.WINDOW_SERVICE) as WindowManager } private var isAdd = false override fun show() { if (!isAdd) { val params = WindowManager.LayoutParams().also { it.width = width it.height = height } params.gravity = Gravity.CENTER wm.addView(content, params) isAdd = true } } override fun hide() { if (isAdd && ViewCompat.isAttachedToWindow(content)) { wm.removeView(content) isAdd = false } } override fun isOverride(): Boolean { return true } } class ActivityNameReminder(private val context: Context, private val className: String): ActivityReminder(className) { override fun show() { Intent(context, Class.forName(className)).also { context.startActivity(it) } } override fun hide() { AppStateManager.currentActivity()?.takeIf { it.javaClass.name == className }?.finish() } } class ActivityNameOverrideReminder(private val context: Context, private val className: String): ActivityReminder(className) { override fun show() { Intent(context, Class.forName(className)).also { context.startActivity(it) } } override fun hide() { AppStateManager.currentActivity()?.takeIf { it.javaClass.name == className }?.finish() } override fun isOverride(): Boolean { return true } } class TestPopupWindowReminder(private val anchor: View, override val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) { override fun show() { popupWindow.showAtLocation(anchor, Gravity.CENTER, 0, 0) } } class TestPopupWindowReminderOverride(private val anchor: View, override val popupWindow: PopupWindow): PopupWindowReminder(popupWindow) { override fun show() { popupWindow.showAtLocation(anchor, Gravity.CENTER, 0, 0) } override fun isOverride(): Boolean { return true } } private fun color(index: Int): Int { if (index > 10) { return Color.BLACK } val alpha = min(255, 255 - index * 20) return Color.argb(alpha, Color.red(Color.RED), Color.green(Color.RED), Color.blue(Color.RED)) } }