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

Commit a3d6fdb9 authored by cocod's avatar cocod
Browse files

Allow device rotation on glanceable hub

Allow screen rotation for mobile hub where keyguard rotation is not
allowed by default. In NotificationShadeWindow, update layout params
orientation to USER if one of the conditions met: 1) idle on hub
2)transitioning to hub 3)transitioning from hub to dream.

Fix bouncer not staying open unless user scrolls up and then right
as showing bouncer will rotate the screen to portrait.
In BouncerSwipeTouchHandler#onScroll listener, once user scrolls up and
past a small screen percentage, show bouncer scrimmed without tracking
user dragging. This ensures bouncer won't hide after rotation.

Bug: b/392708288
Test: atest BouncerSwipeTouchHandlerTest
Test: manually on foldable
Flag: com.android.systemui.glanceable_hub_v2
Change-Id: Ifb3160afc07c94c56371f20fa896b730ed716418
parent ea326c63
Loading
Loading
Loading
Loading
+17 −1
Original line number Original line Diff line number Diff line
@@ -28,6 +28,8 @@ import static org.mockito.Mockito.when;


import android.animation.ValueAnimator;
import android.animation.ValueAnimator;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.Rect;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.EnableFlags;
@@ -54,6 +56,7 @@ import com.android.systemui.scene.ui.view.WindowRootView;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.animation.FlingAnimationUtils;


import org.junit.Before;
import org.junit.Before;
@@ -127,10 +130,16 @@ public class BouncerFullscreenSwipeTouchHandlerTest extends SysuiTestCase {
    @Mock
    @Mock
    WindowRootView mWindowRootView;
    WindowRootView mWindowRootView;


    @Mock
    Resources mResources;

    private SceneInteractor mSceneInteractor;
    private SceneInteractor mSceneInteractor;


    private KeyguardStateController mKeyguardStateController;

    private static final float TOUCH_REGION = .3f;
    private static final float TOUCH_REGION = .3f;
    private static final float MIN_BOUNCER_HEIGHT = .05f;
    private static final float MIN_BOUNCER_HEIGHT = .05f;
    private final Configuration mConfiguration = new Configuration();


    private static final Rect SCREEN_BOUNDS = new Rect(0, 0, 1024, 100);
    private static final Rect SCREEN_BOUNDS = new Rect(0, 0, 1024, 100);
    private static final UserInfo CURRENT_USER_INFO = new UserInfo(
    private static final UserInfo CURRENT_USER_INFO = new UserInfo(
@@ -153,6 +162,8 @@ public class BouncerFullscreenSwipeTouchHandlerTest extends SysuiTestCase {
    public void setup() {
    public void setup() {
        mKosmos = new KosmosJavaAdapter(this);
        mKosmos = new KosmosJavaAdapter(this);
        mSceneInteractor = spy(mKosmos.getSceneInteractor());
        mSceneInteractor = spy(mKosmos.getSceneInteractor());
        mKeyguardStateController = mKosmos.getKeyguardStateController();
        mConfiguration.orientation = Configuration.ORIENTATION_PORTRAIT;


        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        mTouchHandler = new BouncerSwipeTouchHandler(
        mTouchHandler = new BouncerSwipeTouchHandler(
@@ -172,7 +183,9 @@ public class BouncerFullscreenSwipeTouchHandlerTest extends SysuiTestCase {
                mKeyguardInteractor,
                mKeyguardInteractor,
                mSceneInteractor,
                mSceneInteractor,
                mKosmos.getShadeRepository(),
                mKosmos.getShadeRepository(),
                Optional.of(() -> mWindowRootView));
                Optional.of(() -> mWindowRootView),
                mKeyguardStateController,
                mKosmos.getCommunalSettingsInteractor());


        when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
        when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
        when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
        when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
@@ -180,6 +193,9 @@ public class BouncerFullscreenSwipeTouchHandlerTest extends SysuiTestCase {
        when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn(Float.MAX_VALUE);
        when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn(Float.MAX_VALUE);
        when(mTouchSession.getBounds()).thenReturn(SCREEN_BOUNDS);
        when(mTouchSession.getBounds()).thenReturn(SCREEN_BOUNDS);
        when(mKeyguardInteractor.isKeyguardDismissible()).thenReturn(MutableStateFlow(false));
        when(mKeyguardInteractor.isKeyguardDismissible()).thenReturn(MutableStateFlow(false));
        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(true);
        when(mWindowRootView.getResources()).thenReturn(mResources);
        when(mResources.getConfiguration()).thenReturn(mConfiguration);
    }
    }


    /**
    /**
+74 −2
Original line number Original line Diff line number Diff line
@@ -16,6 +16,10 @@


package com.android.systemui.ambient.touch;
package com.android.systemui.ambient.touch;


import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;

import static com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;


import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
@@ -34,6 +38,8 @@ import static org.mockito.Mockito.when;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.DisableFlags;
@@ -63,6 +69,7 @@ import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.wm.shell.animation.FlingAnimationUtils;
import com.android.wm.shell.animation.FlingAnimationUtils;


import org.junit.Before;
import org.junit.Before;
@@ -132,12 +139,16 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
    @Mock
    @Mock
    WindowRootView mWindowRootView;
    WindowRootView mWindowRootView;


    Resources mResources;

    @Mock
    @Mock
    CommunalViewModel mCommunalViewModel;
    CommunalViewModel mCommunalViewModel;


    @Mock
    @Mock
    KeyguardInteractor mKeyguardInteractor;
    KeyguardInteractor mKeyguardInteractor;


    private KeyguardStateController mKeyguardStateController;

    @Captor
    @Captor
    ArgumentCaptor<Rect> mRectCaptor;
    ArgumentCaptor<Rect> mRectCaptor;


@@ -147,6 +158,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
    private static final int SCREEN_WIDTH_PX = 1024;
    private static final int SCREEN_WIDTH_PX = 1024;
    private static final int SCREEN_HEIGHT_PX = 100;
    private static final int SCREEN_HEIGHT_PX = 100;
    private static final float MIN_BOUNCER_HEIGHT = .05f;
    private static final float MIN_BOUNCER_HEIGHT = .05f;
    private final Configuration mConfiguration = new Configuration();


    private static final Rect SCREEN_BOUNDS = new Rect(0, 0, 1024, 100);
    private static final Rect SCREEN_BOUNDS = new Rect(0, 0, 1024, 100);
    private static final UserInfo CURRENT_USER_INFO = new UserInfo(
    private static final UserInfo CURRENT_USER_INFO = new UserInfo(
@@ -157,7 +169,8 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {


    @Parameters(name = "{0}")
    @Parameters(name = "{0}")
    public static List<FlagsParameterization> getParams() {
    public static List<FlagsParameterization> getParams() {
        return SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag();
        return SceneContainerFlagParameterizationKt
                .andSceneContainer(allCombinationsOf(Flags.FLAG_GLANCEABLE_HUB_V2));
    }
    }


    public BouncerSwipeTouchHandlerTest(FlagsParameterization flags) {
    public BouncerSwipeTouchHandlerTest(FlagsParameterization flags) {
@@ -168,7 +181,13 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
    @Before
    @Before
    public void setup() {
    public void setup() {
        mKosmos = new KosmosJavaAdapter(this);
        mKosmos = new KosmosJavaAdapter(this);
        mContext.ensureTestableResources();
        mResources = mContext.getResources();
        overrideConfiguration(mConfiguration);
        mConfiguration.orientation = Configuration.ORIENTATION_PORTRAIT;

        mSceneInteractor = spy(mKosmos.getSceneInteractor());
        mSceneInteractor = spy(mKosmos.getSceneInteractor());
        mKeyguardStateController = mKosmos.getKeyguardStateController();


        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        mTouchHandler = new BouncerSwipeTouchHandler(
        mTouchHandler = new BouncerSwipeTouchHandler(
@@ -188,7 +207,9 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
                mKeyguardInteractor,
                mKeyguardInteractor,
                mSceneInteractor,
                mSceneInteractor,
                mKosmos.getShadeRepository(),
                mKosmos.getShadeRepository(),
                Optional.of(() -> mWindowRootView)
                Optional.of(() -> mWindowRootView),
                mKeyguardStateController,
                mKosmos.getCommunalSettingsInteractor()
        );
        );


        when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
        when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
@@ -197,6 +218,9 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn(Float.MAX_VALUE);
        when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn(Float.MAX_VALUE);
        when(mTouchSession.getBounds()).thenReturn(SCREEN_BOUNDS);
        when(mTouchSession.getBounds()).thenReturn(SCREEN_BOUNDS);
        when(mKeyguardInteractor.isKeyguardDismissible()).thenReturn(MutableStateFlow(false));
        when(mKeyguardInteractor.isKeyguardDismissible()).thenReturn(MutableStateFlow(false));
        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(true);
        when(mWindowRootView.getResources()).thenReturn(mResources);
        setCommunalV2ConfigEnabled(true);
    }
    }


    /**
    /**
@@ -586,6 +610,43 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
        verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_BOUNCER_FULLY_VISIBLE);
        verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_BOUNCER_FULLY_VISIBLE);
    }
    }


    @Test
    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
    @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
    public void swipeUpAboveThresholdInLandscape_keyguardRotationNotAllowed_showsBouncer() {
        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(false);
        mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;

        final float swipeUpPercentage = .1f;
        // The upward velocity is ignored.
        final float velocityY = -1;
        swipeToPosition(swipeUpPercentage, velocityY);

        // Ensure show bouncer scrimmed
        verify(mScrimController).show(true);
        verify(mValueAnimatorCreator, never()).create(anyFloat(), anyFloat());
        verify(mValueAnimator, never()).start();
    }

    @Test
    @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
    @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
    public void swipeUpBelowThreshold_inLandscapeKeyguardRotationNotAllowed_noBouncer() {
        mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;

        final float swipeUpPercentage = .02f;
        // The upward velocity is ignored.
        final float velocityY = -1;
        swipeToPosition(swipeUpPercentage, velocityY);

        // no bouncer shown scrimmed
        verify(mScrimController, never()).show(true);
        // on touch end, bouncer hidden
        verify(mValueAnimatorCreator).create(eq(1 - swipeUpPercentage),
                eq(KeyguardBouncerConstants.EXPANSION_HIDDEN));
        verify(mValueAnimator, never()).addListener(any());
    }

    /**
    /**
     * Tests that swiping up with a speed above the set threshold will continue the expansion.
     * Tests that swiping up with a speed above the set threshold will continue the expansion.
     */
     */
@@ -672,4 +733,15 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {


        inputEventListenerCaptor.getValue().onInputEvent(upEvent);
        inputEventListenerCaptor.getValue().onInputEvent(upEvent);
    }
    }

    private void setCommunalV2ConfigEnabled(boolean enabled) {
        mContext.getOrCreateTestableResources().addOverride(
                com.android.internal.R.bool.config_glanceableHubEnabled,
                enabled);
    }

    private void overrideConfiguration(Configuration configuration) {
        mContext.getOrCreateTestableResources().overrideConfiguration(
                configuration);
    }
}
}
+114 −1
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import android.platform.test.flag.junit.FlagsParameterization
import android.provider.Settings
import android.provider.Settings
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.internal.logging.uiEventLoggerFake
import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
@@ -38,8 +39,13 @@ import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.collectLastValue
@@ -56,11 +62,15 @@ import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.advanceTimeBy
import org.junit.Before
import org.junit.Before
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.kotlin.verify
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
import platform.test.runner.parameterized.Parameters


@@ -93,10 +103,12 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
                communalInteractor = communalInteractor,
                communalInteractor = communalInteractor,
                communalSettingsInteractor = communalSettingsInteractor,
                communalSettingsInteractor = communalSettingsInteractor,
                communalSceneInteractor = communalSceneInteractor,
                communalSceneInteractor = communalSceneInteractor,
                keyguardTransitionInteractor = keyguardTransitionInteractor,
                keyguardInteractor = keyguardInteractor,
                keyguardInteractor = keyguardInteractor,
                systemSettings = fakeSettings,
                systemSettings = fakeSettings,
                notificationShadeWindowController = notificationShadeWindowController,
                notificationShadeWindowController = notificationShadeWindowController,
                bgScope = applicationCoroutineScope,
                bgScope = applicationCoroutineScope,
                applicationScope = applicationCoroutineScope,
                mainDispatcher = testDispatcher,
                mainDispatcher = testDispatcher,
                uiEventLogger = uiEventLoggerFake,
                uiEventLogger = uiEventLoggerFake,
            )
            )
@@ -111,13 +123,13 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
                UserHandle.USER_CURRENT,
                UserHandle.USER_CURRENT,
            )
            )
            fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
            fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
            setCommunalV2ConfigEnabled(true)


            underTest.start()
            underTest.start()


            // Make communal available so that communalInteractor.desiredScene accurately reflects
            // Make communal available so that communalInteractor.desiredScene accurately reflects
            // scene changes instead of just returning Blank.
            // scene changes instead of just returning Blank.
            runBlocking { setCommunalAvailable(true) }
            runBlocking { setCommunalAvailable(true) }
            setCommunalV2ConfigEnabled(true)
        }
        }
    }
    }


@@ -414,6 +426,107 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
        }
        }


    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun glanceableHubOrientationAware_idleOnCommunal() =
        kosmos.runTest {
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            val scene by collectLastValue(communalSceneInteractor.currentScene)
            assertThat(scene).isEqualTo(CommunalScenes.Communal)

            verify(notificationShadeWindowController).setGlanceableHubOrientationAware(true)
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun glanceableHubOrientationAware_transitioningToCommunal() =
        kosmos.runTest {
            val progress = MutableStateFlow(0f)
            val targetScene = CommunalScenes.Communal
            val currentScene = CommunalScenes.Blank
            val transitionState =
                MutableStateFlow(
                    ObservableTransitionState.Transition(
                        fromScene = currentScene,
                        toScene = targetScene,
                        currentScene = flowOf(targetScene),
                        progress = progress,
                        isInitiatedByUserInput = false,
                        isUserInputOngoing = flowOf(false),
                    )
                )
            communalSceneInteractor.setTransitionState(transitionState)

            // Partially transition.
            progress.value = .4f

            val scene by collectLastValue(communalSceneInteractor.currentScene)
            assertThat(scene).isEqualTo(CommunalScenes.Blank)

            verify(notificationShadeWindowController).setGlanceableHubOrientationAware(true)
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun glanceableHubOrientationAware_communalToDreaming() =
        kosmos.runTest {
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            verify(notificationShadeWindowController).setGlanceableHubOrientationAware(true)
            Mockito.clearInvocations(notificationShadeWindowController)

            val progress = MutableStateFlow(0f)
            val currentScene = CommunalScenes.Communal
            val targetScene = CommunalScenes.Blank
            val transitionState =
                MutableStateFlow(
                    ObservableTransitionState.Transition(
                        fromScene = currentScene,
                        toScene = targetScene,
                        currentScene = flowOf(targetScene),
                        progress = progress,
                        isInitiatedByUserInput = false,
                        isUserInputOngoing = flowOf(false),
                    )
                )
            communalSceneInteractor.setTransitionState(transitionState)

            // Partially transitioned out of Communal scene
            progress.value = .4f

            // Started keyguard transitioning from hub -> dreaming.
            fakeKeyguardTransitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.GLANCEABLE_HUB,
                    to = KeyguardState.DREAMING,
                    transitionState = TransitionState.STARTED,
                )
            )
            verify(notificationShadeWindowController).setGlanceableHubOrientationAware(true)
            Mockito.clearInvocations(notificationShadeWindowController)

            fakeKeyguardTransitionRepository.sendTransitionStep(
                from = KeyguardState.GLANCEABLE_HUB,
                to = KeyguardState.DREAMING,
                transitionState = TransitionState.RUNNING,
                value = 0.5f,
            )

            // Transitioned to dreaming.
            fakeKeyguardTransitionRepository.sendTransitionStep(
                from = KeyguardState.GLANCEABLE_HUB,
                to = KeyguardState.DREAMING,
                transitionState = TransitionState.FINISHED,
                value = 1f,
            )
            // Not on hub anymore, let other states take control
            verify(notificationShadeWindowController).setGlanceableHubOrientationAware(false)
        }

    /**
    /**
     * Advances time by duration + 1 millisecond, to ensure that tasks scheduled to run at
     * Advances time by duration + 1 millisecond, to ensure that tasks scheduled to run at
     * currentTime + duration are scheduled.
     * currentTime + duration are scheduled.
+43 −1
Original line number Original line Diff line number Diff line
@@ -134,7 +134,7 @@ class CommunalSceneInteractorTest(flags: FlagsParameterization) : SysuiTestCase(
            underTest.snapToScene(
            underTest.snapToScene(
                CommunalScenes.Communal,
                CommunalScenes.Communal,
                "test",
                "test",
                ActivityTransitionAnimator.TIMINGS.totalDuration
                ActivityTransitionAnimator.TIMINGS.totalDuration,
            )
            )
            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
            advanceTimeBy(ActivityTransitionAnimator.TIMINGS.totalDuration)
            advanceTimeBy(ActivityTransitionAnimator.TIMINGS.totalDuration)
@@ -267,6 +267,48 @@ class CommunalSceneInteractorTest(flags: FlagsParameterization) : SysuiTestCase(
            assertThat(isIdleOnCommunal).isEqualTo(false)
            assertThat(isIdleOnCommunal).isEqualTo(false)
        }
        }


    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    fun isTransitioningToOrIdleOnCommunal() =
        testScope.runTest {
            // isIdleOnCommunal is false when not on communal.
            val isTransitioningToOrIdleOnCommunal by
                collectLastValue(underTest.isTransitioningToOrIdleOnCommunal)
            assertThat(isTransitioningToOrIdleOnCommunal).isEqualTo(false)

            val transitionState: MutableStateFlow<ObservableTransitionState> =
                MutableStateFlow(
                    ObservableTransitionState.Transition(
                        fromScene = CommunalScenes.Blank,
                        toScene = CommunalScenes.Communal,
                        currentScene = flowOf(CommunalScenes.Communal),
                        progress = flowOf(0f),
                        isInitiatedByUserInput = false,
                        isUserInputOngoing = flowOf(false),
                    )
                )

            // Start transition to communal.
            repository.setTransitionState(transitionState)
            assertThat(isTransitioningToOrIdleOnCommunal).isEqualTo(true)

            // Finish transition to communal
            transitionState.value = ObservableTransitionState.Idle(CommunalScenes.Communal)
            assertThat(isTransitioningToOrIdleOnCommunal).isEqualTo(true)

            // Start transition away from communal.
            transitionState.value =
                ObservableTransitionState.Transition(
                    fromScene = CommunalScenes.Communal,
                    toScene = CommunalScenes.Blank,
                    currentScene = flowOf(CommunalScenes.Blank),
                    progress = flowOf(.1f),
                    isInitiatedByUserInput = false,
                    isUserInputOngoing = flowOf(false),
                )
            assertThat(isTransitioningToOrIdleOnCommunal).isEqualTo(false)
        }

    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @Test
    @Test
    fun isCommunalVisible() =
    fun isCommunalVisible() =
+16 −3
Original line number Original line Diff line number Diff line
@@ -84,12 +84,12 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.Spy;


import java.util.List;
import java.util.concurrent.Executor;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;
import platform.test.runner.parameterized.Parameters;


import java.util.List;
import java.util.concurrent.Executor;

@RunWith(ParameterizedAndroidJunit4.class)
@RunWith(ParameterizedAndroidJunit4.class)
@RunWithLooper(setAsMainLooper = true)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
@SmallTest
@@ -409,6 +409,19 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
                .isEqualTo(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
                .isEqualTo(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
    }
    }


    @Test
    public void hubOrientationAware_layoutParamsUpdated() {
        mNotificationShadeWindowController.setKeyguardShowing(false);
        mNotificationShadeWindowController.setBouncerShowing(false);
        mNotificationShadeWindowController.setGlanceableHubOrientationAware(true);
        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(false);
        mNotificationShadeWindowController.onConfigChanged(new Configuration());

        verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), mLayoutParameters.capture());
        assertThat(mLayoutParameters.getValue().screenOrientation)
                .isEqualTo(ActivityInfo.SCREEN_ORIENTATION_USER);
    }

    @Test
    @Test
    public void batchApplyWindowLayoutParams_doesNotDispatchEvents() {
    public void batchApplyWindowLayoutParams_doesNotDispatchEvents() {
        mNotificationShadeWindowController.setForceDozeBrightness(true);
        mNotificationShadeWindowController.setForceDozeBrightness(true);
Loading