Merge "Support individual lock task features" into ub-launcher3-qt-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index 7a6cd2d..e3e339a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -22,6 +22,7 @@
 import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
 import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_PEEK_COMPONENT;
 import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -34,8 +35,10 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.quickstep.OverviewInteractionState;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.QuickStepContract;
 
 /**
  * Touch controller which handles swipe and hold to go to Overview
@@ -99,7 +102,8 @@
      * having it as part of the existing animation to the target state.
      */
     private boolean handlingOverviewAnim() {
-        return mStartState == NORMAL;
+        int stateFlags = OverviewInteractionState.INSTANCE.get(mLauncher).getSystemUiStateFlags();
+        return mStartState == NORMAL && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index e1dd124..18b8af4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -30,6 +30,7 @@
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
 import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 
 import android.view.MotionEvent;
 
@@ -44,10 +45,12 @@
 import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.quickstep.OverviewInteractionState;
 import com.android.quickstep.SysUINavigationMode;
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.system.QuickStepContract;
 
 /**
  * Handles quick switching to a recent task from the home screen.
@@ -80,6 +83,10 @@
 
     @Override
     protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
+        int stateFlags = OverviewInteractionState.INSTANCE.get(mLauncher).getSystemUiStateFlags();
+        if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
+            return NORMAL;
+        }
         return isDragTowardPositive ? QUICK_SWITCH : NORMAL;
     }
 
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 14bdec5..7563c3f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -22,8 +22,11 @@
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
 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_HOME_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
 
 import android.annotation.TargetApi;
 import android.app.ActivityManager;
@@ -79,6 +82,7 @@
 import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
 import com.android.systemui.shared.system.InputConsumerController;
 import com.android.systemui.shared.system.InputMonitorCompat;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
 
 import java.io.FileDescriptor;
@@ -197,6 +201,8 @@
 
         public void onSystemUiStateChanged(int stateFlags) {
             mSystemUiStateFlags = stateFlags;
+            mOverviewInteractionState.setSystemUiStateFlags(stateFlags);
+            mOverviewComponentObserver.onSystemUiStateChanged(stateFlags);
         }
 
         /** Deprecated methods **/
@@ -464,16 +470,13 @@
 
     private boolean validSystemUiFlags() {
         return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
-                && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0;
-    }
-
-    private boolean topTaskLocked() {
-        return ActivityManagerWrapper.getInstance().isLockToAppActive();
+                && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
+                && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
+                        || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
     }
 
     private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) {
-        boolean topTaskLocked = topTaskLocked();
-        boolean isInValidSystemUiState = validSystemUiFlags() && !topTaskLocked;
+        boolean isInValidSystemUiState = validSystemUiFlags();
 
         if (!mIsUserUnlocked) {
             if (isInValidSystemUiState) {
@@ -490,13 +493,15 @@
         if (mMode == Mode.NO_BUTTON) {
             final ActivityControlHelper activityControl =
                     mOverviewComponentObserver.getActivityControlHelper();
-            if (mAssistantAvailable && !topTaskLocked
-                    && AssistantTouchConsumer.withinTouchRegion(this, event)) {
+            if (mAssistantAvailable
+                    && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
+                    && AssistantTouchConsumer.withinTouchRegion(this, event)
+                    && !ActivityManagerWrapper.getInstance().isLockToAppActive()) {
                 base = new AssistantTouchConsumer(this, mISystemUiProxy, activityControl, base,
                         mInputMonitorCompat);
             }
 
-            if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
+            if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
                 // Note: we only allow accessibility to wrap this, and it replaces the previous
                 // base input consumer (which should be NO_OP anyway since topTaskLocked == true).
                 base = new ScreenPinnedInputConsumer(this, mISystemUiProxy, activityControl);
@@ -593,17 +598,14 @@
             // Dump everything
             pw.println("TouchState:");
             pw.println("  navMode=" + mMode);
-            pw.println("  validSystemUiFlags=" + validSystemUiFlags()
-                    + " flags=" + mSystemUiStateFlags);
-            pw.println("  topTaskLocked=" + topTaskLocked());
+            pw.println("  validSystemUiFlags=" + validSystemUiFlags());
+            pw.println("  systemUiFlags=" + mSystemUiStateFlags);
+            pw.println("  systemUiFlagsDesc="
+                    + QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
             pw.println("  isDeviceLocked=" + mKM.isDeviceLocked());
-            pw.println("  screenPinned=" +
-                    ActivityManagerWrapper.getInstance().isScreenPinningActive());
             pw.println("  assistantAvailable=" + mAssistantAvailable);
-            pw.println("  a11yClickable="
-                    + ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0));
-            pw.println("  a11yLongClickable="
-                    + ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0));
+            pw.println("  assistantDisabled="
+                    + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
             pw.println("  resumed="
                     + mOverviewComponentObserver.getActivityControlHelper().isResumed());
             pw.println("  useSharedState=" + mConsumer.useSharedSwipeState());
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 16beb79..ca966c8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -39,6 +39,7 @@
 import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.NEW_TASK;
 import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.RECENTS;
 import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -105,6 +106,7 @@
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.InputConsumerController;
 import com.android.systemui.shared.system.LatencyTrackerCompat;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
 import com.android.systemui.shared.system.WindowCallbacksCompat;
@@ -859,16 +861,9 @@
         }
     }
 
-    @UiThread
-    private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity,
+    private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
             boolean isCancel) {
-        PointF velocityPxPerMs = new PointF(velocity.x / 1000, velocity.y / 1000);
-        long duration = MAX_SWIPE_DURATION;
-        float currentShift = mCurrentShift.value;
         final GestureEndTarget endTarget;
-        float endShift;
-        final float startShift;
-        Interpolator interpolator = DEACCEL;
         final boolean goingToNewTask;
         if (mRecentsView != null) {
             if (!mRecentsAnimationWrapper.hasTargets()) {
@@ -883,7 +878,7 @@
         } else {
             goingToNewTask = false;
         }
-        final boolean reachedOverviewThreshold = currentShift >= MIN_PROGRESS_FOR_OVERVIEW;
+        final boolean reachedOverviewThreshold = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
         if (!isFling) {
             if (isCancel) {
                 endTarget = LAST_TASK;
@@ -893,7 +888,7 @@
                 } else if (goingToNewTask) {
                     endTarget = NEW_TASK;
                 } else {
-                    endTarget = currentShift < MIN_PROGRESS_FOR_OVERVIEW ? LAST_TASK : HOME;
+                    endTarget = !reachedOverviewThreshold ? LAST_TASK : HOME;
                 }
             } else {
                 endTarget = reachedOverviewThreshold && mGestureStarted
@@ -902,12 +897,6 @@
                                 ? NEW_TASK
                                 : LAST_TASK;
             }
-            endShift = endTarget.endShift;
-            long expectedDuration = Math.abs(Math.round((endShift - currentShift)
-                    * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
-            duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
-            startShift = currentShift;
-            interpolator = endTarget == RECENTS ? OVERSHOOT_1_2 : DEACCEL;
         } else {
             if (mMode == Mode.NO_BUTTON && endVelocity < 0 && !mIsShelfPeeking) {
                 // If swiping at a diagonal, base end target on the faster velocity.
@@ -920,7 +909,34 @@
             } else {
                 endTarget = goingToNewTask ? NEW_TASK : LAST_TASK;
             }
-            endShift = endTarget.endShift;
+        }
+
+        int stateFlags = OverviewInteractionState.INSTANCE.get(mActivity).getSystemUiStateFlags();
+        if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0
+                && (endTarget == RECENTS || endTarget == LAST_TASK)) {
+            return LAST_TASK;
+        }
+        return endTarget;
+    }
+
+    @UiThread
+    private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity,
+            boolean isCancel) {
+        PointF velocityPxPerMs = new PointF(velocity.x / 1000, velocity.y / 1000);
+        long duration = MAX_SWIPE_DURATION;
+        float currentShift = mCurrentShift.value;
+        final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
+                isFling, isCancel);
+        float endShift = endTarget.endShift;
+        final float startShift;
+        Interpolator interpolator = DEACCEL;
+        if (!isFling) {
+            long expectedDuration = Math.abs(Math.round((endShift - currentShift)
+                    * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
+            duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
+            startShift = currentShift;
+            interpolator = endTarget == RECENTS ? OVERSHOOT_1_2 : DEACCEL;
+        } else {
             startShift = Utilities.boundToRange(currentShift - velocityPxPerMs.y
                     * SINGLE_FRAME_MS / mTransitionDragLength, 0, mDragLengthFactor);
             float minFlingVelocity = mContext.getResources()
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index 0c29fcf..6030cea 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -26,6 +26,7 @@
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
@@ -46,9 +47,11 @@
 import com.android.launcher3.uioverrides.states.OverviewState;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.quickstep.OverviewInteractionState;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.TouchInteractionService;
 import com.android.quickstep.util.LayoutUtils;
+import com.android.systemui.shared.system.QuickStepContract;
 
 /**
  * Touch controller for handling various state transitions in portrait UI.
@@ -135,7 +138,10 @@
         } else if (fromState == OVERVIEW) {
             return isDragTowardPositive ? ALL_APPS : NORMAL;
         } else if (fromState == NORMAL && isDragTowardPositive) {
+            int stateFlags = OverviewInteractionState.INSTANCE.get(mLauncher)
+                    .getSystemUiStateFlags();
             return mAllowDragToOverview && TouchInteractionService.isConnected()
+                    && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0
                     ? OVERVIEW : ALL_APPS;
         }
         return fromState;
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index a2f07e3..b5da836 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -22,6 +22,7 @@
 
 import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
 import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
 
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -32,6 +33,7 @@
 
 import com.android.systemui.shared.system.PackageManagerWrapper;
 
+import com.android.systemui.shared.system.QuickStepContract;
 import java.util.ArrayList;
 
 /**
@@ -56,6 +58,7 @@
     private String mUpdateRegisteredPackage;
     private ActivityControlHelper mActivityControlHelper;
     private Intent mOverviewIntent;
+    private int mSystemUiStateFlags;
 
     public OverviewComponentObserver(Context context) {
         mContext = context;
@@ -71,6 +74,15 @@
         updateOverviewTargets();
     }
 
+    public void onSystemUiStateChanged(int stateFlags) {
+        boolean homeDisabledChanged = (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED)
+                != (stateFlags & SYSUI_STATE_HOME_DISABLED);
+        mSystemUiStateFlags = stateFlags;
+        if (homeDisabledChanged) {
+            updateOverviewTargets();
+        }
+    }
+
     /**
      * Update overview intent and {@link ActivityControlHelper} based off the current launcher home
      * component.
@@ -81,7 +93,8 @@
 
         final String overviewIntentCategory;
         ComponentName overviewComponent;
-        if (defaultHome == null || mMyHomeComponent.equals(defaultHome)) {
+        if ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0 &&
+                (defaultHome == null || mMyHomeComponent.equals(defaultHome))) {
             // User default home is same as out home app. Use Overview integrated in Launcher.
             overviewComponent = mMyHomeComponent;
             mActivityControlHelper = new LauncherActivityControllerHelper();
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 79d922c..78b48d7 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -53,6 +53,8 @@
     private ISystemUiProxy mISystemUiProxy;
     private float mBackButtonAlpha = 1;
 
+    private int mSystemUiStateFlags;
+
     private OverviewInteractionState(Context context) {
         mContext = context;
 
@@ -83,6 +85,14 @@
         mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
     }
 
+    public void setSystemUiStateFlags(int stateFlags) {
+        mSystemUiStateFlags = stateFlags;
+    }
+
+    public int getSystemUiStateFlags() {
+        return mSystemUiStateFlags;
+    }
+
     private boolean handleUiMessage(Message msg) {
         if (msg.what == MSG_SET_BACK_BUTTON_ALPHA) {
             mBackButtonAlpha = (float) msg.obj;