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

Commit 3a575129 authored by Shivangi Dubey's avatar Shivangi Dubey Committed by Android (Google) Code Review
Browse files

Merge "Separate setRotationAtAngle and Rotation Suggestion Button Flows" into main

parents f15f0541 a5fdefdb
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import androidx.test.runner.AndroidJUnit4;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
import com.android.systemui.rotation.RotationPolicyWrapper;
import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.statusbar.policy.RotationLockController;
@@ -40,7 +41,6 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;

import java.util.function.Supplier;

@@ -60,12 +60,12 @@ public class NavigationBarRotationContextTest extends SysuiTestCase {

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mDependency.injectMockDependency(RotationLockController.class);

        final View view = new View(mContext);
        mRotationButton = mock(RotationButton.class);
        mRotationButtonController = new RotationButtonController(mContext,
        mRotationButtonController = new RotationButtonController(mock(RotationPolicyWrapper.class),
                mContext,
                /* lightIconColor */ 0,
                /* darkIconColor */ 0,
                /* iconCcwStart0 */ 0,
+4 −0
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ import com.android.systemui.navigationbar.views.buttons.NavBarButtonClickLogger;
import com.android.systemui.navigationbar.views.buttons.NavbarOrientationTrackingLogger;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.Recents;
import com.android.systemui.rotation.RotationPolicyWrapper;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.settings.UserContextProvider;
@@ -196,6 +197,8 @@ public class NavigationBarTest extends SysuiTestCase {
    private SysUiState mMockSysUiState;
    @Mock
    private Handler mHandler;
    @Mock
    private RotationPolicyWrapper mMockRotationPolicyWrapper;

    @Mock
    private Handler mBgHandler;
@@ -687,6 +690,7 @@ public class NavigationBarTest extends SysuiTestCase {
                mock(PanelExpansionInteractor.class),
                mock(NotificationRemoteInputManager.class),
                mock(NotificationShadeDepthController.class),
                mMockRotationPolicyWrapper,
                mHandler,
                mFakeExecutor,
                mFakeExecutor,
+95 −28
Original line number Diff line number Diff line
@@ -15,43 +15,74 @@
 */
package com.android.systemui.shared.rotation

import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.testing.TestableLooper.RunWithLooper
import android.view.Display
import android.view.Surface
import android.view.View
import android.view.WindowInsetsController
import android.view.WindowManagerPolicyConstants
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.rotation.RotationPolicyWrapper
import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback
import com.android.window.flags.Flags
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify

@RunWith(AndroidJUnit4::class)
@SmallTest
@RunWithLooper
class RotationButtonControllerTest : SysuiTestCase() {
    @get:Rule
    val setFlagsRule: SetFlagsRule = SetFlagsRule()
    @get:Rule
    val mocks = MockitoJUnit.rule()

    private lateinit var mController: RotationButtonController
    @Mock private lateinit var rotationPolicyWrapper: RotationPolicyWrapper
    @Mock private lateinit var rotationButton: RotationButton
    @Mock private lateinit var view: View
    @Captor private lateinit var onRotateSuggestionClick: ArgumentCaptor<View.OnClickListener>

    @Before
    fun setUp() {
    mController = RotationButtonController(
        mController =
            RotationButtonController(
                rotationPolicyWrapper,
                mContext,
                /* lightIconColor = */ 0,
                /* darkIconColor = */ 0,
                /* iconCcwStart0ResId = */ 0,
                /* iconCcwStart90ResId = */ 0,
                /* iconCwStart0ResId = */ 0,
      /* iconCwStart90ResId = */ 0
    ) { 0 }
                /* iconCwStart90ResId = */ 0,
            ) {
                0
            }
    }

    @Test
    fun ifGestural_showRotationSuggestion() {
        mController.onNavigationBarWindowVisibilityChange(/* showing= */ false)
    mController.onBehaviorChanged(Display.DEFAULT_DISPLAY,
                                  WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE)
        mController.onBehaviorChanged(
            Display.DEFAULT_DISPLAY,
            WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,
        )
        mController.onNavigationModeChanged(WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON)
        mController.onTaskbarStateChange(/* visible= */ false, /* stashed= */ false)
        assertThat(mController.canShowRotationButton()).isFalse()
@@ -60,4 +91,40 @@ class RotationButtonControllerTest : SysuiTestCase() {

        assertThat(mController.canShowRotationButton()).isTrue()
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR)
    fun onRotateSuggestionClick_rotationButtonClicked_setRotationAtAngleIfAllowedIsCalled() {
        clickRotationSuggestionButton()

        verify(rotationPolicyWrapper, times(1)).setRotationAtAngleIfAllowed(any(), any())
        verify(rotationPolicyWrapper, never()).setRotationLockAtAngle(any(), any(), any())
    }

    @Test
    fun setRotationAtAngle_forceSetRotationAtAngle_setRotationAtAngleIsCalled() {
        mController.setRotationAtAngle(
            /* isLocked= */ true,
            /* rotationSuggestion = */ Surface.ROTATION_270,
            /* caller= */ "",
        )

        verify(rotationPolicyWrapper, never()).setRotationAtAngleIfAllowed(any(), any())
        verify(rotationPolicyWrapper, times(1))
            .setRotationLockAtAngle(eq(true), eq(Surface.ROTATION_270), eq(""))
    }

    private fun clickRotationSuggestionButton() {
        mController.setRotationButton(
            rotationButton,
            object : RotationButtonUpdatesCallback {
                override fun onVisibilityChanged(isVisible: Boolean) {}

                override fun onPositionChanged() {}
            },
        )

        verify(rotationButton, times(1)).setOnClickListener(onRotateSuggestionClick.capture())
        onRotateSuggestionClick.value.onClick(view)
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ android_library {
        "SystemUIUnfoldLib",
        "SystemUISharedLib-Keyguard",
        "WindowManager-Shell-shared",
        "com.android.systemui.rotation-api",
        "com.android.systemui.rotation-impl",
        "//frameworks/libs/systemui:tracinglib-platform",
        "androidx.dynamicanimation_dynamicanimation",
        "androidx.concurrent_concurrent-futures",
+63 −22
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.view.RotationPolicy;
import com.android.systemui.rotation.RotationPolicyWrapper;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.recents.utilities.ViewRippler;
import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback;
@@ -75,6 +75,10 @@ import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.window.flags.Flags;

import dagger.assisted.Assisted;
import dagger.assisted.AssistedFactory;
import dagger.assisted.AssistedInject;

import java.io.PrintWriter;
import java.util.List;
import java.util.Optional;
@@ -102,6 +106,7 @@ public class RotationButtonController {
    private final UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
    private final ViewRippler mViewRippler = new ViewRippler();
    private final Supplier<Integer> mWindowRotationProvider;
    private final RotationPolicyWrapper mRotationPolicyWrapper;
    @Nullable private RotationButton mRotationButton;

    private boolean mIsRecentsAnimationRunning;
@@ -207,12 +212,14 @@ public class RotationButtonController {
        return (disable2Flags & StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS) != 0;
    }

    public RotationButtonController(Context context,
        @ColorInt int lightIconColor, @ColorInt int darkIconColor,
        @DrawableRes int iconCcwStart0ResId,
        @DrawableRes int iconCcwStart90ResId,
        @DrawableRes int iconCwStart0ResId,
        @DrawableRes int iconCwStart90ResId,
    @AssistedInject
    public RotationButtonController(RotationPolicyWrapper rotationPolicyWrapper, Context context,
            @Assisted("lightIconColor") @ColorInt int lightIconColor,
            @Assisted("darkIconColor") @ColorInt int darkIconColor,
            @Assisted("iconCcwStart0ResId") @DrawableRes int iconCcwStart0ResId,
            @Assisted("iconCcwStart90ResId") @DrawableRes int iconCcwStart90ResId,
            @Assisted("iconCwStart0ResId") @DrawableRes int iconCwStart0ResId,
            @Assisted("iconCwStart90ResId") @DrawableRes int iconCwStart90ResId,
            Supplier<Integer> windowRotationProvider) {

        mContext = context;
@@ -228,6 +235,7 @@ public class RotationButtonController {
        mAccessibilityManager = AccessibilityManager.getInstance(context);
        mTaskStackListener = new TaskStackListenerImpl();
        mWindowRotationProvider = windowRotationProvider;
        mRotationPolicyWrapper = rotationPolicyWrapper;

        mBgExecutor = context.getMainExecutor();
    }
@@ -337,24 +345,27 @@ public class RotationButtonController {
    }

    /**
     * Sets device rotation to {@code rotationSuggestion} if {@code isLocked} is true and
     * {@link Flags#enableDeviceStateAutoRotateSettingRefactor()} is disabled.
     * <p> When {@link Flags#enableDeviceStateAutoRotateSettingRefactor()} is enabled, the rotation
     * change in system server is conditional on auto-rotate still being OFF.
     * Sets the device rotation to the specified {@code rotation} if {@code isLocked} is true.
     *
     * This method is used to change the device's rotation in scenarios other than a rotation
     * suggestion button click. For example, if a user is in an app with a rotation value of
     * {@code ROTATION_270} but then navigates to the home screen where only {@code ROTATION_0}
     * is allowed, this method will be called to set the rotation to {@code ROTATION_0}. The
     * rotation is changed without further checks beyond verifying the value of the 'isLocked'
     * parameter.
     *
     * @param rotation The desired rotation.
     * @param isLocked {@code true} to apply the rotation; {@code false} to do nothing.
     */
    public void setRotationAtAngle(
            @Nullable Boolean isLocked, int rotationSuggestion, String caller) {
            @Nullable Boolean isLocked, int rotation, String caller) {
        if (isLocked == null) {
            // Ignore if we can't read the setting for the current user
            return;
        }
        if (isFoldable() && Flags.enableDeviceStateAutoRotateSettingRefactor()) {
            RotationPolicy.setRotationAtAngleIfAllowed(rotationSuggestion, caller);
            return;
        }

        RotationPolicy.setRotationLockAtAngle(mContext, /* enabled= */ isLocked,
                /* rotation= */ rotationSuggestion, caller);
        mRotationPolicyWrapper.setRotationLockAtAngle(/* enabled= */ isLocked,
                /* rotation= */ rotation, /* caller= */ caller);
    }

    public void setRotateSuggestionButtonState(boolean visible) {
@@ -652,13 +663,28 @@ public class RotationButtonController {
    private void onRotateSuggestionClick(View v) {
        mUiEventLogger.log(RotationButtonEvent.ROTATION_SUGGESTION_ACCEPTED);
        incrementNumAcceptedRotationSuggestionsIfNeeded();
        setRotationAtAngle(
                RotationPolicyUtil.isRotationLocked(mContext), mLastRotationSuggestion,
                /* caller= */ "RotationButtonController#onRotateSuggestionClick");
        setRotationForSuggestionIfAllowed(RotationPolicyUtil.isRotationLocked(mContext),
                mLastRotationSuggestion);
        Log.i(TAG, "onRotateSuggestionClick() mLastRotationSuggestion=" + mLastRotationSuggestion);
        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
    }

    private void setRotationForSuggestionIfAllowed(@Nullable Boolean isLocked,
            int rotationSuggestion) {
        if (isLocked == null) {
            // Ignore if we can't read the setting for the current user
            return;
        }
        final String caller = "RotationButtonController#onRotateSuggestionClick";

        if (Flags.enableDeviceStateAutoRotateSettingRefactor()) {
            mRotationPolicyWrapper.setRotationAtAngleIfAllowed(rotationSuggestion, caller);
            return;
        }

        setRotationAtAngle(isLocked, rotationSuggestion, caller);
    }

    private boolean onRotateSuggestionHover(View v, MotionEvent event) {
        final int action = event.getActionMasked();
        mHoveringRotationSuggestion = (action == MotionEvent.ACTION_HOVER_ENTER)
@@ -798,6 +824,21 @@ public class RotationButtonController {
        }
    }

    /**
     * Assisted factory for creating instances of {@link RotationButtonController}.
     */
    @AssistedFactory
    public interface Factory {
        RotationButtonController create(
                @Assisted("lightIconColor") @ColorInt int lightIconColor,
                @Assisted("darkIconColor") @ColorInt int darkIconColor,
                @Assisted("iconCcwStart0ResId") @DrawableRes int iconCcwStart0ResId,
                @Assisted("iconCcwStart90ResId") @DrawableRes int iconCcwStart90ResId,
                @Assisted("iconCwStart0ResId") @DrawableRes int iconCwStart0ResId,
                @Assisted("iconCwStart90ResId") @DrawableRes int iconCwStart90ResId
        );
    }

    enum RotationButtonEvent implements UiEventLogger.UiEventEnum {
        @UiEvent(doc = "The rotation button was shown")
        ROTATION_SUGGESTION_SHOWN(206),
Loading