Merge changes I2ade7f48,I78485a16 into ub-launcher3-master

* changes:
  2/ Move device state logic to its own class
  1/ Renaming some classes for clarity
diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index ddf0fff..b1a3881 100644
--- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -32,7 +32,7 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.LauncherAnimationRunner;
 import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
 import com.android.quickstep.views.IconRecentsView;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
 import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
@@ -113,8 +113,8 @@
             return anim;
         }
 
-        RemoteAnimationTargetSet targetSet =
-                new RemoteAnimationTargetSet(appTargets, wallpaperTargets, MODE_CLOSING);
+        RemoteAnimationTargets targetSet =
+                new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_CLOSING);
         mRecentsView.setTransitionedFromApp(!targetSet.isAnimatingHome());
 
         RemoteAnimationTargetCompat recentsTarget = null;
diff --git a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
index 4994526..37c2c04 100644
--- a/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/go/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -27,7 +27,7 @@
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.quickstep.util.ActivityInitListener;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
 import com.android.quickstep.views.IconRecentsView;
 
 import java.util.function.BiPredicate;
@@ -59,7 +59,7 @@
             boolean isAnimatingToRecents = false;
 
             @Override
-            public void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) {
+            public void onRemoteAnimationReceived(RemoteAnimationTargets targets) {
                 isAnimatingToRecents = targets != null && targets.isAnimatingHome();
                 if (!isAnimatingToRecents) {
                     rv.setAlpha(1);
diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 19dd82f..6b936cb 100644
--- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -34,6 +34,8 @@
 
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.DefaultDisplay;
+import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 
@@ -44,15 +46,6 @@
 public class TouchInteractionService extends Service {
 
     private static final String TAG = "GoTouchInteractionService";
-    private boolean mIsUserUnlocked;
-    private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
-                initWhenUserUnlocked();
-            }
-        }
-    };
 
     private final IBinder mMyBinder = new IOverviewProxy.Stub() {
 
@@ -68,21 +61,21 @@
 
         @Override
         public void onOverviewToggle() {
-            if (mIsUserUnlocked) {
+            if (mDeviceState.isUserUnlocked()) {
                 mOverviewCommandHelper.onOverviewToggle();
             }
         }
 
         @Override
         public void onOverviewShown(boolean triggeredFromAltTab) {
-            if (mIsUserUnlocked) {
+            if (mDeviceState.isUserUnlocked()) {
                 mOverviewCommandHelper.onOverviewShown(triggeredFromAltTab);
             }
         }
 
         @Override
         public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
-            if (mIsUserUnlocked && triggeredFromAltTab && !triggeredFromHomeKey) {
+            if (mDeviceState.isUserUnlocked() && triggeredFromAltTab && !triggeredFromHomeKey) {
                 // onOverviewShownFromAltTab hides the overview and ends at the target app
                 mOverviewCommandHelper.onOverviewHidden();
             }
@@ -90,7 +83,7 @@
 
         @Override
         public void onTip(int actionType, int viewType) {
-            if (mIsUserUnlocked) {
+            if (mDeviceState.isUserUnlocked()) {
                 mOverviewCommandHelper.onTip(actionType, viewType);
             }
         }
@@ -140,35 +133,30 @@
     private RecentsModel mRecentsModel;
     private OverviewComponentObserver mOverviewComponentObserver;
     private OverviewCommandHelper mOverviewCommandHelper;
+    private RecentsAnimationDeviceState mDeviceState;
 
     @Override
     public void onCreate() {
         super.onCreate();
-        if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) {
-            initWhenUserUnlocked();
-        } else {
-            mIsUserUnlocked = false;
-            registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
-        }
+        mDeviceState = new RecentsAnimationDeviceState(this);
+        mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
 
         sConnected = true;
     }
 
-    private void initWhenUserUnlocked() {
+    public void onUserUnlocked() {
         mRecentsModel = RecentsModel.INSTANCE.get(this);
-        mOverviewComponentObserver = new OverviewComponentObserver(this);
+        mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
         mOverviewCommandHelper = new OverviewCommandHelper(this,
                 mOverviewComponentObserver);
-        mIsUserUnlocked = true;
-        Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
     }
 
     @Override
     public void onDestroy() {
-        if (mIsUserUnlocked) {
+        if (mDeviceState.isUserUnlocked()) {
             mOverviewComponentObserver.onDestroy();
         }
-        Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
+        mDeviceState.destroy();
         sConnected = false;
         super.onDestroy();
     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 3384397..d842484 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -36,7 +36,7 @@
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.anim.SpringAnimationBuilder;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -71,7 +71,7 @@
 
         TaskView taskView = findTaskViewToLaunch(mLauncher, v, appTargets);
 
-        ClipAnimationHelper helper = new ClipAnimationHelper(mLauncher);
+        AppWindowAnimationHelper helper = new AppWindowAnimationHelper(mLauncher);
         anim.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, appTargets,
                 wallpaperTargets, helper).setDuration(RECENTS_LAUNCH_DURATION));
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 468b8af..e4e60a0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -78,7 +78,7 @@
         } else {
             dummyTask = recentsView.getTaskViewAt(0);
         }
-        return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask)
+        return recentsView.getTempAppWindowAnimationHelper().updateForFullscreenOverview(dummyTask)
                 .getScaleAndTranslation();
     }
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index 89c34d3..1b49732 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -30,9 +30,9 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.anim.AnimationSuccessListener;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
 import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
@@ -115,7 +115,7 @@
             return anim;
         }
 
-        RemoteAnimationTargetSet targetSet = new RemoteAnimationTargetSet(appTargets,
+        RemoteAnimationTargets targetSet = new RemoteAnimationTargets(appTargets,
                 wallpaperTargets, MODE_CLOSING);
 
         // Use the top closing app to determine the insets for the animation
@@ -126,7 +126,7 @@
             return anim;
         }
 
-        final ClipAnimationHelper clipHelper = new ClipAnimationHelper(mActivity);
+        final AppWindowAnimationHelper clipHelper = new AppWindowAnimationHelper(mActivity);
 
         // At this point, the activity is already started and laid-out. Get the home-bounds
         // relative to the screen using the rootView of the activity.
@@ -142,7 +142,7 @@
         clipHelper.updateTargetRect(targetRect);
         clipHelper.prepareAnimation(mActivity.getDeviceProfile(), false /* isOpening */);
 
-        ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
+        AppWindowAnimationHelper.TransformParams params = new AppWindowAnimationHelper.TransformParams()
                 .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(rootView));
         ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
         valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
@@ -156,7 +156,7 @@
 
         if (targetSet.isAnimatingHome()) {
             // If we are animating home, fade in the opening targets
-            RemoteAnimationTargetSet openingSet = new RemoteAnimationTargetSet(appTargets,
+            RemoteAnimationTargets openingSet = new RemoteAnimationTargets(appTargets,
                     wallpaperTargets, MODE_OPENING);
 
             TransactionCompat transaction = new TransactionCompat();
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 ed6a7e8..770857b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -61,12 +61,12 @@
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.inputconsumers.InputConsumer;
 import com.android.quickstep.util.ActivityInitListener;
-import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
+import com.android.quickstep.util.AppWindowAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
 import com.android.quickstep.util.RectFSpringAnim;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.quickstep.util.RemoteAnimationTargets;
+import com.android.quickstep.util.RecentsAnimationTargets;
+import com.android.quickstep.util.RecentsAnimationCallbacks.RecentsAnimationListener;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.system.InputConsumerController;
@@ -80,7 +80,7 @@
  */
 @TargetApi(Build.VERSION_CODES.Q)
 public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q extends RecentsView>
-        implements SwipeAnimationListener {
+        implements RecentsAnimationListener {
 
     private static final String TAG = "BaseSwipeUpHandler";
     protected static final Rect TEMP_RECT = new Rect();
@@ -102,7 +102,7 @@
     protected final RecentsModel mRecentsModel;
     protected final int mRunningTaskId;
 
-    protected final ClipAnimationHelper mClipAnimationHelper;
+    protected final AppWindowAnimationHelper mAppWindowAnimationHelper;
     protected final TransformParams mTransformParams = new TransformParams();
 
     private final Vibrator mVibrator;
@@ -144,7 +144,7 @@
                 this::createNewInputProxyHandler);
         mMode = SysUINavigationMode.getMode(context);
 
-        mClipAnimationHelper = new ClipAnimationHelper(context);
+        mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
         mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
         mVibrator = context.getSystemService(Vibrator.class);
         initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext)
@@ -220,7 +220,7 @@
             }
         });
         mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper);
-        mRecentsView.setClipAnimationHelper(mClipAnimationHelper);
+        mRecentsView.setAppWindowAnimationHelper(mAppWindowAnimationHelper);
     }
 
     protected void startNewTask(int successStateFlag, Consumer<Boolean> resultCallback) {
@@ -257,7 +257,7 @@
     }
 
     @Override
-    public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+    public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
         DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
         final Rect overviewStackBounds;
         RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId);
@@ -275,10 +275,10 @@
         dp.updateInsets(targetSet.homeContentInsets);
         dp.updateIsSeascape(mContext);
         if (runningTaskTarget != null) {
-            mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
+            mAppWindowAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
         }
 
-        mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */);
+        mAppWindowAnimationHelper.prepareAnimation(dp, false /* isOpening */);
         initTransitionEndpoints(dp);
 
         mRecentsAnimationWrapper.setController(targetSet);
@@ -306,9 +306,9 @@
             // screen of the launcher window may be stale (position is not updated until first
             // traversal after the window is resized).  We only do this for non-multiwindow because
             // we otherwise use the minimized home bounds provided by the system.
-            mClipAnimationHelper.updateHomeBounds(getStackBounds(dp));
+            mAppWindowAnimationHelper.updateHomeBounds(getStackBounds(dp));
         }
-        mClipAnimationHelper.updateTargetRect(TEMP_RECT);
+        mAppWindowAnimationHelper.updateTargetRect(TEMP_RECT);
         if (mMode == Mode.NO_BUTTON) {
             // We can drag all the way to the top of the screen.
             mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
@@ -366,13 +366,13 @@
         float shift = mCurrentShift.value;
         float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset();
         float offsetScale = getTaskCurveScaleForOffsetX(offsetX,
-                mClipAnimationHelper.getTargetRect().width());
+        mAppWindowAnimationHelper.getTargetRect().width());
         mTransformParams.setProgress(shift)
                 .setOffsetX(offsetX)
                 .setOffsetScale(offsetScale)
                 .setTargetSet(mRecentsAnimationWrapper.targetSet)
                 .setLauncherOnTop(true);
-        mClipAnimationHelper.applyTransform(mTransformParams);
+        mAppWindowAnimationHelper.applyTransform(mTransformParams);
     }
 
     private float getTaskCurveScaleForOffsetX(float offsetX, float taskWidth) {
@@ -388,9 +388,9 @@
      */
     protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
             HomeAnimationFactory homeAnimationFactory) {
-        final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
+        final RemoteAnimationTargets targetSet = mRecentsAnimationWrapper.targetSet;
         final RectF startRect = new RectF(
-                mClipAnimationHelper.applyTransform(
+                mAppWindowAnimationHelper.applyTransform(
                         mTransformParams.setProgress(startProgress)
                                 .setTargetSet(targetSet)
                                 .setLauncherOnTop(false)));
@@ -409,7 +409,7 @@
 
         // End on a "round-enough" radius so that the shape reveal doesn't have to do too much
         // rounding at the end of the animation.
-        float startRadius = mClipAnimationHelper.getCurrentCornerRadius();
+        float startRadius = mAppWindowAnimationHelper.getCurrentCornerRadius();
         float endRadius = startRect.width() / 6f;
         // We want the window alpha to be 0 once this threshold is met, so that the
         // FolderIconView can be seen morphing into the icon shape.
@@ -440,11 +440,11 @@
                     mTransformParams.setCornerRadius(endRadius * progress + startRadius
                             * (1f - progress));
                 }
-                mClipAnimationHelper.applyTransform(mTransformParams);
+                mAppWindowAnimationHelper.applyTransform(mTransformParams);
 
                 if (isFloatingIconView) {
                     ((FloatingIconView) floatingView).update(currentRect, 1f, progress,
-                            windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(),
+                            windowAlphaThreshold, mAppWindowAnimationHelper.getCurrentCornerRadius(),
                             false);
                 }
             }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
index 33180a9..04ece7c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -37,7 +37,7 @@
 import com.android.quickstep.fallback.FallbackRecentsView;
 import com.android.quickstep.util.ActivityInitListener;
 import com.android.quickstep.util.LayoutUtils;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
@@ -138,7 +138,7 @@
             boolean isAnimatingToRecents = false;
 
             @Override
-            public void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) {
+            public void onRemoteAnimationReceived(RemoteAnimationTargets targets) {
                 isAnimatingToRecents = targets != null && targets.isAnimatingHome();
                 if (!isAnimatingToRecents) {
                     rv.setContentAlpha(1);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index bb73521..c749761 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -38,7 +38,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.Region;
 import android.os.UserHandle;
 import android.view.MotionEvent;
 import android.view.View;
@@ -441,8 +440,8 @@
     }
 
     @Override
-    public boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
-        return activeNavBarRegion.contains((int) ev.getX(), (int) ev.getY());
+    public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
+        return deviceState.isInDeferredGestureRegion(ev);
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
index c4f375a..6ac7546 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -5,10 +5,12 @@
 import android.content.Context;
 import android.os.Bundle;
 
+import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.testing.TestInformationHandler;
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.uioverrides.states.OverviewState;
 import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
+import com.android.launcher3.util.DefaultDisplay;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.views.RecentsView;
 
@@ -78,7 +80,8 @@
     }
 
     private RecentsView getRecentsView() {
-        OverviewComponentObserver observer = new OverviewComponentObserver(mContext);
+        OverviewComponentObserver observer = new OverviewComponentObserver(mContext,
+                new RecentsAnimationDeviceState(mContext));
         try {
             return observer.getActivityControlHelper().getCreatedActivity().getOverviewPanel();
         } finally {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index 4a9aa2d..7b8ec4d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -42,7 +42,7 @@
 import com.android.launcher3.views.BaseDragLayer;
 import com.android.quickstep.fallback.FallbackRecentsView;
 import com.android.quickstep.fallback.RecentsRootView;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
@@ -177,7 +177,7 @@
             RemoteAnimationTargetCompat[] wallpaperTargets) {
         AnimatorSet target = new AnimatorSet();
         boolean activityClosing = taskIsATargetWithMode(appTargets, getTaskId(), MODE_CLOSING);
-        ClipAnimationHelper helper = new ClipAnimationHelper(this);
+        AppWindowAnimationHelper helper = new AppWindowAnimationHelper(this);
         target.play(getRecentsWindowAnimator(taskView, !activityClosing, appTargets,
                 wallpaperTargets, helper).setDuration(RECENTS_LAUNCH_DURATION));
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
index c4d3fa0..43c4a0b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -29,7 +29,7 @@
 
 import com.android.launcher3.util.Preconditions;
 import com.android.quickstep.inputconsumers.InputConsumer;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.RecentsAnimationTargets;
 import com.android.systemui.shared.system.InputConsumerController;
 
 import java.util.ArrayList;
@@ -46,7 +46,7 @@
     // than the state callbacks as these run on the current worker thread.
     private final ArrayList<Runnable> mCallbacks = new ArrayList<>();
 
-    public SwipeAnimationTargetSet targetSet;
+    public RecentsAnimationTargets targetSet;
 
     private boolean mWindowThresholdCrossed = false;
 
@@ -69,7 +69,7 @@
     }
 
     @UiThread
-    public synchronized void setController(SwipeAnimationTargetSet targetSet) {
+    public synchronized void setController(RecentsAnimationTargets targetSet) {
         Preconditions.assertUIThread();
         this.targetSet = targetSet;
 
@@ -127,7 +127,7 @@
 
     private void finishAndClear(boolean toRecents, Runnable onFinishComplete,
             boolean sendUserLeaveHint) {
-        SwipeAnimationTargetSet controller = targetSet;
+        RecentsAnimationTargets controller = targetSet;
         targetSet = null;
         disableInputProxy();
         if (controller != null) {
@@ -221,7 +221,7 @@
         }
     }
 
-    public SwipeAnimationTargetSet getController() {
+    public RecentsAnimationTargets getController() {
         return targetSet;
     }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
index 8301f36..6b98a89 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
@@ -22,9 +22,10 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.Preconditions;
-import com.android.quickstep.util.RecentsAnimationListenerSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.quickstep.util.RecentsAnimationCallbacks;
+import com.android.quickstep.util.RecentsAnimationTargets;
+import com.android.quickstep.util.RecentsAnimationCallbacks.RecentsAnimationListener;
+
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
 import java.io.PrintWriter;
@@ -32,12 +33,14 @@
 /**
  * Utility class used to store state information shared across multiple transitions.
  */
-public class SwipeSharedState implements SwipeAnimationListener {
+public class SwipeSharedState implements RecentsAnimationListener {
 
     private OverviewComponentObserver mOverviewComponentObserver;
 
-    private RecentsAnimationListenerSet mRecentsAnimationListener;
-    private SwipeAnimationTargetSet mLastAnimationTarget;
+    private RecentsAnimationCallbacks mRecentsAnimationListener;
+    private RecentsAnimationTargets mLastAnimationTarget;
+
+    // TODO: Remove
     private Runnable mRecentsAnimationCanceledCallback;
 
     private boolean mLastAnimationCancelled = false;
@@ -54,7 +57,7 @@
     }
 
     @Override
-    public final void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+    public final void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
         mLastAnimationTarget = targetSet;
 
         mLastAnimationCancelled = false;
@@ -113,13 +116,13 @@
         mLastAnimationRunning = false;
     }
 
-    private void onSwipeAnimationFinished(SwipeAnimationTargetSet targetSet) {
+    private void onSwipeAnimationFinished(RecentsAnimationTargets targetSet) {
         if (mLastAnimationTarget == targetSet) {
             mLastAnimationRunning = false;
         }
     }
 
-    public RecentsAnimationListenerSet newRecentsAnimationListenerSet() {
+    public RecentsAnimationCallbacks newRecentsAnimationListenerSet() {
         Preconditions.assertUIThread();
 
         if (mLastAnimationRunning) {
@@ -134,17 +137,17 @@
         clearListenerState(false /* finishAnimation */);
         boolean shouldMinimiseSplitScreen = mOverviewComponentObserver == null ? false
                 : mOverviewComponentObserver.getActivityControlHelper().shouldMinimizeSplitScreen();
-        mRecentsAnimationListener = new RecentsAnimationListenerSet(
+        mRecentsAnimationListener = new RecentsAnimationCallbacks(
                 shouldMinimiseSplitScreen, this::onSwipeAnimationFinished);
         mRecentsAnimationListener.addListener(this);
         return mRecentsAnimationListener;
     }
 
-    public RecentsAnimationListenerSet getActiveListener() {
+    public RecentsAnimationCallbacks getActiveListener() {
         return mRecentsAnimationListener;
     }
 
-    public void applyActiveRecentsAnimationState(SwipeAnimationListener listener) {
+    public void applyActiveRecentsAnimationState(RecentsAnimationListener listener) {
         if (mLastAnimationTarget != null) {
             listener.onRecentsAnimationStart(mLastAnimationTarget);
         } else if (mLastAnimationCancelled) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index b4a7996..b55fd8b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -31,9 +31,9 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Utilities;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
 import com.android.quickstep.util.MultiValueUpdateListener;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.Task;
@@ -118,16 +118,17 @@
      */
     public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
             RemoteAnimationTargetCompat[] appTargets,
-            RemoteAnimationTargetCompat[] wallpaperTargets, final ClipAnimationHelper inOutHelper) {
+            RemoteAnimationTargetCompat[] wallpaperTargets, final AppWindowAnimationHelper inOutHelper) {
         SyncRtSurfaceTransactionApplierCompat applier =
                 new SyncRtSurfaceTransactionApplierCompat(v);
-        final RemoteAnimationTargetSet targetSet =
-                new RemoteAnimationTargetSet(appTargets, wallpaperTargets, MODE_OPENING);
+        final RemoteAnimationTargets targetSet =
+                new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_OPENING);
         targetSet.addDependentTransactionApplier(applier);
-        ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
-                .setSyncTransactionApplier(applier)
-                .setTargetSet(targetSet)
-                .setLauncherOnTop(true);
+        AppWindowAnimationHelper.TransformParams params =
+                new AppWindowAnimationHelper.TransformParams()
+                    .setSyncTransactionApplier(applier)
+                    .setTargetSet(targetSet)
+                    .setLauncherOnTop(true);
 
         final RecentsView recentsView = v.getRecentsView();
         final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
@@ -165,19 +166,19 @@
                     // Append the surface transform params for the app that's being opened.
                     Collections.addAll(surfaceParamsList, inOutHelper.getSurfaceParams(params));
 
-                    ClipAnimationHelper liveTileClipAnimationHelper =
+                    AppWindowAnimationHelper liveTileAnimationHelper =
                             v.getRecentsView().getClipAnimationHelper();
-                    if (liveTileClipAnimationHelper != null) {
+                    if (liveTileAnimationHelper != null) {
                         // Append the surface transform params for the live tile app.
-                        ClipAnimationHelper.TransformParams liveTileParams =
+                        AppWindowAnimationHelper.TransformParams liveTileParams =
                                 v.getRecentsView().getLiveTileParams(true /* mightNeedToRefill */);
                         if (liveTileParams != null) {
                             Collections.addAll(surfaceParamsList,
-                                    liveTileClipAnimationHelper.getSurfaceParams(liveTileParams));
+                                    liveTileAnimationHelper.getSurfaceParams(liveTileParams));
                         }
                     }
                     // Apply surface transform using the surface params list.
-                    ClipAnimationHelper.applySurfaceParams(params.syncTransactionApplier,
+                    AppWindowAnimationHelper.applySurfaceParams(params.syncTransactionApplier,
                             surfaceParamsList.toArray(new SurfaceParams[surfaceParamsList.size()]));
                     // Get the task bounds for the app that's being opened after surface transform
                     // update.
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 7c1bc4e..4ca8055 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -27,15 +27,6 @@
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 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_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_QUICK_SETTINGS_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;
 
 import android.annotation.TargetApi;
@@ -43,48 +34,35 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.Service;
 import android.app.TaskInfo;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.RectF;
 import android.graphics.Region;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Process;
 import android.os.RemoteException;
-import android.text.TextUtils;
 import android.util.Log;
 import android.view.Choreographer;
 import android.view.InputEvent;
 import android.view.MotionEvent;
-import android.view.Surface;
 
-import androidx.annotation.BinderThread;
 import androidx.annotation.UiThread;
 import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.R;
-import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.logging.EventLogArray;
 import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.model.AppLaunchTracker;
 import com.android.launcher3.provider.RestoreDbTask;
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.uioverrides.DejankBinderTracker;
-import com.android.launcher3.util.DefaultDisplay;
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
 import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
-import com.android.quickstep.inputconsumers.AssistantTouchConsumer;
+import com.android.quickstep.inputconsumers.AssistantInputConsumer;
 import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
 import com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer;
 import com.android.quickstep.inputconsumers.InputConsumer;
@@ -99,10 +77,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 com.android.systemui.shared.system.RecentsAnimationListener;
-import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
 import com.android.systemui.shared.system.TaskInfoCompat;
 
 import java.io.FileDescriptor;
@@ -133,7 +108,7 @@
  */
 @TargetApi(Build.VERSION_CODES.Q)
 public class TouchInteractionService extends Service implements
-        NavigationModeChangeListener, DefaultDisplay.DisplayInfoChangeListener {
+        NavigationModeChangeListener {
 
     /**
      * NOTE: This value should be kept same as
@@ -154,10 +129,6 @@
 
     private final IBinder mMyBinder = new IOverviewProxy.Stub() {
 
-        public void onActiveNavBarRegionChanges(Region region) {
-            mActiveNavBarRegion = region;
-        }
-
         public void onInitialize(Bundle bundle) {
             mISystemUiProxy = ISystemUiProxy.Stub
                     .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
@@ -192,14 +163,14 @@
 
         @Override
         public void onAssistantAvailable(boolean available) {
-            mAssistantAvailable = available;
+            MAIN_EXECUTOR.execute(() -> mDeviceState.setAssistantAvailable(available));
+            MAIN_EXECUTOR.execute(TouchInteractionService.this::onAssistantVisibilityChanged);
         }
 
         @Override
         public void onAssistantVisibilityChanged(float visibility) {
-            mLastAssistantVisibility = visibility;
-            MAIN_EXECUTOR.execute(
-                    TouchInteractionService.this::onAssistantVisibilityChanged);
+            MAIN_EXECUTOR.execute(() -> mDeviceState.setAssistantVisibility(visibility));
+            MAIN_EXECUTOR.execute(TouchInteractionService.this::onAssistantVisibilityChanged);
         }
 
         public void onBackAction(boolean completed, int downX, int downY, boolean isButton,
@@ -219,10 +190,14 @@
         }
 
         public void onSystemUiStateChanged(int stateFlags) {
-            mSystemUiStateFlags = stateFlags;
+            MAIN_EXECUTOR.execute(() -> mDeviceState.setSystemUiFlags(stateFlags));
             MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged);
         }
 
+        public void onActiveNavBarRegionChanges(Region region) {
+            MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
+        }
+
         /** Deprecated methods **/
         public void onQuickStep(MotionEvent motionEvent) { }
 
@@ -272,71 +247,28 @@
     private OverviewCommandHelper mOverviewCommandHelper;
     private OverviewComponentObserver mOverviewComponentObserver;
     private OverviewInteractionState mOverviewInteractionState;
-    private TaskOverlayFactory mTaskOverlayFactory;
     private InputConsumerController mInputConsumer;
-    private boolean mAssistantAvailable;
-    private float mLastAssistantVisibility = 0;
-    private @SystemUiStateFlags int mSystemUiStateFlags;
-
-    private boolean mIsUserUnlocked;
-    private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
-                initWhenUserUnlocked();
-            }
-        }
-    };
+    private RecentsAnimationDeviceState mDeviceState;
 
     private InputConsumer mUncheckedConsumer = InputConsumer.NO_OP;
     private InputConsumer mConsumer = InputConsumer.NO_OP;
     private Choreographer mMainChoreographer;
 
-    private Region mActiveNavBarRegion = new Region();
-
     private InputMonitorCompat mInputMonitorCompat;
     private InputEventReceiver mInputEventReceiver;
     private Mode mMode = Mode.THREE_BUTTONS;
-    private int mDefaultDisplayId;
-    private final RectF mSwipeTouchRegion = new RectF();
-    private final RectF mAssistantLeftRegion = new RectF();
-    private final RectF mAssistantRightRegion = new RectF();
-
-    private ComponentName mGestureBlockingActivity;
-
-    private Region mExclusionRegion;
-    private SystemGestureExclusionListenerCompat mExclusionListener;
 
     @Override
     public void onCreate() {
         super.onCreate();
+        mDeviceState = new RecentsAnimationDeviceState(this);
+        mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
 
         // Initialize anything here that is needed in direct boot mode.
-        // Everything else should be initialized in initWhenUserUnlocked() below.
+        // Everything else should be initialized in onUserUnlocked() below.
         mMainChoreographer = Choreographer.getInstance();
         mAM = ActivityManagerWrapper.getInstance();
 
-        if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) {
-            initWhenUserUnlocked();
-        } else {
-            mIsUserUnlocked = false;
-            registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
-        }
-
-        mDefaultDisplayId = DefaultDisplay.INSTANCE.get(this).getInfo().id;
-        String blockingActivity = getString(R.string.gesture_blocking_activity);
-        mGestureBlockingActivity = TextUtils.isEmpty(blockingActivity) ? null :
-                ComponentName.unflattenFromString(blockingActivity);
-
-        mExclusionListener = new SystemGestureExclusionListenerCompat(mDefaultDisplayId) {
-            @Override
-            @BinderThread
-            public void onExclusionChanged(Region region) {
-                // Assignments are atomic, it should be safe on binder thread
-                mExclusionRegion = region;
-            }
-        };
-
         onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this));
         sConnected = true;
     }
@@ -359,17 +291,18 @@
         if (TestProtocol.sDebugTracing) {
             Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 1");
         }
+        disposeEventHandlers();
         if (!mMode.hasGestures || mISystemUiProxy == null) {
             return;
         }
-        disposeEventHandlers();
         if (TestProtocol.sDebugTracing) {
             Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 2");
         }
 
         try {
             mInputMonitorCompat = InputMonitorCompat.fromBundle(mISystemUiProxy
-                    .monitorGestureInput("swipe-up", mDefaultDisplayId), KEY_EXTRA_INPUT_MONITOR);
+                    .monitorGestureInput("swipe-up", mDeviceState.getDisplayId()),
+                    KEY_EXTRA_INPUT_MONITOR);
             mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
                     mMainChoreographer, this::onInputEvent);
             if (TestProtocol.sDebugTracing) {
@@ -378,55 +311,8 @@
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to create input monitor", e);
         }
-        initTouchBounds();
-    }
 
-    private int getNavbarSize(String resName) {
-        return ResourceUtils.getNavbarSize(resName, getResources());
-    }
-
-    private void initTouchBounds() {
-        if (!mMode.hasGestures) {
-            return;
-        }
-
-        DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(this).getInfo();
-        Point realSize = new Point(displayInfo.realSize);
-        mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y);
-        if (mMode == Mode.NO_BUTTON) {
-            int touchHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
-            mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - touchHeight;
-
-            final int assistantWidth = getResources()
-                    .getDimensionPixelSize(R.dimen.gestures_assistant_width);
-            final float assistantHeight = Math.max(touchHeight,
-                    QuickStepContract.getWindowCornerRadius(getResources()));
-            mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = mSwipeTouchRegion.bottom;
-            mAssistantLeftRegion.top = mAssistantRightRegion.top =
-                    mSwipeTouchRegion.bottom - assistantHeight;
-
-            mAssistantLeftRegion.left = 0;
-            mAssistantLeftRegion.right = assistantWidth;
-
-            mAssistantRightRegion.right = mSwipeTouchRegion.right;
-            mAssistantRightRegion.left = mSwipeTouchRegion.right - assistantWidth;
-        } else {
-            mAssistantLeftRegion.setEmpty();
-            mAssistantRightRegion.setEmpty();
-            switch (displayInfo.rotation) {
-                case Surface.ROTATION_90:
-                    mSwipeTouchRegion.left = mSwipeTouchRegion.right
-                            - getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
-                    break;
-                case Surface.ROTATION_270:
-                    mSwipeTouchRegion.right = mSwipeTouchRegion.left
-                            + getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
-                    break;
-                default:
-                    mSwipeTouchRegion.top = mSwipeTouchRegion.bottom
-                            - getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
-            }
-        }
+        mDeviceState.updateGestureTouchRegions();
     }
 
     @Override
@@ -434,43 +320,17 @@
         if (TestProtocol.sDebugTracing) {
             Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onNavigationModeChanged " + newMode);
         }
-        if (mMode.hasGestures != newMode.hasGestures) {
-            if (newMode.hasGestures) {
-                DefaultDisplay.INSTANCE.get(this).addChangeListener(this);
-            } else {
-                DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
-            }
-        }
         mMode = newMode;
-
-        disposeEventHandlers();
         initInputMonitor();
-
-        if (mMode == Mode.NO_BUTTON) {
-            mExclusionListener.register();
-        } else {
-            mExclusionListener.unregister();
-        }
     }
 
-    @Override
-    public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
-        if (info.id != mDefaultDisplayId) {
-            return;
-        }
-
-        initTouchBounds();
-    }
-
-    private void initWhenUserUnlocked() {
+    public void onUserUnlocked() {
         mRecentsModel = RecentsModel.INSTANCE.get(this);
-        mOverviewComponentObserver = new OverviewComponentObserver(this);
+        mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
 
         mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
         mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
-        mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
         mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
-        mIsUserUnlocked = true;
 
         sSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver);
         mInputConsumer.registerInputConsumer();
@@ -482,13 +342,11 @@
         // new ModelPreload().start(this);
         mBackGestureNotificationCounter = Math.max(0, Utilities.getDevicePrefs(this)
                 .getInt(KEY_BACK_NOTIFICATION_COUNT, MAX_BACK_NOTIFICATION_COUNT));
-
-        Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
     }
 
     @UiThread
     private void onSystemUiProxySet() {
-        if (mIsUserUnlocked) {
+        if (mDeviceState.isUserUnlocked()) {
             mRecentsModel.setSystemUiProxy(mISystemUiProxy);
             mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
         }
@@ -496,37 +354,32 @@
 
     @UiThread
     private void onSystemUiFlagsChanged() {
-        if (mIsUserUnlocked) {
-            mOverviewInteractionState.setSystemUiStateFlags(mSystemUiStateFlags);
-            mOverviewComponentObserver.onSystemUiStateChanged(mSystemUiStateFlags);
+        if (mDeviceState.isUserUnlocked()) {
+            mOverviewInteractionState.setSystemUiStateFlags(mDeviceState.getSystemUiStateFlags());
+            mOverviewComponentObserver.onSystemUiStateChanged();
         }
     }
 
     @UiThread
     private void onAssistantVisibilityChanged() {
-        if (mIsUserUnlocked) {
+        if (mDeviceState.isUserUnlocked()) {
             mOverviewComponentObserver.getActivityControlHelper().onAssistantVisibilityChanged(
-                    mLastAssistantVisibility);
+                    mDeviceState.getAssistantVisibility());
         }
     }
 
     @Override
     public void onDestroy() {
         sIsInitialized = false;
-        if (mIsUserUnlocked) {
+        if (mDeviceState.isUserUnlocked()) {
             mInputConsumer.unregisterInputConsumer();
             mOverviewComponentObserver.onDestroy();
         }
         disposeEventHandlers();
-        if (mMode.hasGestures) {
-            DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
-        }
+        SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
+        mDeviceState.destroy();
 
         sConnected = false;
-        Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
-        SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
-        mExclusionListener.unregister();
-
         super.onDestroy();
     }
 
@@ -551,19 +404,19 @@
             mLogId = TOUCH_INTERACTION_LOG.generateAndSetLogId();
             sSwipeSharedState.setLogTraceId(mLogId);
 
-            if (mSwipeTouchRegion.contains(event.getX(), event.getY())) {
+            if (mDeviceState.isInSwipeUpTouchRegion(event)) {
                 boolean useSharedState = mConsumer.useSharedSwipeState();
                 mConsumer.onConsumerAboutToBeSwitched();
                 mConsumer = newConsumer(useSharedState, event);
                 TOUCH_INTERACTION_LOG.addLog("setInputConsumer", mConsumer.getType());
                 mUncheckedConsumer = mConsumer;
-            } else if (mIsUserUnlocked && mMode == Mode.NO_BUTTON
-                    && canTriggerAssistantAction(event)) {
+            } else if (mDeviceState.isUserUnlocked() && mMode == Mode.NO_BUTTON
+                    && mDeviceState.canTriggerAssistantAction(event)) {
                 // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we should
                 // not interrupt it. QuickSwitch assumes that interruption can only happen if the
                 // next gesture is also quick switch.
                 mUncheckedConsumer =
-                        new AssistantTouchConsumer(this, mISystemUiProxy,
+                        new AssistantInputConsumer(this, mISystemUiProxy,
                                 mOverviewComponentObserver.getActivityControlHelper(),
                                 InputConsumer.NO_OP, mInputMonitorCompat);
             } else {
@@ -576,27 +429,11 @@
         DejankBinderTracker.disallowBinderTrackingInTests();
     }
 
-    private boolean validSystemUiFlags() {
-        return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
-                && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
-                && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
-                && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
-                        || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
-    }
-
-    private boolean canTriggerAssistantAction(MotionEvent ev) {
-        return mAssistantAvailable
-                && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
-                && (mAssistantLeftRegion.contains(ev.getX(), ev.getY()) ||
-                    mAssistantRightRegion.contains(ev.getX(), ev.getY()))
-                && !ActivityManagerWrapper.getInstance().isLockToAppActive();
-    }
-
     private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) {
-        boolean isInValidSystemUiState = validSystemUiFlags();
+        boolean canStartSystemGesture = mDeviceState.canStartSystemGesture();
 
-        if (!mIsUserUnlocked) {
-            if (isInValidSystemUiState) {
+        if (!mDeviceState.isUserUnlocked()) {
+            if (canStartSystemGesture) {
                 // This handles apps launched in direct boot mode (e.g. dialer) as well as apps
                 // launched while device is locked even after exiting direct boot mode (e.g. camera).
                 return createDeviceLockedInputConsumer(mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
@@ -607,29 +444,28 @@
 
         // When using sharedState, bypass systemState check as this is a followup gesture and the
         // first gesture started in a valid system state.
-        InputConsumer base = isInValidSystemUiState || useSharedState
+        InputConsumer base = canStartSystemGesture || useSharedState
                 ? newBaseConsumer(useSharedState, event) : mResetGestureInputConsumer;
         if (mMode == Mode.NO_BUTTON) {
             final ActivityControlHelper activityControl =
                     mOverviewComponentObserver.getActivityControlHelper();
-            if (canTriggerAssistantAction(event)) {
-                base = new AssistantTouchConsumer(this, mISystemUiProxy, activityControl, base,
+            if (mDeviceState.canTriggerAssistantAction(event)) {
+                base = new AssistantInputConsumer(this, mISystemUiProxy, activityControl, base,
                         mInputMonitorCompat);
             }
 
-            if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
+            if (mDeviceState.isScreenPinningActive()) {
                 // 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);
             }
 
-            if ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) {
-                base = new AccessibilityInputConsumer(this, mISystemUiProxy,
-                        (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0, base,
-                        mInputMonitorCompat, mSwipeTouchRegion);
+            if (mDeviceState.isAccessibilityMenuAvailable()) {
+                base = new AccessibilityInputConsumer(this, mDeviceState, mISystemUiProxy, base,
+                        mInputMonitorCompat);
             }
         } else {
-            if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
+            if (mDeviceState.isScreenPinningActive()) {
                 base = mResetGestureInputConsumer;
             }
         }
@@ -642,7 +478,7 @@
         if (!useSharedState) {
             sSwipeSharedState.clearAllState(false /* finishAnimation */);
         }
-        if ((mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0) {
+        if (mDeviceState.isKeyguardShowingOccluded()) {
             // This handles apps showing over the lockscreen (e.g. camera)
             return createDeviceLockedInputConsumer(runningTaskInfo);
         }
@@ -678,8 +514,7 @@
             return createOverviewInputConsumer(event);
         } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
             return createOverviewInputConsumer(event);
-        } else if (mGestureBlockingActivity != null && runningTaskInfo != null
-                && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
+        } else if (mDeviceState.isGestureBlockedActivity(runningTaskInfo)) {
             return mResetGestureInputConsumer;
         } else {
             return createOtherActivityInputConsumer(event, runningTaskInfo);
@@ -692,13 +527,6 @@
                 && (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
     }
 
-    private boolean disableHorizontalSwipe(MotionEvent event) {
-        // mExclusionRegion can change on binder thread, use a local instance here.
-        Region exclusionRegion = mExclusionRegion;
-        return mMode == Mode.NO_BUTTON && exclusionRegion != null
-                && exclusionRegion.contains((int) event.getX(), (int) event.getY());
-    }
-
     private InputConsumer createOtherActivityInputConsumer(MotionEvent event,
             RunningTaskInfo runningTaskInfo) {
 
@@ -711,19 +539,20 @@
             shouldDefer = !sSwipeSharedState.recentsAnimationFinishInterrupted;
             factory = mFallbackNoButtonFactory;
         } else {
-            shouldDefer = activityControlHelper.deferStartingActivity(mActiveNavBarRegion, event);
+            shouldDefer = activityControlHelper.deferStartingActivity(mDeviceState, event);
             factory = mWindowTreansformFactory;
         }
 
-        return new OtherActivityInputConsumer(this, runningTaskInfo, shouldDefer,
-                this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
-                disableHorizontalSwipe(event), activityControlHelper, factory, mLogId);
+        final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
+        return new OtherActivityInputConsumer(this, mDeviceState, runningTaskInfo, shouldDefer,
+                this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat,
+                disableHorizontalSwipe, activityControlHelper, factory, mLogId);
     }
 
     private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
         if (mMode == Mode.NO_BUTTON && taskInfo != null) {
-            return new DeviceLockedInputConsumer(this, sSwipeSharedState, mInputMonitorCompat,
-                    mSwipeTouchRegion, taskInfo.taskId, mLogId);
+            return new DeviceLockedInputConsumer(this, mDeviceState, sSwipeSharedState,
+                    mInputMonitorCompat, taskInfo.taskId, mLogId);
         } else {
             return mResetGestureInputConsumer;
         }
@@ -741,8 +570,9 @@
             return new OverviewInputConsumer(activity, mInputMonitorCompat,
                     false /* startingInActivityBounds */, activityControl);
         } else {
+            final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
             return new OverviewWithoutFocusInputConsumer(activity, mInputMonitorCompat,
-                    activityControl, disableHorizontalSwipe(event));
+                    activityControl, disableHorizontalSwipe);
         }
     }
 
@@ -757,7 +587,7 @@
     }
 
     private void preloadOverview(boolean fromInit) {
-        if (!mIsUserUnlocked) {
+        if (!mDeviceState.isUserUnlocked()) {
             return;
         }
         if (!mMode.hasGestures && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
@@ -793,7 +623,7 @@
 
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
-        if (!mIsUserUnlocked) {
+        if (!mDeviceState.isUserUnlocked()) {
             return;
         }
         final ActivityControlHelper activityControl =
@@ -826,15 +656,9 @@
             }
         } else {
             // Dump everything
+            mDeviceState.dump(pw);
             pw.println("TouchState:");
             pw.println("  navMode=" + mMode);
-            pw.println("  validSystemUiFlags=" + validSystemUiFlags());
-            pw.println("  systemUiFlags=" + mSystemUiStateFlags);
-            pw.println("  systemUiFlagsDesc="
-                    + QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
-            pw.println("  assistantAvailable=" + mAssistantAvailable);
-            pw.println("  assistantDisabled="
-                    + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
             boolean resumed = mOverviewComponentObserver != null
                     && mOverviewComponentObserver.getActivityControlHelper().isResumed();
             pw.println("  resumed=" + resumed);
@@ -870,7 +694,7 @@
 
     private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask,
             long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) {
-        return  new WindowTransformSwipeHandler(runningTask, this, touchTimeMs,
+        return  new WindowTransformSwipeHandler(mDeviceState, runningTask, this, touchTimeMs,
                 mOverviewComponentObserver, continuingLastGesture, mInputConsumer, mRecentsModel);
     }
 
@@ -882,7 +706,7 @@
 
     protected boolean shouldNotifyBackGesture() {
         return mBackGestureNotificationCounter > 0 &&
-                mGestureBlockingActivity != null;
+                mDeviceState.getGestureBlockedActivityPackage() != null;
     }
 
     @WorkerThread
@@ -892,7 +716,7 @@
             Utilities.getDevicePrefs(this).edit()
                     .putInt(KEY_BACK_NOTIFICATION_COUNT, mBackGestureNotificationCounter).apply();
             sendBroadcast(new Intent(NOTIFY_ACTION_BACK).setPackage(
-                    mGestureBlockingActivity.getPackageName()));
+                    mDeviceState.getGestureBlockedActivityPackage()));
         }
     }
 
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 5c90d71..5cf987a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -35,7 +35,6 @@
 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;
@@ -79,9 +78,9 @@
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.inputconsumers.InputConsumer;
 import com.android.quickstep.inputconsumers.OverviewInputConsumer;
-import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider;
+import com.android.quickstep.util.AppWindowAnimationHelper.TargetAlphaProvider;
 import com.android.quickstep.util.RectFSpringAnim;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.RecentsAnimationTargets;
 import com.android.quickstep.views.LiveTileOverlay;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
@@ -198,6 +197,8 @@
      */
     private static final int LOG_NO_OP_PAGE_INDEX = -1;
 
+    private RecentsAnimationDeviceState mDeviceState;
+
     private GestureEndTarget mGestureEndTarget;
     // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
     private RunningWindowAnim mRunningWindowAnim;
@@ -229,11 +230,12 @@
     private final long mTouchTimeMs;
     private long mLauncherFrameDrawnTime;
 
-    public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context,
-            long touchTimeMs, OverviewComponentObserver overviewComponentObserver,
-            boolean continuingLastGesture,
+    public WindowTransformSwipeHandler(RecentsAnimationDeviceState deviceState,
+            RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs,
+            OverviewComponentObserver overviewComponentObserver, boolean continuingLastGesture,
             InputConsumerController inputConsumer, RecentsModel recentsModel) {
         super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id);
+        mDeviceState = deviceState;
         mTouchTimeMs = touchTimeMs;
         mContinuingLastGesture = continuingLastGesture;
         initStateCallbacks();
@@ -547,7 +549,7 @@
     @Override
     public void updateFinalShift() {
 
-        SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController();
+        RecentsAnimationTargets controller = mRecentsAnimationWrapper.getController();
         if (controller != null) {
             applyTransformUnchecked();
             updateSysUiFlags(mCurrentShift.value);
@@ -555,8 +557,8 @@
 
         if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
             if (mRecentsAnimationWrapper.getController() != null) {
-                mLiveTileOverlay.update(mClipAnimationHelper.getCurrentRectWithInsets(),
-                        mClipAnimationHelper.getCurrentCornerRadius());
+                mLiveTileOverlay.update(mAppWindowAnimationHelper.getCurrentRectWithInsets(),
+                        mAppWindowAnimationHelper.getCurrentCornerRadius());
             }
         }
 
@@ -605,7 +607,7 @@
     }
 
     @Override
-    public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+    public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
         super.onRecentsAnimationStart(targetSet);
         TOUCH_INTERACTION_LOG.addLog("startRecentsAnimationCallback", targetSet.apps.length);
         setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
@@ -755,9 +757,7 @@
             }
         }
 
-        int stateFlags = OverviewInteractionState.INSTANCE.get(mActivity).getSystemUiStateFlags();
-        if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0
-                && (endTarget == RECENTS || endTarget == LAST_TASK)) {
+        if (mDeviceState.isOverviewDisabled() && (endTarget == RECENTS || endTarget == LAST_TASK)) {
             return LAST_TASK;
         }
         return endTarget;
@@ -886,7 +886,7 @@
                     @NonNull
                     @Override
                     public RectF getWindowTargetRect() {
-                        RectF fallbackTarget = new RectF(mClipAnimationHelper.getTargetRect());
+                        RectF fallbackTarget = new RectF(mAppWindowAnimationHelper.getTargetRect());
                         Utilities.scaleRectFAboutCenter(fallbackTarget, 0.25f);
                         return fallbackTarget;
                     }
@@ -1108,7 +1108,7 @@
     }
 
     private void switchToScreenshot() {
-        SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController();
+        RecentsAnimationTargets controller = mRecentsAnimationWrapper.getController();
         if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
             if (controller != null) {
                 // Update the screenshot of the task
@@ -1191,7 +1191,7 @@
     }
 
     private void setTargetAlphaProvider(TargetAlphaProvider provider) {
-        mClipAnimationHelper.setTaskAlphaCallback(provider);
+        mAppWindowAnimationHelper.setTaskAlphaCallback(provider);
         updateFinalShift();
     }
 
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 7f1aae5..79e71a1 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
@@ -142,7 +142,7 @@
             mZoomTranslationY = 0f;
         } else {
             TaskView dummyTask = getTaskViewAt(0);
-            ScaleAndTranslation sat = getTempClipAnimationHelper()
+            ScaleAndTranslation sat = getTempAppWindowAnimationHelper()
                     .updateForFullscreenOverview(dummyTask)
                     .getScaleAndTranslation();
             mZoomScale = sat.scale;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
index 1f73a28..92bcfb5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
@@ -23,7 +23,6 @@
 import static android.view.MotionEvent.ACTION_UP;
 
 import android.content.Context;
-import android.graphics.RectF;
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.Display;
@@ -32,12 +31,13 @@
 import android.view.ViewConfiguration;
 
 import com.android.launcher3.R;
+import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
 /**
- * Touch consumer for two finger swipe actions for accessibility actions
+ * Input consumer for two finger swipe actions for accessibility actions
  */
 public class AccessibilityInputConsumer extends DelegateInputConsumer {
 
@@ -46,8 +46,7 @@
     private final ISystemUiProxy mSystemUiProxy;
     private final VelocityTracker mVelocityTracker;
     private final MotionPauseDetector mMotionPauseDetector;
-    private final boolean mAllowLongClick;
-    private final RectF mSwipeTouchRegion;
+    private final RecentsAnimationDeviceState mDeviceState;
 
     private final float mMinGestureDistance;
     private final float mMinFlingVelocity;
@@ -56,19 +55,17 @@
     private float mDownY;
     private float mTotalY;
 
-    public AccessibilityInputConsumer(Context context, ISystemUiProxy systemUiProxy,
-            boolean allowLongClick, InputConsumer delegate, InputMonitorCompat inputMonitor,
-            RectF swipeTouchRegion) {
+    public AccessibilityInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
+            ISystemUiProxy systemUiProxy, InputConsumer delegate, InputMonitorCompat inputMonitor) {
         super(delegate, inputMonitor);
         mSystemUiProxy = systemUiProxy;
         mVelocityTracker = VelocityTracker.obtain();
         mMinGestureDistance = context.getResources()
                 .getDimension(R.dimen.accessibility_gesture_min_swipe_distance);
         mMinFlingVelocity = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
-        mSwipeTouchRegion = swipeTouchRegion;
+        mDeviceState = deviceState;
 
         mMotionPauseDetector = new MotionPauseDetector(context);
-        mAllowLongClick = allowLongClick;
     }
 
     @Override
@@ -103,7 +100,7 @@
             case ACTION_POINTER_DOWN: {
                 if (mState == STATE_INACTIVE) {
                     int pointerIndex = ev.getActionIndex();
-                    if (mSwipeTouchRegion.contains(ev.getX(pointerIndex), ev.getY(pointerIndex))
+                    if (mDeviceState.isInSwipeUpTouchRegion(ev, pointerIndex)
                             && mDelegate.allowInterceptByParent()) {
                         setActive(ev);
 
@@ -116,7 +113,7 @@
                 break;
             }
             case ACTION_MOVE: {
-                if (mState == STATE_ACTIVE && mAllowLongClick) {
+                if (mState == STATE_ACTIVE && mDeviceState.isAccessibilityMenuShortcutAvailable()) {
                     int pointerIndex = ev.findPointerIndex(mActivePointerId);
                     if (pointerIndex == -1) {
                         break;
@@ -130,7 +127,8 @@
             case ACTION_UP:
                 if (mState == STATE_ACTIVE) {
                     try {
-                        if (mAllowLongClick && mMotionPauseDetector.isPaused()) {
+                        if (mDeviceState.isAccessibilityMenuShortcutAvailable()
+                                && mMotionPauseDetector.isPaused()) {
                             mSystemUiProxy.notifyAccessibilityButtonLongClicked();
                         } else {
                             mTotalY += (ev.getY() - mDownY);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
similarity index 98%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index 346969e..a2a1c43 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -57,9 +57,9 @@
 /**
  * Touch consumer for handling events to launch assistant from launcher
  */
-public class AssistantTouchConsumer extends DelegateInputConsumer {
+public class AssistantInputConsumer extends DelegateInputConsumer {
 
-    private static final String TAG = "AssistantTouchConsumer";
+    private static final String TAG = "AssistantInputConsumer";
     private static final long RETRACT_ANIMATION_DURATION_MS = 300;
 
     // From //java/com/google/android/apps/gsa/search/shared/util/OpaContract.java.
@@ -92,7 +92,7 @@
     private final Context mContext;
     private final GestureDetector mGestureDetector;
 
-    public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy,
+    public AssistantInputConsumer(Context context, ISystemUiProxy systemUiProxy,
             ActivityControlHelper activityControlHelper, InputConsumer delegate,
             InputMonitorCompat inputMonitor) {
         super(delegate, inputMonitor);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index d11afaf..ba2d6d1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -32,7 +32,6 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
@@ -42,10 +41,12 @@
 import com.android.launcher3.util.DefaultDisplay;
 import com.android.quickstep.LockScreenRecentsActivity;
 import com.android.quickstep.MultiStateCallback;
+import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.SwipeSharedState;
-import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.RecentsAnimationListenerSet;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.AppWindowAnimationHelper;
+import com.android.quickstep.util.RecentsAnimationCallbacks;
+import com.android.quickstep.util.RecentsAnimationTargets;
+
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.InputMonitorCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -54,7 +55,7 @@
  * A dummy input consumer used when the device is still locked, e.g. from secure camera.
  */
 public class DeviceLockedInputConsumer implements InputConsumer,
-        SwipeAnimationTargetSet.SwipeAnimationListener {
+        RecentsAnimationCallbacks.RecentsAnimationListener {
 
     private static final float SCALE_DOWN = 0.75f;
 
@@ -72,17 +73,17 @@
             getFlagForIndex(1, "STATE_HANDLER_INVALIDATED");
 
     private final Context mContext;
+    private final RecentsAnimationDeviceState mDeviceState;
     private final float mTouchSlopSquared;
     private final SwipeSharedState mSwipeSharedState;
     private final InputMonitorCompat mInputMonitorCompat;
 
     private final PointF mTouchDown = new PointF();
-    private final ClipAnimationHelper mClipAnimationHelper;
+    private final AppWindowAnimationHelper mAppWindowAnimationHelper;
     private int mLogId;
-    private final ClipAnimationHelper.TransformParams mTransformParams;
+    private final AppWindowAnimationHelper.TransformParams mTransformParams;
     private final Point mDisplaySize;
     private final MultiStateCallback mStateCallback;
-    private final RectF mSwipeTouchRegion;
     public final int mRunningTaskId;
 
     private VelocityTracker mVelocityTracker;
@@ -90,19 +91,19 @@
 
     private boolean mThresholdCrossed = false;
 
-    private SwipeAnimationTargetSet mTargetSet;
+    private RecentsAnimationTargets mTargetSet;
 
-    public DeviceLockedInputConsumer(Context context, SwipeSharedState swipeSharedState,
-            InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, int runningTaskId,
-            int logId) {
+    public DeviceLockedInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
+            SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
+            int runningTaskId, int logId) {
         mContext = context;
+        mDeviceState = deviceState;
         mTouchSlopSquared = squaredTouchSlop(context);
         mSwipeSharedState = swipeSharedState;
-        mClipAnimationHelper = new ClipAnimationHelper(context);
+        mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
         mLogId = logId;
-        mTransformParams = new ClipAnimationHelper.TransformParams();
+        mTransformParams = new AppWindowAnimationHelper.TransformParams();
         mInputMonitorCompat = inputMonitorCompat;
-        mSwipeTouchRegion = swipeTouchRegion;
         mRunningTaskId = runningTaskId;
 
         // Do not use DeviceProfile as the user data might be locked
@@ -138,7 +139,7 @@
                 if (!mThresholdCrossed) {
                     // Cancel interaction in case of multi-touch interaction
                     int ptrIdx = ev.getActionIndex();
-                    if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
+                    if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
                         int action = ev.getAction();
                         ev.setAction(ACTION_CANCEL);
                         finishTouchTracking(ev);
@@ -156,7 +157,7 @@
                     float dy = Math.max(mTouchDown.y - y, 0);
                     mProgress = dy / mDisplaySize.y;
                     mTransformParams.setProgress(mProgress);
-                    mClipAnimationHelper.applyTransform(mTransformParams);
+                    mAppWindowAnimationHelper.applyTransform(mTransformParams);
                 }
                 break;
             }
@@ -201,7 +202,7 @@
 
     private void startRecentsTransition() {
         mThresholdCrossed = true;
-        RecentsAnimationListenerSet newListenerSet =
+        RecentsAnimationCallbacks newListenerSet =
                 mSwipeSharedState.newRecentsAnimationListenerSet();
         newListenerSet.addListener(this);
         Intent intent = new Intent(Intent.ACTION_MAIN)
@@ -215,20 +216,21 @@
     }
 
     @Override
-    public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+    public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
         mTargetSet = targetSet;
 
         Rect displaySize = new Rect(0, 0, mDisplaySize.x, mDisplaySize.y);
         RemoteAnimationTargetCompat targetCompat = targetSet.findTask(mRunningTaskId);
         if (targetCompat != null) {
-            mClipAnimationHelper.updateSource(displaySize, targetCompat);
+            mAppWindowAnimationHelper.updateSource(displaySize, targetCompat);
         }
 
         Utilities.scaleRectAboutCenter(displaySize, SCALE_DOWN);
         displaySize.offsetTo(displaySize.left, 0);
-        mClipAnimationHelper.updateTargetRect(displaySize);
-        mTransformParams.setTargetSet(mTargetSet).setLauncherOnTop(true);
-        mClipAnimationHelper.applyTransform(mTransformParams);
+        mTransformParams.setTargetSet(mTargetSet)
+                .setLauncherOnTop(true);
+        mAppWindowAnimationHelper.updateTargetRect(displaySize);
+        mAppWindowAnimationHelper.applyTransform(mTransformParams);
 
         mStateCallback.setState(STATE_TARGET_RECEIVED);
     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
index 629d240..59efb2d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
@@ -49,7 +49,7 @@
 import com.android.quickstep.SwipeSharedState;
 import com.android.quickstep.fallback.FallbackRecentsView;
 import com.android.quickstep.util.RectFSpringAnim;
-import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.util.RecentsAnimationTargets;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -127,9 +127,9 @@
         mSwipeUpOverHome = mRunningOverHome && !mInQuickSwitchMode;
 
         if (mSwipeUpOverHome) {
-            mClipAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
+            mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value);
         } else {
-            mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
+            mAppWindowAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value);
         }
 
         initStateCallbacks();
@@ -414,12 +414,12 @@
     }
 
     @Override
-    public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) {
+    public void onRecentsAnimationStart(RecentsAnimationTargets targetSet) {
         super.onRecentsAnimationStart(targetSet);
         mRecentsAnimationWrapper.enableInputConsumer();
 
         if (mRunningOverHome) {
-            mClipAnimationHelper.prepareAnimation(mDp, true);
+            mAppWindowAnimationHelper.prepareAnimation(mDp, true);
         }
         applyTransformUnchecked();
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index f06702d..6776e84 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -38,7 +38,6 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.graphics.PointF;
-import android.graphics.RectF;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -55,13 +54,14 @@
 import com.android.quickstep.ActivityControlHelper;
 import com.android.quickstep.BaseSwipeUpHandler;
 import com.android.quickstep.BaseSwipeUpHandler.Factory;
+import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.SwipeSharedState;
 import com.android.quickstep.SysUINavigationMode;
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.util.CachedEventDispatcher;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.quickstep.util.NavBarPosition;
-import com.android.quickstep.util.RecentsAnimationListenerSet;
+import com.android.quickstep.util.RecentsAnimationCallbacks;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
@@ -79,12 +79,12 @@
     // TODO: Move to quickstep contract
     public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3;
 
+    private final RecentsAnimationDeviceState mDeviceState;
     private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
     private final RunningTaskInfo mRunningTask;
     private final SwipeSharedState mSwipeSharedState;
     private final InputMonitorCompat mInputMonitorCompat;
     private final SysUINavigationMode.Mode mMode;
-    private final RectF mSwipeTouchRegion;
     private final ActivityControlHelper mActivityControlHelper;
 
     private final BaseSwipeUpHandler.Factory mHandlerFactory;
@@ -124,19 +124,19 @@
     };
     private int mLogId;
 
-    public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo,
-            boolean isDeferredDownTarget, Consumer<OtherActivityInputConsumer> onCompleteCallback,
+    public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState,
+            RunningTaskInfo runningTaskInfo, boolean isDeferredDownTarget,
+            Consumer<OtherActivityInputConsumer> onCompleteCallback,
             SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
-            RectF swipeTouchRegion, boolean disableHorizontalSwipe,
-            ActivityControlHelper activityControlHelper,
+            boolean disableHorizontalSwipe, ActivityControlHelper activityControlHelper,
             Factory handlerFactory, int logId) {
         super(base);
         mLogId = logId;
 
+        mDeviceState = deviceState;
         mMainThreadHandler = new Handler(Looper.getMainLooper());
         mRunningTask = runningTaskInfo;
         mMode = SysUINavigationMode.getMode(base);
-        mSwipeTouchRegion = swipeTouchRegion;
         mHandlerFactory = handlerFactory;
         mActivityControlHelper = activityControlHelper;
 
@@ -217,7 +217,7 @@
                 if (!mPassedPilferInputSlop) {
                     // Cancel interaction in case of multi-touch interaction
                     int ptrIdx = ev.getActionIndex();
-                    if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
+                    if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
                         forceCancelGesture(ev);
                     }
                 }
@@ -329,7 +329,7 @@
             long touchTimeMs, boolean isLikelyToStartNewTask) {
         TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
 
-        RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
+        RecentsAnimationCallbacks listenerSet = mSwipeSharedState.getActiveListener();
         final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs,
                 listenerSet != null, isLikelyToStartNewTask);
 
@@ -343,7 +343,7 @@
             mSwipeSharedState.applyActiveRecentsAnimationState(handler);
             notifyGestureStarted();
         } else {
-            RecentsAnimationListenerSet newListenerSet =
+            RecentsAnimationCallbacks newListenerSet =
                     mSwipeSharedState.newRecentsAnimationListenerSet();
             newListenerSet.addListener(handler);
             Intent intent = handler.getLaunchIntent();
@@ -416,7 +416,7 @@
     }
 
     private void removeListener() {
-        RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
+        RecentsAnimationCallbacks listenerSet = mSwipeSharedState.getActiveListener();
         if (listenerSet != null) {
             listenerSet.removeListener(mInteractionHandler);
         }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
similarity index 98%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index 587e9f2..dddfc8d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -50,13 +50,11 @@
 import com.android.systemui.shared.system.TransactionCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
-import java.util.function.BiFunction;
-
 /**
  * Utility class to handle window clip animation
  */
 @TargetApi(Build.VERSION_CODES.P)
-public class ClipAnimationHelper {
+public class AppWindowAnimationHelper {
 
     // The bounds of the source app in device coordinates
     private final Rect mSourceStackBounds = new Rect();
@@ -102,7 +100,7 @@
     private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a;
     private TargetAlphaProvider mBaseAlphaCallback = (t, a) -> 1;
 
-    public ClipAnimationHelper(Context context) {
+    public AppWindowAnimationHelper(Context context) {
         mWindowCornerRadius = getWindowCornerRadius(context.getResources());
         mSupportsRoundedCornersOnWindows = supportsRoundedCornersOnWindows(context.getResources());
         mTaskCornerRadius = TaskCornerRadius.get(context);
@@ -319,7 +317,7 @@
     /**
      * Compute scale and translation y such that the specified task view fills the screen.
      */
-    public ClipAnimationHelper updateForFullscreenOverview(TaskView v) {
+    public AppWindowAnimationHelper updateForFullscreenOverview(TaskView v) {
         TaskThumbnailView thumbnailView = v.getThumbnail();
         RecentsView recentsView = v.getRecentsView();
         fromTaskThumbnailView(thumbnailView, recentsView);
@@ -395,7 +393,7 @@
         float cornerRadius;
         boolean launcherOnTop;
 
-        public RemoteAnimationTargetSet targetSet;
+        public RemoteAnimationTargets targetSet;
         public SyncRtSurfaceTransactionApplierCompat syncTransactionApplier;
 
         public TransformParams() {
@@ -446,7 +444,7 @@
             return this;
         }
 
-        public TransformParams setTargetSet(RemoteAnimationTargetSet targetSet) {
+        public TransformParams setTargetSet(RemoteAnimationTargets targetSet) {
             this.targetSet = targetSet;
             return this;
         }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationCallbacks.java
similarity index 69%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationCallbacks.java
index 41017ca..415f767 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationCallbacks.java
@@ -26,30 +26,29 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.Preconditions;
 import com.android.quickstep.TouchInteractionService;
-import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
-import com.android.systemui.shared.system.RecentsAnimationListener;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
 import java.util.Set;
 import java.util.function.Consumer;
 
 /**
- * Wrapper around {@link RecentsAnimationListener} which delegates callbacks to multiple listeners
+ * Wrapper around {@link com.android.systemui.shared.system.RecentsAnimationListener} which delegates callbacks to multiple listeners
  * on the main thread
  */
-public class RecentsAnimationListenerSet implements RecentsAnimationListener {
+public class RecentsAnimationCallbacks implements
+        com.android.systemui.shared.system.RecentsAnimationListener {
 
-    private final Set<SwipeAnimationListener> mListeners = new ArraySet<>();
+    private final Set<RecentsAnimationListener> mListeners = new ArraySet<>();
     private final boolean mShouldMinimizeSplitScreen;
-    private final Consumer<SwipeAnimationTargetSet> mOnFinishListener;
+    private final Consumer<RecentsAnimationTargets> mOnFinishListener;
     private RecentsAnimationControllerCompat mController;
 
     private boolean mCancelled;
 
-    public RecentsAnimationListenerSet(boolean shouldMinimizeSplitScreen,
-            Consumer<SwipeAnimationTargetSet> onFinishListener) {
+    public RecentsAnimationCallbacks(boolean shouldMinimizeSplitScreen,
+            Consumer<RecentsAnimationTargets> onFinishListener) {
         mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen;
         mOnFinishListener = onFinishListener;
         TouchInteractionService.getSwipeSharedState().setRecentsAnimationCanceledCallback(
@@ -57,13 +56,13 @@
     }
 
     @UiThread
-    public void addListener(SwipeAnimationListener listener) {
+    public void addListener(RecentsAnimationListener listener) {
         Preconditions.assertUIThread();
         mListeners.add(listener);
     }
 
     @UiThread
-    public void removeListener(SwipeAnimationListener listener) {
+    public void removeListener(RecentsAnimationListener listener) {
         Preconditions.assertUIThread();
         mListeners.remove(listener);
     }
@@ -75,7 +74,7 @@
             RemoteAnimationTargetCompat[] wallpaperTargets,
             Rect homeContentInsets, Rect minimizedHomeBounds) {
         mController = controller;
-        SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, appTargets,
+        RecentsAnimationTargets targetSet = new RecentsAnimationTargets(controller, appTargets,
                 wallpaperTargets, homeContentInsets, minimizedHomeBounds,
                 mShouldMinimizeSplitScreen, mOnFinishListener);
 
@@ -83,7 +82,7 @@
             targetSet.cancelAnimation();
         } else {
             Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
-                for (SwipeAnimationListener listener : getListeners()) {
+                for (RecentsAnimationListener listener : getListeners()) {
                     listener.onRecentsAnimationStart(targetSet);
                 }
             });
@@ -104,18 +103,31 @@
     @Override
     public final void onAnimationCanceled(ThumbnailData thumbnailData) {
         Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
-            for (SwipeAnimationListener listener : getListeners()) {
+            for (RecentsAnimationListener listener : getListeners()) {
                 listener.onRecentsAnimationCanceled(thumbnailData);
             }
         });
     }
 
-    private SwipeAnimationListener[] getListeners() {
-        return mListeners.toArray(new SwipeAnimationListener[mListeners.size()]);
+    private RecentsAnimationListener[] getListeners() {
+        return mListeners.toArray(new RecentsAnimationListener[mListeners.size()]);
     }
 
     public void cancelListener() {
         mCancelled = true;
         onAnimationCanceled(null);
     }
+
+    /**
+     * Listener for the recents animation callbacks.
+     */
+    public interface RecentsAnimationListener {
+        void onRecentsAnimationStart(RecentsAnimationTargets targetSet);
+
+        /**
+         * Callback from the system when the recents animation is canceled. {@param thumbnailData}
+         * is passed back for rendering screenshot to replace live tile.
+         */
+        void onRecentsAnimationCanceled(ThumbnailData thumbnailData);
+    }
 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationTargets.java
similarity index 82%
rename from quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
rename to quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationTargets.java
index 5ab335a..187a404 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationTargets.java
@@ -28,22 +28,22 @@
 import java.util.function.Consumer;
 
 /**
- * Extension of {@link RemoteAnimationTargetSet} with additional information about swipe
+ * Extension of {@link RemoteAnimationTargets} with additional information about swipe
  * up animation
  */
-public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet {
+public class RecentsAnimationTargets extends RemoteAnimationTargets {
 
     private final boolean mShouldMinimizeSplitScreen;
-    private final Consumer<SwipeAnimationTargetSet> mOnFinishListener;
+    private final Consumer<RecentsAnimationTargets> mOnFinishListener;
 
     public final RecentsAnimationControllerCompat controller;
     public final Rect homeContentInsets;
     public final Rect minimizedHomeBounds;
 
-    public SwipeAnimationTargetSet(RecentsAnimationControllerCompat controller,
+    public RecentsAnimationTargets(RecentsAnimationControllerCompat controller,
             RemoteAnimationTargetCompat[] apps, RemoteAnimationTargetCompat[] wallpapers,
             Rect homeContentInsets, Rect minimizedHomeBounds, boolean shouldMinimizeSplitScreen,
-            Consumer<SwipeAnimationTargetSet> onFinishListener) {
+            Consumer<RecentsAnimationTargets> onFinishListener) {
         super(apps, wallpapers, MODE_CLOSING);
         this.controller = controller;
         this.homeContentInsets = homeContentInsets;
@@ -60,8 +60,8 @@
      * Clones the target set without any actual targets. Used only when continuing a gesture after
      * the actual recents animation has finished.
      */
-    public SwipeAnimationTargetSet cloneWithoutTargets() {
-        return new SwipeAnimationTargetSet(controller, new RemoteAnimationTargetCompat[0],
+    public RecentsAnimationTargets cloneWithoutTargets() {
+        return new RecentsAnimationTargets(controller, new RemoteAnimationTargetCompat[0],
                 new RemoteAnimationTargetCompat[0], homeContentInsets, minimizedHomeBounds,
                 mShouldMinimizeSplitScreen, mOnFinishListener);
     }
@@ -109,15 +109,4 @@
     public void finishAnimation() {
         finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
     }
-
-    public interface SwipeAnimationListener {
-
-        void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet);
-
-        /**
-         * Callback from the system when the recents animation is canceled. {@param thumbnailData}
-         * is passed back for rendering screenshot to replace live tile.
-         */
-        void onRecentsAnimationCanceled(ThumbnailData thumbnailData);
-    }
 }
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 8651095..0f9184f 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
@@ -48,8 +48,8 @@
 import com.android.launcher3.uioverrides.DejankBinderTracker;
 import com.android.launcher3.views.ScrimView;
 import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.util.ClipAnimationHelper;
-import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
+import com.android.quickstep.util.AppWindowAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
 import com.android.quickstep.util.LayoutUtils;
 
 /**
@@ -120,7 +120,7 @@
      */
     @Override
     public AnimatorSet createAdjacentPageAnimForTaskLaunch(TaskView tv,
-            ClipAnimationHelper helper) {
+            AppWindowAnimationHelper helper) {
         AnimatorSet anim = super.createAdjacentPageAnimForTaskLaunch(tv, helper);
 
         if (!SysUINavigationMode.getMode(mActivity).hasGestures) {
@@ -178,7 +178,7 @@
                 mTransformParams.setProgress(1 - progress)
                         .setSyncTransactionApplier(mSyncTransactionApplier)
                         .setForLiveTile(true);
-                mClipAnimationHelper.applyTransform(mTransformParams);
+                mAppWindowAnimationHelper.applyTransform(mTransformParams);
             } else {
                 redrawLiveTile(true);
             }
@@ -211,17 +211,17 @@
 
     @Override
     public void redrawLiveTile(boolean mightNeedToRefill) {
-        ClipAnimationHelper.TransformParams transformParams = getLiveTileParams(mightNeedToRefill);
+        AppWindowAnimationHelper.TransformParams transformParams = getLiveTileParams(mightNeedToRefill);
         if (transformParams != null) {
-            mClipAnimationHelper.applyTransform(transformParams);
+            mAppWindowAnimationHelper.applyTransform(transformParams);
         }
     }
 
     @Override
-    public ClipAnimationHelper.TransformParams getLiveTileParams(
+    public AppWindowAnimationHelper.TransformParams getLiveTileParams(
             boolean mightNeedToRefill) {
         if (!mEnableDrawingLiveTile || mRecentsAnimationWrapper == null
-                || mClipAnimationHelper == null) {
+                || mAppWindowAnimationHelper == null) {
             return null;
         }
         TaskView taskView = getRunningTaskView();
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 c69bcb6..cefe264 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
@@ -107,7 +107,7 @@
 import com.android.quickstep.TaskThumbnailCache;
 import com.android.quickstep.TaskUtils;
 import com.android.quickstep.ViewUtils;
-import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.AppWindowAnimationHelper;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -156,7 +156,7 @@
             };
 
     protected RecentsAnimationWrapper mRecentsAnimationWrapper;
-    protected ClipAnimationHelper mClipAnimationHelper;
+    protected AppWindowAnimationHelper mAppWindowAnimationHelper;
     protected SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
     protected int mTaskWidth;
     protected int mTaskHeight;
@@ -176,7 +176,7 @@
     private final ClearAllButton mClearAllButton;
     private final Rect mClearAllButtonDeadZoneRect = new Rect();
     private final Rect mTaskViewDeadZoneRect = new Rect();
-    protected final ClipAnimationHelper mTempClipAnimationHelper;
+    protected final AppWindowAnimationHelper mTempAppWindowAnimationHelper;
 
     private final ScrollState mScrollState = new ScrollState();
     // Keeps track of the previously known visible tasks for purposes of loading/unloading task data
@@ -327,7 +327,7 @@
         mActivity = (T) BaseActivity.fromContext(context);
         mModel = RecentsModel.INSTANCE.get(context);
         mIdp = InvariantDeviceProfile.INSTANCE.get(context);
-        mTempClipAnimationHelper = new ClipAnimationHelper(context);
+        mTempAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
 
         mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
                 .inflate(R.layout.overview_clear_all_button, this, false);
@@ -808,7 +808,7 @@
         mTaskListChangeId = -1;
 
         mRecentsAnimationWrapper = null;
-        mClipAnimationHelper = null;
+        mAppWindowAnimationHelper = null;
 
         unloadVisibleTaskData();
         setCurrentPage(0);
@@ -1519,14 +1519,14 @@
      * to the right.
      */
     public AnimatorSet createAdjacentPageAnimForTaskLaunch(
-            TaskView tv, ClipAnimationHelper clipAnimationHelper) {
+            TaskView tv, AppWindowAnimationHelper appWindowAnimationHelper) {
         AnimatorSet anim = new AnimatorSet();
 
         int taskIndex = indexOfChild(tv);
         int centerTaskIndex = getCurrentPage();
         boolean launchingCenterTask = taskIndex == centerTaskIndex;
 
-        LauncherState.ScaleAndTranslation toScaleAndTranslation = clipAnimationHelper
+        LauncherState.ScaleAndTranslation toScaleAndTranslation = appWindowAnimationHelper
                 .getScaleAndTranslation();
         float toScale = toScaleAndTranslation.scale;
         float toTranslationY = toScaleAndTranslation.translationY;
@@ -1586,10 +1586,10 @@
             }
         });
 
-        ClipAnimationHelper clipAnimationHelper = new ClipAnimationHelper(mActivity);
-        clipAnimationHelper.fromTaskThumbnailView(tv.getThumbnail(), this);
-        clipAnimationHelper.prepareAnimation(mActivity.getDeviceProfile(), true /* isOpening */);
-        AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv, clipAnimationHelper);
+        AppWindowAnimationHelper appWindowAnimationHelper = new AppWindowAnimationHelper(mActivity);
+        appWindowAnimationHelper.fromTaskThumbnailView(tv.getThumbnail(), this);
+        appWindowAnimationHelper.prepareAnimation(mActivity.getDeviceProfile(), true /* isOpening */);
+        AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv, appWindowAnimationHelper);
         anim.play(progressAnim);
         anim.setDuration(duration);
 
@@ -1696,8 +1696,8 @@
         mRecentsAnimationWrapper = recentsAnimationWrapper;
     }
 
-    public void setClipAnimationHelper(ClipAnimationHelper clipAnimationHelper) {
-        mClipAnimationHelper = clipAnimationHelper;
+    public void setAppWindowAnimationHelper(AppWindowAnimationHelper appWindowAnimationHelper) {
+        mAppWindowAnimationHelper = appWindowAnimationHelper;
     }
 
     public void setLiveTileOverlay(LiveTileOverlay liveTileOverlay) {
@@ -1805,15 +1805,15 @@
         }
     }
 
-    public ClipAnimationHelper getClipAnimationHelper() {
-        return mClipAnimationHelper;
+    public AppWindowAnimationHelper getClipAnimationHelper() {
+        return mAppWindowAnimationHelper;
     }
 
-    public ClipAnimationHelper getTempClipAnimationHelper() {
-        return mTempClipAnimationHelper;
+    public AppWindowAnimationHelper getTempAppWindowAnimationHelper() {
+        return mTempAppWindowAnimationHelper;
     }
 
-    public ClipAnimationHelper.TransformParams getLiveTileParams(
+    public AppWindowAnimationHelper.TransformParams getLiveTileParams(
             boolean mightNeedToRefill) {
         return null;
     }
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 7cd8786..af75364 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -71,7 +71,7 @@
 import com.android.launcher3.views.FloatingIconView;
 import com.android.quickstep.util.MultiValueUpdateListener;
 import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
 import com.android.systemui.shared.system.ActivityCompat;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
 import com.android.systemui.shared.system.QuickStepContract;
@@ -433,7 +433,7 @@
         Rect crop = new Rect();
         Matrix matrix = new Matrix();
 
-        RemoteAnimationTargetSet openingTargets = new RemoteAnimationTargetSet(appTargets,
+        RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets,
                 wallpaperTargets, MODE_OPENING);
         SyncRtSurfaceTransactionApplierCompat surfaceApplier =
                 new SyncRtSurfaceTransactionApplierCompat(floatingView);
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 27b94f0..132d6ab 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.Region;
 import android.os.Build;
 import android.view.MotionEvent;
 import android.view.View;
@@ -33,7 +32,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.quickstep.util.ActivityInitListener;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.util.RemoteAnimationTargets;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
@@ -81,7 +80,7 @@
 
     boolean shouldMinimizeSplitScreen();
 
-    default boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
+    default boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
         return true;
     }
 
@@ -112,7 +111,7 @@
             public final boolean shouldPreformHaptic;
         }
 
-        default void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) { }
+        default void onRemoteAnimationReceived(RemoteAnimationTargets targets) { }
 
         void createActivityController(long transitionLength);
 
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 88a4eb6..331183a 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -22,7 +22,6 @@
 
 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;
@@ -57,6 +56,7 @@
         }
     };
     private final Context mContext;
+    private final RecentsAnimationDeviceState mDeviceState;
     private final Intent mCurrentHomeIntent;
     private final Intent mMyHomeIntent;
     private final Intent mFallbackIntent;
@@ -64,12 +64,13 @@
     private String mUpdateRegisteredPackage;
     private ActivityControlHelper mActivityControlHelper;
     private Intent mOverviewIntent;
-    private int mSystemUiStateFlags;
     private boolean mIsHomeAndOverviewSame;
     private boolean mIsDefaultHome;
+    private boolean mIsHomeDisabled;
 
-    public OverviewComponentObserver(Context context) {
+    public OverviewComponentObserver(Context context, RecentsAnimationDeviceState deviceState) {
         mContext = context;
+        mDeviceState = deviceState;
 
         mCurrentHomeIntent = new Intent(Intent.ACTION_MAIN)
                 .addCategory(Intent.CATEGORY_HOME)
@@ -98,11 +99,8 @@
         updateOverviewTargets();
     }
 
-    public void onSystemUiStateChanged(int stateFlags) {
-        boolean homeDisabledChanged = (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED)
-                != (stateFlags & SYSUI_STATE_HOME_DISABLED);
-        mSystemUiStateFlags = stateFlags;
-        if (homeDisabledChanged) {
+    public void onSystemUiStateChanged() {
+        if (mDeviceState.isHomeDisabled() != mIsHomeDisabled) {
             updateOverviewTargets();
         }
     }
@@ -115,6 +113,7 @@
         ComponentName defaultHome = PackageManagerWrapper.getInstance()
                 .getHomeActivities(new ArrayList<>());
 
+        mIsHomeDisabled = mDeviceState.isHomeDisabled();
         mIsDefaultHome = Objects.equals(mMyHomeIntent.getComponent(), defaultHome);
 
         // Set assistant visibility to 0 from launcher's perspective, ensures any elements that
@@ -124,8 +123,7 @@
             mActivityControlHelper.onAssistantVisibilityChanged(0.f);
         }
 
-        if ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
-                && (defaultHome == null || mIsDefaultHome)) {
+        if (!mDeviceState.isHomeDisabled() && (defaultHome == null || mIsDefaultHome)) {
             // User default home is same as out home app. Use Overview integrated in Launcher.
             mActivityControlHelper = new LauncherActivityControllerHelper();
             mIsHomeAndOverviewSame = true;
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 858c3b6..17462ab 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -86,6 +86,7 @@
         mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
     }
 
+    // TODO(141886704): See if we can remove this
     public void setSystemUiStateFlags(int stateFlags) {
         mSystemUiStateFlags = stateFlags;
     }
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
new file mode 100644
index 0000000..9b094f6
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static android.content.Intent.ACTION_USER_UNLOCKED;
+import static com.android.launcher3.ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE;
+import static com.android.launcher3.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
+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_QUICK_SETTINGS_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.os.Process;
+import android.text.TextUtils;
+import android.view.MotionEvent;
+import android.view.Surface;
+import androidx.annotation.BinderThread;
+import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.DefaultDisplay;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Manages the state of the system during a swipe up gesture.
+ */
+public class RecentsAnimationDeviceState implements
+        SysUINavigationMode.NavigationModeChangeListener,
+        DefaultDisplay.DisplayInfoChangeListener {
+
+    private Context mContext;
+    private UserManagerCompat mUserManager;
+    private SysUINavigationMode mSysUiNavMode;
+    private DefaultDisplay mDefaultDisplay;
+    private int mDisplayId;
+
+    private @SystemUiStateFlags int mSystemUiStateFlags;
+    private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
+
+    private final RectF mSwipeUpTouchRegion = new RectF();
+    private final Region mDeferredGestureRegion = new Region();
+    private final RectF mAssistantLeftRegion = new RectF();
+    private final RectF mAssistantRightRegion = new RectF();
+    private boolean mAssistantAvailable;
+    private float mAssistantVisibility;
+
+    private boolean mIsUserUnlocked;
+    private final ArrayList<Runnable> mUserUnlockedActions = new ArrayList<>();
+    private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+                mIsUserUnlocked = true;
+                notifyUserUnlocked();
+            }
+        }
+    };
+
+    private Region mExclusionRegion;
+    private SystemGestureExclusionListenerCompat mExclusionListener;
+
+    private ComponentName mGestureBlockedActivity;
+
+    public RecentsAnimationDeviceState(Context context) {
+        mContext = context;
+        mUserManager = UserManagerCompat.getInstance(context);
+        mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
+        mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
+        mDisplayId = mDefaultDisplay.getInfo().id;
+
+        // Register for user unlocked if necessary
+        mIsUserUnlocked = mUserManager.isUserUnlocked(Process.myUserHandle());
+        if (!mIsUserUnlocked) {
+            mContext.registerReceiver(mUserUnlockedReceiver,
+                    new IntentFilter(ACTION_USER_UNLOCKED));
+        }
+
+        // Register for exclusion updates
+        mExclusionListener = new SystemGestureExclusionListenerCompat(mDisplayId) {
+            @Override
+            @BinderThread
+            public void onExclusionChanged(Region region) {
+                // Assignments are atomic, it should be safe on binder thread
+                mExclusionRegion = region;
+            }
+        };
+        onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
+
+        // Add any blocked activities
+        String blockingActivity = context.getString(R.string.gesture_blocking_activity);
+        if (!TextUtils.isEmpty(blockingActivity)) {
+            mGestureBlockedActivity = ComponentName.unflattenFromString(blockingActivity);
+        }
+    }
+
+    /**
+     * Cleans up all the registered listeners and receivers.
+     */
+    public void destroy() {
+        Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver);
+        mSysUiNavMode.removeModeChangeListener(this);
+        mDefaultDisplay.removeChangeListener(this);
+        mExclusionListener.unregister();
+    }
+
+    @Override
+    public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
+        mDefaultDisplay.removeChangeListener(this);
+        if (newMode.hasGestures) {
+            mDefaultDisplay.addChangeListener(this);
+        }
+
+        if (mMode == NO_BUTTON) {
+            mExclusionListener.register();
+        } else {
+            mExclusionListener.unregister();
+        }
+        mMode = newMode;
+    }
+
+    @Override
+    public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
+        if (info.id != getDisplayId()) {
+            return;
+        }
+
+        updateGestureTouchRegions();
+    }
+
+    /**
+     * @return the display id for the display that Launcher is running on.
+     */
+    public int getDisplayId() {
+        return mDisplayId;
+    }
+
+    /**
+     * Adds a callback for when a user is unlocked. If the user is already unlocked, this listener
+     * will be called back immediately.
+     */
+    public void runOnUserUnlocked(Runnable action) {
+        if (mIsUserUnlocked) {
+            action.run();
+        } else {
+            mUserUnlockedActions.add(action);
+        }
+    }
+
+    /**
+     * @return whether the user is unlocked.
+     */
+    public boolean isUserUnlocked() {
+        return mIsUserUnlocked;
+    }
+
+    private void notifyUserUnlocked() {
+        for (Runnable action : mUserUnlockedActions) {
+            action.run();
+        }
+        mUserUnlockedActions.clear();
+        Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver);
+    }
+
+    /**
+     * @return whether the given running task info matches the gesture-blocked activity.
+     */
+    public boolean isGestureBlockedActivity(ActivityManager.RunningTaskInfo runningTaskInfo) {
+        return runningTaskInfo != null
+                && mGestureBlockedActivity.equals(runningTaskInfo.topActivity);
+    }
+
+    /**
+     * @return the package of the gesture-blocked activity or {@code null} if there is none.
+     */
+    public String getGestureBlockedActivityPackage() {
+        return (mGestureBlockedActivity != null)
+                ? mGestureBlockedActivity.getPackageName()
+                : null;
+    }
+
+    /**
+     * Updates the system ui state flags from SystemUI.
+     */
+    public void setSystemUiFlags(int stateFlags) {
+        mSystemUiStateFlags = stateFlags;
+    }
+
+    /**
+     * @return the system ui state flags.
+     */
+    // TODO(141886704): See if we can remove this
+    public @SystemUiStateFlags int getSystemUiStateFlags() {
+        return mSystemUiStateFlags;
+    }
+
+    /**
+     * @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
+                && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
+                && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
+                && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
+                        || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
+    }
+
+    /**
+     * @return whether the keyguard is showing and is occluded by an app showing above the keyguard
+     *         (like camera or maps)
+     */
+    public boolean isKeyguardShowingOccluded() {
+        return (mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
+    }
+
+    /**
+     * @return whether screen pinning is enabled and active
+     */
+    public boolean isScreenPinningActive() {
+        return (mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
+    }
+
+    /**
+     * @return whether lock-task mode is active
+     */
+    public boolean isLockToAppActive() {
+        return ActivityManagerWrapper.getInstance().isLockToAppActive();
+    }
+
+    /**
+     * @return whether the accessibility menu is available.
+     */
+    public boolean isAccessibilityMenuAvailable() {
+        return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+    }
+
+    /**
+     * @return whether the accessibility menu shortcut is available.
+     */
+    public boolean isAccessibilityMenuShortcutAvailable() {
+        return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+    }
+
+    /**
+     * @return whether home is disabled (either by SUW/SysUI/device policy)
+     */
+    public boolean isHomeDisabled() {
+        return (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
+    }
+
+    /**
+     * @return whether overview is disabled (either by SUW/SysUI/device policy)
+     */
+    public boolean isOverviewDisabled() {
+        return (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+    }
+
+    /**
+     * Updates the regions for detecting the swipe up/quickswitch and assistant gestures.
+     */
+    public void updateGestureTouchRegions() {
+        if (!mMode.hasGestures) {
+            return;
+        }
+
+        Resources res = mContext.getResources();
+        DefaultDisplay.Info displayInfo = mDefaultDisplay.getInfo();
+        Point realSize = new Point(displayInfo.realSize);
+        mSwipeUpTouchRegion.set(0, 0, realSize.x, realSize.y);
+        if (mMode == NO_BUTTON) {
+            int touchHeight = ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE, res);
+            mSwipeUpTouchRegion.top = mSwipeUpTouchRegion.bottom - touchHeight;
+
+            final int assistantWidth = res.getDimensionPixelSize(R.dimen.gestures_assistant_width);
+            final float assistantHeight = Math.max(touchHeight,
+                    QuickStepContract.getWindowCornerRadius(res));
+            mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = mSwipeUpTouchRegion.bottom;
+            mAssistantLeftRegion.top = mAssistantRightRegion.top =
+                    mSwipeUpTouchRegion.bottom - assistantHeight;
+
+            mAssistantLeftRegion.left = 0;
+            mAssistantLeftRegion.right = assistantWidth;
+
+            mAssistantRightRegion.right = mSwipeUpTouchRegion.right;
+            mAssistantRightRegion.left = mSwipeUpTouchRegion.right - assistantWidth;
+        } else {
+            mAssistantLeftRegion.setEmpty();
+            mAssistantRightRegion.setEmpty();
+            switch (displayInfo.rotation) {
+                case Surface.ROTATION_90:
+                    mSwipeUpTouchRegion.left = mSwipeUpTouchRegion.right
+                            - ResourceUtils.getNavbarSize(NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE, res);
+                    break;
+                case Surface.ROTATION_270:
+                    mSwipeUpTouchRegion.right = mSwipeUpTouchRegion.left
+                            + ResourceUtils.getNavbarSize(NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE, res);
+                    break;
+                default:
+                    mSwipeUpTouchRegion.top = mSwipeUpTouchRegion.bottom
+                            - ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE, res);
+            }
+        }
+    }
+
+    /**
+     * @return whether the coordinates of the {@param event} is in the swipe up gesture region.
+     */
+    public boolean isInSwipeUpTouchRegion(MotionEvent event) {
+        return mSwipeUpTouchRegion.contains(event.getX(), event.getY());
+    }
+
+    /**
+     * @return whether the coordinates of the {@param event} with the given {@param pointerIndex}
+     *         is in the swipe up gesture region.
+     */
+    public boolean isInSwipeUpTouchRegion(MotionEvent event, int pointerIndex) {
+        return mSwipeUpTouchRegion.contains(event.getX(pointerIndex), event.getY(pointerIndex));
+    }
+
+    /**
+     * Sets the region in screen space where the gestures should be deferred (ie. due to specific
+     * nav bar ui).
+     */
+    public void setDeferredGestureRegion(Region deferredGestureRegion) {
+        mDeferredGestureRegion.set(deferredGestureRegion);
+    }
+
+    /**
+     * @return whether the given {@param event} is in the deferred gesture region indicating that
+     *         the Launcher should not immediately start the recents animation until the gesture
+     *         passes a certain threshold.
+     */
+    public boolean isInDeferredGestureRegion(MotionEvent event) {
+        return mDeferredGestureRegion.contains((int) event.getX(), (int) event.getY());
+    }
+
+    /**
+     * @return whether the given {@param event} is in the app-requested gesture-exclusion region.
+     *         This is only used for quickswitch, and not swipe up.
+     */
+    public boolean isInExclusionRegion(MotionEvent event) {
+        // mExclusionRegion can change on binder thread, use a local instance here.
+        Region exclusionRegion = mExclusionRegion;
+        return mMode == NO_BUTTON && exclusionRegion != null
+                && exclusionRegion.contains((int) event.getX(), (int) event.getY());
+    }
+
+    /**
+     * Sets whether the assistant is available.
+     */
+    public void setAssistantAvailable(boolean assistantAvailable) {
+        mAssistantAvailable = assistantAvailable;
+    }
+
+    /**
+     * Sets the visibility fraction of the assistant.
+     */
+    public void setAssistantVisibility(float visibility) {
+        mAssistantVisibility = visibility;
+    }
+
+    /**
+     * @return the visibility fraction of the assistant.
+     */
+    public float getAssistantVisibility() {
+        return mAssistantVisibility;
+    }
+
+    /**
+     * @param ev An ACTION_DOWN motion event
+     * @return whether the given motion event can trigger the assistant.
+     */
+    public boolean canTriggerAssistantAction(MotionEvent ev) {
+        return mAssistantAvailable
+                && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
+                && (mAssistantLeftRegion.contains(ev.getX(), ev.getY())
+                        || mAssistantRightRegion.contains(ev.getX(), ev.getY()))
+                && !isLockToAppActive();
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("DeviceState:");
+        pw.println("  canStartSystemGesture=" + canStartSystemGesture());
+        pw.println("  systemUiFlags=" + mSystemUiStateFlags);
+        pw.println("  systemUiFlagsDesc="
+                + QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
+        pw.println("  assistantAvailable=" + mAssistantAvailable);
+        pw.println("  assistantDisabled="
+                + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargets.java
similarity index 96%
rename from quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java
rename to quickstep/src/com/android/quickstep/util/RemoteAnimationTargets.java
index d769248..ff726a1 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargets.java
@@ -25,7 +25,7 @@
 /**
  * Holds a collection of RemoteAnimationTargets, filtered by different properties.
  */
-public class RemoteAnimationTargetSet {
+public class RemoteAnimationTargets {
 
     private final Queue<SyncRtSurfaceTransactionApplierCompat> mDependentTransactionAppliers =
             new ArrayDeque<>(1);
@@ -36,7 +36,7 @@
     public final int targetMode;
     public final boolean hasRecents;
 
-    public RemoteAnimationTargetSet(RemoteAnimationTargetCompat[] apps,
+    public RemoteAnimationTargets(RemoteAnimationTargetCompat[] apps,
             RemoteAnimationTargetCompat[] wallpapers, int targetMode) {
         ArrayList<RemoteAnimationTargetCompat> filteredApps = new ArrayList<>();
         boolean hasRecents = false;
diff --git a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
index 1d0851c..7f6aba9 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java
@@ -29,12 +29,12 @@
  */
 public class RemoteFadeOutAnimationListener implements AnimatorUpdateListener {
 
-    private final RemoteAnimationTargetSet mTarget;
+    private final RemoteAnimationTargets mTarget;
     private boolean mFirstFrame = true;
 
     public RemoteFadeOutAnimationListener(RemoteAnimationTargetCompat[] appTargets,
             RemoteAnimationTargetCompat[] wallpaperTargets) {
-        mTarget = new RemoteAnimationTargetSet(appTargets, wallpaperTargets, MODE_CLOSING);
+        mTarget = new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_CLOSING);
     }
 
     @Override