Moving various orientation related config in RecentsOrientaedState

> Fixing RecentsOrientationState values for fallback recents
> Using proper rotation in task simulator

Change-Id: I770e7c8850e469f5dc0ce6f89889672f2decdc0d
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 32ab98b..d22e5af 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -334,7 +334,7 @@
             mAppWindowAnimationHelper.updateHomeBounds(getStackBounds(dp));
         }
         int displayRotation = 0;
-        if (mOrientedState != null && !mOrientedState.areMultipleLayoutOrientationsDisabled()) {
+        if (mOrientedState != null && mOrientedState.isMultipleOrientationSupportedByDevice()) {
             // TODO(b/150300347): The first recents animation after launcher is started with the
             //  foreground app not in landscape will look funky until that bug is fixed
             displayRotation = mOrientedState.getDisplayRotation();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
index 5a64382..bf01780 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
@@ -208,7 +208,8 @@
         mTaskAnimationManager = taskAnimationManager;
         mTouchTimeMs = touchTimeMs;
         mContinuingLastGesture = continuingLastGesture;
-        mTaskViewSimulator = new TaskViewSimulator(context, LayoutUtils::calculateLauncherTaskSize);
+        mTaskViewSimulator = new TaskViewSimulator(
+                context, LayoutUtils::calculateLauncherTaskSize, true);
 
         initAfterSubclassConstructor();
         initStateCallbacks();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 9b5a935..28c2b97 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -23,6 +23,7 @@
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 import static com.android.quickstep.GestureState.DEFAULT_STATE;
+import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
@@ -597,7 +598,7 @@
     }
 
     private void handleOrientationSetup(InputConsumer baseInputConsumer) {
-        if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
+        if (!isFixedRotationTransformEnabled(this)) {
             return;
         }
         mDeviceState.enableMultipleRegions(baseInputConsumer instanceof OtherActivityInputConsumer);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 235ac16..3cf9b2c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -65,7 +65,7 @@
     }
 
     public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        super(context, attrs, defStyleAttr, false);
     }
 
     @Override
@@ -195,9 +195,4 @@
         }
         super.applyLoadPlan(tasks);
     }
-
-    @Override
-    protected boolean supportsVerticalLandscape() {
-        return false;
-    }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index 00329b8..9309110 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -267,7 +267,8 @@
             mTmpRectF.set(mTargetRect);
             Utilities.scaleRectFAboutCenter(mTmpRectF, params.mOffsetScale);
             mCurrentRect.set(mRectFEvaluator.evaluate(params.mProgress, mSourceRect, mTmpRectF));
-            if (mOrientedState == null || mOrientedState.areMultipleLayoutOrientationsDisabled()) {
+            if (mOrientedState == null
+                    || !mOrientedState.isMultipleOrientationSupportedByDevice()) {
                 mCurrentRect.offset(params.mOffset, 0);
             } else {
                 int displayRotation = mOrientedState.getDisplayRotation();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
index 0131fdf..0bc021b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -15,9 +15,13 @@
  */
 package com.android.quickstep.util;
 
+import static android.view.Surface.ROTATION_0;
+
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.states.RotationHelper.deltaRotation;
 import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
 import static com.android.quickstep.util.AppWindowAnimationHelper.applySurfaceParams;
+import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled;
 import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -33,7 +37,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.quickstep.AnimatedFloat;
 import com.android.quickstep.RecentsAnimationTargets;
@@ -91,11 +94,17 @@
     private boolean mLayoutValid = false;
     private boolean mScrollValid = false;
 
-    public TaskViewSimulator(Context context, TaskSizeProvider sizeProvider) {
+    public TaskViewSimulator(Context context, TaskSizeProvider sizeProvider,
+            boolean rotationSupportedByActivity) {
         mContext = context;
         mSizeProvider = sizeProvider;
         mPositionHelper = new PreviewPositionHelper(context);
-        mOrientationState = new RecentsOrientedState(context);
+
+        mOrientationState = new RecentsOrientedState(context, rotationSupportedByActivity,
+                i -> { });
+        // We do not need to attach listeners as the simulator is created just for the gesture
+        // duration, and any settings are unlikely to change during this
+        mOrientationState.initWithoutListeners();
 
         mCurrentFullscreenParams = new FullscreenDrawParams(context);
         mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
@@ -114,11 +123,15 @@
      * @see com.android.quickstep.views.RecentsView#setLayoutRotation(int, int)
      */
     public void setLayoutRotation(int touchRotation, int displayRotation) {
-        if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
-            return;
+        int launcherRotation;
+        if (!mOrientationState.isMultipleOrientationSupportedByDevice()
+                || mOrientationState.isHomeRotationAllowed()) {
+            launcherRotation = displayRotation;
+        } else {
+            launcherRotation = ROTATION_0;
         }
-        mOrientationState.update(touchRotation, displayRotation,
-                mOrientationState.getLauncherRotation());
+
+        mOrientationState.update(touchRotation, displayRotation, launcherRotation);
         mLayoutValid = false;
     }
 
@@ -180,7 +193,7 @@
             mLayoutValid = true;
 
             getFullScreenScale();
-            mThumbnailData.rotation = FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()
+            mThumbnailData.rotation = isFixedRotationTransformEnabled(mContext)
                     ? mOrientationState.getDisplayRotation() : mPositionHelper.getCurrentRotation();
 
             mPositionHelper.updateThumbnailMatrix(mThumbnailPosition, mThumbnailData,
@@ -226,7 +239,8 @@
 
         // Apply recensView matrix
         mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
-        postDisplayRotation(mOrientationState.getDisplayRotation(),
+        postDisplayRotation(deltaRotation(
+                mOrientationState.getLauncherRotation(), mOrientationState.getDisplayRotation()),
                 mDp.widthPx, mDp.heightPx, mMatrix);
 
         // Crop rect is the inverse of thumbnail matrix
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 454223e..0b6d340 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -45,7 +45,6 @@
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.appprediction.PredictionUiStateManager;
 import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 import com.android.launcher3.util.TraceHelper;
@@ -96,7 +95,7 @@
     }
 
     public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        super(context, attrs, defStyleAttr, true);
         mActivity.getStateManager().addStateListener(this);
     }
 
@@ -265,12 +264,6 @@
     }
 
     @Override
-    protected boolean supportsVerticalLandscape() {
-        return FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()
-                && !mOrientationState.areMultipleLayoutOrientationsDisabled();
-    }
-
-    @Override
     public void reset() {
         super.reset();
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
index 93e68c0..d160686 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
@@ -48,7 +48,8 @@
             HIDDEN_NON_ZERO_ROTATION,
             HIDDEN_NO_TASKS,
             HIDDEN_GESTURE_RUNNING,
-            HIDDEN_NO_RECENTS})
+            HIDDEN_NO_RECENTS,
+            HIDDEN_FULLESCREEN_PROGRESS})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ActionsHiddenFlags { }
 
@@ -58,6 +59,7 @@
     public static final int HIDDEN_NO_TASKS = 1 << 3;
     public static final int HIDDEN_GESTURE_RUNNING = 1 << 4;
     public static final int HIDDEN_NO_RECENTS = 1 << 5;
+    public static final int HIDDEN_FULLESCREEN_PROGRESS = 1 << 6;
 
     private static final int INDEX_CONTENT_ALPHA = 0;
     private static final int INDEX_VISIBILITY_ALPHA = 1;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index b687920..90dc5a4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -38,6 +38,7 @@
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
 import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_FULLESCREEN_PROGRESS;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_GESTURE_RUNNING;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
@@ -75,8 +76,6 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
-import android.view.OrientationEventListener;
-import android.view.Surface;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
@@ -103,7 +102,6 @@
 import com.android.launcher3.compat.AccessibilityManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.statehandlers.DepthController;
-import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.touch.PagedOrientationHandler.CurveProperties;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -191,8 +189,6 @@
             };
 
     protected final RecentsOrientedState mOrientationState;
-    private OrientationEventListener mOrientationListener;
-    private int mPreviousRotation;
     protected RecentsAnimationController mRecentsAnimationController;
     protected RecentsAnimationTargets mRecentsAnimationTargets;
     protected AppWindowAnimationHelper mAppWindowAnimationHelper;
@@ -301,9 +297,6 @@
         }
     };
 
-    private final RecentsOrientedState.SystemRotationChangeListener mSystemRotationChangeListener =
-            enabled -> toggleOrientationEventListener();
-
     private final PinnedStackAnimationListener mIPinnedStackAnimationListener =
             new PinnedStackAnimationListener();
 
@@ -360,11 +353,13 @@
         }
     };
 
-    public RecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
+    public RecentsView(Context context, AttributeSet attrs, int defStyleAttr,
+            boolean rotationSupportedByActivity) {
         super(context, attrs, defStyleAttr);
         setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
         setEnableFreeScroll(true);
-        mOrientationState = new RecentsOrientedState(context);
+        mOrientationState = new RecentsOrientedState(
+                context, rotationSupportedByActivity, this::animateRecentsRotationInPlace);
 
         mFastFlingVelocity = getResources()
                 .getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
@@ -399,21 +394,10 @@
                 .getDimensionPixelSize(R.dimen.recents_empty_message_text_padding);
         setWillNotDraw(false);
         updateEmptyMessage();
-        disableMultipleLayoutRotations(!supportsVerticalLandscape());
+        mOrientationHandler = mOrientationState.getOrientationHandler();
 
         // Initialize quickstep specific cache params here, as this is constructed only once
         mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
-
-        mOrientationListener = new OrientationEventListener(getContext()) {
-            @Override
-            public void onOrientationChanged(int i) {
-                int rotation = RecentsOrientedState.getRotationForUserDegreesRotated(i);
-                if (mPreviousRotation != rotation) {
-                    animateRecentsRotationInPlace(rotation);
-                    mPreviousRotation = rotation;
-                }
-            }
-        };
     }
 
     public OverScroller getScroller() {
@@ -502,7 +486,6 @@
         SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
                 mIPinnedStackAnimationListener);
         mOrientationState.init();
-        mOrientationState.addSystemRotationChangeListener(mSystemRotationChangeListener);
     }
 
     @Override
@@ -517,7 +500,6 @@
         mIdp.removeOnChangeListener(this);
         SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
         mIPinnedStackAnimationListener.setActivity(null);
-        mOrientationState.removeSystemRotationChangeListener(mSystemRotationChangeListener);
         mOrientationState.destroy();
     }
 
@@ -576,31 +558,12 @@
     public void setOverviewStateEnabled(boolean enabled) {
         mOverviewStateEnabled = enabled;
         updateTaskStackListenerState();
+        mOrientationState.setRotationWatcherEnabled(enabled);
         if (!enabled) {
             // Reset the running task when leaving overview since it can still have a reference to
             // its thumbnail
             mTmpRunningTask = null;
         }
-        toggleOrientationEventListener();
-    }
-
-    private void toggleOrientationEventListener() {
-        boolean canEnable = canEnableOverviewRotationAnimation() && mOverviewStateEnabled;
-        UI_HELPER_EXECUTOR.execute(() -> {
-            if (canEnable) {
-                mOrientationListener.enable();
-            } else {
-                mOrientationListener.disable();
-            }
-        });
-    }
-
-    private boolean canEnableOverviewRotationAnimation() {
-        return supportsVerticalLandscape() // not 3P launcher
-                && !TestProtocol.sDisableSensorRotation // Ignore hardware dependency for tests..
-                && mOrientationListener.canDetectOrientation() // ..but does the hardware even work?
-                && (mOrientationState.isSystemRotationAllowed() &&
-                    !mOrientationState.canLauncherRotate()); // launcher is going to rotate itself
     }
 
     public void onDigitalWellbeingToastShown() {
@@ -820,9 +783,7 @@
         for (int i = 0; i < taskCount; i++) {
             getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
         }
-        if (mActionsView != null && mOrientationState.getLauncherRotation() == Surface.ROTATION_0) {
-            mActionsView.setVisibility(fullscreenProgress == 0 ? VISIBLE : INVISIBLE);
-        }
+        mActionsView.updateHiddenFlags(HIDDEN_FULLESCREEN_PROGRESS, fullscreenProgress > 0);
     }
 
     private void updateTaskStackListenerState() {
@@ -1039,10 +1000,6 @@
     }
 
     private void animateRecentsRotationInPlace(int newRotation) {
-        if (!supportsVerticalLandscape()) {
-            return;
-        }
-
         AnimatorSet pa = setRecentsChangedOrientation(true);
         pa.addListener(AnimationSuccessListener.forRunnable(() -> {
             setLayoutRotation(newRotation, mOrientationState.getDisplayRotation());
@@ -1067,7 +1024,6 @@
         return as;
     }
 
-    abstract protected boolean supportsVerticalLandscape();
 
     private void rotateAllChildTasks() {
         for (int i = 0; i < getTaskViewCount(); i++) {
@@ -1611,17 +1567,12 @@
             setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
             mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
             mActivity.getDragLayer().recreateControllers();
-            mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION, touchRotation != 0);
+            mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
+                    touchRotation != 0 || launcherRotation != 0);
             requestLayout();
         }
     }
 
-    public void disableMultipleLayoutRotations(boolean disable) {
-        mOrientationState.disableMultipleOrientations(disable);
-        mOrientationHandler = mOrientationState.getOrientationHandler();
-        requestLayout();
-    }
-
     public RecentsOrientedState getPagedViewOrientedState() {
         return mOrientationState;
     }
@@ -2083,8 +2034,7 @@
     public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
         float degreesRotated;
         if (navbarRotation == 0) {
-            degreesRotated = mOrientationState.areMultipleLayoutOrientationsDisabled() ? 0 :
-                    mOrientationHandler.getDegreesRotated();
+            degreesRotated = mOrientationHandler.getDegreesRotated();
         } else {
             degreesRotated = -navbarRotation;
         }
@@ -2097,7 +2047,7 @@
         // PagedOrientationHandler
         return e -> {
             if (navbarRotation != 0
-                    && !mOrientationState.areMultipleLayoutOrientationsDisabled()
+                    && mOrientationState.isMultipleOrientationSupportedByDevice()
                     && !mOrientationState.getOrientationHandler().isLayoutNaturalToLauncher()) {
                 mOrientationState.flipVertical(e);
                 super.onTouchEvent(e);
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 0a00a61..a6ce2b5 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -21,6 +21,7 @@
 import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
 import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
 import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
+import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
@@ -35,7 +36,6 @@
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -51,8 +51,6 @@
 
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.util.DefaultDisplay;
 import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
 import com.android.quickstep.util.NavBarPosition;
@@ -176,7 +174,7 @@
     }
 
     private void setupOrientationSwipeHandler() {
-        if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
+        if (!isFixedRotationTransformEnabled(mContext)) {
             return;
         }
 
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 5be0675..74daeca 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -16,17 +16,13 @@
 
 package com.android.quickstep.util;
 
-import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
-import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATION_TRANSFORM;
 import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
-import static com.android.launcher3.states.RotationHelper.FIXED_ROTATION_TRANSFORM_SETTING_NAME;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -44,19 +40,18 @@
 import android.provider.Settings;
 import android.util.Log;
 import android.view.MotionEvent;
+import android.view.OrientationEventListener;
 import android.view.Surface;
 
 import androidx.annotation.IntDef;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.touch.PortraitPagedViewHandler;
 
 import java.lang.annotation.Retention;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.function.IntConsumer;
 
 /**
  * Container to hold orientation/rotation related information for Launcher.
@@ -71,6 +66,8 @@
     private static final String TAG = "RecentsOrientedState";
     private static final boolean DEBUG = false;
 
+    private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
+
     private ContentObserver mSystemAutoRotateObserver = new ContentObserver(new Handler()) {
         @Override
         public void onChange(boolean selfChange) {
@@ -87,46 +84,79 @@
     private @SurfaceRotation int mDisplayRotation = ROTATION_0;
     private @SurfaceRotation int mLauncherRotation = Surface.ROTATION_0;
 
-    public interface SystemRotationChangeListener {
-        void onSystemRotationChanged(boolean enabled);
-    }
+    // Launcher activity supports multiple orientation, but fallback activity does not
+    private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY = 1 << 0;
+    // Multiple orientation is only supported if density is < 600
+    private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY = 1 << 1;
+    // Feature flag controlling the multi-orientation feature
+    private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_FLAG = 1 << 2;
+    // Shared prefs for rotation, only if activity supports it
+    private static final int FLAG_HOME_ROTATION_ALLOWED_IN_PREFS = 1 << 3;
+    // If the user has enabled system rotation
+    private static final int FLAG_SYSTEM_ROTATION_ALLOWED = 1 << 4;
+    // Whether to rotation sensor is supported on the device
+    private static final int FLAG_ROTATION_WATCHER_SUPPORTED = 1 << 5;
+    // Whether to enable rotation watcher when multi-rotation is supported
+    private static final int FLAG_ROTATION_WATCHER_ENABLED = 1 << 6;
 
-    /**
-     * If {@code true} we default to {@link PortraitPagedViewHandler} and don't support any fake
-     * launcher orientations.
-     */
-    private boolean mDisableMultipleOrientations;
-    private boolean mIsHomeRotationAllowed;
-    private boolean mIsSystemRotationAllowed;
+    private static final int MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE =
+            FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY
+            | FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY
+            | FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_FLAG;
+
+    private static final int MASK_ACTIVITY_ROTATING =
+            FLAG_HOME_ROTATION_ALLOWED_IN_PREFS | FLAG_SYSTEM_ROTATION_ALLOWED;
+
+    // State for which rotation watcher will be enabled.
+    // We skip it when home rotation is enabled as in that case, activity itself rotates
+    private static final int VALUE_ROTATION_WATCHER_ENABLED =
+            MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE | FLAG_SYSTEM_ROTATION_ALLOWED
+                    | FLAG_ROTATION_WATCHER_SUPPORTED | FLAG_ROTATION_WATCHER_ENABLED;
 
     private final ContentResolver mContentResolver;
     private final SharedPreferences mSharedPrefs;
-    private final boolean mAllowConfigurationDefaultValue;
-
-    private List<SystemRotationChangeListener> mSystemRotationChangeListeners = new ArrayList<>();
+    private final OrientationEventListener mOrientationListener;
 
     private final Matrix mTmpMatrix = new Matrix();
     private final Matrix mTmpInverseMatrix = new Matrix();
 
-    public RecentsOrientedState(Context context) {
+    private int mFlags;
+    private int mPreviousRotation = ROTATION_0;
+
+    /**
+     * @param rotationChangeListener Callback for receiving rotation events when rotation watcher
+     *                              is enabled
+     * @see #setRotationWatcherEnabled(boolean)
+     */
+    public RecentsOrientedState(Context context, boolean rotationSupportedByActivity,
+            IntConsumer rotationChangeListener) {
         mContentResolver = context.getContentResolver();
         mSharedPrefs = Utilities.getPrefs(context);
+        mOrientationListener = new OrientationEventListener(context) {
+            @Override
+            public void onOrientationChanged(int degrees) {
+                int newRotation = getRotationForUserDegreesRotated(degrees);
+                if (newRotation != mPreviousRotation) {
+                    mPreviousRotation = newRotation;
+                    rotationChangeListener.accept(newRotation);
+                }
+            }
+        };
+
+        mFlags = rotationSupportedByActivity ? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
 
         Resources res = context.getResources();
         int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
                 * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
-        mAllowConfigurationDefaultValue = originalSmallestWidth >= 600;
-
-        boolean isForcedRotation = Utilities.getFeatureFlagsPrefs(context)
-                .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true)
-                && !mAllowConfigurationDefaultValue;
-        UI_HELPER_EXECUTOR.execute(() -> {
-            if (context.checkSelfPermission(WRITE_SECURE_SETTINGS) == PERMISSION_GRANTED) {
-                Settings.Global.putInt(mContentResolver, FIXED_ROTATION_TRANSFORM_SETTING_NAME,
-                        isForcedRotation ? 1 : 0);
-            }
-        });
-        disableMultipleOrientations(!isForcedRotation);
+        if (originalSmallestWidth < 600) {
+            mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY;
+        }
+        if (isFixedRotationTransformEnabled(context)) {
+            mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_FLAG;
+        }
+        if (mOrientationListener.canDetectOrientation()) {
+            mFlags |= FLAG_ROTATION_WATCHER_SUPPORTED;
+        }
     }
 
     /**
@@ -140,10 +170,7 @@
     public boolean update(
             @SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation,
             @SurfaceRotation int launcherRotation) {
-        if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) {
-            return false;
-        }
-        if (mDisableMultipleOrientations) {
+        if (!isMultipleOrientationSupportedByDevice()) {
             return false;
         }
         if (mDisplayRotation == displayRotation && mTouchRotation == touchRotation
@@ -155,8 +182,7 @@
         mDisplayRotation = displayRotation;
         mTouchRotation = touchRotation;
 
-        if ((mIsHomeRotationAllowed && mIsSystemRotationAllowed) ||
-                mLauncherRotation == mTouchRotation) {
+        if (canLauncherRotate() || mLauncherRotation == mTouchRotation) {
             // TODO(b/153476489) Need to determine when launcher is rotated
             mOrientationHandler = PagedOrientationHandler.HOME_ROTATED;
             if (DEBUG) {
@@ -178,14 +204,25 @@
         return true;
     }
 
-    /**
-     * Setting this preference renders future calls to {@link #update(int, int, int)} as a no-op.
-     */
-    public void disableMultipleOrientations(boolean disable) {
-        mDisableMultipleOrientations = disable;
-        if (disable) {
-            mDisplayRotation = mTouchRotation = ROTATION_0;
-            mOrientationHandler = PagedOrientationHandler.PORTRAIT;
+    private void setFlag(int mask, boolean enabled) {
+        boolean wasRotationEnabled = !TestProtocol.sDisableSensorRotation
+                && mFlags == VALUE_ROTATION_WATCHER_ENABLED;
+        if (enabled) {
+            mFlags |= mask;
+        } else {
+            mFlags &= ~mask;
+        }
+
+        boolean isRotationEnabled = !TestProtocol.sDisableSensorRotation
+                && mFlags == VALUE_ROTATION_WATCHER_ENABLED;
+        if (wasRotationEnabled != isRotationEnabled) {
+            UI_HELPER_EXECUTOR.execute(() -> {
+                if (isRotationEnabled) {
+                    mOrientationListener.enable();
+                } else {
+                    mOrientationListener.disable();
+                }
+            });
         }
     }
 
@@ -195,47 +232,49 @@
     }
 
     private void updateAutoRotateSetting() {
-        try {
-            mIsSystemRotationAllowed = Settings.System.getInt(mContentResolver,
-                    Settings.System.ACCELEROMETER_ROTATION) == 1;
-        } catch (Settings.SettingNotFoundException e) {
-            Log.e(TAG, "autorotate setting not found", e);
-        }
-
-        for (SystemRotationChangeListener listener : mSystemRotationChangeListeners) {
-            listener.onSystemRotationChanged(mIsSystemRotationAllowed);
-        }
+        setFlag(FLAG_SYSTEM_ROTATION_ALLOWED, Settings.System.getInt(mContentResolver,
+                Settings.System.ACCELEROMETER_ROTATION, 1) == 1);
     }
 
     private void updateHomeRotationSetting() {
-        mIsHomeRotationAllowed = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
-                mAllowConfigurationDefaultValue);
+        setFlag(FLAG_HOME_ROTATION_ALLOWED_IN_PREFS,
+                mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, false));
     }
 
-    public void addSystemRotationChangeListener(SystemRotationChangeListener listener) {
-        mSystemRotationChangeListeners.add(listener);
-        listener.onSystemRotationChanged(mIsSystemRotationAllowed);
-    }
-
-    public void removeSystemRotationChangeListener(SystemRotationChangeListener listener) {
-        mSystemRotationChangeListeners.remove(listener);
-    }
-
+    /**
+     * Initializes aany system values and registers corresponding change listeners. It must be
+     * paired with {@link #destroy()} call
+     */
     public void init() {
-        mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
-        mContentResolver.registerContentObserver(
-                Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
-                false, mSystemAutoRotateObserver);
+        if (isMultipleOrientationSupportedByDevice()) {
+            mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
+            mContentResolver.registerContentObserver(
+                    Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
+                    false, mSystemAutoRotateObserver);
+        }
+        initWithoutListeners();
+    }
+
+    /**
+     * Unregisters any previously registered listeners.
+     */
+    public void destroy() {
+        if (isMultipleOrientationSupportedByDevice()) {
+            mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
+            mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
+        }
+        setRotationWatcherEnabled(false);
+    }
+
+    /**
+     * Initializes the OrientationState without attaching any listeners. This can be used when
+     * the object is short lived.
+     */
+    public void initWithoutListeners() {
         updateAutoRotateSetting();
         updateHomeRotationSetting();
     }
 
-    public void destroy() {
-        mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
-        mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
-        mSystemRotationChangeListeners.clear();
-    }
-
     @SurfaceRotation
     public int getDisplayRotation() {
         return mDisplayRotation;
@@ -251,20 +290,24 @@
         return mLauncherRotation;
     }
 
-    public boolean areMultipleLayoutOrientationsDisabled() {
-        return mDisableMultipleOrientations;
-    }
-
-    public boolean isSystemRotationAllowed() {
-        return mIsSystemRotationAllowed;
+    public boolean isMultipleOrientationSupportedByDevice() {
+        return (mFlags & MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE)
+                == MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE;
     }
 
     public boolean isHomeRotationAllowed() {
-        return mIsHomeRotationAllowed;
+        return (mFlags & FLAG_HOME_ROTATION_ALLOWED_IN_PREFS) != 0;
     }
 
     public boolean canLauncherRotate() {
-        return isSystemRotationAllowed() && isHomeRotationAllowed();
+        return (mFlags & MASK_ACTIVITY_ROTATING) == MASK_ACTIVITY_ROTATING;
+    }
+
+    /**
+     * Enables or disables the rotation watcher for listening to rotation callbacks
+     */
+    public void setRotationWatcherEnabled(boolean isEnabled) {
+        setFlag(FLAG_ROTATION_WATCHER_ENABLED, isEnabled);
     }
 
     public int getTouchRotationDegrees() {
@@ -388,4 +431,13 @@
                 break;
         }
     }
+
+    /**
+     * Returns true if system can keep Launcher fixed to portrait layout even if the
+     * foreground app is rotated
+     */
+    public static boolean isFixedRotationTransformEnabled(Context context) {
+        return Settings.Global.getInt(
+                context.getContentResolver(), FIXED_ROTATION_TRANSFORM_SETTING_NAME, 1) == 1;
+    }
 }
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 2b91cb1..65d3cd2 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -159,10 +159,6 @@
             "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false,
             "Always use hardware optimization for folder animations.");
 
-    public static final BooleanFlag ENABLE_FIXED_ROTATION_TRANSFORM = getDebugFlag(
-            FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true,
-            "Launch/close apps without rotation animation. Fix Launcher to portrait");
-
     public static void initialize(Context context) {
         synchronized (sDebugFlags) {
             for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 3640d8b..5a60f53 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -43,7 +43,6 @@
 
     public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
 
-    public static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
     private final ContentResolver mContentResolver;
     private boolean mSystemAutoRotateEnabled;