Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f4e842a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix crash when trying to open a Mode's settings from lockscreen" into main

parents 4d0c46f5 1223df19
Loading
Loading
Loading
Loading
+25 −18
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy.ui.dialog

import android.app.Dialog
import android.content.Intent
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -25,10 +26,10 @@ import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.animation.mockActivityTransitionAnimatorController
import com.android.systemui.animation.mockDialogTransitionAnimator
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.backgroundCoroutineContext
import com.android.systemui.kosmos.mainCoroutineContext
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.activityStarter
import com.android.systemui.runOnMainThreadAndWaitForIdleSync
import com.android.systemui.shade.data.repository.shadeDialogContextInteractor
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.systemUIDialogFactory
@@ -49,6 +50,7 @@ import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class ModesDialogDelegateTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
@@ -76,19 +78,27 @@ class ModesDialogDelegateTest : SysuiTestCase() {
                activityStarter,
                { kosmos.modesDialogViewModel },
                mockDialogEventLogger,
                kosmos.applicationCoroutineScope,
                kosmos.mainCoroutineContext,
                kosmos.backgroundCoroutineContext,
                kosmos.shadeDialogContextInteractor,
            )
    }

    @Test
    fun launchFromDialog_whenDialogNotOpen() {
    fun launchFromDialog_whenDialogNotOpen() =
        testScope.runTest {
            val intent: Intent = mock()

        runOnMainThreadAndWaitForIdleSync { underTest.launchFromDialog(intent) }
            underTest.launchFromDialog(intent)
            runCurrent()

            verify(activityStarter)
            .startActivity(eq(intent), eq(true), eq<ActivityTransitionAnimator.Controller?>(null))
                .startActivity(
                    eq(intent),
                    eq(true),
                    eq<ActivityTransitionAnimator.Controller?>(null),
                )
        }

    @Test
@@ -97,29 +107,26 @@ class ModesDialogDelegateTest : SysuiTestCase() {
            val intent: Intent = mock()
            lateinit var dialog: Dialog

            runOnMainThreadAndWaitForIdleSync {
            kosmos.applicationCoroutineScope.launch { dialog = underTest.showDialog() }
            runCurrent()
            underTest.launchFromDialog(intent)
            }
            runCurrent()

            verify(mockDialogTransitionAnimator)
                .createActivityTransitionController(any<Dialog>(), eq(null))
            verify(activityStarter).startActivity(eq(intent), eq(true), eq(mockAnimationController))

            runOnMainThreadAndWaitForIdleSync { dialog.dismiss() }
            dialog.dismiss()
        }

    @Test
    fun dismiss_clearsDialogReference() {
        val dialog = runOnMainThreadAndWaitForIdleSync { underTest.createDialog() }
        val dialog = underTest.createDialog()

        assertThat(underTest.currentDialog).isEqualTo(dialog)

        runOnMainThreadAndWaitForIdleSync {
        dialog.show()
        dialog.dismiss()
        }

        assertThat(underTest.currentDialog).isNull()
    }
+19 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.systemui.statusbar.policy.ui.dialog

import android.annotation.UiThread;
import android.annotation.UiThread
import android.app.Dialog
import android.content.Context
import android.content.Intent
@@ -44,6 +44,8 @@ import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dialog.ui.composable.AlertDialogContent
import com.android.systemui.plugins.ActivityStarter
@@ -60,6 +62,8 @@ import com.android.systemui.util.Assert
import javax.inject.Inject
import javax.inject.Provider
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

@SysUISingleton
@@ -73,7 +77,9 @@ constructor(
    // Using a provider to avoid a circular dependency.
    private val viewModel: Provider<ModesDialogViewModel>,
    private val dialogEventLogger: ModesDialogEventLogger,
    @Application private val applicationCoroutineScope: CoroutineScope,
    @Main private val mainCoroutineContext: CoroutineContext,
    @Background private val bgContext: CoroutineContext,
    private val shadeDisplayContextRepository: ShadeDialogContextInteractor,
) : SystemUIDialog.Delegate {
    // NOTE: This should only be accessed/written from the main thread.
@@ -185,6 +191,18 @@ constructor(
     * launches it normally without animating.
     */
    fun launchFromDialog(intent: Intent) {
        // TODO: b/394571336 - Remove this method and inline "actual" if b/394571336 fixed.
        // Workaround for Compose bug, see b/394241061 and b/394571336 -- Need to post on the main
        // thread so that dialog dismissal doesn't crash after a long press inside it (the *double*
        // jump, out and back in, is because mainCoroutineContext is .immediate).
        applicationCoroutineScope.launch {
            withContext(bgContext) {
                withContext(mainCoroutineContext) { actualLaunchFromDialog(intent) }
            }
        }
    }

    private fun actualLaunchFromDialog(intent: Intent) {
        Assert.isMainThread()
        if (currentDialog == null) {
            Log.w(
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.policy.ui.dialog
import android.content.mockedContext
import com.android.systemui.animation.dialogTransitionAnimator
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.backgroundCoroutineContext
import com.android.systemui.kosmos.mainCoroutineContext
import com.android.systemui.plugins.activityStarter
import com.android.systemui.shade.data.repository.shadeDialogContextInteractor
@@ -37,7 +39,9 @@ var Kosmos.modesDialogDelegate: ModesDialogDelegate by
            activityStarter,
            { modesDialogViewModel },
            modesDialogEventLogger,
            applicationCoroutineScope,
            mainCoroutineContext,
            backgroundCoroutineContext,
            shadeDialogContextInteractor,
        )
    }
+2 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.systemui.statusbar.policy.ui.dialog.viewmodel

import android.content.mockedContext
import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
@@ -27,7 +27,7 @@ import javax.inject.Provider
val Kosmos.modesDialogViewModel: ModesDialogViewModel by
    Kosmos.Fixture {
        ModesDialogViewModel(
            mockedContext,
            applicationContext,
            zenModeInteractor,
            testDispatcher,
            Provider { modesDialogDelegate }.get(),