Merge "Updates Assistant gesture regions when no longer tracking multiple." into ub-launcher3-rvc-dev
diff --git a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
index 0b7d4bf..e649ce1 100644
--- a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
+++ b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Color;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
 import android.system.Os;
@@ -171,11 +172,16 @@
             }
 
             case TestProtocol.REQUEST_CLEAR_DATA: {
-                LauncherSettings.Settings.call(mContext.getContentResolver(),
-                        LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
-                MAIN_EXECUTOR.submit(() ->
-                        LauncherAppState.getInstance(mContext).getModel().forceReload());
-                return response;
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    LauncherSettings.Settings.call(mContext.getContentResolver(),
+                            LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
+                    MAIN_EXECUTOR.submit(() ->
+                            LauncherAppState.getInstance(mContext).getModel().forceReload());
+                    return response;
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
             }
 
             default:
diff --git a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
index 36c9b00..1dab482 100644
--- a/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
+++ b/quickstep/recents_ui_overrides/res/layout/predicted_hotseat_edu.xml
@@ -90,6 +90,7 @@
                         android:layout_height="wrap_content"
                         android:background="?android:attr/selectableItemBackground"
                         android:text="@string/hotseat_edu_dismiss"
+                        android:layout_gravity="start|center_vertical"
                         android:textColor="@android:color/white"/>
                 </FrameLayout>
                 <FrameLayout
@@ -102,7 +103,7 @@
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:background="?android:attr/selectableItemBackground"
-                        android:gravity="end"
+                        android:layout_gravity="end|center_vertical"
                         android:text="@string/hotseat_edu_accept"
                         android:textColor="@android:color/white"/>
                 </FrameLayout>
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index a1218ae..4f95254 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -47,7 +47,6 @@
  */
 public class HotseatEduController {
 
-    public static final String KEY_HOTSEAT_EDU_SEEN = "hotseat_edu_seen";
     public static final String HOTSEAT_EDU_ACTION =
             "com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU";
     public static final String SETTINGS_ACTION =
@@ -229,7 +228,6 @@
 
     void finishOnboarding() {
         mOnOnboardingComplete.run();
-        mLauncher.getSharedPrefs().edit().putBoolean(KEY_HOTSEAT_EDU_SEEN, true).apply();
     }
 
     void showDimissTip() {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 7334d80..1dbb9e2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -155,14 +155,6 @@
     }
 
     /**
-     * Returns whether or not user has seen hybrid hotseat education
-     */
-    public boolean isEduSeen() {
-        return mLauncher.getSharedPrefs().getBoolean(HotseatEduController.KEY_HOTSEAT_EDU_SEEN,
-                false);
-    }
-
-    /**
      * Shows appropriate hotseat education based on prediction enabled and migration states.
      */
     public void showEdu() {
@@ -172,7 +164,7 @@
                 Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
                         R.string.hotseat_prediction_settings, null,
                         () -> mLauncher.startActivity(getSettingsIntent()));
-            } else if (isEduSeen() || getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) {
+            } else if (getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) {
                 showDiscoveryTip();
             } else {
                 HotseatEduController eduController = new HotseatEduController(mLauncher,
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index 01936e4..e9614d1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
@@ -148,7 +148,7 @@
                 boolean rotated) {
             final boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
 
-            mActionsView.updateDisabledFlags(DISABLED_ROTATED, rotated);
+            getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
 
             getActionsView().setCallbacks(new OverlayUICallbacks() {
                 @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
index 512bbac..ef66b7a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
@@ -235,7 +235,8 @@
         Rect insets = mActivity.getDragLayer().getInsets();
         BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
         params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail());
-        params.gravity = Gravity.START;
+        // Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
+        params.gravity = Gravity.LEFT;
         setLayoutParams(params);
         setScaleX(taskView.getScaleX());
         setScaleY(taskView.getScaleY());
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index b091807..1081548 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -68,13 +68,13 @@
     private Resources mResources;
     private OrientationRectF mLastRectTouched;
     /**
-     * The rotation of the last touched nav bar. Derived from {@link #mLastRectTouched}, but has a
-     * longer lifetime than the rect. Note this is different than {@link #mQuickStepStartingRotation}
-     * as it always updates its value on every touch whereas mQuickstepStartingRotation only
-     * updates when device rotation matches touch rotation. Maybe this will be only one necessary
-     * after TODO(b/154580671) is in. TBD.
+     * The rotation of the last touched nav bar, whether that be through the last region the user
+     * touched down on or valid rotation user turned their device to.
+     * Note this is different than
+     * {@link #mQuickStepStartingRotation} as it always updates its value on every touch whereas
+     * mQuickstepStartingRotation only updates when device rotation matches touch rotation.
      */
-    private int mLastRectRotation;
+    private int mActiveTouchRotation;
     private SysUINavigationMode.Mode mMode;
     private QuickStepContractInfo mContractInfo;
 
@@ -159,13 +159,27 @@
         if (mEnableMultipleRegions) {
             mQuickStepStartingRotation = info.rotation;
         } else {
-            mLastRectRotation = 0;
+            mActiveTouchRotation = 0;
             mQuickStepStartingRotation = QUICKSTEP_ROTATION_UNINITIALIZED;
         }
         resetSwipeRegions(info);
     }
 
     /**
+     * Call when removing multiple regions to swipe from, but still in active quickswitch mode (task
+     * list is still frozen).
+     * Ex. This would be called when user has quickswitched to the same app rotation that
+     * they started quickswitching in, indicating that extra nav regions can be ignored. Calling
+     * this will update the value of {@link #mActiveTouchRotation}
+     *
+     * @param displayInfo The display whos rotation will be used as the current active rotation
+     */
+    void setSingleActiveRegion(DefaultDisplay.Info displayInfo) {
+        mActiveTouchRotation = displayInfo.rotation;
+        resetSwipeRegions(displayInfo);
+    }
+
+    /**
      * Only saves the swipe region represented by {@param region}, clears the
      * rest from {@link #mSwipeTouchRegions}
      * To be called whenever we want to stop tracking more than one swipe region.
@@ -266,7 +280,7 @@
     }
 
     int getCurrentActiveRotation() {
-        return mLastRectRotation;
+        return mActiveTouchRotation;
     }
 
     int getQuickStepStartingRotation() {
@@ -311,8 +325,9 @@
                             Log.d(TestProtocol.NO_SWIPE_TO_HOME, "setting mLastRectTouched");
                         }
                         mLastRectTouched = rect;
-                        mLastRectRotation = rect.mRotation;
-                        if (mEnableMultipleRegions && mCurrentDisplayRotation == mLastRectRotation) {
+                        mActiveTouchRotation = rect.mRotation;
+                        if (mEnableMultipleRegions
+                                && mCurrentDisplayRotation == mActiveTouchRotation) {
                             // TODO(b/154580671) might make this block unnecessary
                             // Start a touch session for the default nav region for the display
                             mQuickStepStartingRotation = mLastRectTouched.mRotation;
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 79b38f2..0a70bd6 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -151,7 +151,7 @@
      * sysui to adjust the navbar.
      */
     private OrientationEventListener mOrientationListener;
-    private int mPreviousRotation = ROTATION_0;
+    private int mSensorRotation = ROTATION_0;
     /**
      * This is the configuration of the foreground app or the app that will be in the foreground
      * once a quickstep gesture finishes.
@@ -246,18 +246,18 @@
             @Override
             public void onOrientationChanged(int degrees) {
                 int newRotation = RecentsOrientedState.getRotationForUserDegreesRotated(degrees,
-                        mPreviousRotation);
-                if (newRotation == mPreviousRotation) {
+                        mSensorRotation);
+                if (newRotation == mSensorRotation) {
                     return;
                 }
 
-                mPreviousRotation = newRotation;
+                mSensorRotation = newRotation;
                 mPrioritizeDeviceRotation = true;
 
                 if (newRotation == mCurrentAppRotation) {
                     // When user rotates device to the orientation of the foreground app after
                     // quickstepping
-                    toggleSecondaryNavBarsForRotation(false);
+                    toggleSecondaryNavBarsForRotation();
                 }
             }
         };
@@ -339,14 +339,16 @@
         mCurrentAppRotation = mDisplayRotation;
 
         /* Update nav bars on the following:
-         * a) if we're not expecting quickswitch, this is coming from an activity rotation
-         * b) we launch an app in the orientation that user is already in
-         * c) We're not in overview, since overview will always be portrait (w/o home rotation)
+         * a) if this is coming from an activity rotation OR
+         *   aa) we launch an app in the orientation that user is already in
+         * b) We're not in overview, since overview will always be portrait (w/o home rotation)
+         * c) We're actively in quickswitch mode
          */
         if ((mPrioritizeDeviceRotation
-                || mCurrentAppRotation == mPreviousRotation) // switch to an app of orientation user is in
-                && !mInOverview) {
-            toggleSecondaryNavBarsForRotation(false);
+                || mCurrentAppRotation == mSensorRotation) // switch to an app of orientation user is in
+                && !mInOverview
+                && mTaskListFrozen) {
+            toggleSecondaryNavBarsForRotation();
         }
     }
 
@@ -461,7 +463,9 @@
      * @return whether SystemUI is in a state where we can start a system gesture.
      */
     public boolean canStartSystemGesture() {
-        return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+        boolean canStartWithNavHidden = (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+                || mTaskListFrozen;
+        return canStartWithNavHidden
                 && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
                 && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
                 && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
@@ -634,29 +638,26 @@
     }
 
     private void enableMultipleRegions(boolean enable) {
-        toggleSecondaryNavBarsForRotation(enable);
-        if (enable && !TestProtocol.sDisableSensorRotation) {
+        mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
+        notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
+        if (enable && !mInOverview && !TestProtocol.sDisableSensorRotation) {
+            // Clear any previous state from sensor manager
+            mSensorRotation = mCurrentAppRotation;
             mOrientationListener.enable();
         } else {
             mOrientationListener.disable();
         }
     }
 
-    private void notifySysuiForRotation(int rotation) {
-        UI_HELPER_EXECUTOR.execute(() ->
-                SystemUiProxy.INSTANCE.get(mContext).onQuickSwitchToNewTask(rotation));
-    }
-
     public void onStartGesture() {
         if (mTaskListFrozen) {
             // Prioritize whatever nav bar user touches once in quickstep
             // This case is specifically when user changes what nav bar they are using mid
             // quickswitch session before tasks list is unfrozen
-            notifySysuiForRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
+            notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
         }
     }
 
-
     void onEndTargetCalculated(GestureState.GestureEndTarget endTarget,
             BaseActivityInterface activityInterface) {
         if (endTarget == GestureState.GestureEndTarget.RECENTS) {
@@ -673,7 +674,8 @@
                 // First gesture to start quickswitch
                 enableMultipleRegions(true);
             } else {
-                notifySysuiForRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
+                notifySysuiOfCurrentRotation(
+                        mOrientationTouchTransformer.getCurrentActiveRotation());
             }
 
             // A new gesture is starting, reset the current device rotation
@@ -685,7 +687,7 @@
                 // touched nav bar but didn't go anywhere and not quickswitching, do nothing
                 return;
             }
-            notifySysuiForRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
+            notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
         }
     }
 
@@ -697,13 +699,10 @@
     /**
      * Disables/Enables multiple nav bars on {@link OrientationTouchTransformer} and then
      * notifies system UI of the primary rotation the user is interacting with
-     *
-     * @param enable if {@code true}, this will report to sysUI the navbar of the region the gesture
-     *               started in (during ACTION_DOWN), otherwise will report {@param displayRotation}
      */
-    private void toggleSecondaryNavBarsForRotation(boolean enable) {
-        mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
-        notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
+    private void toggleSecondaryNavBarsForRotation() {
+        mOrientationTouchTransformer.setSingleActiveRegion(mDefaultDisplay.getInfo());
+        notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
     }
 
     public int getCurrentActiveRotation() {
diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java
index 150fb5b..35788a5 100644
--- a/src/com/android/launcher3/util/DefaultDisplay.java
+++ b/src/com/android/launcher3/util/DefaultDisplay.java
@@ -49,20 +49,25 @@
 
     public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION | CHANGE_FRAME_DELAY;
 
-    private final Context mContext;
+    private final Context mDisplayContext;
     private final int mId;
     private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
     private final Handler mChangeHandler;
     private Info mInfo;
 
     private DefaultDisplay(Context context) {
-        mContext = context;
-        mInfo = new Info(context);
+        DisplayManager dm = context.getSystemService(DisplayManager.class);
+        // Use application context to create display context so that it can have its own Resources.
+        mDisplayContext = context.getApplicationContext().createDisplayContext(
+                dm.getDisplay(DEFAULT_DISPLAY));
+        // Note that the Display object must be obtained from DisplayManager which is associated to
+        // the display context, so the Display is isolated from Activity and Application to provide
+        // the actual state of device that excludes the additional adjustment and override.
+        mInfo = new Info(mDisplayContext);
         mId = mInfo.id;
         mChangeHandler = new Handler(this::onChange);
 
-        context.getSystemService(DisplayManager.class)
-                .registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
+        dm.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
     }
 
     @Override
@@ -78,7 +83,7 @@
         }
 
         Info oldInfo = mInfo;
-        Info info = new Info(mContext);
+        Info info = new Info(mDisplayContext);
 
         int change = 0;
         if (info.hasDifferentSize(oldInfo)) {
@@ -162,8 +167,7 @@
             display.getRealSize(realSize);
             display.getCurrentSizeRange(smallestSize, largestSize);
 
-            Context defaultDisplayContext = context.createDisplayContext(display);
-            metrics = defaultDisplayContext.getResources().getDisplayMetrics();
+            metrics = context.getResources().getDisplayMetrics();
         }
 
         private boolean hasDifferentSize(Info info) {