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

Commit 18a0ed8d authored by Shawn Lee's avatar Shawn Lee Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Re-enable HUN remote input dismissal on outside touch" into main

parents f8512c1b 9475afce
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ package com.android.systemui.scene.ui.viewmodel
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_DOWN
import android.view.MotionEvent.ACTION_OUTSIDE
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -43,6 +45,7 @@ import com.android.systemui.shade.data.repository.fakeShadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.data.repository.fakeRemoteInputRepository
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -68,6 +71,7 @@ class SceneContainerViewModelTest : SysuiTestCase() {
    private val fakeSceneDataSource by lazy { kosmos.fakeSceneDataSource }
    private val fakeShadeRepository by lazy { kosmos.fakeShadeRepository }
    private val sceneContainerConfig by lazy { kosmos.sceneContainerConfig }
    private val fakeRemoteInputRepository by lazy { kosmos.fakeRemoteInputRepository }
    private val falsingManager by lazy { kosmos.fakeFalsingManager }
    private val view = mock<View>()

@@ -233,6 +237,35 @@ class SceneContainerViewModelTest : SysuiTestCase() {
            assertThat(kosmos.fakePowerRepository.userTouchRegistered).isTrue()
        }

    @Test
    fun userInputOnEmptySpace_insideEvent() =
        testScope.runTest {
            assertThat(fakeRemoteInputRepository.areRemoteInputsClosed).isFalse()
            val insideMotionEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0f, 0f, 0)
            underTest.onEmptySpaceMotionEvent(insideMotionEvent)
            assertThat(fakeRemoteInputRepository.areRemoteInputsClosed).isFalse()
        }

    @Test
    fun userInputOnEmptySpace_outsideEvent_remoteInputActive() =
        testScope.runTest {
            fakeRemoteInputRepository.isRemoteInputActive.value = true
            assertThat(fakeRemoteInputRepository.areRemoteInputsClosed).isFalse()
            val outsideMotionEvent = MotionEvent.obtain(0, 0, ACTION_OUTSIDE, 0f, 0f, 0)
            underTest.onEmptySpaceMotionEvent(outsideMotionEvent)
            assertThat(fakeRemoteInputRepository.areRemoteInputsClosed).isTrue()
        }

    @Test
    fun userInputOnEmptySpace_outsideEvent_remoteInputInactive() =
        testScope.runTest {
            fakeRemoteInputRepository.isRemoteInputActive.value = false
            assertThat(fakeRemoteInputRepository.areRemoteInputsClosed).isFalse()
            val outsideMotionEvent = MotionEvent.obtain(0, 0, ACTION_OUTSIDE, 0f, 0f, 0)
            underTest.onEmptySpaceMotionEvent(outsideMotionEvent)
            assertThat(fakeRemoteInputRepository.areRemoteInputsClosed).isFalse()
        }

    @Test
    fun remoteUserInteraction_keepsContainerVisible() =
        testScope.runTest {
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ class RemoteInputRepositoryImplTest : SysuiTestCase() {
        MockitoAnnotations.initMocks(this)

        testScope = TestScope()
        underTest = RemoteInputRepositoryImpl(remoteInputManager)
        underTest = RemoteInputRepositoryImpl(testScope.backgroundScope, remoteInputManager)
    }

    @Test
+5 −0
Original line number Diff line number Diff line
@@ -77,6 +77,11 @@ class SceneWindowRootView(context: Context, attrs: AttributeSet?) : WindowRootVi
        }
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        event?.let { motionEventHandler?.onEmptySpaceMotionEvent(it) }
        return super.onTouchEvent(event)
    }

    companion object {
        private const val TAG = "SceneWindowRootView"
    }
+26 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.Overlay
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -48,7 +49,6 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import com.android.app.tracing.coroutines.launchTraced as launch

/** Models UI state for the scene container. */
class SceneContainerViewModel
@@ -58,6 +58,7 @@ constructor(
    private val falsingInteractor: FalsingInteractor,
    private val powerInteractor: PowerInteractor,
    shadeInteractor: ShadeInteractor,
    private val remoteInputInteractor: RemoteInputInteractor,
    private val splitEdgeDetector: SplitEdgeDetector,
    private val logger: SceneLogger,
    hapticsViewModelFactory: SceneContainerHapticsViewModel.Factory,
@@ -101,6 +102,10 @@ constructor(
                        this@SceneContainerViewModel.onMotionEvent(motionEvent)
                    }

                    override fun onEmptySpaceMotionEvent(motionEvent: MotionEvent) {
                        this@SceneContainerViewModel.onEmptySpaceMotionEvent(motionEvent)
                    }

                    override fun onMotionEventComplete() {
                        this@SceneContainerViewModel.onMotionEventComplete()
                    }
@@ -146,6 +151,23 @@ constructor(
        }
    }

    /**
     * Notifies that a [MotionEvent] has propagated through the entire [SharedNotificationContainer]
     * and Composable scene container hierarchy without being handled.
     *
     * Call this after the [MotionEvent] has finished propagating through the UI hierarchy.
     */
    fun onEmptySpaceMotionEvent(event: MotionEvent) {
        // check if the touch is outside the window and if remote input is active.
        // If true, close any active remote inputs.
        if (
            event.action == MotionEvent.ACTION_OUTSIDE &&
                (remoteInputInteractor.isRemoteInputActive as StateFlow).value
        ) {
            remoteInputInteractor.closeRemoteInputs()
        }
    }

    /**
     * Notifies that a scene container user interaction has begun.
     *
@@ -263,6 +285,9 @@ constructor(
        /** Notifies that a [MotionEvent] has occurred. */
        fun onMotionEvent(motionEvent: MotionEvent)

        /** Notifies that a [MotionEvent] has occurred outside the root window. */
        fun onEmptySpaceMotionEvent(motionEvent: MotionEvent)

        /**
         * Notifies that the previous [MotionEvent] reported by [onMotionEvent] has finished
         * processing.
+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.dagger.CentralSurfacesDependenciesModule;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
@@ -686,6 +687,7 @@ public class NotificationRemoteInputManager implements CoreStartable {
    }

    public void checkRemoteInputOutside(MotionEvent event) {
        SceneContainerFlag.assertInLegacyMode();
        if (event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
                && event.getX() == 0 && event.getY() == 0  // a touch outside both bars
                && isRemoteInputActive()) {
Loading