Moving SysUI with legacy Recents to another build target

- Move all legacy recents code out of the core sysui code
- Add separate target for products which still depend on it
- Move overview proxy implementation into another implementation of the
  recents interface

Test: atest SystemUITests
Test: Push SystemUiWithLegacyRecents to the system image
      adb shell pm disable com.google.android.apps.nexuslauncher/com.android.quickstep.TouchInteractionService
      and ensure that the old recents implementation still works (and split
      screen)

Change-Id: Iad67218ec37c13c79b6393d87f6bdc4f3996e2c6
Signed-off-by: Winson Chung <winsonc@google.com>
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index b0fe190..b7844bc 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -44,13 +44,14 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginInitializerImpl;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManagerImpl;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
 import com.android.systemui.power.PowerNotificationWarnings;
 import com.android.systemui.power.PowerUI;
-import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.shared.plugins.PluginManagerImpl;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
deleted file mode 100644
index fb343f9..0000000
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2013 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.systemui;
-
-import android.graphics.Rect;
-import android.view.Display;
-import android.view.View;
-
-public interface RecentsComponent {
-    void showRecentApps(boolean triggeredFromAltTab);
-
-    /**
-     * Docks the top-most task and opens recents.
-     */
-    boolean splitPrimaryTask(int stackCreateMode, Rect initialBounds,
-            int metricsDockAction);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java b/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
index 36dbb0f..e0fc31b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/BasePipManager.java
@@ -21,9 +21,11 @@
 
 import java.io.PrintWriter;
 
-public interface  BasePipManager {
+public interface BasePipManager {
     void initialize(Context context);
     void showPictureInPictureMenu();
+    default void expandPip() {}
+    default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {}
     void onConfigurationChanged(Configuration newConfig);
-    void dump(PrintWriter pw);
+    default void dump(PrintWriter pw) {}
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
index 864a6f9..70b581a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
@@ -24,8 +24,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import com.android.systemui.SystemUI;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.component.ExpandPipEvent;
 import com.android.systemui.statusbar.CommandQueue;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -68,7 +66,11 @@
     }
 
     public void expandPip() {
-        EventBus.getDefault().send(new ExpandPipEvent());
+        mPipManager.expandPip();
+    }
+
+    public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {
+        mPipManager.hidePipMenu(onStartCallback, onEndCallback);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 04746c1..08208e5 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -38,8 +38,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.pip.BasePipManager;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.component.ExpandPipEvent;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.InputConsumerController;
 import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -197,7 +195,6 @@
                 mMenuController, mInputConsumerController);
         mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
                 mTouchHandler.getMotionHelper());
-        EventBus.getDefault().register(this);
     }
 
     /**
@@ -210,11 +207,20 @@
     /**
      * Expands the PIP.
      */
-    public final void onBusEvent(ExpandPipEvent event) {
+    @Override
+    public void expandPip() {
         mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
     }
 
     /**
+     * Hides the PIP menu.
+     */
+    @Override
+    public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {
+        mMenuController.hideMenu(onStartCallback, onEndCallback);
+    }
+
+    /**
      * Sent from KEYCODE_WINDOW handler in PhoneWindowManager, to request the menu to be shown.
      */
     public void showPictureInPictureMenu() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 2dc531a..b746c19 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -72,8 +72,6 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.component.HidePipMenuEvent;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -151,7 +149,7 @@
                     cancelDelayedFinish();
                     break;
                 case MESSAGE_HIDE_MENU:
-                    hideMenu();
+                    hideMenu((Runnable) msg.obj);
                     break;
                 case MESSAGE_UPDATE_ACTIONS: {
                     final Bundle data = (Bundle) msg.obj;
@@ -275,7 +273,6 @@
         super.onStop();
 
         cancelDelayedFinish();
-        EventBus.getDefault().unregister(this);
     }
 
     @Override
@@ -335,19 +332,6 @@
         // Do nothing
     }
 
-    public final void onBusEvent(HidePipMenuEvent event) {
-        if (mMenuState != MENU_STATE_NONE) {
-            // If the menu is visible in either the closed or full state, then hide the menu and
-            // trigger the animation trigger afterwards
-            event.getAnimationTrigger().increment();
-            hideMenu(() -> {
-                mHandler.post(() -> {
-                    event.getAnimationTrigger().decrement();
-                });
-            }, true /* notifyMenuVisibility */, false /* isDismissing */);
-        }
-    }
-
     private void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
             boolean allowMenuTimeout, boolean resizeMenuOnShow) {
         mAllowMenuTimeout = allowMenuTimeout;
@@ -398,8 +382,11 @@
     }
 
     private void hideMenu() {
-        hideMenu(null /* animationFinishedRunnable */, true /* notifyMenuVisibility */,
-                false /* isDismissing */);
+        hideMenu(null);
+    }
+
+    private void hideMenu(Runnable animationEndCallback) {
+        hideMenu(animationEndCallback, true /* notifyMenuVisibility */, false /* isDismissing */);
     }
 
     private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
@@ -450,9 +437,6 @@
         }
         notifyActivityCallback(mMessenger);
 
-        // Register for HidePipMenuEvents once we notify the controller of this activity
-        EventBus.getDefault().register(this);
-
         ParceledListSlice actions = intent.getParcelableExtra(EXTRA_ACTIONS);
         if (actions != null) {
             mActions.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 360fe73..56b8324 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -19,9 +19,9 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 
-import android.app.ActivityTaskManager;
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
 import android.app.IActivityManager;
 import android.app.RemoteAction;
 import android.content.Context;
@@ -37,14 +37,8 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
-import android.view.IWindowManager;
-
 import com.android.systemui.pip.phone.PipMediaController.ActionListener;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.component.HidePipMenuEvent;
-import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.shared.system.InputConsumerController;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -131,7 +125,7 @@
     // The dismiss fraction update is sent frequently, so use a temporary bundle for the message
     private Bundle mTmpDismissFractionData = new Bundle();
 
-    private ReferenceCountedTrigger mOnAttachDecrementTrigger;
+    private Runnable mOnAnimationEndRunnable;
     private boolean mStartActivityRequested;
     private long mStartActivityRequestedTime;
     private Messenger mToActivityMessenger;
@@ -171,9 +165,9 @@
                 case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
                     mToActivityMessenger = msg.replyTo;
                     setStartActivityRequested(false);
-                    if (mOnAttachDecrementTrigger != null) {
-                        mOnAttachDecrementTrigger.decrement();
-                        mOnAttachDecrementTrigger = null;
+                    if (mOnAnimationEndRunnable != null) {
+                        mOnAnimationEndRunnable.run();
+                        mOnAnimationEndRunnable = null;
                     }
                     // Mark the menu as invisible once the activity finishes as well
                     if (mToActivityMessenger == null) {
@@ -188,9 +182,9 @@
 
     private Runnable mStartActivityRequestedTimeoutRunnable = () -> {
         setStartActivityRequested(false);
-        if (mOnAttachDecrementTrigger != null) {
-            mOnAttachDecrementTrigger.decrement();
-            mOnAttachDecrementTrigger = null;
+        if (mOnAnimationEndRunnable != null) {
+            mOnAnimationEndRunnable.run();
+            mOnAnimationEndRunnable = null;
         }
         Log.e(TAG, "Expected start menu activity request timed out");
     };
@@ -209,8 +203,6 @@
         mActivityManager = activityManager;
         mMediaController = mediaController;
         mInputConsumerController = inputConsumerController;
-
-        EventBus.getDefault().register(this);
     }
 
     public boolean isMenuActivityVisible() {
@@ -353,6 +345,36 @@
     }
 
     /**
+     * Hides the menu activity.
+     */
+    public void hideMenu(Runnable onStartCallback, Runnable onEndCallback) {
+        if (mStartActivityRequested) {
+            // If the menu has been start-requested, but not actually started, then we defer the
+            // trigger callback until the menu has started and called back to the controller.
+            mOnAnimationEndRunnable = onEndCallback;
+            onStartCallback.run();
+
+            // Fallback for b/63752800, we have started the PipMenuActivity but it has not made any
+            // callbacks. Don't continue to wait for the menu to show past some timeout.
+            mHandler.removeCallbacks(mStartActivityRequestedTimeoutRunnable);
+            mHandler.postDelayed(mStartActivityRequestedTimeoutRunnable,
+                    START_ACTIVITY_REQUEST_TIMEOUT_MS);
+        } else if (mMenuState != MENU_STATE_NONE && mToActivityMessenger != null) {
+            // If the menu is visible in either the closed or full state, then hide the menu and
+            // trigger the animation trigger afterwards
+            onStartCallback.run();
+            Message m = Message.obtain();
+            m.what = PipMenuActivity.MESSAGE_HIDE_MENU;
+            m.obj = onEndCallback;
+            try {
+                mToActivityMessenger.send(m);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not notify hide menu", e);
+            }
+        }
+    }
+
+    /**
      * Preemptively mark the menu as invisible, used when we are directly manipulating the pinned
      * stack and don't want to trigger a resize which can animate the stack in a conflicting way
      * (ie. when manually expanding or dismissing).
@@ -496,21 +518,6 @@
         mStartActivityRequestedTime = requested ? SystemClock.uptimeMillis() : 0;
     }
 
-    public final void onBusEvent(HidePipMenuEvent event) {
-        if (mStartActivityRequested) {
-            // If the menu has been start-requested, but not actually started, then we defer the
-            // trigger callback until the menu has started and called back to the controller.
-            mOnAttachDecrementTrigger = event.getAnimationTrigger();
-            mOnAttachDecrementTrigger.increment();
-
-            // Fallback for b/63752800, we have started the PipMenuActivity but it has not made any
-            // callbacks. Don't continue to wait for the menu to show past some timeout.
-            mHandler.removeCallbacks(mStartActivityRequestedTimeoutRunnable);
-            mHandler.postDelayed(mStartActivityRequestedTimeoutRunnable,
-                    START_ACTIVITY_REQUEST_TIMEOUT_MS);
-        }
-    }
-
     public void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 43e9db7..e17e0bc 100755
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -758,9 +758,4 @@
             WindowManagerWrapper.getInstance().setPipVisibility(visible);
         });
     }
-
-    @Override
-    public void dump(PrintWriter pw) {
-        // Do nothing
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
deleted file mode 100644
index 003379f..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents;
-
-/**
- * Constants
- */
-public class Constants {
-
-    // TODO: Move into RecentsMetrics
-    public static class Metrics {
-        // DO NOT MODIFY THE ORDER OF THESE METRICS
-        public static final int DismissSourceKeyboard = 0;
-        public static final int DismissSourceSwipeGesture = 1;
-        public static final int DismissSourceHeaderButton = 2;
-        @Deprecated
-        public static final int DismissSourceHistorySwipeGesture = 3;
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
deleted file mode 100644
index 90c1099..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents;
-
-import android.graphics.Rect;
-
-/**
- * Due to the fact that RecentsActivity is per-user, we need to establish an
- * interface (this) for the system user to callback to the secondary users in
- * response to UI events coming in from the system user's SystemUI.
- */
-oneway interface IRecentsNonSystemUserCallbacks {
-    void preloadRecents();
-    void cancelPreloadingRecents();
-    void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, boolean animate,
-            int recentsGrowTarget);
-    void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
-    void toggleRecents(int recentsGrowTarget);
-    void onConfigurationChanged();
-    void splitPrimaryTask(int topTaskId, int stackCreateMode, in Rect initialBounds);
-    void onDraggingInRecents(float distanceFromTop);
-    void onDraggingInRecentsEnded(float velocity);
-    void showCurrentUserToast(int msgResId, int msgLength);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
deleted file mode 100644
index e977144..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents;
-
-import android.graphics.Rect;
-
-/**
- * Due to the fact that RecentsActivity is per-user, we need to establish an
- * interface (this) for the non-system user to register itself for callbacks and to
- * callback to the system user to update internal state.
- */
-oneway interface IRecentsSystemUserCallbacks {
-    void registerNonSystemUserCallbacks(IBinder nonSystemUserCallbacks, int userId);
-
-    void updateRecentsVisibility(boolean visible);
-    void startScreenPinning(int taskId);
-    void sendRecentsDrawnEvent();
-    void sendDockingTopTaskEvent(in Rect initialRect);
-    void sendLaunchRecentsEvent();
-    void sendDockedFirstAnimationFrameEvent();
-    void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
new file mode 100644
index 0000000..661b958
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2014 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.systemui.recents;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+
+import android.app.ActivityManager;
+import android.app.trust.TrustManager;
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.Display;
+import android.widget.Toast;
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.shared.recents.IOverviewProxy;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+/**
+ * An implementation of the Recents interface which proxies to the OverviewProxyService.
+ */
+public class OverviewProxyRecentsImpl implements RecentsImplementation {
+
+    private final static String TAG = "OverviewProxyRecentsImpl";
+
+    private SysUiServiceProvider mSysUiServiceProvider;
+    private Context mContext;
+    private Handler mHandler;
+    private TrustManager mTrustManager;
+    private OverviewProxyService mOverviewProxyService;
+
+    @Override
+    public void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {
+        mContext = context;
+        mSysUiServiceProvider = sysUiServiceProvider;
+        mHandler = new Handler();
+        mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
+        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+    }
+
+    @Override
+    public void showRecentApps(boolean triggeredFromAltTab) {
+        IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
+        if (overviewProxy != null) {
+            try {
+                overviewProxy.onOverviewShown(triggeredFromAltTab);
+                return;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to send overview show event to launcher.", e);
+            }
+        } else {
+            // Do nothing
+        }
+    }
+
+    @Override
+    public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+        IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
+        if (overviewProxy != null) {
+            try {
+                overviewProxy.onOverviewHidden(triggeredFromAltTab, triggeredFromHomeKey);
+                return;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to send overview hide event to launcher.", e);
+            }
+        } else {
+            // Do nothing
+        }
+    }
+
+    @Override
+    public void toggleRecentApps() {
+        // If connected to launcher service, let it handle the toggle logic
+        IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
+        if (overviewProxy != null) {
+            final Runnable toggleRecents = () -> {
+                try {
+                    if (mOverviewProxyService.getProxy() != null) {
+                        mOverviewProxyService.getProxy().onOverviewToggle();
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Cannot send toggle recents through proxy service.", e);
+                }
+            };
+            // Preload only if device for current user is unlocked
+            final StatusBar statusBar = mSysUiServiceProvider.getComponent(StatusBar.class);
+            if (statusBar != null && statusBar.isKeyguardShowing()) {
+                statusBar.executeRunnableDismissingKeyguard(() -> {
+                        // Flush trustmanager before checking device locked per user
+                        mTrustManager.reportKeyguardShowingChanged();
+                        mHandler.post(toggleRecents);
+                    }, null,  true /* dismissShade */, false /* afterKeyguardGone */,
+                    true /* deferred */);
+            } else {
+                toggleRecents.run();
+            }
+            return;
+        } else {
+            // Do nothing
+        }
+    }
+
+    @Override
+    public boolean splitPrimaryTask(int stackCreateMode, Rect initialBounds,
+            int metricsDockAction) {
+        Point realSize = new Point();
+        if (initialBounds == null) {
+            mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
+                    .getRealSize(realSize);
+            initialBounds = new Rect(0, 0, realSize.x, realSize.y);
+        }
+
+        ActivityManager.RunningTaskInfo runningTask =
+                ActivityManagerWrapper.getInstance().getRunningTask();
+        final int activityType = runningTask != null
+                ? runningTask.configuration.windowConfiguration.getActivityType()
+                : ACTIVITY_TYPE_UNDEFINED;
+        boolean screenPinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
+        boolean isRunningTaskInHomeOrRecentsStack =
+                activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS;
+        if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
+            if (runningTask.supportsSplitScreenMultiWindow) {
+                if (ActivityManagerWrapper.getInstance().setTaskWindowingModeSplitScreenPrimary(
+                        runningTask.id, stackCreateMode, initialBounds)) {
+                    // The overview service is handling split screen, so just skip the wait for the
+                    // first draw and notify the divider to start animating now
+                    final Divider divider = mSysUiServiceProvider.getComponent(Divider.class);
+                    if (divider != null) {
+                        divider.onRecentsDrawn();
+                    }
+                    return true;
+                }
+            } else {
+                Toast.makeText(mContext, R.string.dock_non_resizeble_failed_to_dock_text,
+                        Toast.LENGTH_SHORT).show();
+            }
+        }
+        return false;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
rename to packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 1bf8750..19f7675 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.systemui;
+package com.android.systemui.recents;
 
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.view.MotionEvent.ACTION_DOWN;
@@ -42,7 +42,11 @@
 import android.provider.Settings;
 import android.util.Log;
 import android.view.MotionEvent;
-import com.android.systemui.OverviewProxyService.OverviewProxyListener;
+import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
+import com.android.systemui.Prefs;
+import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 74f6c2d..de22d21 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -16,232 +16,29 @@
 
 package com.android.systemui.recents;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
-
-import android.app.ActivityManager;
-import android.app.trust.TrustManager;
-import android.content.ComponentName;
 import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Point;
 import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
 import android.provider.Settings;
-import android.util.EventLog;
-import android.util.Log;
-import android.view.Display;
-import android.widget.Toast;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Dependency;
-import com.android.systemui.EventLogConstants;
-import com.android.systemui.EventLogTags;
-import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
-import com.android.systemui.RecentsComponent;
-import com.android.systemui.SystemUIApplication;
-import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
-import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.SystemUI;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
-import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
-import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
-import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
-import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
-import com.android.systemui.recents.events.component.ShowUserToastEvent;
-import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.model.RecentsTaskLoader;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
-
-import com.android.systemui.statusbar.phone.StatusBar;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
 
 /**
- * An implementation of the SystemUI recents component, which supports both system and secondary
- * users.
+ * A proxy to a Recents implementation.
  */
-public class Recents extends SystemUI
-        implements RecentsComponent, CommandQueue.Callbacks {
+public class Recents extends SystemUI implements CommandQueue.Callbacks {
 
-    private final static String TAG = "Recents";
-
-    public final static int EVENT_BUS_PRIORITY = 1;
-    public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
-
-    public final static Set<String> RECENTS_ACTIVITIES = new HashSet<>();
-    static {
-        RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
-    }
-
-    private static final String COUNTER_WINDOW_SUPPORTED = "window_enter_supported";
-    private static final String COUNTER_WINDOW_UNSUPPORTED = "window_enter_unsupported";
-    private static final String COUNTER_WINDOW_INCOMPATIBLE = "window_enter_incompatible";
-
-    private static SystemServicesProxy sSystemServicesProxy;
-    private static RecentsDebugFlags sDebugFlags;
-    private static RecentsTaskLoader sTaskLoader;
-    private static RecentsConfiguration sConfiguration;
-
-    private OverviewProxyService mOverviewProxyService;
-
-    private Handler mHandler;
-    private RecentsImpl mImpl;
-    private TrustManager mTrustManager;
-    private int mDraggingInRecentsCurrentUser;
-
-    // Only For system user, this is the callbacks instance we return to each secondary user
-    private RecentsSystemUser mSystemToUserCallbacks;
-
-    // Only for secondary users, this is the callbacks instance provided by the system user to make
-    // calls back
-    private IRecentsSystemUserCallbacks mUserToSystemCallbacks;
-
-    // The set of runnables to run after binding to the system user's service.
-    private final ArrayList<Runnable> mOnConnectRunnables = new ArrayList<>();
-
-    // Only for secondary users, this is the death handler for the binder from the system user
-    private final IBinder.DeathRecipient mUserToSystemCallbacksDeathRcpt = new IBinder.DeathRecipient() {
-        @Override
-        public void binderDied() {
-            mUserToSystemCallbacks = null;
-            EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
-                    EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_UNBOUND,
-                    sSystemServicesProxy.getProcessUser());
-
-            // Retry after a fixed duration
-            mHandler.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    registerWithSystemUser();
-                }
-            }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
-        }
-    };
-
-    // Only for secondary users, this is the service connection we use to connect to the system user
-    private final ServiceConnection mUserToSystemServiceConnection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            if (service != null) {
-                mUserToSystemCallbacks = IRecentsSystemUserCallbacks.Stub.asInterface(
-                        service);
-                EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
-                        EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_BOUND,
-                        sSystemServicesProxy.getProcessUser());
-
-                // Listen for system user's death, so that we can reconnect later
-                try {
-                    service.linkToDeath(mUserToSystemCallbacksDeathRcpt, 0);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Lost connection to (System) SystemUI", e);
-                }
-
-                // Run each of the queued runnables
-                runAndFlushOnConnectRunnables();
-            }
-
-            // Unbind ourselves now that we've registered our callbacks.  The
-            // binder to the system user are still valid at this point.
-            mContext.unbindService(this);
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            // Do nothing
-        }
-    };
-
-    /**
-     * Returns the callbacks interface that non-system users can call.
-     */
-    public IBinder getSystemUserCallbacks() {
-        return mSystemToUserCallbacks;
-    }
-
-    public static RecentsTaskLoader getTaskLoader() {
-        return sTaskLoader;
-    }
-
-
-    public static SystemServicesProxy getSystemServices() {
-        return sSystemServicesProxy;
-    }
-
-    public static RecentsConfiguration getConfiguration() {
-        return sConfiguration;
-    }
-
-    public static RecentsDebugFlags getDebugFlags() {
-        return sDebugFlags;
-    }
+    private RecentsImplementation mImpl;
 
     @Override
     public void start() {
-        final Resources res = mContext.getResources();
-        final int defaultTaskBarBackgroundColor =
-                mContext.getColor(R.color.recents_task_bar_default_background_color);
-        final int defaultTaskViewBackgroundColor =
-                mContext.getColor(R.color.recents_task_view_default_background_color);
-        sDebugFlags = new RecentsDebugFlags();
-        sSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
-        sConfiguration = new RecentsConfiguration(mContext);
-        sTaskLoader = new RecentsTaskLoader(mContext,
-                // TODO: Once we start building the AAR, move these into the loader
-                res.getInteger(R.integer.config_recents_max_thumbnail_count),
-                res.getInteger(R.integer.config_recents_max_icon_count),
-                res.getInteger(R.integer.recents_svelte_level));
-        sTaskLoader.setDefaultColors(defaultTaskBarBackgroundColor, defaultTaskViewBackgroundColor);
-        mHandler = new Handler();
-        mImpl = new RecentsImpl(mContext);
-        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
-
-        // Register with the event bus
-        EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
-        EventBus.getDefault().register(sSystemServicesProxy, EVENT_BUS_PRIORITY);
-        EventBus.getDefault().register(sTaskLoader, EVENT_BUS_PRIORITY);
-
-        // Due to the fact that RecentsActivity is per-user, we need to establish and interface for
-        // the system user's Recents component to pass events (like show/hide/toggleRecents) to the
-        // secondary user, and vice versa (like visibility change, screen pinning).
-        final int processUser = sSystemServicesProxy.getProcessUser();
-        if (sSystemServicesProxy.isSystemUser(processUser)) {
-            // For the system user, initialize an instance of the interface that we can pass to the
-            // secondary user
-            getComponent(CommandQueue.class).addCallbacks(this);
-            mSystemToUserCallbacks = new RecentsSystemUser(mContext, mImpl);
-        } else {
-            // For the secondary user, bind to the primary user's service to get a persistent
-            // interface to register its implementation and to later update its state
-            registerWithSystemUser();
-        }
+        getComponent(CommandQueue.class).addCallbacks(this);
         putComponent(Recents.class, this);
-
-        mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+        mImpl = createRecentsImplementationFromConfig();
+        mImpl.onStart(mContext, this);
     }
 
     @Override
@@ -249,13 +46,20 @@
         mImpl.onBootCompleted();
     }
 
-    public void growRecents() {
-        EventBus.getDefault().send(new RecentsGrowingEvent());
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        mImpl.onConfigurationChanged(newConfig);
     }
 
-    /**
-     * Shows the Recents.
-     */
+    @Override
+    public void appTransitionFinished() {
+        mImpl.onAppTransitionFinished();
+    }
+
+    public void growRecents() {
+        mImpl.growRecents();
+    }
+
     @Override
     public void showRecentApps(boolean triggeredFromAltTab) {
         // Ensure the device has been provisioned before allowing the user to interact with
@@ -264,43 +68,9 @@
             return;
         }
 
-        IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
-        if (overviewProxy != null) {
-            try {
-                overviewProxy.onOverviewShown(triggeredFromAltTab);
-                return;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to send overview show event to launcher.", e);
-            }
-        }
-
-        ActivityManagerWrapper.getInstance().closeSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
-        int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        if (sSystemServicesProxy.isSystemUser(currentUser)) {
-            mImpl.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
-                    true /* animate */, recentsGrowTarget);
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
-                                true /* animate */, recentsGrowTarget);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                }
-            }
-        }
+        mImpl.showRecentApps(triggeredFromAltTab);
     }
 
-    /**
-     * Hides the Recents.
-     */
     @Override
     public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         // Ensure the device has been provisioned before allowing the user to interact with
@@ -309,39 +79,9 @@
             return;
         }
 
-        IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
-        if (overviewProxy != null) {
-            try {
-                overviewProxy.onOverviewHidden(triggeredFromAltTab, triggeredFromHomeKey);
-                return;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to send overview hide event to launcher.", e);
-            }
-        }
-
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        if (sSystemServicesProxy.isSystemUser(currentUser)) {
-            mImpl.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                }
-            }
-        }
+        mImpl.hideRecentApps(triggeredFromAltTab, triggeredFromHomeKey);
     }
 
-    /**
-     * Toggles the Recents activity.
-     */
     @Override
     public void toggleRecentApps() {
         // Ensure the device has been provisioned before allowing the user to interact with
@@ -350,57 +90,9 @@
             return;
         }
 
-        // If connected to launcher service, let it handle the toggle logic
-        IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
-        if (overviewProxy != null) {
-            final Runnable toggleRecents = () -> {
-                try {
-                    if (mOverviewProxyService.getProxy() != null) {
-                        mOverviewProxyService.getProxy().onOverviewToggle();
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Cannot send toggle recents through proxy service.", e);
-                }
-            };
-            // Preload only if device for current user is unlocked
-            final StatusBar statusBar = getComponent(StatusBar.class);
-            if (statusBar != null && statusBar.isKeyguardShowing()) {
-                statusBar.executeRunnableDismissingKeyguard(() -> {
-                        // Flush trustmanager before checking device locked per user
-                        mTrustManager.reportKeyguardShowingChanged();
-                        mHandler.post(toggleRecents);
-                    }, null,  true /* dismissShade */, false /* afterKeyguardGone */,
-                    true /* deferred */);
-            } else {
-                toggleRecents.run();
-            }
-            return;
-        }
-
-        int growTarget = getComponent(Divider.class).getView().growsRecents();
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        if (sSystemServicesProxy.isSystemUser(currentUser)) {
-            mImpl.toggleRecents(growTarget);
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.toggleRecents(growTarget);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                }
-            }
-        }
+        mImpl.toggleRecentApps();
     }
 
-    /**
-     * Preloads info for the Recents activity.
-     */
     @Override
     public void preloadRecentApps() {
         // Ensure the device has been provisioned before allowing the user to interact with
@@ -409,29 +101,7 @@
             return;
         }
 
-        if (mOverviewProxyService.getProxy() != null) {
-            // TODO: Proxy to Launcher
-            return;
-        }
-
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        if (sSystemServicesProxy.isSystemUser(currentUser)) {
-            mImpl.preloadRecents();
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.preloadRecents();
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                }
-            }
-        }
+        mImpl.preloadRecentApps();
     }
 
     @Override
@@ -442,32 +112,9 @@
             return;
         }
 
-        if (mOverviewProxyService.getProxy() != null) {
-            // TODO: Proxy to Launcher
-            return;
-        }
-
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        if (sSystemServicesProxy.isSystemUser(currentUser)) {
-            mImpl.cancelPreloadingRecents();
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.cancelPreloadingRecents();
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                }
-            }
-        }
+        mImpl.cancelPreloadRecentApps();
     }
 
-    @Override
     public boolean splitPrimaryTask(int stackCreateMode, Rect initialBounds,
             int metricsDockAction) {
         // Ensure the device has been provisioned before allowing the user to interact with
@@ -476,380 +123,7 @@
             return false;
         }
 
-        Point realSize = new Point();
-        if (initialBounds == null) {
-            mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
-                    .getRealSize(realSize);
-            initialBounds = new Rect(0, 0, realSize.x, realSize.y);
-        }
-
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        ActivityManager.RunningTaskInfo runningTask =
-                ActivityManagerWrapper.getInstance().getRunningTask();
-        final int activityType = runningTask != null
-                ? runningTask.configuration.windowConfiguration.getActivityType()
-                : ACTIVITY_TYPE_UNDEFINED;
-        boolean screenPinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
-        boolean isRunningTaskInHomeOrRecentsStack =
-                activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS;
-        if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
-            logDockAttempt(mContext, runningTask.topActivity, runningTask.resizeMode);
-            if (runningTask.supportsSplitScreenMultiWindow) {
-                if (metricsDockAction != -1) {
-                    MetricsLogger.action(mContext, metricsDockAction,
-                            runningTask.topActivity.flattenToShortString());
-                }
-                if (sSystemServicesProxy.isSystemUser(currentUser)) {
-                    mImpl.splitPrimaryTask(runningTask.id, stackCreateMode, initialBounds);
-                } else {
-                    if (mSystemToUserCallbacks != null) {
-                        IRecentsNonSystemUserCallbacks callbacks =
-                                mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                        if (callbacks != null) {
-                            try {
-                                callbacks.splitPrimaryTask(runningTask.id, stackCreateMode,
-                                        initialBounds);
-                            } catch (RemoteException e) {
-                                Log.e(TAG, "Callback failed", e);
-                            }
-                        } else {
-                            Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                        }
-                    }
-                }
-                mDraggingInRecentsCurrentUser = currentUser;
-
-                if (mOverviewProxyService.getProxy() != null) {
-                    // The overview service is handling split screen, so just skip the wait for the
-                    // first draw and notify the divider to start animating now
-                    EventBus.getDefault().post(new RecentsDrawnEvent());
-                }
-
-                return true;
-            } else {
-                EventBus.getDefault().send(new ShowUserToastEvent(
-                        R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT));
-                return false;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    public static void logDockAttempt(Context ctx, ComponentName activity, int resizeMode) {
-        if (resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE) {
-            MetricsLogger.action(ctx, MetricsEvent.ACTION_WINDOW_DOCK_UNRESIZABLE,
-                    activity.flattenToShortString());
-        }
-        MetricsLogger.count(ctx, getMetricsCounterForResizeMode(resizeMode), 1);
-    }
-
-    private static String getMetricsCounterForResizeMode(int resizeMode) {
-        switch (resizeMode) {
-            case ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE:
-                return COUNTER_WINDOW_UNSUPPORTED;
-            case ActivityInfo.RESIZE_MODE_RESIZEABLE:
-            case ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION:
-                return COUNTER_WINDOW_SUPPORTED;
-            default:
-                return COUNTER_WINDOW_INCOMPATIBLE;
-        }
-    }
-
-    public void showNextAffiliatedTask() {
-        // Ensure the device has been provisioned before allowing the user to interact with
-        // recents
-        if (!isUserSetup()) {
-            return;
-        }
-
-        mImpl.showNextAffiliatedTask();
-    }
-
-    public void showPrevAffiliatedTask() {
-        // Ensure the device has been provisioned before allowing the user to interact with
-        // recents
-        if (!isUserSetup()) {
-            return;
-        }
-
-        mImpl.showPrevAffiliatedTask();
-    }
-
-    @Override
-    public void appTransitionFinished() {
-        if (!Recents.getConfiguration().isLowRamDevice) {
-            // Fallback, reset the flag once an app transition ends
-            EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(
-                    false /* waitingForTransitionStart */));
-        }
-    }
-
-    /**
-     * Updates on configuration change.
-     */
-    public void onConfigurationChanged(Configuration newConfig) {
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        if (sSystemServicesProxy.isSystemUser(currentUser)) {
-            mImpl.onConfigurationChanged();
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.onConfigurationChanged();
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                }
-            }
-        }
-    }
-
-    /**
-     * Handle Recents activity visibility changed.
-     */
-    public final void onBusEvent(final RecentsVisibilityChangedEvent event) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        int processUser = ssp.getProcessUser();
-        if (ssp.isSystemUser(processUser)) {
-            mImpl.onVisibilityChanged(event.applicationContext, event.visible);
-        } else {
-            postToSystemUser(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mUserToSystemCallbacks.updateRecentsVisibility(event.visible);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                }
-            });
-        }
-
-        // This will catch the cases when a user launches from recents to another app
-        // (and vice versa) that is not in the recents stack (such as home or bugreport) and it
-        // would not reset the wait for transition flag. This will catch it and make sure that the
-        // flag is reset.
-        if (!event.visible) {
-            mImpl.setWaitingForTransitionStart(false);
-        }
-    }
-
-    public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        int processUser = ssp.getProcessUser();
-        if (ssp.isSystemUser(processUser)) {
-            final Divider divider = getComponent(Divider.class);
-            if (divider != null) {
-                divider.onDockedFirstAnimationFrame();
-            }
-        } else {
-            postToSystemUser(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mUserToSystemCallbacks.sendDockedFirstAnimationFrameEvent();
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Handle screen pinning request.
-     */
-    public final void onBusEvent(final ScreenPinningRequestEvent event) {
-        int processUser = sSystemServicesProxy.getProcessUser();
-        if (sSystemServicesProxy.isSystemUser(processUser)) {
-            mImpl.onStartScreenPinning(event.applicationContext, event.taskId);
-        } else {
-            postToSystemUser(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mUserToSystemCallbacks.startScreenPinning(event.taskId);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                }
-            });
-        }
-    }
-
-    public final void onBusEvent(final RecentsDrawnEvent event) {
-        int processUser = sSystemServicesProxy.getProcessUser();
-        if (sSystemServicesProxy.isSystemUser(processUser)) {
-            final Divider divider = getComponent(Divider.class);
-            if (divider != null) {
-                divider.onRecentsDrawn();
-            }
-        } else {
-            postToSystemUser(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mUserToSystemCallbacks.sendRecentsDrawnEvent();
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                }
-            });
-        }
-    }
-
-    public final void onBusEvent(final DockedTopTaskEvent event) {
-        int processUser = sSystemServicesProxy.getProcessUser();
-        if (sSystemServicesProxy.isSystemUser(processUser)) {
-            final Divider divider = getComponent(Divider.class);
-            if (divider != null) {
-                divider.onDockedTopTask();
-            }
-        } else {
-            postToSystemUser(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mUserToSystemCallbacks.sendDockingTopTaskEvent(event.initialRect);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                }
-            });
-        }
-    }
-
-    public final void onBusEvent(final RecentsActivityStartingEvent event) {
-        int processUser = sSystemServicesProxy.getProcessUser();
-        if (sSystemServicesProxy.isSystemUser(processUser)) {
-            final Divider divider = getComponent(Divider.class);
-            if (divider != null) {
-                divider.onRecentsActivityStarting();
-            }
-        } else {
-            postToSystemUser(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mUserToSystemCallbacks.sendLaunchRecentsEvent();
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                }
-            });
-        }
-    }
-
-    public final void onBusEvent(LaunchTaskFailedEvent event) {
-        // Reset the transition when tasks fail to launch
-        mImpl.setWaitingForTransitionStart(false);
-    }
-
-    public final void onBusEvent(ConfigurationChangedEvent event) {
-        // Update the configuration for the Recents component when the activity configuration
-        // changes as well
-        mImpl.onConfigurationChanged();
-    }
-
-    public final void onBusEvent(ShowUserToastEvent event) {
-        int currentUser = sSystemServicesProxy.getCurrentUser();
-        if (sSystemServicesProxy.isSystemUser(currentUser)) {
-            mImpl.onShowCurrentUserToast(event.msgResId, event.msgLength);
-        } else {
-            if (mSystemToUserCallbacks != null) {
-                IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
-                if (callbacks != null) {
-                    try {
-                        callbacks.showCurrentUserToast(event.msgResId, event.msgLength);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                } else {
-                    Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
-                }
-            }
-        }
-    }
-
-    public final void onBusEvent(SetWaitingForTransitionStartEvent event) {
-        int processUser = sSystemServicesProxy.getProcessUser();
-        if (sSystemServicesProxy.isSystemUser(processUser)) {
-            mImpl.setWaitingForTransitionStart(event.waitingForTransitionStart);
-        } else {
-            postToSystemUser(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        mUserToSystemCallbacks.setWaitingForTransitionStartEvent(
-                                event.waitingForTransitionStart);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Callback failed", e);
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Attempts to register with the system user.
-     */
-    private void registerWithSystemUser() {
-        final int processUser = sSystemServicesProxy.getProcessUser();
-        postToSystemUser(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    mUserToSystemCallbacks.registerNonSystemUserCallbacks(
-                            new RecentsImplProxy(mImpl), processUser);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to register", e);
-                }
-            }
-        });
-    }
-
-    /**
-     * Runs the runnable in the system user's Recents context, connecting to the service if
-     * necessary.
-     */
-    private void postToSystemUser(final Runnable onConnectRunnable) {
-        mOnConnectRunnables.add(onConnectRunnable);
-        if (mUserToSystemCallbacks == null) {
-            Intent systemUserServiceIntent = new Intent();
-            systemUserServiceIntent.setClass(mContext, RecentsSystemUserService.class);
-            boolean bound = mContext.bindServiceAsUser(systemUserServiceIntent,
-                    mUserToSystemServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
-            EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
-                    EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE,
-                    sSystemServicesProxy.getProcessUser());
-            if (!bound) {
-                // Retry after a fixed duration
-                mHandler.postDelayed(new Runnable() {
-                    @Override
-                    public void run() {
-                        registerWithSystemUser();
-                    }
-                }, BIND_TO_SYSTEM_USER_RETRY_DELAY);
-            }
-        } else {
-            runAndFlushOnConnectRunnables();
-        }
-    }
-
-    /**
-     * Runs all the queued runnables after a service connection is made.
-     */
-    private void runAndFlushOnConnectRunnables() {
-        for (Runnable r : mOnConnectRunnables) {
-            r.run();
-        }
-        mOnConnectRunnables.clear();
+        return mImpl.splitPrimaryTask(stackCreateMode, initialBounds, metricsDockAction);
     }
 
     /**
@@ -861,9 +135,30 @@
                 (Settings.Secure.getInt(cr, Settings.Secure.USER_SETUP_COMPLETE, 0) != 0);
     }
 
+    /**
+     * @return The recents implementation from the config.
+     */
+    private RecentsImplementation createRecentsImplementationFromConfig() {
+        final String clsName = mContext.getString(R.string.config_recentsComponent);
+        if (clsName == null || clsName.length() == 0) {
+            throw new RuntimeException("No recents component configured", null);
+        }
+        Class<?> cls = null;
+        try {
+            cls = mContext.getClassLoader().loadClass(clsName);
+        } catch (Throwable t) {
+            throw new RuntimeException("Error loading recents component: " + clsName, t);
+        }
+        try {
+            RecentsImplementation impl = (RecentsImplementation) cls.newInstance();
+            return impl;
+        } catch (Throwable t) {
+            throw new RuntimeException("Error creating recents component: " + clsName, t);
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("Recents");
-        pw.println("  currentUserId=" + SystemServicesProxy.getInstance(mContext).getCurrentUser());
+        mImpl.dump(pw);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
deleted file mode 100644
index 36a1255..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents;
-
-import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_HOME_KEY;
-
-import android.app.Activity;
-import android.app.ActivityOptions;
-import android.app.TaskStackBuilder;
-import android.app.WallpaperManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnPreDrawListener;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-
-import com.android.internal.colorextraction.ColorExtractor;
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.util.LatencyTracker;
-import com.android.systemui.DejankUtils;
-import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
-import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
-import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
-import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.HideRecentsEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
-import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
-import com.android.systemui.recents.events.activity.PackagesChangedEvent;
-import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
-import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
-import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
-import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
-import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
-import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
-import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
-import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
-import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
-import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
-import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
-import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
-import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
-import com.android.systemui.recents.events.ui.UserInteractionEvent;
-import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
-import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
-import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
-import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
-import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
-import com.android.systemui.shared.recents.model.RecentsTaskLoader;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.recents.views.RecentsView;
-import com.android.systemui.recents.views.SystemBarScrimViews;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-
-import com.android.systemui.shared.system.WindowManagerWrapper;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * The main Recents activity that is started from RecentsComponent.
- */
-public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener,
-        ColorExtractor.OnColorsChangedListener {
-
-    private final static String TAG = "RecentsActivity";
-    private final static boolean DEBUG = false;
-
-    public final static int EVENT_BUS_PRIORITY = Recents.EVENT_BUS_PRIORITY + 1;
-    public final static int INCOMPATIBLE_APP_ALPHA_DURATION = 150;
-
-    private PackageMonitor mPackageMonitor = new PackageMonitor() {
-            @Override
-            public void onPackageRemoved(String packageName, int uid) {
-                RecentsActivity.this.onPackageChanged(packageName, getChangingUserId());
-            }
-
-            @Override
-            public boolean onPackageChanged(String packageName, int uid, String[] components) {
-                RecentsActivity.this.onPackageChanged(packageName, getChangingUserId());
-                return true;
-            }
-
-            @Override
-            public void onPackageModified(String packageName) {
-                RecentsActivity.this.onPackageChanged(packageName, getChangingUserId());
-            }
-        };
-    private Handler mHandler = new Handler();
-    private long mLastTabKeyEventTime;
-    private boolean mFinishedOnStartup;
-    private boolean mIgnoreAltTabRelease;
-    private boolean mIsVisible;
-    private boolean mRecentsStartRequested;
-    private Configuration mLastConfig;
-
-    // Top level views
-    private RecentsView mRecentsView;
-    private SystemBarScrimViews mScrimViews;
-    private View mIncompatibleAppOverlay;
-
-    // Runnables to finish the Recents activity
-    private Intent mHomeIntent;
-
-    // The trigger to automatically launch the current task
-    private int mFocusTimerDuration;
-    private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
-
-    // Theme and colors
-    private SysuiColorExtractor mColorExtractor;
-    private boolean mUsingDarkText;
-
-    /**
-     * A common Runnable to finish Recents by launching Home with an animation depending on the
-     * last activity launch state. Generally we always launch home when we exit Recents rather than
-     * just finishing the activity since we don't know what is behind Recents in the task stack.
-     */
-    class LaunchHomeRunnable implements Runnable {
-
-        Intent mLaunchIntent;
-        ActivityOptions mOpts;
-
-        /**
-         * Creates a finish runnable that starts the specified intent.
-         */
-        public LaunchHomeRunnable(Intent launchIntent, ActivityOptions opts) {
-            mLaunchIntent = launchIntent;
-            mOpts = opts;
-        }
-
-        @Override
-        public void run() {
-            try {
-                mHandler.post(() -> {
-                    ActivityOptions opts = mOpts;
-                    if (opts == null) {
-                        opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this,
-                                R.anim.recents_to_launcher_enter, R.anim.recents_to_launcher_exit);
-                    }
-                    startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
-                });
-            } catch (Exception e) {
-                Log.e(TAG, getString(R.string.recents_launch_error_message, "Home"), e);
-            }
-        }
-    }
-
-    /**
-     * Broadcast receiver to handle messages from the system
-     */
-    final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context ctx, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(Intent.ACTION_SCREEN_OFF)) {
-                // When the screen turns off, dismiss Recents to Home
-                dismissRecentsToHomeIfVisible(false);
-            } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
-                // When switching users, dismiss Recents to Home similar to screen off
-                finish();
-            }
-        }
-    };
-
-    private final OnPreDrawListener mRecentsDrawnEventListener =
-            new ViewTreeObserver.OnPreDrawListener() {
-                @Override
-                public boolean onPreDraw() {
-                    mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
-                    EventBus.getDefault().post(new RecentsDrawnEvent());
-                    if (LatencyTracker.isEnabled(getApplicationContext())) {
-                        DejankUtils.postAfterTraversal(() -> LatencyTracker.getInstance(
-                                getApplicationContext()).onActionEnd(
-                                LatencyTracker.ACTION_TOGGLE_RECENTS));
-                    }
-                    DejankUtils.postAfterTraversal(() -> {
-                        Recents.getTaskLoader().startLoader(RecentsActivity.this);
-                        Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(true);
-                    });
-                    return true;
-                }
-            };
-
-    /**
-     * Dismisses recents if we are already visible and the intent is to toggle the recents view.
-     */
-    boolean dismissRecentsToFocusedTask(int logCategory) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsActivityVisible()) {
-            // If we have a focused Task, launch that Task now
-            if (mRecentsView.launchFocusedTask(logCategory)) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Dismisses recents back to the launch target task.
-     */
-    boolean dismissRecentsToLaunchTargetTaskOrHome() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsActivityVisible()) {
-            // If we have a focused Task, launch that Task now
-            if (mRecentsView.launchPreviousTask()) return true;
-            // If none of the other cases apply, then just go Home
-            dismissRecentsToHome(true /* animateTaskViews */);
-        }
-        return false;
-    }
-
-    /**
-     * Dismisses recents if we are already visible and the intent is to toggle the recents view.
-     */
-    boolean dismissRecentsToFocusedTaskOrHome() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsActivityVisible()) {
-            // If we have a focused Task, launch that Task now
-            if (mRecentsView.launchFocusedTask(0 /* logCategory */)) return true;
-            // If none of the other cases apply, then just go Home
-            dismissRecentsToHome(true /* animateTaskViews */);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Dismisses Recents directly to Home without checking whether it is currently visible.
-     */
-    void dismissRecentsToHome(boolean animateTaskViews) {
-        dismissRecentsToHome(animateTaskViews, null);
-    }
-
-    /**
-     * Dismisses Recents directly to Home without checking whether it is currently visible.
-     *
-     * @param overrideAnimation If not null, will override the default animation that is based on
-     *                          how Recents was launched.
-     */
-    void dismissRecentsToHome(boolean animateTaskViews, ActivityOptions overrideAnimation) {
-        DismissRecentsToHomeAnimationStarted dismissEvent =
-                new DismissRecentsToHomeAnimationStarted(animateTaskViews);
-        dismissEvent.addPostAnimationCallback(new LaunchHomeRunnable(mHomeIntent,
-                overrideAnimation));
-        ActivityManagerWrapper.getInstance().closeSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
-        EventBus.getDefault().send(dismissEvent);
-    }
-
-    /** Dismisses Recents directly to Home if we currently aren't transitioning. */
-    boolean dismissRecentsToHomeIfVisible(boolean animated) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsActivityVisible()) {
-            // Return to Home
-            dismissRecentsToHome(animated);
-            return true;
-        }
-        return false;
-    }
-
-    /** Called with the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mFinishedOnStartup = false;
-
-        // In the case that the activity starts up before the Recents component has initialized
-        // (usually when debugging/pushing the SysUI apk), just finish this activity.
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp == null) {
-            mFinishedOnStartup = true;
-            finish();
-            return;
-        }
-
-        // Register this activity with the event bus
-        EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
-
-        // Initialize the package monitor
-        mPackageMonitor.register(this, Looper.getMainLooper(), UserHandle.ALL,
-                true /* externalStorage */);
-
-        // Select theme based on wallpaper colors
-        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
-        mColorExtractor.addOnColorsChangedListener(this);
-        mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK,
-                WallpaperManager.FLAG_SYSTEM, true).supportsDarkText();
-        setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
-                : R.style.RecentsTheme_Wallpaper);
-
-        // Set the Recents layout
-        setContentView(R.layout.recents);
-        takeKeyEvents(true);
-        mRecentsView = findViewById(R.id.recents_view);
-        mScrimViews = new SystemBarScrimViews(this);
-        getWindow().getAttributes().privateFlags |=
-                WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
-        if (Recents.getConfiguration().isLowRamDevice) {
-            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
-        }
-
-        mLastConfig = new Configuration(Utilities.getAppConfiguration(this));
-
-        // Set the window background
-        mRecentsView.updateBackgroundScrim(getWindow(), isInMultiWindowMode());
-
-        // Create the home intent runnable
-        mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
-        mHomeIntent.addCategory(Intent.CATEGORY_HOME);
-        mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
-        // Register the broadcast receiver to handle messages when the screen is turned off
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(Intent.ACTION_USER_SWITCHED);
-        registerReceiver(mSystemBroadcastReceiver, filter);
-
-        getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION);
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        // Reload the stack view whenever we are made visible again
-        reloadStackView();
-
-        // Notify that recents is now visible
-        EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
-        MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
-
-        // Getting system scrim colors ignoring wallpaper visibility since it should never be grey.
-        ColorExtractor.GradientColors systemColors = mColorExtractor.getColors(
-                ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true);
-        // We don't want to interpolate colors because we're defining the initial state.
-        // Gradient should be set/ready when you open "Recents".
-        mRecentsView.setScrimColors(systemColors, false);
-
-        // Notify of the next draw
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);
-
-        // If Recents was restarted, then it should complete the enter animation with partially
-        // reset launch state with dock, app and home set to false
-        Object isRelaunching = getLastNonConfigurationInstance();
-        if (isRelaunching != null && isRelaunching instanceof Boolean && (boolean) isRelaunching) {
-            RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-            launchState.launchedViaDockGesture = false;
-            launchState.launchedFromApp = false;
-            launchState.launchedFromHome = false;
-            onEnterAnimationComplete();
-        }
-        mRecentsStartRequested = false;
-    }
-
-    @Override
-    public void onColorsChanged(ColorExtractor colorExtractor, int which) {
-        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
-            // Recents doesn't care about the wallpaper being visible or not, it always
-            // wants to scrim with wallpaper colors
-            ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                    WallpaperManager.FLAG_SYSTEM,
-                    ColorExtractor.TYPE_DARK, true /* ignoreVis */);
-            boolean darkText = colors.supportsDarkText();
-            if (darkText != mUsingDarkText) {
-                mUsingDarkText = darkText;
-                setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
-                        : R.style.RecentsTheme_Wallpaper);
-                mRecentsView.reevaluateStyles();
-            }
-            mRecentsView.setScrimColors(colors, true /* animated */);
-        }
-    }
-
-    /**
-     * Reloads the stack views upon launching Recents.
-     */
-    private void reloadStackView() {
-        // If the Recents component has preloaded a load plan, then use that to prevent
-        // reconstructing the task stack
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan loadPlan = RecentsImpl.consumeInstanceLoadPlan();
-        if (loadPlan == null) {
-            loadPlan = new RecentsTaskLoadPlan(this);
-        }
-
-        // Start loading tasks according to the load plan
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        if (!loadPlan.hasTasks()) {
-            loader.preloadTasks(loadPlan, launchState.launchedToTaskId);
-        }
-
-        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
-        loadOpts.runningTaskId = launchState.launchedToTaskId;
-        loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
-        loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
-        loader.loadTasks(loadPlan, loadOpts);
-        TaskStack stack = loadPlan.getTaskStack();
-        mRecentsView.onReload(stack, mIsVisible);
-
-        // Update the nav bar scrim, but defer the animation until the enter-window event
-        boolean animateNavBarScrim = !launchState.launchedViaDockGesture;
-        mScrimViews.updateNavBarScrim(animateNavBarScrim, stack.getTaskCount() > 0, null);
-
-        // If this is a new instance relaunched by AM, without going through the normal mechanisms,
-        // then we have to manually trigger the enter animation state
-        boolean wasLaunchedByAm = !launchState.launchedFromHome &&
-                !launchState.launchedFromApp;
-        if (wasLaunchedByAm) {
-            EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
-        }
-
-        // Keep track of whether we launched from the nav bar button or via alt-tab
-        if (launchState.launchedWithAltTab) {
-            MetricsLogger.count(this, "overview_trigger_alttab", 1);
-        } else {
-            MetricsLogger.count(this, "overview_trigger_nav_btn", 1);
-        }
-
-        // Keep track of whether we launched from an app or from home
-        if (launchState.launchedFromApp) {
-            Task launchTarget = stack.getLaunchTarget();
-            int launchTaskIndexInStack = launchTarget != null
-                    ? stack.indexOfTask(launchTarget)
-                    : 0;
-            MetricsLogger.count(this, "overview_source_app", 1);
-            // If from an app, track the stack index of the app in the stack (for affiliated tasks)
-            MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack);
-        } else {
-            MetricsLogger.count(this, "overview_source_home", 1);
-        }
-
-        // Keep track of the total stack task count
-        int taskCount = mRecentsView.getStack().getTaskCount();
-        MetricsLogger.histogram(this, "overview_task_count", taskCount);
-
-        // After we have resumed, set the visible state until the next onStop() call
-        mIsVisible = true;
-    }
-
-    @Override
-    public void onEnterAnimationComplete() {
-        super.onEnterAnimationComplete();
-        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
-
-        // Workaround for b/64694148: The animation started callback is not made (see
-        // RecentsImpl.getThumbnailTransitionActivityOptions) so reset the transition-waiting state
-        // once the enter animation has completed.
-        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
-    }
-
-    @Override
-    public Object onRetainNonConfigurationInstance() {
-        return true;
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-
-        mIgnoreAltTabRelease = false;
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        // Notify of the config change
-        Configuration newDeviceConfiguration = Utilities.getAppConfiguration(this);
-        int numStackTasks = mRecentsView.getStack().getTaskCount();
-        EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
-                mLastConfig.orientation != newDeviceConfiguration.orientation,
-                mLastConfig.densityDpi != newDeviceConfiguration.densityDpi, numStackTasks > 0));
-
-        mLastConfig.updateFrom(newDeviceConfiguration);
-    }
-
-    @Override
-    public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
-        super.onMultiWindowModeChanged(isInMultiWindowMode);
-
-        // Set the window background
-        mRecentsView.updateBackgroundScrim(getWindow(), isInMultiWindowMode);
-
-        // Reload the task stack view if we are still visible to pick up the change in tasks that
-        // result from entering/exiting multi-window
-        if (mIsVisible) {
-            reloadTaskStack(isInMultiWindowMode, true /* sendConfigChangedEvent */);
-        }
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-
-        // Notify that recents is now hidden
-        mIsVisible = false;
-        EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
-        MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
-        Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(false);
-
-        // When recents starts again before onStop, do not reset launch flags so entrance animation
-        // can run
-        if (!isChangingConfigurations() && !mRecentsStartRequested) {
-            // Workaround for b/22542869, if the RecentsActivity is started again, but without going
-            // through SystemUI, we need to reset the config launch flags to ensure that we do not
-            // wait on the system to send a signal that was never queued.
-            RecentsConfiguration config = Recents.getConfiguration();
-            RecentsActivityLaunchState launchState = config.getLaunchState();
-            launchState.reset();
-        }
-
-        // Force a gc to attempt to clean up bitmap references more quickly (b/38258699)
-        Recents.getSystemServices().gc();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-
-        // In the case that the activity finished on startup, just skip the unregistration below
-        if (mFinishedOnStartup) {
-            return;
-        }
-
-        // Unregister the system broadcast receivers
-        unregisterReceiver(mSystemBroadcastReceiver);
-
-        // Unregister any broadcast receivers for the task loader
-        mPackageMonitor.unregister();
-
-        EventBus.getDefault().unregister(this);
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        EventBus.getDefault().register(mScrimViews, EVENT_BUS_PRIORITY);
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        EventBus.getDefault().unregister(mScrimViews);
-    }
-
-    @Override
-    public void onTrimMemory(int level) {
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        if (loader != null) {
-            loader.onTrimMemory(level);
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_TAB: {
-                int altTabKeyDelay = getResources().getInteger(R.integer.recents_alt_tab_key_delay);
-                boolean hasRepKeyTimeElapsed = (SystemClock.elapsedRealtime() -
-                        mLastTabKeyEventTime) > altTabKeyDelay;
-                if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) {
-                    // Focus the next task in the stack
-                    final boolean backward = event.isShiftPressed();
-                    if (backward) {
-                        EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
-                    } else {
-                        EventBus.getDefault().send(new FocusNextTaskViewEvent());
-                    }
-                    mLastTabKeyEventTime = SystemClock.elapsedRealtime();
-
-                    // In the case of another ALT event, don't ignore the next release
-                    if (event.isAltPressed()) {
-                        mIgnoreAltTabRelease = false;
-                    }
-                }
-                return true;
-            }
-            case KeyEvent.KEYCODE_DPAD_UP:
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-            case KeyEvent.KEYCODE_DPAD_RIGHT: {
-                final Direction direction = NavigateTaskViewEvent.getDirectionFromKeyCode(keyCode);
-                EventBus.getDefault().send(new NavigateTaskViewEvent(direction));
-                return true;
-            }
-            case KeyEvent.KEYCODE_DEL:
-            case KeyEvent.KEYCODE_FORWARD_DEL: {
-                if (event.getRepeatCount() <= 0) {
-                    EventBus.getDefault().send(new DismissFocusedTaskViewEvent());
-
-                    // Keep track of deletions by keyboard
-                    MetricsLogger.histogram(this, "overview_task_dismissed_source",
-                            Constants.Metrics.DismissSourceKeyboard);
-                    return true;
-                }
-            }
-            default:
-                break;
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public void onUserInteraction() {
-        EventBus.getDefault().send(mUserInteractionEvent);
-    }
-
-    @Override
-    public void onBackPressed() {
-        // Back behaves like the recents button so just trigger a toggle event
-        EventBus.getDefault().send(new ToggleRecentsEvent());
-    }
-
-    /**** EventBus events ****/
-
-    public final void onBusEvent(ToggleRecentsEvent event) {
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-        if (launchState.launchedFromHome) {
-            dismissRecentsToHome(true /* animateTaskViews */);
-        } else {
-            dismissRecentsToLaunchTargetTaskOrHome();
-        }
-    }
-
-    public final void onBusEvent(RecentsActivityStartingEvent event) {
-        mRecentsStartRequested = true;
-    }
-
-    public final void onBusEvent(HideRecentsEvent event) {
-        if (event.triggeredFromAltTab) {
-            // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
-            if (!mIgnoreAltTabRelease) {
-                dismissRecentsToFocusedTaskOrHome();
-            }
-        } else if (event.triggeredFromHomeKey) {
-            dismissRecentsToHome(true /* animateTaskViews */);
-
-            // Cancel any pending dozes
-            EventBus.getDefault().send(mUserInteractionEvent);
-        } else {
-            // Do nothing
-        }
-    }
-
-    public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
-        mRecentsView.invalidate();
-    }
-
-    public final void onBusEvent(ExitRecentsWindowFirstAnimationFrameEvent event) {
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
-        mRecentsView.invalidate();
-    }
-
-    public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
-        mRecentsView.invalidate();
-    }
-
-    public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-        int launchToTaskId = launchState.launchedToTaskId;
-        if (launchToTaskId != -1 &&
-                (event.launchTask == null || launchToTaskId != event.launchTask.key.id)) {
-            ActivityManagerWrapper am = ActivityManagerWrapper.getInstance();
-            am.cancelWindowTransition(launchState.launchedToTaskId);
-        }
-    }
-
-    public final void onBusEvent(ShowApplicationInfoEvent event) {
-        // Create a new task stack with the application info details activity
-        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
-                Uri.fromParts("package", event.task.key.getComponent().getPackageName(), null));
-        intent.setComponent(intent.resolveActivity(getPackageManager()));
-        TaskStackBuilder.create(this)
-                .addNextIntentWithParentStack(intent).startActivities(null,
-                        new UserHandle(event.task.key.userId));
-
-        // Keep track of app-info invocations
-        MetricsLogger.count(this, "overview_app_info", 1);
-    }
-
-    public final void onBusEvent(ShowIncompatibleAppOverlayEvent event) {
-        if (mIncompatibleAppOverlay == null) {
-            mIncompatibleAppOverlay = Utilities.findViewStubById(this,
-                    R.id.incompatible_app_overlay_stub).inflate();
-            mIncompatibleAppOverlay.setWillNotDraw(false);
-            mIncompatibleAppOverlay.setVisibility(View.VISIBLE);
-        }
-        mIncompatibleAppOverlay.animate()
-                .alpha(1f)
-                .setDuration(INCOMPATIBLE_APP_ALPHA_DURATION)
-                .setInterpolator(Interpolators.ALPHA_IN)
-                .start();
-    }
-
-    public final void onBusEvent(HideIncompatibleAppOverlayEvent event) {
-        if (mIncompatibleAppOverlay != null) {
-            mIncompatibleAppOverlay.animate()
-                    .alpha(0f)
-                    .setDuration(INCOMPATIBLE_APP_ALPHA_DURATION)
-                    .setInterpolator(Interpolators.ALPHA_OUT)
-                    .start();
-        }
-    }
-
-    public final void onBusEvent(DeleteTaskDataEvent event) {
-        // Remove any stored data from the loader
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        loader.deleteTaskData(event.task, false);
-
-        // Remove the task from activity manager
-        ActivityManagerWrapper.getInstance().removeTask(event.task.key.id);
-    }
-
-    public final void onBusEvent(TaskViewDismissedEvent event) {
-        mRecentsView.updateScrimOpacity();
-    }
-
-    public final void onBusEvent(AllTaskViewsDismissedEvent event) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.hasDockedTask()) {
-            mRecentsView.showEmptyView(event.msgResId);
-        } else {
-            // Just go straight home (no animation necessary because there are no more task views)
-            dismissRecentsToHome(false /* animateTaskViews */);
-        }
-
-        // Keep track of all-deletions
-        MetricsLogger.count(this, "overview_task_all_dismissed", 1);
-    }
-
-    public final void onBusEvent(LaunchTaskSucceededEvent event) {
-        MetricsLogger.histogram(this, "overview_task_launch_index", event.taskIndexFromStackFront);
-    }
-
-    public final void onBusEvent(LaunchTaskFailedEvent event) {
-        // Return to Home
-        dismissRecentsToHome(true /* animateTaskViews */);
-
-        MetricsLogger.count(this, "overview_task_launch_failed", 1);
-    }
-
-    public final void onBusEvent(ScreenPinningRequestEvent event) {
-        MetricsLogger.count(this, "overview_screen_pinned", 1);
-    }
-
-    public final void onBusEvent(StackViewScrolledEvent event) {
-        // Once the user has scrolled while holding alt-tab, then we should ignore the release of
-        // the key
-        mIgnoreAltTabRelease = true;
-    }
-
-    public final void onBusEvent(final DockedTopTaskEvent event) {
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);
-        mRecentsView.invalidate();
-    }
-
-    public final void onBusEvent(final ActivityUnpinnedEvent event) {
-        if (mIsVisible) {
-            // Skip the configuration change event as the PiP activity does not actually affect the
-            // config of recents
-            reloadTaskStack(isInMultiWindowMode(), false /* sendConfigChangedEvent */);
-        }
-    }
-
-    private void reloadTaskStack(boolean isInMultiWindowMode, boolean sendConfigChangedEvent) {
-        // Reload the task stack completely
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(this);
-        loader.preloadTasks(loadPlan, -1 /* runningTaskId */);
-
-        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
-        loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
-        loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
-        loader.loadTasks(loadPlan, loadOpts);
-
-        TaskStack stack = loadPlan.getTaskStack();
-        int numStackTasks = stack.getTaskCount();
-        boolean showDeferredAnimation = numStackTasks > 0;
-
-        if (sendConfigChangedEvent) {
-            EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
-                    false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
-                    numStackTasks > 0));
-        }
-        EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
-                showDeferredAnimation, stack));
-    }
-
-    @Override
-    public boolean onPreDraw() {
-        mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
-        return true;
-    }
-
-    public void onPackageChanged(String packageName, int userId) {
-        Recents.getTaskLoader().onPackageChanged(packageName);
-        EventBus.getDefault().send(new PackagesChangedEvent(packageName, userId));
-    }
-
-    @Override
-    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
-        super.dump(prefix, fd, writer, args);
-        EventBus.getDefault().dump(prefix, writer);
-        Recents.getTaskLoader().dump(prefix, writer);
-
-        String id = Integer.toHexString(System.identityHashCode(this));
-
-        writer.print(prefix); writer.print(TAG);
-        writer.print(" visible="); writer.print(mIsVisible ? "Y" : "N");
-        writer.print(" currentTime="); writer.print(System.currentTimeMillis());
-        writer.print(" [0x"); writer.print(id); writer.print("]");
-        writer.println();
-
-        if (mRecentsView != null) {
-            mRecentsView.dump(prefix, writer);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
deleted file mode 100644
index 14fda95..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents;
-
-/**
- * The launch state of the RecentsActivity.
- *
- * Current Constraints:
- *  - needed in onStart() before onNewIntent()
- *  - needs to be reset when Recents is hidden
- *  - needs to be computed in Recents component
- *  - needs to be accessible by views
- */
-public class RecentsActivityLaunchState {
-
-    public boolean launchedWithAltTab;
-    public boolean launchedFromApp;
-    // Set if the activity that we launched from entered PiP during the transition into Recents
-    public boolean launchedFromPipApp;
-    // Set if the next activity that quick-switch will launch is the PiP activity
-    public boolean launchedWithNextPipApp;
-    public boolean launchedFromHome;
-    public boolean launchedViaDragGesture;
-    public boolean launchedViaDockGesture;
-    public int launchedToTaskId;
-    public int launchedNumVisibleTasks;
-    public int launchedNumVisibleThumbnails;
-
-    public void reset() {
-        launchedFromHome = false;
-        launchedFromApp = false;
-        launchedFromPipApp = false;
-        launchedWithNextPipApp = false;
-        launchedToTaskId = -1;
-        launchedWithAltTab = false;
-        launchedViaDragGesture = false;
-        launchedViaDockGesture = false;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
deleted file mode 100644
index 68df1d5..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-
-import android.os.SystemProperties;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.views.DockState;
-import com.android.systemui.shared.recents.model.TaskStack;
-
-/**
- * Represents the dock regions for each orientation.
- */
-class DockRegion {
-    public static DockState[] PHONE_LANDSCAPE = {
-            // We only allow docking to the left in landscape for now on small devices
-            DockState.LEFT
-    };
-    public static DockState[] PHONE_PORTRAIT = {
-            // We only allow docking to the top for now on small devices
-            DockState.TOP
-    };
-    public static DockState[] TABLET_LANDSCAPE = {
-            DockState.LEFT,
-            DockState.RIGHT
-    };
-    public static DockState[] TABLET_PORTRAIT = PHONE_PORTRAIT;
-}
-
-/**
- * Application resources that can be retrieved from the application context and are not specifically
- * tied to the current activity.
- */
-public class RecentsConfiguration {
-
-    private static final int LARGE_SCREEN_MIN_DP = 600;
-    private static final int XLARGE_SCREEN_MIN_DP = 720;
-
-    // Launch states
-    public RecentsActivityLaunchState mLaunchState = new RecentsActivityLaunchState();
-
-    // Since the positions in Recents has to be calculated globally (before the RecentsActivity
-    // starts), we need to calculate some resource values ourselves, instead of relying on framework
-    // resources.
-    public final boolean isLargeScreen;
-    public final boolean isXLargeScreen;
-    public final int smallestWidth;
-
-    /** Misc **/
-    public boolean fakeShadows;
-    public int svelteLevel;
-
-    // Whether this product supports Grid-based Recents. If this is field is set to true, then
-    // Recents will layout task views in a grid mode when there's enough space in the screen.
-    public boolean isGridEnabled;
-
-    // Support for Android Recents for low ram devices. If this field is set to true, then Recents
-    // will use the alternative layout.
-    public boolean isLowRamDevice;
-
-    // Enable drag and drop split from Recents. Disabled for low ram devices.
-    public boolean dragToSplitEnabled;
-
-    private final Context mAppContext;
-
-    public RecentsConfiguration(Context context) {
-        // Load only resources that can not change after the first load either through developer
-        // settings or via multi window
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        mAppContext = context.getApplicationContext();
-        Resources res = mAppContext.getResources();
-        fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows);
-        svelteLevel = res.getInteger(R.integer.recents_svelte_level);
-        isGridEnabled = SystemProperties.getBoolean("ro.recents.grid", false);
-        isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
-        dragToSplitEnabled = !isLowRamDevice;
-
-        float screenDensity = context.getResources().getDisplayMetrics().density;
-        smallestWidth = ssp.getDeviceSmallestWidth();
-        isLargeScreen = smallestWidth >= (int) (screenDensity * LARGE_SCREEN_MIN_DP);
-        isXLargeScreen = smallestWidth >= (int) (screenDensity * XLARGE_SCREEN_MIN_DP);
-    }
-
-    /**
-     * Returns the activity launch state.
-     * TODO: This will be refactored out of RecentsConfiguration.
-     */
-    public RecentsActivityLaunchState getLaunchState() {
-        return mLaunchState;
-    }
-
-    /**
-     * Returns the preferred dock states for the current orientation.
-     * @return a list of dock states for device and its orientation
-     */
-    public DockState[] getDockStatesForCurrentOrientation() {
-        boolean isLandscape = mAppContext.getResources().getConfiguration().orientation ==
-                Configuration.ORIENTATION_LANDSCAPE;
-        RecentsConfiguration config = Recents.getConfiguration();
-        if (config.isLargeScreen) {
-            return isLandscape ? DockRegion.TABLET_LANDSCAPE : DockRegion.TABLET_PORTRAIT;
-        } else {
-            return isLandscape ? DockRegion.PHONE_LANDSCAPE : DockRegion.PHONE_PORTRAIT;
-        }
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
deleted file mode 100644
index 1918593..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents;
-
-public class RecentsDebugFlags {
-
-    public static class Static {
-        // Enables debug drawing for the transition thumbnail
-        public static final boolean EnableTransitionThumbnailDebugMode = false;
-
-        // Disables enter and exit transitions for other tasks for low ram devices
-        public static final boolean DisableRecentsLowRamEnterExitAnimation = false;
-
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
deleted file mode 100644
index d95c731..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ /dev/null
@@ -1,1132 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.view.View.MeasureSpec;
-
-import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
-
-import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.app.trust.TrustManager;
-import android.content.ActivityNotFoundException;
-import android.content.ComponentCallbacks2;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.MutableBoolean;
-import android.util.Pair;
-import android.view.LayoutInflater;
-import android.view.ViewConfiguration;
-import android.view.WindowManager;
-
-import android.widget.Toast;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.OverviewProxyService;
-import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.pip.phone.ForegroundThread;
-import com.google.android.collect.Lists;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.policy.DockedDividerUtils;
-import com.android.systemui.R;
-import com.android.systemui.SystemUIApplication;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.HideRecentsEvent;
-import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
-import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
-import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
-import com.android.systemui.recents.events.component.ActivityPinnedEvent;
-import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
-import com.android.systemui.recents.events.component.HidePipMenuEvent;
-import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
-import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
-import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
-import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
-import com.android.systemui.recents.events.ui.TaskSnapshotChangedEvent;
-import com.android.systemui.recents.misc.DozeTrigger;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
-import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
-import com.android.systemui.shared.recents.model.RecentsTaskLoader;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.Task.TaskKey;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
-import com.android.systemui.recents.views.TaskStackLayoutAlgorithm.VisibilityReport;
-import com.android.systemui.recents.views.TaskStackView;
-import com.android.systemui.recents.views.TaskViewHeader;
-import com.android.systemui.recents.views.TaskViewTransform;
-import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
-import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
-import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
-import com.android.systemui.shared.recents.view.RecentsTransition;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.stackdivider.DividerView;
-import com.android.systemui.statusbar.phone.StatusBar;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An implementation of the Recents component for the current user.  For secondary users, this can
- * be called remotely from the system user.
- */
-public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener {
-
-    private final static String TAG = "RecentsImpl";
-
-    // The minimum amount of time between each recents button press that we will handle
-    private final static int MIN_TOGGLE_DELAY_MS = 350;
-
-    // The duration within which the user releasing the alt tab (from when they pressed alt tab)
-    // that the fast alt-tab animation will run.  If the user's alt-tab takes longer than this
-    // duration, then we will toggle recents after this duration.
-    private final static int FAST_ALT_TAB_DELAY_MS = 225;
-
-    private final static ArraySet<TaskKey> EMPTY_SET = new ArraySet<>();
-
-    public final static String RECENTS_PACKAGE = "com.android.systemui";
-    public final static String RECENTS_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
-
-    /**
-     * An implementation of SysUiTaskStackChangeListener, that allows us to listen for changes to the system
-     * task stacks and update recents accordingly.
-     */
-    class TaskStackListenerImpl extends SysUiTaskStackChangeListener {
-
-        private OverviewProxyService mOverviewProxyService;
-
-        public TaskStackListenerImpl() {
-            mOverviewProxyService = Dependency.get(OverviewProxyService.class);
-        }
-
-        @Override
-        public void onTaskStackChangedBackground() {
-            // Skip background preloading recents in SystemUI if the overview services is bound
-            if (mOverviewProxyService.isEnabled()) {
-                return;
-            }
-
-            // Check this is for the right user
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
-            // Preloads the next task
-            RecentsConfiguration config = Recents.getConfiguration();
-            if (config.svelteLevel == RecentsTaskLoader.SVELTE_NONE) {
-                Rect windowRect = getWindowRect(null /* windowRectOverride */);
-                if (windowRect.isEmpty()) {
-                    return;
-                }
-
-                // Load the next task only if we aren't svelte
-                ActivityManager.RunningTaskInfo runningTaskInfo =
-                        ActivityManagerWrapper.getInstance().getRunningTask();
-                RecentsTaskLoader loader = Recents.getTaskLoader();
-                RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(mContext);
-                loader.preloadTasks(plan, -1);
-                TaskStack stack = plan.getTaskStack();
-                RecentsActivityLaunchState launchState = new RecentsActivityLaunchState();
-                RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
-
-                synchronized (mBackgroundLayoutAlgorithm) {
-                    // This callback is made when a new activity is launched and the old one is
-                    // paused so ignore the current activity and try and preload the thumbnail for
-                    // the previous one.
-                    updateDummyStackViewLayout(mBackgroundLayoutAlgorithm, stack, windowRect);
-
-                    // Launched from app is always the worst case (in terms of how many
-                    // thumbnails/tasks visible)
-                    launchState.launchedFromApp = true;
-                    mBackgroundLayoutAlgorithm.update(plan.getTaskStack(), EMPTY_SET, launchState,
-                            -1 /* lastScrollPPresent */);
-                    VisibilityReport visibilityReport =
-                            mBackgroundLayoutAlgorithm.computeStackVisibilityReport(
-                                    stack.getTasks());
-
-                    launchOpts.runningTaskId = runningTaskInfo != null ? runningTaskInfo.id : -1;
-                    launchOpts.numVisibleTasks = visibilityReport.numVisibleTasks;
-                    launchOpts.numVisibleTaskThumbnails = visibilityReport.numVisibleThumbnails;
-                    launchOpts.onlyLoadForCache = true;
-                    launchOpts.onlyLoadPausedActivities = true;
-                    launchOpts.loadThumbnails = true;
-                }
-                loader.loadTasks(plan, launchOpts);
-            }
-        }
-
-        @Override
-        public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
-            // Check this is for the right user
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
-            // This time needs to be fetched the same way the last active time is fetched in
-            // {@link TaskRecord#touchActiveTime}
-            Recents.getConfiguration().getLaunchState().launchedFromPipApp = true;
-            Recents.getConfiguration().getLaunchState().launchedWithNextPipApp = false;
-            EventBus.getDefault().send(new ActivityPinnedEvent(taskId));
-            consumeInstanceLoadPlan();
-            sLastPipTime = System.currentTimeMillis();
-        }
-
-        @Override
-        public void onActivityUnpinned() {
-            // Check this is for the right user
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
-            EventBus.getDefault().send(new ActivityUnpinnedEvent());
-            sLastPipTime = -1;
-        }
-
-        @Override
-        public void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
-            // Check this is for the right user
-            if (!checkCurrentUserId(mContext, false /* debug */)) {
-                return;
-            }
-
-            EventBus.getDefault().send(new TaskSnapshotChangedEvent(taskId, snapshot));
-        }
-    }
-
-    protected static RecentsTaskLoadPlan sInstanceLoadPlan;
-    // Stores the last pinned task time
-    protected static long sLastPipTime = -1;
-    // Stores whether we are waiting for a transition to/from recents to start. During this time,
-    // we disallow the user from manually toggling recents until the transition has started.
-    private static boolean mWaitingForTransitionStart = false;
-    // Stores whether or not the user toggled while we were waiting for a transition to/from
-    // recents. In this case, we defer the toggle state until then and apply it immediately after.
-    private static boolean mToggleFollowingTransitionStart = true;
-
-    private Runnable mResetToggleFlagListener = new Runnable() {
-        @Override
-        public void run() {
-            setWaitingForTransitionStart(false);
-        }
-    };
-
-    private TrustManager mTrustManager;
-    protected Context mContext;
-    protected Handler mHandler;
-    TaskStackListenerImpl mTaskStackListener;
-    boolean mDraggingInRecents;
-    boolean mLaunchedWhileDocking;
-
-    // Task launching
-    Rect mTmpBounds = new Rect();
-    TaskViewTransform mTmpTransform = new TaskViewTransform();
-    int mTaskBarHeight;
-
-    // Header (for transition)
-    TaskViewHeader mHeaderBar;
-    final Object mHeaderBarLock = new Object();
-    private TaskStackView mDummyStackView;
-    private TaskStackLayoutAlgorithm mBackgroundLayoutAlgorithm;
-
-    // Variables to keep track of if we need to start recents after binding
-    protected boolean mTriggeredFromAltTab;
-    protected long mLastToggleTime;
-    DozeTrigger mFastAltTabTrigger = new DozeTrigger(FAST_ALT_TAB_DELAY_MS, new Runnable() {
-        @Override
-        public void run() {
-            // When this fires, then the user has not released alt-tab for at least
-            // FAST_ALT_TAB_DELAY_MS milliseconds
-            showRecents(mTriggeredFromAltTab, false /* draggingInRecents */, true /* animate */,
-                    DividerView.INVALID_RECENTS_GROW_TARGET);
-        }
-    });
-
-    private OverviewProxyService.OverviewProxyListener mOverviewProxyListener =
-            new OverviewProxyService.OverviewProxyListener() {
-        @Override
-        public void onConnectionChanged(boolean isConnected) {
-            if (!isConnected) {
-                // Clear everything when the connection to the overview service
-                Recents.getTaskLoader().onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
-            }
-        }
-    };
-
-    // Used to reset the dummy stack view
-    private final TaskStack mEmptyTaskStack = new TaskStack();
-
-    public RecentsImpl(Context context) {
-        mContext = context;
-        mHandler = new Handler();
-        mBackgroundLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null);
-
-        // Initialize the static foreground thread
-        ForegroundThread.get();
-
-        // Register the task stack listener
-        mTaskStackListener = new TaskStackListenerImpl();
-        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
-
-        // Initialize the static configuration resources
-        mDummyStackView = new TaskStackView(mContext);
-        reloadResources();
-
-        mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-    }
-
-    public void onBootCompleted() {
-        // Skip preloading tasks if we are already bound to the service
-        if (Dependency.get(OverviewProxyService.class).isEnabled()) {
-            return;
-        }
-
-        // When we start, preload the data associated with the previous recent tasks.
-        // We can use a new plan since the caches will be the same.
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(mContext);
-        loader.preloadTasks(plan, -1);
-        RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
-        launchOpts.numVisibleTasks = loader.getIconCacheSize();
-        launchOpts.numVisibleTaskThumbnails = loader.getThumbnailCacheSize();
-        launchOpts.onlyLoadForCache = true;
-        loader.loadTasks(plan, launchOpts);
-    }
-
-    public void onConfigurationChanged() {
-        reloadResources();
-        mDummyStackView.reloadOnConfigurationChange();
-        synchronized (mBackgroundLayoutAlgorithm) {
-            mBackgroundLayoutAlgorithm.reloadOnConfigurationChange(mContext);
-        }
-    }
-
-    /**
-     * This is only called from the system user's Recents.  Secondary users will instead proxy their
-     * visibility change events through to the system user via
-     * {@link Recents#onBusEvent(RecentsVisibilityChangedEvent)}.
-     */
-    public void onVisibilityChanged(Context context, boolean visible) {
-        Recents.getSystemServices().setRecentsVisibility(visible);
-    }
-
-    /**
-     * This is only called from the system user's Recents.  Secondary users will instead proxy their
-     * visibility change events through to the system user via
-     * {@link Recents#onBusEvent(ScreenPinningRequestEvent)}.
-     */
-    public void onStartScreenPinning(Context context, int taskId) {
-        final StatusBar statusBar = getStatusBar();
-        if (statusBar != null) {
-            statusBar.showScreenPinningRequest(taskId, false);
-        }
-    }
-
-    public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents,
-            boolean animate, int growTarget) {
-        final SystemServicesProxy ssp = Recents.getSystemServices();
-        final MutableBoolean isHomeStackVisible = new MutableBoolean(true);
-        final boolean isRecentsVisible = Recents.getSystemServices().isRecentsActivityVisible(
-                isHomeStackVisible);
-        final boolean fromHome = isHomeStackVisible.value;
-        final boolean launchedWhileDockingTask =
-                Recents.getSystemServices().getSplitScreenPrimaryStack() != null;
-
-        mTriggeredFromAltTab = triggeredFromAltTab;
-        mDraggingInRecents = draggingInRecents;
-        mLaunchedWhileDocking = launchedWhileDockingTask;
-        if (mFastAltTabTrigger.isAsleep()) {
-            // Fast alt-tab duration has elapsed, fall through to showing Recents and reset
-            mFastAltTabTrigger.stopDozing();
-        } else if (mFastAltTabTrigger.isDozing()) {
-            // Fast alt-tab duration has not elapsed.  If this is triggered by a different
-            // showRecents() call, then ignore that call for now.
-            // TODO: We can not handle quick tabs that happen between the initial showRecents() call
-            //       that started the activity and the activity starting up.  The severity of this
-            //       is inversely proportional to the FAST_ALT_TAB_DELAY_MS duration though.
-            if (!triggeredFromAltTab) {
-                return;
-            }
-            mFastAltTabTrigger.stopDozing();
-        } else if (triggeredFromAltTab) {
-            // The fast alt-tab detector is not yet running, so start the trigger and wait for the
-            // hideRecents() call, or for the fast alt-tab duration to elapse
-            mFastAltTabTrigger.startDozing();
-            return;
-        }
-
-        try {
-            // Check if the top task is in the home stack, and start the recents activity
-            final boolean forceVisible = launchedWhileDockingTask || draggingInRecents;
-            if (forceVisible || !isRecentsVisible) {
-                ActivityManager.RunningTaskInfo runningTask =
-                        ActivityManagerWrapper.getInstance().getRunningTask();
-                startRecentsActivityAndDismissKeyguardIfNeeded(runningTask,
-                        isHomeStackVisible.value || fromHome, animate, growTarget);
-            }
-        } catch (ActivityNotFoundException e) {
-            Log.e(TAG, "Failed to launch RecentsActivity", e);
-        }
-    }
-
-    public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
-        if (triggeredFromAltTab && mFastAltTabTrigger.isDozing()) {
-            // The user has released alt-tab before the trigger has run, so just show the next
-            // task immediately
-            showNextTask();
-
-            // Cancel the fast alt-tab trigger
-            mFastAltTabTrigger.stopDozing();
-            return;
-        }
-
-        // Defer to the activity to handle hiding recents, if it handles it, then it must still
-        // be visible
-        EventBus.getDefault().post(new HideRecentsEvent(triggeredFromAltTab,
-                triggeredFromHomeKey));
-    }
-
-    public void toggleRecents(int growTarget) {
-        if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
-            return;
-        }
-
-        // Skip this toggle if we are already waiting to trigger recents via alt-tab
-        if (mFastAltTabTrigger.isDozing()) {
-            return;
-        }
-
-        if (mWaitingForTransitionStart) {
-            mToggleFollowingTransitionStart = true;
-            return;
-        }
-
-        mDraggingInRecents = false;
-        mLaunchedWhileDocking = false;
-        mTriggeredFromAltTab = false;
-
-        try {
-            MutableBoolean isHomeStackVisible = new MutableBoolean(true);
-            long elapsedTime = SystemClock.elapsedRealtime() - mLastToggleTime;
-
-            SystemServicesProxy ssp = Recents.getSystemServices();
-            if (ssp.isRecentsActivityVisible(isHomeStackVisible)) {
-                RecentsConfiguration config = Recents.getConfiguration();
-                RecentsActivityLaunchState launchState = config.getLaunchState();
-                if (!launchState.launchedWithAltTab) {
-                    if (Recents.getConfiguration().isGridEnabled) {
-                        // Has the user tapped quickly?
-                        boolean isQuickTap = elapsedTime < ViewConfiguration.getDoubleTapTimeout();
-                        if (isQuickTap) {
-                            EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
-                        } else {
-                            EventBus.getDefault().post(new LaunchMostRecentTaskRequestEvent());
-                        }
-                    } else {
-                        // Launch the next focused task
-                        EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
-                    }
-                } else {
-                    // If the user has toggled it too quickly, then just eat up the event here (it's
-                    // better than showing a janky screenshot).
-                    // NOTE: Ideally, the screenshot mechanism would take the window transform into
-                    // account
-                    if (elapsedTime < MIN_TOGGLE_DELAY_MS) {
-                        return;
-                    }
-
-                    EventBus.getDefault().post(new ToggleRecentsEvent());
-                    mLastToggleTime = SystemClock.elapsedRealtime();
-                }
-                return;
-            } else {
-                // If the user has toggled it too quickly, then just eat up the event here (it's
-                // better than showing a janky screenshot).
-                // NOTE: Ideally, the screenshot mechanism would take the window transform into
-                // account
-                if (elapsedTime < MIN_TOGGLE_DELAY_MS) {
-                    return;
-                }
-
-                // Otherwise, start the recents activity
-                ActivityManager.RunningTaskInfo runningTask =
-                        ActivityManagerWrapper.getInstance().getRunningTask();
-                startRecentsActivityAndDismissKeyguardIfNeeded(runningTask,
-                        isHomeStackVisible.value, true /* animate */, growTarget);
-
-                // Only close the other system windows if we are actually showing recents
-                ActivityManagerWrapper.getInstance().closeSystemWindows(
-                        SYSTEM_DIALOG_REASON_RECENT_APPS);
-                mLastToggleTime = SystemClock.elapsedRealtime();
-            }
-        } catch (ActivityNotFoundException e) {
-            Log.e(TAG, "Failed to launch RecentsActivity", e);
-        }
-    }
-
-    public void preloadRecents() {
-        if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
-            return;
-        }
-
-        // Skip preloading recents when keyguard is showing
-        final StatusBar statusBar = getStatusBar();
-        if (statusBar != null && statusBar.isKeyguardShowing()) {
-            return;
-        }
-
-        // Preload only the raw task list into a new load plan (which will be consumed by the
-        // RecentsActivity) only if there is a task to animate to.  Post this to ensure that we
-        // don't block the touch feedback on the nav bar button which triggers this.
-        mHandler.post(() -> {
-            SystemServicesProxy ssp = Recents.getSystemServices();
-            if (!ssp.isRecentsActivityVisible(null)) {
-                ActivityManager.RunningTaskInfo runningTask =
-                        ActivityManagerWrapper.getInstance().getRunningTask();
-                if (runningTask == null) {
-                    return;
-                }
-
-                RecentsTaskLoader loader = Recents.getTaskLoader();
-                sInstanceLoadPlan = new RecentsTaskLoadPlan(mContext);
-                loader.preloadTasks(sInstanceLoadPlan, runningTask.id);
-                TaskStack stack = sInstanceLoadPlan.getTaskStack();
-                if (stack.getTaskCount() > 0) {
-                    // Only preload the icon (but not the thumbnail since it may not have been taken
-                    // for the pausing activity)
-                    preloadIcon(runningTask.id);
-
-                    // At this point, we don't know anything about the stack state.  So only
-                    // calculate the dimensions of the thumbnail that we need for the transition
-                    // into Recents, but do not draw it until we construct the activity options when
-                    // we start Recents
-                    updateHeaderBarLayout(stack, null /* window rect override*/);
-                }
-            }
-        });
-    }
-
-    public void cancelPreloadingRecents() {
-        // Do nothing
-    }
-
-    public void onDraggingInRecents(float distanceFromTop) {
-        EventBus.getDefault().sendOntoMainThread(new DraggingInRecentsEvent(distanceFromTop));
-    }
-
-    public void onDraggingInRecentsEnded(float velocity) {
-        EventBus.getDefault().sendOntoMainThread(new DraggingInRecentsEndedEvent(velocity));
-    }
-
-    public void onShowCurrentUserToast(int msgResId, int msgLength) {
-        Toast.makeText(mContext, msgResId, msgLength).show();
-    }
-
-    /**
-     * Transitions to the next recent task in the stack.
-     */
-    public void showNextTask() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(mContext);
-        loader.preloadTasks(plan, -1);
-        TaskStack focusedStack = plan.getTaskStack();
-
-        // Return early if there are no tasks in the focused stack
-        if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
-
-        // Return early if there is no running task
-        ActivityManager.RunningTaskInfo runningTask =
-                ActivityManagerWrapper.getInstance().getRunningTask();
-        if (runningTask == null) return;
-
-        // Find the task in the recents list
-        boolean isRunningTaskInHomeStack =
-                runningTask.configuration.windowConfiguration.getActivityType()
-                        == ACTIVITY_TYPE_HOME;
-        ArrayList<Task> tasks = focusedStack.getTasks();
-        Task toTask = null;
-        ActivityOptions launchOpts = null;
-        int taskCount = tasks.size();
-        for (int i = taskCount - 1; i >= 1; i--) {
-            Task task = tasks.get(i);
-            if (isRunningTaskInHomeStack) {
-                toTask = tasks.get(i - 1);
-                launchOpts = ActivityOptions.makeCustomAnimation(mContext,
-                        R.anim.recents_launch_next_affiliated_task_target,
-                        R.anim.recents_fast_toggle_app_home_exit);
-                break;
-            } else if (task.key.id == runningTask.id) {
-                toTask = tasks.get(i - 1);
-                launchOpts = ActivityOptions.makeCustomAnimation(mContext,
-                        R.anim.recents_launch_prev_affiliated_task_target,
-                        R.anim.recents_launch_prev_affiliated_task_source);
-                break;
-            }
-        }
-
-        // Return early if there is no next task
-        if (toTask == null) {
-            ssp.startInPlaceAnimationOnFrontMostApplication(
-                    ActivityOptions.makeCustomInPlaceAnimation(mContext,
-                            R.anim.recents_launch_prev_affiliated_task_bounce));
-            return;
-        }
-
-        // Launch the task
-        ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(toTask.key, launchOpts,
-                null /* resultCallback */, null /* resultCallbackHandler */);
-    }
-
-    /**
-     * Transitions to the next affiliated task.
-     */
-    public void showRelativeAffiliatedTask(boolean showNextTask) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(mContext);
-        loader.preloadTasks(plan, -1);
-        TaskStack focusedStack = plan.getTaskStack();
-
-        // Return early if there are no tasks in the focused stack
-        if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
-
-        // Return early if there is no running task (can't determine affiliated tasks in this case)
-        ActivityManager.RunningTaskInfo runningTask =
-                ActivityManagerWrapper.getInstance().getRunningTask();
-        final int activityType = runningTask.configuration.windowConfiguration.getActivityType();
-        if (runningTask == null) return;
-        // Return early if the running task is in the home/recents stack (optimization)
-        if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) return;
-
-        // Find the task in the recents list
-        ArrayList<Task> tasks = focusedStack.getTasks();
-        Task toTask = null;
-        ActivityOptions launchOpts = null;
-        int taskCount = tasks.size();
-        for (int i = 0; i < taskCount; i++) {
-            Task task = tasks.get(i);
-            if (task.key.id == runningTask.id) {
-                if (showNextTask) {
-                    if ((i + 1) < taskCount) {
-                        toTask = tasks.get(i + 1);
-                        launchOpts = ActivityOptions.makeCustomAnimation(mContext,
-                                R.anim.recents_launch_next_affiliated_task_target,
-                                R.anim.recents_launch_next_affiliated_task_source);
-                    }
-                } else {
-                    if ((i - 1) >= 0) {
-                        toTask = tasks.get(i - 1);
-                        launchOpts = ActivityOptions.makeCustomAnimation(mContext,
-                                R.anim.recents_launch_prev_affiliated_task_target,
-                                R.anim.recents_launch_prev_affiliated_task_source);
-                    }
-                }
-                break;
-            }
-        }
-
-        // Return early if there is no next task
-        if (toTask == null) {
-            if (showNextTask) {
-                ssp.startInPlaceAnimationOnFrontMostApplication(
-                        ActivityOptions.makeCustomInPlaceAnimation(mContext,
-                                R.anim.recents_launch_next_affiliated_task_bounce));
-            } else {
-                ssp.startInPlaceAnimationOnFrontMostApplication(
-                        ActivityOptions.makeCustomInPlaceAnimation(mContext,
-                                R.anim.recents_launch_prev_affiliated_task_bounce));
-            }
-            return;
-        }
-
-        // Keep track of actually launched affiliated tasks
-        MetricsLogger.count(mContext, "overview_affiliated_task_launch", 1);
-
-        // Launch the task
-        ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(toTask.key, launchOpts,
-                null /* resultListener */, null /* resultCallbackHandler */);
-    }
-
-    public void showNextAffiliatedTask() {
-        // Keep track of when the affiliated task is triggered
-        MetricsLogger.count(mContext, "overview_affiliated_task_next", 1);
-        showRelativeAffiliatedTask(true);
-    }
-
-    public void showPrevAffiliatedTask() {
-        // Keep track of when the affiliated task is triggered
-        MetricsLogger.count(mContext, "overview_affiliated_task_prev", 1);
-        showRelativeAffiliatedTask(false);
-    }
-
-    public void splitPrimaryTask(int taskId, int stackCreateMode, Rect initialBounds) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-
-        // Make sure we inform DividerView before we actually start the activity so we can change
-        // the resize mode already.
-        if (ssp.setTaskWindowingModeSplitScreenPrimary(taskId, stackCreateMode, initialBounds)) {
-            EventBus.getDefault().send(new DockedTopTaskEvent(initialBounds));
-        }
-    }
-
-    public void setWaitingForTransitionStart(boolean waitingForTransitionStart) {
-        if (mWaitingForTransitionStart == waitingForTransitionStart) {
-            return;
-        }
-
-        mWaitingForTransitionStart = waitingForTransitionStart;
-        if (!waitingForTransitionStart && mToggleFollowingTransitionStart) {
-            mHandler.post(() -> toggleRecents(DividerView.INVALID_RECENTS_GROW_TARGET));
-        }
-        mToggleFollowingTransitionStart = false;
-    }
-
-    /**
-     * Returns the preloaded load plan and invalidates it.
-     */
-    public static RecentsTaskLoadPlan consumeInstanceLoadPlan() {
-        RecentsTaskLoadPlan plan = sInstanceLoadPlan;
-        sInstanceLoadPlan = null;
-        return plan;
-    }
-
-    /**
-     * @return the time at which a task last entered picture-in-picture.
-     */
-    public static long getLastPipTime() {
-        return sLastPipTime;
-    }
-
-    /**
-     * Clears the time at which a task last entered picture-in-picture.
-     */
-    public static void clearLastPipTime() {
-        sLastPipTime = -1;
-    }
-
-    /**
-     * Reloads all the resources for the current configuration.
-     */
-    private void reloadResources() {
-        Resources res = mContext.getResources();
-
-        mTaskBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(mContext,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height_tablet_land,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height_tablet_land,
-                R.dimen.recents_grid_task_view_header_height);
-
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        mHeaderBar = (TaskViewHeader) inflater.inflate(R.layout.recents_task_view_header,
-                null, false);
-        mHeaderBar.setLayoutDirection(res.getConfiguration().getLayoutDirection());
-    }
-
-    private void updateDummyStackViewLayout(TaskStackLayoutAlgorithm stackLayout,
-            TaskStack stack, Rect windowRect) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        Rect displayRect = ssp.getDisplayRect();
-        Rect systemInsets = new Rect();
-        ssp.getStableInsets(systemInsets);
-
-        // When docked, the nav bar insets are consumed and the activity is measured without insets.
-        // However, the window bounds include the insets, so we need to subtract them here to make
-        // them identical.
-        if (ssp.hasDockedTask()) {
-            if (systemInsets.bottom < windowRect.height()) {
-                // Only apply inset if it isn't going to cause the rect height to go negative.
-                windowRect.bottom -= systemInsets.bottom;
-            }
-            systemInsets.bottom = 0;
-        }
-        calculateWindowStableInsets(systemInsets, windowRect, displayRect);
-        windowRect.offsetTo(0, 0);
-
-        // Rebind the header bar and draw it for the transition
-        stackLayout.setSystemInsets(systemInsets);
-        if (stack != null) {
-            stackLayout.getTaskStackBounds(displayRect, windowRect, systemInsets.top,
-                    systemInsets.left, systemInsets.right, mTmpBounds);
-            stackLayout.reset();
-            stackLayout.initialize(displayRect, windowRect, mTmpBounds);
-        }
-    }
-
-    private Rect getWindowRect(Rect windowRectOverride) {
-       return windowRectOverride != null
-                ? new Rect(windowRectOverride)
-                : Recents.getSystemServices().getWindowRect();
-    }
-
-    /**
-     * Prepares the header bar layout for the next transition, if the task view bounds has changed
-     * since the last call, it will attempt to re-measure and layout the header bar to the new size.
-     *
-     * @param stack the stack to initialize the stack layout with
-     * @param windowRectOverride the rectangle to use when calculating the stack state which can
-     *                           be different from the current window rect if recents is resizing
-     *                           while being launched
-     */
-    private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) {
-        Rect windowRect = getWindowRect(windowRectOverride);
-        int taskViewWidth = 0;
-        boolean useGridLayout = mDummyStackView.useGridLayout();
-        updateDummyStackViewLayout(mDummyStackView.getStackAlgorithm(), stack, windowRect);
-        if (stack != null) {
-            TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
-            mDummyStackView.getStack().removeAllTasks(false /* notifyStackChanges */);
-            mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
-            // Get the width of a task view so that we know how wide to draw the header bar.
-            if (useGridLayout) {
-                TaskGridLayoutAlgorithm gridLayout = mDummyStackView.getGridAlgorithm();
-                gridLayout.initialize(windowRect);
-                taskViewWidth = (int) gridLayout.getTransform(0 /* taskIndex */,
-                        stack.getTaskCount(), new TaskViewTransform(),
-                        stackLayout).rect.width();
-            } else {
-                Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
-                if (!taskViewBounds.isEmpty()) {
-                    taskViewWidth = taskViewBounds.width();
-                }
-            }
-        }
-
-        if (stack != null && taskViewWidth > 0) {
-            synchronized (mHeaderBarLock) {
-                if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
-                        mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
-                    if (useGridLayout) {
-                        mHeaderBar.setShouldDarkenBackgroundColor(true);
-                        mHeaderBar.setNoUserInteractionState();
-                    }
-                    mHeaderBar.forceLayout();
-                    mHeaderBar.measure(
-                            MeasureSpec.makeMeasureSpec(taskViewWidth, MeasureSpec.EXACTLY),
-                            MeasureSpec.makeMeasureSpec(mTaskBarHeight, MeasureSpec.EXACTLY));
-                }
-                mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
-            }
-        }
-    }
-
-    /**
-     * Given the stable insets and the rect for our window, calculates the insets that affect our
-     * window.
-     */
-    private void calculateWindowStableInsets(Rect inOutInsets, Rect windowRect, Rect displayRect) {
-
-        // Display rect without insets - available app space
-        Rect appRect = new Rect(displayRect);
-        appRect.inset(inOutInsets);
-
-        // Our window intersected with available app space
-        Rect windowRectWithInsets = new Rect(windowRect);
-        windowRectWithInsets.intersect(appRect);
-        inOutInsets.left = windowRectWithInsets.left - windowRect.left;
-        inOutInsets.top = windowRectWithInsets.top - windowRect.top;
-        inOutInsets.right = windowRect.right - windowRectWithInsets.right;
-        inOutInsets.bottom = windowRect.bottom - windowRectWithInsets.bottom;
-    }
-
-    /**
-     * Preloads the icon of a task.
-     */
-    private void preloadIcon(int runningTaskId) {
-        // Ensure that we load the running task's icon
-        RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
-        launchOpts.runningTaskId = runningTaskId;
-        launchOpts.loadThumbnails = false;
-        launchOpts.onlyLoadForCache = true;
-        Recents.getTaskLoader().loadTasks(sInstanceLoadPlan, launchOpts);
-    }
-
-    /**
-     * Creates the activity options for a unknown state->recents transition.
-     */
-    protected ActivityOptions getUnknownTransitionActivityOptions() {
-        return ActivityOptions.makeCustomAnimation(mContext,
-                R.anim.recents_from_unknown_enter,
-                R.anim.recents_from_unknown_exit,
-                mHandler, null);
-    }
-
-    /**
-     * Creates the activity options for a home->recents transition.
-     */
-    protected ActivityOptions getHomeTransitionActivityOptions() {
-        return ActivityOptions.makeCustomAnimation(mContext,
-                R.anim.recents_from_launcher_enter,
-                R.anim.recents_from_launcher_exit,
-                mHandler, null);
-    }
-
-    /**
-     * Creates the activity options for an app->recents transition.
-     */
-    private Pair<ActivityOptions, AppTransitionAnimationSpecsFuture>
-            getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo runningTask,
-                    Rect windowOverrideRect) {
-        final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice;
-
-        // Update the destination rect
-        Task toTask = new Task();
-        TaskViewTransform toTransform = getThumbnailTransitionTransform(mDummyStackView, toTask,
-                windowOverrideRect);
-
-        RectF toTaskRect = toTransform.rect;
-        AppTransitionAnimationSpecsFuture future = new AppTransitionAnimationSpecsFuture(mHandler) {
-            @Override
-            public List<AppTransitionAnimationSpecCompat> composeSpecs() {
-                Rect rect = new Rect();
-                toTaskRect.round(rect);
-                Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform);
-                return Lists.newArrayList(new AppTransitionAnimationSpecCompat(toTask.key.id,
-                        thumbnail, rect));
-            }
-        };
-
-        // For low end ram devices, wait for transition flag is reset when Recents entrance
-        // animation is complete instead of when the transition animation starts
-        return new Pair<>(RecentsTransition.createAspectScaleAnimation(mContext, mHandler,
-                false /* scaleUp */, future, isLowRamDevice ? null : mResetToggleFlagListener),
-                future);
-    }
-
-    /**
-     * Returns the transition rect for the given task id.
-     */
-    private TaskViewTransform getThumbnailTransitionTransform(TaskStackView stackView,
-            Task runningTaskOut, Rect windowOverrideRect) {
-        // Find the running task in the TaskStack
-        TaskStack stack = stackView.getStack();
-        Task launchTask = stack.getLaunchTarget();
-        if (launchTask != null) {
-            runningTaskOut.copyFrom(launchTask);
-        } else {
-            // If no task is specified or we can not find the task just use the front most one
-            launchTask = stack.getFrontMostTask();
-            runningTaskOut.copyFrom(launchTask);
-        }
-
-        // Get the transform for the running task
-        stackView.updateLayoutAlgorithm(true /* boundScroll */);
-        stackView.updateToInitialState();
-        stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
-                stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect);
-        return mTmpTransform;
-    }
-
-    /**
-     * Draws the header of a task used for the window animation into a bitmap.
-     */
-    private Bitmap drawThumbnailTransitionBitmap(Task toTask,
-            TaskViewTransform toTransform) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        int width = (int) toTransform.rect.width();
-        int height = (int) toTransform.rect.height();
-        if (toTransform != null && toTask.key != null && width > 0 && height > 0) {
-            synchronized (mHeaderBarLock) {
-                boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode();
-                mHeaderBar.onTaskViewSizeChanged(width, height);
-                if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
-                    return RecentsTransition.drawViewIntoHardwareBitmap(width, mTaskBarHeight,
-                            null, 1f, 0xFFff0000);
-                } else {
-                    // Workaround for b/27815919, reset the callback so that we do not trigger an
-                    // invalidate on the header bar as a result of updating the icon
-                    Drawable icon = mHeaderBar.getIconView().getDrawable();
-                    if (icon != null) {
-                        icon.setCallback(null);
-                    }
-                    mHeaderBar.bindToTask(toTask, false /* touchExplorationEnabled */,
-                            disabledInSafeMode);
-                    mHeaderBar.onTaskDataLoaded();
-                    mHeaderBar.setDimAlpha(toTransform.dimAlpha);
-                    return RecentsTransition.drawViewIntoHardwareBitmap(width, mTaskBarHeight,
-                            mHeaderBar, 1f, 0);
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Shows the recents activity after dismissing the keyguard if visible
-     */
-    protected void startRecentsActivityAndDismissKeyguardIfNeeded(
-            final ActivityManager.RunningTaskInfo runningTask, final boolean isHomeStackVisible,
-            final boolean animate, final int growTarget) {
-        // Preload only if device for current user is unlocked
-        final StatusBar statusBar = getStatusBar();
-        if (statusBar != null && statusBar.isKeyguardShowing()) {
-            statusBar.executeRunnableDismissingKeyguard(() -> {
-                    // Flush trustmanager before checking device locked per user when preloading
-                    mTrustManager.reportKeyguardShowingChanged();
-                    mHandler.post(() -> startRecentsActivity(runningTask, isHomeStackVisible,
-                            animate, growTarget));
-                }, null,  true /* dismissShade */, false /* afterKeyguardGone */,
-                true /* deferred */);
-        } else {
-            startRecentsActivity(runningTask, isHomeStackVisible, animate, growTarget);
-        }
-    }
-
-    private void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
-            boolean isHomeStackVisible, boolean animate, int growTarget) {
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-
-        int runningTaskId = !mLaunchedWhileDocking && (runningTask != null)
-                ? runningTask.id
-                : -1;
-
-        // In the case where alt-tab is triggered, we never get a preloadRecents() call, so we
-        // should always preload the tasks now. If we are dragging in recents, reload them as
-        // the stacks might have changed.
-        if (mLaunchedWhileDocking || mTriggeredFromAltTab || sInstanceLoadPlan == null) {
-            // Create a new load plan if preloadRecents() was never triggered
-            sInstanceLoadPlan = new RecentsTaskLoadPlan(mContext);
-        }
-        if (mLaunchedWhileDocking || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
-            loader.preloadTasks(sInstanceLoadPlan, runningTaskId);
-        }
-
-        TaskStack stack = sInstanceLoadPlan.getTaskStack();
-        boolean hasRecentTasks = stack.getTaskCount() > 0;
-        boolean useThumbnailTransition = (runningTask != null) && !isHomeStackVisible &&
-                hasRecentTasks;
-
-        // Update the launch state that we need in updateHeaderBarLayout()
-        launchState.launchedFromHome = !useThumbnailTransition && !mLaunchedWhileDocking;
-        launchState.launchedFromApp = useThumbnailTransition || mLaunchedWhileDocking;
-        launchState.launchedFromPipApp = false;
-        launchState.launchedWithNextPipApp =
-                stack.isNextLaunchTargetPip(RecentsImpl.getLastPipTime());
-        launchState.launchedViaDockGesture = mLaunchedWhileDocking;
-        launchState.launchedViaDragGesture = mDraggingInRecents;
-        launchState.launchedToTaskId = runningTaskId;
-        launchState.launchedWithAltTab = mTriggeredFromAltTab;
-
-        // Disable toggling of recents between starting the activity and it is visible and the app
-        // has started its transition into recents.
-        setWaitingForTransitionStart(useThumbnailTransition);
-
-        // Preload the icon (this will be a null-op if we have preloaded the icon already in
-        // preloadRecents())
-        preloadIcon(runningTaskId);
-
-        // Update the header bar if necessary
-        Rect windowOverrideRect = getWindowRectOverride(growTarget);
-        updateHeaderBarLayout(stack, windowOverrideRect);
-
-        // Prepare the dummy stack for the transition
-        TaskStackLayoutAlgorithm.VisibilityReport stackVr =
-                mDummyStackView.computeStackVisibilityReport();
-
-        // Update the remaining launch state
-        launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks;
-        launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails;
-
-        if (!animate) {
-            startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext, -1, -1),
-                    null /* future */);
-            return;
-        }
-
-        Pair<ActivityOptions, AppTransitionAnimationSpecsFuture> pair;
-        if (useThumbnailTransition) {
-            // Try starting with a thumbnail transition
-            pair = getThumbnailTransitionActivityOptions(runningTask, windowOverrideRect);
-        } else {
-            // If there is no thumbnail transition, but is launching from home into recents, then
-            // use a quick home transition
-            pair = new Pair<>(hasRecentTasks
-                    ? getHomeTransitionActivityOptions()
-                    : getUnknownTransitionActivityOptions(), null);
-        }
-        startRecentsActivity(pair.first, pair.second);
-        mLastToggleTime = SystemClock.elapsedRealtime();
-    }
-
-    private Rect getWindowRectOverride(int growTarget) {
-        if (growTarget == DividerView.INVALID_RECENTS_GROW_TARGET) {
-            return SystemServicesProxy.getInstance(mContext).getWindowRect();
-        }
-        Rect result = new Rect();
-        Rect displayRect = Recents.getSystemServices().getDisplayRect();
-        DockedDividerUtils.calculateBoundsForPosition(growTarget, WindowManager.DOCKED_BOTTOM,
-                result, displayRect.width(), displayRect.height(),
-                Recents.getSystemServices().getDockedDividerSize(mContext));
-        return result;
-    }
-
-    private StatusBar getStatusBar() {
-        return SysUiServiceProvider.getComponent(mContext, StatusBar.class);
-    }
-
-    /**
-     * Starts the recents activity.
-     */
-    private void startRecentsActivity(ActivityOptions opts,
-            final AppTransitionAnimationSpecsFuture future) {
-        Intent intent = new Intent();
-        intent.setClassName(RECENTS_PACKAGE, RECENTS_ACTIVITY);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
-        HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
-        hideMenuEvent.addPostAnimationCallback(() -> {
-            Recents.getSystemServices().startActivityAsUserAsync(intent, opts);
-            EventBus.getDefault().send(new RecentsActivityStartingEvent());
-            if (future != null) {
-                future.composeSpecsSynchronous();
-            }
-        });
-        EventBus.getDefault().send(hideMenuEvent);
-
-        // Once we have launched the activity, reset the dummy stack view tasks so we don't hold
-        // onto references to the same tasks consumed by the activity
-        mDummyStackView.setTasks(mEmptyTaskStack, false /* notifyStackChanges */);
-    }
-
-    /**** OnAnimationFinishedListener Implementation ****/
-
-    @Override
-    public void onAnimationFinished() {
-        EventBus.getDefault().post(new EnterRecentsWindowLastAnimationFrameEvent());
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
deleted file mode 100644
index a1da785..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents;
-
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-
-import com.android.internal.os.SomeArgs;
-
-/**
- * A proxy class which directs all methods from {@link IRecentsNonSystemUserCallbacks} to
- * {@link RecentsImpl} and makes sure they are called from the main thread.
- */
-public class RecentsImplProxy extends IRecentsNonSystemUserCallbacks.Stub {
-
-    private static final int MSG_PRELOAD_RECENTS = 1;
-    private static final int MSG_CANCEL_PRELOADING_RECENTS = 2;
-    private static final int MSG_SHOW_RECENTS = 3;
-    private static final int MSG_HIDE_RECENTS = 4;
-    private static final int MSG_TOGGLE_RECENTS = 5;
-    private static final int MSG_ON_CONFIGURATION_CHANGED = 6;
-    private static final int MSG_DOCK_TOP_TASK = 7;
-    private static final int MSG_ON_DRAGGING_IN_RECENTS = 8;
-    private static final int MSG_ON_DRAGGING_IN_RECENTS_ENDED = 9;
-    private static final int MSG_SHOW_USER_TOAST = 10;
-
-    private RecentsImpl mImpl;
-
-    public RecentsImplProxy(RecentsImpl recentsImpl) {
-        mImpl = recentsImpl;
-    }
-
-    @Override
-    public void preloadRecents() throws RemoteException {
-        mHandler.sendEmptyMessage(MSG_PRELOAD_RECENTS);
-    }
-
-    @Override
-    public void cancelPreloadingRecents() throws RemoteException {
-        mHandler.sendEmptyMessage(MSG_CANCEL_PRELOADING_RECENTS);
-    }
-
-    @Override
-    public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, boolean animate,
-            int growTarget) throws RemoteException {
-        SomeArgs args = SomeArgs.obtain();
-        args.argi1 = triggeredFromAltTab ? 1 : 0;
-        args.argi2 = draggingInRecents ? 1 : 0;
-        args.argi3 = animate ? 1 : 0;
-        args.argi4 = growTarget;
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_SHOW_RECENTS, args));
-    }
-
-    @Override
-    public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)
-            throws RemoteException {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_HIDE_RECENTS, triggeredFromAltTab ? 1 :0,
-                triggeredFromHomeKey ? 1 : 0));
-    }
-
-    @Override
-    public void toggleRecents(int growTarget) throws RemoteException {
-        SomeArgs args = SomeArgs.obtain();
-        args.argi1 = growTarget;
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_TOGGLE_RECENTS, args));
-    }
-
-    @Override
-    public void onConfigurationChanged() throws RemoteException {
-        mHandler.sendEmptyMessage(MSG_ON_CONFIGURATION_CHANGED);
-    }
-
-    @Override
-    public void splitPrimaryTask(int topTaskId, int stackCreateMode, Rect initialBounds)
-            throws RemoteException {
-        SomeArgs args = SomeArgs.obtain();
-        args.argi1 = topTaskId;
-        args.argi2 = stackCreateMode;
-        args.arg1 = initialBounds;
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_DOCK_TOP_TASK, args));
-    }
-
-    @Override
-    public void onDraggingInRecents(float distanceFromTop) throws RemoteException {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_DRAGGING_IN_RECENTS, distanceFromTop));
-    }
-
-    @Override
-    public void onDraggingInRecentsEnded(float velocity) throws RemoteException {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_DRAGGING_IN_RECENTS_ENDED, velocity));
-    }
-
-    @Override
-    public void showCurrentUserToast(int msgResId, int msgLength) {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_SHOW_USER_TOAST, msgResId, msgLength));
-    }
-
-    private final Handler mHandler = new Handler() {
-
-        @Override
-        public void handleMessage(Message msg) {
-            SomeArgs args;
-            switch (msg.what) {
-                case MSG_PRELOAD_RECENTS:
-                    mImpl.preloadRecents();
-                    break;
-                case MSG_CANCEL_PRELOADING_RECENTS:
-                    mImpl.cancelPreloadingRecents();
-                    break;
-                case MSG_SHOW_RECENTS:
-                    args = (SomeArgs) msg.obj;
-                    mImpl.showRecents(args.argi1 != 0, args.argi2 != 0, args.argi3 != 0,
-                            args.argi4);
-                    break;
-                case MSG_HIDE_RECENTS:
-                    mImpl.hideRecents(msg.arg1 != 0, msg.arg2 != 0);
-                    break;
-                case MSG_TOGGLE_RECENTS:
-                    args = (SomeArgs) msg.obj;
-                    mImpl.toggleRecents(args.argi1);
-                    break;
-                case MSG_ON_CONFIGURATION_CHANGED:
-                    mImpl.onConfigurationChanged();
-                    break;
-                case MSG_DOCK_TOP_TASK:
-                    args = (SomeArgs) msg.obj;
-                    mImpl.splitPrimaryTask(args.argi1, args.argi2 = 0,
-                            (Rect) args.arg1);
-                    break;
-                case MSG_ON_DRAGGING_IN_RECENTS:
-                    mImpl.onDraggingInRecents((Float) msg.obj);
-                    break;
-                case MSG_ON_DRAGGING_IN_RECENTS_ENDED:
-                    mImpl.onDraggingInRecentsEnded((Float) msg.obj);
-                    break;
-                case MSG_SHOW_USER_TOAST:
-                    mImpl.onShowCurrentUserToast(msg.arg1, msg.arg2);
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-            super.handleMessage(msg);
-        }
-    };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
new file mode 100644
index 0000000..8a04c11
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.systemui.recents;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import com.android.systemui.SysUiServiceProvider;
+import java.io.PrintWriter;
+
+interface RecentsImplementation {
+    default void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {}
+    default void onBootCompleted() {}
+    default void onAppTransitionFinished() {}
+    default void onConfigurationChanged(Configuration newConfig) {}
+
+    default void preloadRecentApps() {}
+    default void cancelPreloadRecentApps() {}
+    default void showRecentApps(boolean triggeredFromAltTab) {}
+    default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {}
+    default void toggleRecentApps() {}
+    default void growRecents() {}
+    default boolean splitPrimaryTask(int stackCreateMode, Rect initialBounds,
+            int metricsDockAction) {
+        return false;
+    }
+
+    default void dump(PrintWriter pw) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index db2b69f..af0ebdc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -59,13 +59,11 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.android.systemui.OverviewProxyService;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-
+import com.android.systemui.shared.system.TaskStackChangeListener;
 import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.HashSet;
@@ -119,7 +117,7 @@
     private int mNumAppsLaunchedSinceSwipeUpTipDismiss;
     private int mOverviewOpenedCountSinceQuickScrubTipDismiss;
 
-    private final SysUiTaskStackChangeListener mTaskListener = new SysUiTaskStackChangeListener() {
+    private final TaskStackChangeListener mTaskListener = new TaskStackChangeListener() {
         private String mLastPackageName;
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
deleted file mode 100644
index c5e9f04..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.systemui.EventLogConstants;
-import com.android.systemui.EventLogTags;
-import com.android.systemui.pip.phone.ForegroundThread;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
-import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
-import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
-
-/**
- * An implementation of the system user's Recents interface to be called remotely by secondary
- * users.
- */
-public class RecentsSystemUser extends IRecentsSystemUserCallbacks.Stub {
-
-    private static final String TAG = "RecentsSystemUser";
-
-    private Context mContext;
-    private RecentsImpl mImpl;
-    private final SparseArray<IRecentsNonSystemUserCallbacks> mNonSystemUserRecents =
-            new SparseArray<>();
-
-    public RecentsSystemUser(Context context, RecentsImpl impl) {
-        mContext = context;
-        mImpl = impl;
-    }
-
-    @Override
-    public void registerNonSystemUserCallbacks(final IBinder nonSystemUserCallbacks,
-            final int userId) {
-        try {
-            final IRecentsNonSystemUserCallbacks callback =
-                    IRecentsNonSystemUserCallbacks.Stub.asInterface(nonSystemUserCallbacks);
-            nonSystemUserCallbacks.linkToDeath(new IBinder.DeathRecipient() {
-                @Override
-                public void binderDied() {
-                    mNonSystemUserRecents.removeAt(mNonSystemUserRecents.indexOfValue(callback));
-                    EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
-                            EventLogConstants.SYSUI_RECENTS_CONNECTION_SYSTEM_UNREGISTER_USER,
-                            userId);
-                }
-            }, 0);
-            mNonSystemUserRecents.put(userId, callback);
-            EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
-                    EventLogConstants.SYSUI_RECENTS_CONNECTION_SYSTEM_REGISTER_USER, userId);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to register NonSystemUserCallbacks", e);
-        }
-    }
-
-    public IRecentsNonSystemUserCallbacks getNonSystemUserRecentsForUser(int userId) {
-        return mNonSystemUserRecents.get(userId);
-    }
-
-    @Override
-    public void updateRecentsVisibility(boolean visible) {
-        ForegroundThread.getHandler().post(() -> {
-            mImpl.onVisibilityChanged(mContext, visible);
-        });
-    }
-
-    @Override
-    public void startScreenPinning(int taskId) {
-        ForegroundThread.getHandler().post(() -> {
-            mImpl.onStartScreenPinning(mContext, taskId);
-        });
-    }
-
-    @Override
-    public void sendRecentsDrawnEvent() {
-        EventBus.getDefault().post(new RecentsDrawnEvent());
-    }
-
-    @Override
-    public void sendDockingTopTaskEvent(Rect initialRect) throws RemoteException {
-        EventBus.getDefault().post(new DockedTopTaskEvent(initialRect));
-    }
-
-    @Override
-    public void sendLaunchRecentsEvent() throws RemoteException {
-        EventBus.getDefault().post(new RecentsActivityStartingEvent());
-    }
-
-    @Override
-    public void sendDockedFirstAnimationFrameEvent() throws RemoteException {
-        EventBus.getDefault().post(new DockedFirstAnimationFrameEvent());
-    }
-
-    @Override
-    public void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
-        EventBus.getDefault().post(new SetWaitingForTransitionStartEvent(
-                waitingForTransitionStart));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUserService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUserService.java
deleted file mode 100644
index b4212d3..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUserService.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 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.systemui.recents;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-import android.util.Log;
-
-import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.SystemUIApplication;
-
-/**
- * A strictly system-user service that is started by the secondary user's Recents (with a limited
- * lifespan), to get the interface that the secondary user's Recents can call through to the system
- * user's Recents.
- */
-public class RecentsSystemUserService extends Service {
-
-    private static final String TAG = "RecentsSystemUserService";
-    private static final boolean DEBUG = false;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        Recents recents = SysUiServiceProvider.getComponent(this, Recents.class);
-        if (DEBUG) {
-            Log.d(TAG, "onBind: " + recents);
-        }
-        if (recents != null) {
-            return recents.getSystemUserCallbacks();
-        }
-        return null;
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index b7eee36..f92c50a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -29,7 +29,6 @@
 import android.os.Binder;
 import android.os.RemoteException;
 import android.util.DisplayMetrics;
-import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -42,9 +41,9 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.util.leak.RotationUtils;
@@ -220,8 +219,7 @@
             mLayout.findViewById(R.id.screen_pinning_text_area)
                     .setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
             View buttons = mLayout.findViewById(R.id.screen_pinning_buttons);
-            if (Recents.getSystemServices() != null &&
-                    Recents.getSystemServices().hasSoftNavigationBar()) {
+            if (WindowManagerWrapper.getInstance().hasSoftNavigationBar()) {
                 buttons.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
                 swapChildrenIfRtlAndVertical(buttons);
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java b/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
deleted file mode 100644
index 177362c..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.events;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.systemui.recents.misc.ReferenceCountedTrigger;
-
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Represents a subscriber, which implements various event bus handler methods.
- */
-class Subscriber {
-    private WeakReference<Object> mSubscriber;
-
-    long registrationTime;
-
-    Subscriber(Object subscriber, long registrationTime) {
-        mSubscriber = new WeakReference<>(subscriber);
-        this.registrationTime = registrationTime;
-    }
-
-    public String toString(int priority) {
-        Object sub = mSubscriber.get();
-        String id = Integer.toHexString(System.identityHashCode(sub));
-        return sub.getClass().getSimpleName() + " [0x" + id + ", P" + priority + "]";
-    }
-
-    public Object getReference() {
-        return mSubscriber.get();
-    }
-}
-
-/**
- * Represents an event handler with a priority.
- */
-class EventHandler {
-    int priority;
-    Subscriber subscriber;
-    EventHandlerMethod method;
-
-    EventHandler(Subscriber subscriber, EventHandlerMethod method, int priority) {
-        this.subscriber = subscriber;
-        this.method = method;
-        this.priority = priority;
-    }
-
-    @Override
-    public String toString() {
-        return subscriber.toString(priority) + " " + method.toString();
-    }
-}
-
-/**
- * Represents the low level method handling a particular event.
- */
-class EventHandlerMethod {
-    private Method mMethod;
-    Class<? extends EventBus.Event> eventType;
-
-    EventHandlerMethod(Method method, Class<? extends EventBus.Event> eventType) {
-        mMethod = method;
-        mMethod.setAccessible(true);
-        this.eventType = eventType;
-    }
-
-    public void invoke(Object target, EventBus.Event event)
-            throws InvocationTargetException, IllegalAccessException {
-        mMethod.invoke(target, event);
-    }
-
-    @Override
-    public String toString() {
-        return mMethod.getName() + "(" + eventType.getSimpleName() + ")";
-    }
-}
-
-/**
- * A simple in-process event bus.  It is simple because we can make assumptions about the state of
- * SystemUI and Recent's lifecycle.
- *
- * <p>
- * Currently, there is a single EventBus that handles {@link EventBus.Event}s for each subscriber
- * on the main application thread.  Publishers can send() events to synchronously call subscribers
- * of that event, or post() events to be processed in the next run of the {@link Looper}.
- *
- * <p>
- * Subscribers must be registered with a particular EventBus before they will receive events, and
- * handler methods must match a specific signature.
- *
- * <p>
- * Event method signature:<ul>
- * <li>Methods must be public final
- * <li>Methods must return void
- * <li>Methods must be called "onBusEvent"
- * <li>Methods must take one parameter, of class type deriving from {@link EventBus.Event}
- * </ul>
- *
- * </p>
- * Each subscriber can be registered with a given priority (default 1), and events will be dispatch
- * in decreasing order of priority.  For subscribers with the same priority, events will be
- * dispatched by latest registration time to earliest.
- *
- * <p>
- * Caveats:<ul>
- * <li>The EventBus keeps a {@link WeakReference} to the publisher to prevent memory leaks, so
- * there must be another strong reference to the publisher for it to not get garbage-collected and
- * continue receiving events.
- * <li>Because the event handlers are called back using reflection, the EventBus is not intended
- * for use in tight, performance criticial loops.  For most user input/system callback events, this
- * is generally of low enough frequency to use the EventBus.
- * <li>Because the event handlers are called back using reflection, there will often be no
- * references to them from actual code.  The proguard configuration will be need to be updated to
- * keep these extra methods:
- *
- * -keepclassmembers class ** {
- * public void onBusEvent(**);
- * public void onInterprocessBusEvent(**);
- * }
- * -keepclassmembers class ** extends **.EventBus$InterprocessEvent {
- * public <init>(android.os.Bundle);
- * }
- *
- * <li>Subscriber registration can be expensive depending on the subscriber's {@link Class}.  This
- * is only done once per class type, but if possible, it is best to pre-register an instance of
- * that class beforehand or when idle.
- * <li>Each event should be sent once.  Events may hold internal information about the current
- * dispatch, or may be queued to be dispatched on another thread (if posted from a non-main thread),
- * so it may be unsafe to edit, change, or re-send the event again.
- * <li>Events should follow a pattern of public-final POD (plain old data) objects, where they are
- * initialized by the constructor and read by each subscriber of that event.  Subscribers should
- * never alter events as they are processed, and this enforces that pattern.
- * </ul>
- *
- * <p>
- * Future optimizations:
- * <li>throw exception/log when a subscriber loses the reference
- * <li>trace cost per registration & invocation
- * <li>trace cross-process invocation
- * <li>register(subscriber, Class&lt;?&gt;...) -- pass in exact class types you want registered
- * <li>setSubscriberEventHandlerPriority(subscriber, Class<Event>, priority)
- * <li>allow subscribers to implement interface, ie. EventBus.Subscriber, which lets then test a
- * message before invocation (ie. check if task id == this task id)
- * <li>add postOnce() which automatically debounces
- * <li>add postDelayed() which delays / postDelayedOnce() which delays and bounces
- * <li>consolidate register() and registerInterprocess()
- * <li>sendForResult&lt;ReturnType&gt;(Event) to send and get a result, but who will send the
- * result?
- * </p>
- */
-public class EventBus {
-
-    private static final String TAG = "EventBus";
-    private static final boolean DEBUG_TRACE_ALL = false;
-
-    /**
-     * An event super class that allows us to track internal event state across subscriber
-     * invocations.
-     *
-     * Events should not be edited by subscribers.
-     */
-    public static class Event implements Cloneable {
-        // Indicates that this event's dispatch should be traced and logged to logcat
-        boolean trace;
-        // Indicates that this event must be posted on the EventBus's looper thread before invocation
-        boolean requiresPost;
-        // Not currently exposed, allows a subscriber to cancel further dispatch of this event
-        boolean cancelled;
-
-        // Only accessible from derived events
-        protected Event() {}
-
-        /**
-         * Called by the EventBus prior to dispatching this event to any subscriber of this event.
-         */
-        void onPreDispatch() {
-            // Do nothing
-        }
-
-        /**
-         * Called by the EventBus after dispatching this event to every subscriber of this event.
-         */
-        void onPostDispatch() {
-            // Do nothing
-        }
-
-        @Override
-        protected Object clone() throws CloneNotSupportedException {
-            Event evt = (Event) super.clone();
-            // When cloning an event, reset the cancelled-dispatch state
-            evt.cancelled = false;
-            return evt;
-        }
-    }
-
-    /**
-     * An event that represents an animated state change, which allows subscribers to coordinate
-     * callbacks which happen after the animation has taken place.
-     *
-     * Internally, it is guaranteed that increment() and decrement() will be called before and the
-     * after the event is dispatched.
-     */
-    public static class AnimatedEvent extends Event {
-
-        private final ReferenceCountedTrigger mTrigger = new ReferenceCountedTrigger();
-
-        // Only accessible from derived events
-        protected AnimatedEvent() {}
-
-        /**
-         * Returns the reference counted trigger that coordinates the animations for this event.
-         */
-        public ReferenceCountedTrigger getAnimationTrigger() {
-            return mTrigger;
-        }
-
-        /**
-         * Adds a callback that is guaranteed to be called after the state has changed regardless of
-         * whether an actual animation took place.
-         */
-        public void addPostAnimationCallback(Runnable r) {
-            mTrigger.addLastDecrementRunnable(r);
-        }
-
-        @Override
-        void onPreDispatch() {
-            mTrigger.increment();
-        }
-
-        @Override
-        void onPostDispatch() {
-            mTrigger.decrement();
-        }
-
-        @Override
-        protected Object clone() throws CloneNotSupportedException {
-            throw new CloneNotSupportedException();
-        }
-    }
-
-    /**
-     * An event that can be reusable, only used for situations where we want to reduce memory
-     * allocations when events are sent frequently (ie. on scroll).
-     */
-    public static class ReusableEvent extends Event {
-
-        private int mDispatchCount;
-
-        protected ReusableEvent() {}
-
-        @Override
-        void onPostDispatch() {
-            super.onPostDispatch();
-            mDispatchCount++;
-        }
-
-        @Override
-        protected Object clone() throws CloneNotSupportedException {
-            throw new CloneNotSupportedException();
-        }
-    }
-
-    /**
-     * Proguard must also know, and keep, all methods matching this signature.
-     *
-     * -keepclassmembers class ** {
-     *     public void onBusEvent(**);
-     *     public void onInterprocessBusEvent(**);
-     * }
-     */
-    private static final String METHOD_PREFIX = "onBusEvent";
-
-    // The default priority of all subscribers
-    private static final int DEFAULT_SUBSCRIBER_PRIORITY = 1;
-
-    // Orders the handlers by priority and registration time
-    private static final Comparator<EventHandler> EVENT_HANDLER_COMPARATOR = new Comparator<EventHandler>() {
-        @Override
-        public int compare(EventHandler h1, EventHandler h2) {
-            // Rank the handlers by priority descending, followed by registration time descending.
-            // aka. the later registered
-            if (h1.priority != h2.priority) {
-                return h2.priority - h1.priority;
-            } else {
-                return Long.compare(h2.subscriber.registrationTime, h1.subscriber.registrationTime);
-            }
-        }
-    };
-
-    // Used for initializing the default bus
-    private static final Object sLock = new Object();
-    private static volatile EventBus sDefaultBus;
-
-    // The handler to post all events
-    private Handler mHandler;
-
-    /**
-     * Map from event class -> event handler list.  Keeps track of the actual mapping from event
-     * to subscriber method.
-     */
-    private HashMap<Class<? extends Event>, ArrayList<EventHandler>> mEventTypeMap = new HashMap<>();
-
-    /**
-     * Map from subscriber class -> event handler method lists.  Used to determine upon registration
-     * of a new subscriber whether we need to read all the subscriber's methods again using
-     * reflection or whether we can just add the subscriber to the event type map.
-     */
-    private HashMap<Class<? extends Object>, ArrayList<EventHandlerMethod>> mSubscriberTypeMap = new HashMap<>();
-
-    /**
-     * Set of all currently registered subscribers
-     */
-    private ArrayList<Subscriber> mSubscribers = new ArrayList<>();
-
-    // For tracing
-    private int mCallCount;
-    private long mCallDurationMicros;
-
-    /**
-     * Private constructor to create an event bus for a given looper.
-     */
-    private EventBus(Looper looper) {
-        mHandler = new Handler(looper);
-    }
-
-    /**
-     * @return the default event bus for the application's main thread.
-     */
-    public static EventBus getDefault() {
-        if (sDefaultBus == null)
-        synchronized (sLock) {
-            if (sDefaultBus == null) {
-                if (DEBUG_TRACE_ALL) {
-                    logWithPid("New EventBus");
-                }
-                sDefaultBus = new EventBus(Looper.getMainLooper());
-            }
-        }
-        return sDefaultBus;
-    }
-
-    /**
-     * Registers a subscriber to receive events with the default priority.
-     *
-     * @param subscriber the subscriber to handle events.  If this is the first instance of the
-     *                   subscriber's class type that has been registered, the class's methods will
-     *                   be scanned for appropriate event handler methods.
-     */
-    public void register(Object subscriber) {
-        registerSubscriber(subscriber, DEFAULT_SUBSCRIBER_PRIORITY);
-    }
-
-    /**
-     * Registers a subscriber to receive events with the given priority.
-     *
-     * @param subscriber the subscriber to handle events.  If this is the first instance of the
-     *                   subscriber's class type that has been registered, the class's methods will
-     *                   be scanned for appropriate event handler methods.
-     * @param priority the priority that this subscriber will receive events relative to other
-     *                 subscribers
-     */
-    public void register(Object subscriber, int priority) {
-        registerSubscriber(subscriber, priority);
-    }
-
-    /**
-     * Remove all EventHandlers pointing to the specified subscriber.  This does not remove the
-     * mapping of subscriber type to event handler method, in case new instances of this subscriber
-     * are registered.
-     */
-    public void unregister(Object subscriber) {
-        if (DEBUG_TRACE_ALL) {
-            logWithPid("unregister()");
-        }
-
-        // Fail immediately if we are being called from the non-main thread
-        long callingThreadId = Thread.currentThread().getId();
-        if (callingThreadId != mHandler.getLooper().getThread().getId()) {
-            throw new RuntimeException("Can not unregister() a subscriber from a non-main thread.");
-        }
-
-        // Return early if this is not a registered subscriber
-        if (!findRegisteredSubscriber(subscriber, true /* removeFoundSubscriber */)) {
-            return;
-        }
-
-        Class<?> subscriberType = subscriber.getClass();
-        ArrayList<EventHandlerMethod> subscriberMethods = mSubscriberTypeMap.get(subscriberType);
-        if (subscriberMethods != null) {
-            // For each of the event handlers the subscriber handles, remove all references of that
-            // handler
-            for (EventHandlerMethod method : subscriberMethods) {
-                ArrayList<EventHandler> eventHandlers = mEventTypeMap.get(method.eventType);
-                for (int i = eventHandlers.size() - 1; i >= 0; i--) {
-                    if (eventHandlers.get(i).subscriber.getReference() == subscriber) {
-                        eventHandlers.remove(i);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Sends an event to the subscribers of the given event type immediately.  This can only be
-     * called from the same thread as the EventBus's looper thread (for the default EventBus, this
-     * is the main application thread).
-     */
-    public void send(Event event) {
-        // Fail immediately if we are being called from the non-main thread
-        long callingThreadId = Thread.currentThread().getId();
-        if (callingThreadId != mHandler.getLooper().getThread().getId()) {
-            throw new RuntimeException("Can not send() a message from a non-main thread.");
-        }
-
-        if (DEBUG_TRACE_ALL) {
-            logWithPid("send(" + event.getClass().getSimpleName() + ")");
-        }
-
-        // Reset the event's cancelled state
-        event.requiresPost = false;
-        event.cancelled = false;
-        queueEvent(event);
-    }
-
-    /**
-     * Post a message to the subscribers of the given event type.  The messages will be posted on
-     * the EventBus's looper thread (for the default EventBus, this is the main application thread).
-     */
-    public void post(Event event) {
-        if (DEBUG_TRACE_ALL) {
-            logWithPid("post(" + event.getClass().getSimpleName() + ")");
-        }
-
-        // Reset the event's cancelled state
-        event.requiresPost = true;
-        event.cancelled = false;
-        queueEvent(event);
-    }
-
-    /**
-     * If this method is called from the main thread, it will be handled directly. If this method
-     * is not called from the main thread, it will be posted onto the main thread.
-     */
-    public void sendOntoMainThread(Event event) {
-        long callingThreadId = Thread.currentThread().getId();
-        if (callingThreadId != mHandler.getLooper().getThread().getId()) {
-            post(event);
-        } else {
-            send(event);
-        }
-    }
-
-    /**
-     * @return a dump of the current state of the EventBus
-     */
-    public void dump(String prefix, PrintWriter writer) {
-        writer.println(dumpInternal(prefix));
-    }
-
-    public String dumpInternal(String prefix) {
-        String innerPrefix = prefix + "  ";
-        String innerInnerPrefix = innerPrefix + "  ";
-        StringBuilder output = new StringBuilder();
-        output.append(prefix);
-        output.append("Registered class types:");
-        output.append("\n");
-        ArrayList<Class<?>> subsciberTypes = new ArrayList<>(mSubscriberTypeMap.keySet());
-        Collections.sort(subsciberTypes, new Comparator<Class<?>>() {
-            @Override
-            public int compare(Class<?> o1, Class<?> o2) {
-                return o1.getSimpleName().compareTo(o2.getSimpleName());
-            }
-        });
-        for (int i = 0; i < subsciberTypes.size(); i++) {
-            Class<?> clz = subsciberTypes.get(i);
-            output.append(innerPrefix);
-            output.append(clz.getSimpleName());
-            output.append("\n");
-        }
-        output.append(prefix);
-        output.append("Event map:");
-        output.append("\n");
-        ArrayList<Class<?>> classes = new ArrayList<>(mEventTypeMap.keySet());
-        Collections.sort(classes, new Comparator<Class<?>>() {
-            @Override
-            public int compare(Class<?> o1, Class<?> o2) {
-                return o1.getSimpleName().compareTo(o2.getSimpleName());
-            }
-        });
-        for (int i = 0; i < classes.size(); i++) {
-            Class<?> clz = classes.get(i);
-            output.append(innerPrefix);
-            output.append(clz.getSimpleName());
-            output.append(" -> ");
-            output.append("\n");
-            ArrayList<EventHandler> handlers = mEventTypeMap.get(clz);
-            for (EventHandler handler : handlers) {
-                Object subscriber = handler.subscriber.getReference();
-                if (subscriber != null) {
-                    String id = Integer.toHexString(System.identityHashCode(subscriber));
-                    output.append(innerInnerPrefix);
-                    output.append(subscriber.getClass().getSimpleName());
-                    output.append(" [0x" + id + ", #" + handler.priority + "]");
-                    output.append("\n");
-                }
-            }
-        }
-        return output.toString();
-    }
-
-    /**
-     * Registers a new subscriber.
-     */
-    private void registerSubscriber(Object subscriber, int priority) {
-        // Fail immediately if we are being called from the non-main thread
-        long callingThreadId = Thread.currentThread().getId();
-        if (callingThreadId != mHandler.getLooper().getThread().getId()) {
-            throw new RuntimeException("Can not register() a subscriber from a non-main thread.");
-        }
-
-        // Return immediately if this exact subscriber is already registered
-        if (findRegisteredSubscriber(subscriber, false /* removeFoundSubscriber */)) {
-            return;
-        }
-
-        long t1 = 0;
-        if (DEBUG_TRACE_ALL) {
-            t1 = SystemClock.currentTimeMicro();
-            logWithPid("registerSubscriber(" + subscriber.getClass().getSimpleName() + ")");
-        }
-        Subscriber sub = new Subscriber(subscriber, SystemClock.uptimeMillis());
-        Class<?> subscriberType = subscriber.getClass();
-        ArrayList<EventHandlerMethod> subscriberMethods = mSubscriberTypeMap.get(subscriberType);
-        if (subscriberMethods != null) {
-            if (DEBUG_TRACE_ALL) {
-                logWithPid("Subscriber class type already registered");
-            }
-
-            // If we've parsed this subscriber type before, just add to the set for all the known
-            // events
-            for (EventHandlerMethod method : subscriberMethods) {
-                ArrayList<EventHandler> eventTypeHandlers = mEventTypeMap.get(method.eventType);
-                eventTypeHandlers.add(new EventHandler(sub, method, priority));
-                sortEventHandlersByPriority(eventTypeHandlers);
-            }
-            mSubscribers.add(sub);
-            return;
-        } else {
-            if (DEBUG_TRACE_ALL) {
-                logWithPid("Subscriber class type requires registration");
-            }
-
-            // If we are parsing this type from scratch, ensure we add it to the subscriber type
-            // map, and pull out he handler methods below
-            subscriberMethods = new ArrayList<>();
-            mSubscriberTypeMap.put(subscriberType, subscriberMethods);
-            mSubscribers.add(sub);
-        }
-
-        // Find all the valid event bus handler methods of the subscriber
-        Method[] methods = subscriberType.getDeclaredMethods();
-        for (Method m : methods) {
-            Class<?>[] parameterTypes = m.getParameterTypes();
-            if (isValidEventBusHandlerMethod(m, parameterTypes)) {
-                Class<? extends Event> eventType = (Class<? extends Event>) parameterTypes[0];
-                ArrayList<EventHandler> eventTypeHandlers = mEventTypeMap.get(eventType);
-                if (eventTypeHandlers == null) {
-                    eventTypeHandlers = new ArrayList<>();
-                    mEventTypeMap.put(eventType, eventTypeHandlers);
-                }
-                EventHandlerMethod method = new EventHandlerMethod(m, eventType);
-                EventHandler handler = new EventHandler(sub, method, priority);
-                eventTypeHandlers.add(handler);
-                subscriberMethods.add(method);
-                sortEventHandlersByPriority(eventTypeHandlers);
-
-                if (DEBUG_TRACE_ALL) {
-                    logWithPid("  * Method: " + m.getName() +
-                            " event: " + parameterTypes[0].getSimpleName());
-                }
-            }
-        }
-        if (DEBUG_TRACE_ALL) {
-            logWithPid("Registered " + subscriber.getClass().getSimpleName() + " in " +
-                    (SystemClock.currentTimeMicro() - t1) + " microseconds");
-        }
-    }
-
-    /**
-     * Adds a new message.
-     */
-    private void queueEvent(final Event event) {
-        ArrayList<EventHandler> eventHandlers = mEventTypeMap.get(event.getClass());
-        if (eventHandlers == null) {
-            // This is just an optimization to return early if there are no handlers. However, we
-            // should still ensure that we call pre/post dispatch callbacks so that AnimatedEvents
-            // are still cleaned up correctly if a listener has not been registered to handle them
-            event.onPreDispatch();
-            event.onPostDispatch();
-            return;
-        }
-
-        // Prepare this event
-        boolean hasPostedEvent = false;
-        event.onPreDispatch();
-
-        // We need to clone the list in case a subscriber unregisters itself during traversal
-        // TODO: Investigate whether we can skip the object creation here
-        eventHandlers = (ArrayList<EventHandler>) eventHandlers.clone();
-        int eventHandlerCount = eventHandlers.size();
-        for (int i = 0; i < eventHandlerCount; i++) {
-            final EventHandler eventHandler = eventHandlers.get(i);
-            if (eventHandler.subscriber.getReference() != null) {
-                if (event.requiresPost) {
-                    mHandler.post(() -> processEvent(eventHandler, event));
-                    hasPostedEvent = true;
-                } else {
-                    processEvent(eventHandler, event);
-                }
-            }
-        }
-
-        // Clean up after this event, deferring until all subscribers have been called
-        if (hasPostedEvent) {
-            mHandler.post(event::onPostDispatch);
-        } else {
-            event.onPostDispatch();
-        }
-    }
-
-    /**
-     * Processes and dispatches the given event to the given event handler, on the thread of whoever
-     * calls this method.
-     */
-    private void processEvent(final EventHandler eventHandler, final Event event) {
-        // Skip if the event was already cancelled
-        if (event.cancelled) {
-            if (event.trace || DEBUG_TRACE_ALL) {
-                logWithPid("Event dispatch cancelled");
-            }
-            return;
-        }
-
-        try {
-            if (event.trace || DEBUG_TRACE_ALL) {
-                logWithPid(" -> " + eventHandler.toString());
-            }
-            Object sub = eventHandler.subscriber.getReference();
-            if (sub != null) {
-                long t1 = 0;
-                if (DEBUG_TRACE_ALL) {
-                    t1 = SystemClock.currentTimeMicro();
-                }
-                eventHandler.method.invoke(sub, event);
-                if (DEBUG_TRACE_ALL) {
-                    long duration = (SystemClock.currentTimeMicro() - t1);
-                    mCallDurationMicros += duration;
-                    mCallCount++;
-                    logWithPid(eventHandler.method.toString() + " duration: " + duration +
-                            " microseconds, avg: " + (mCallDurationMicros / mCallCount));
-                }
-            } else {
-                Log.e(TAG, "Failed to deliver event to null subscriber");
-            }
-        } catch (IllegalAccessException e) {
-            Log.e(TAG, "Failed to invoke method", e.getCause());
-        } catch (InvocationTargetException e) {
-            throw new RuntimeException(e.getCause());
-        }
-    }
-
-    /**
-     * Returns whether this subscriber is currently registered.  If {@param removeFoundSubscriber}
-     * is true, then remove the subscriber before returning.
-     */
-    private boolean findRegisteredSubscriber(Object subscriber, boolean removeFoundSubscriber) {
-        for (int i = mSubscribers.size() - 1; i >= 0; i--) {
-            Subscriber sub = mSubscribers.get(i);
-            if (sub.getReference() == subscriber) {
-                if (removeFoundSubscriber) {
-                    mSubscribers.remove(i);
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return whether {@param method} is a valid (normal or interprocess) event bus handler method
-     */
-    private boolean isValidEventBusHandlerMethod(Method method, Class<?>[] parameterTypes) {
-        int modifiers = method.getModifiers();
-        if (Modifier.isPublic(modifiers) &&
-                Modifier.isFinal(modifiers) &&
-                method.getReturnType().equals(Void.TYPE) &&
-                parameterTypes.length == 1) {
-            if (EventBus.Event.class.isAssignableFrom(parameterTypes[0]) &&
-                            method.getName().startsWith(METHOD_PREFIX)) {
-                return true;
-            } else {
-                if (DEBUG_TRACE_ALL) {
-                    if (!EventBus.Event.class.isAssignableFrom(parameterTypes[0])) {
-                        logWithPid("  Expected method take an Event-based parameter: " + method.getName());
-                    }
-                }
-            }
-        } else {
-            if (DEBUG_TRACE_ALL) {
-                if (!Modifier.isPublic(modifiers)) {
-                    logWithPid("  Expected method to be public: " + method.getName());
-                } else if (!Modifier.isFinal(modifiers)) {
-                    logWithPid("  Expected method to be final: " + method.getName());
-                } else if (!method.getReturnType().equals(Void.TYPE)) {
-                    logWithPid("  Expected method to return null: " + method.getName());
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Sorts the event handlers by priority and registration time.
-     */
-    private void sortEventHandlersByPriority(List<EventHandler> eventHandlers) {
-        Collections.sort(eventHandlers, EVENT_HANDLER_COMPARATOR);
-    }
-
-    /**
-     * Helper method to log the given {@param text} with the current process and user id.
-     */
-    private static void logWithPid(String text) {
-        Log.d(TAG, "[" + android.os.Process.myPid() + ", u" + UserHandle.myUserId() + "] " + text);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java
deleted file mode 100644
index 4738eed..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Sent when an app transition has finished playing.
- */
-public class AppTransitionFinishedEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/CancelEnterRecentsWindowAnimationEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/CancelEnterRecentsWindowAnimationEvent.java
deleted file mode 100644
index fec34e3..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/CancelEnterRecentsWindowAnimationEvent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-
-/**
- * This is sent when we want to cancel the enter-recents window animation for the launch task.
- */
-public class CancelEnterRecentsWindowAnimationEvent extends EventBus.Event {
-
-    // This is set for the task that is launching, which allows us to ensure that we are not
-    // cancelling the same task animation (it will just be overwritten instead)
-    public final Task launchTask;
-
-    public CancelEnterRecentsWindowAnimationEvent(Task launchTask) {
-        this.launchTask = launchTask;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
deleted file mode 100644
index 294c1e7..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the Recents activity configuration has changed.
- */
-public class ConfigurationChangedEvent extends EventBus.AnimatedEvent {
-
-    public final boolean fromMultiWindow;
-    public final boolean fromDeviceOrientationChange;
-    public final boolean fromDisplayDensityChange;
-    public final boolean hasStackTasks;
-
-    public ConfigurationChangedEvent(boolean fromMultiWindow, boolean fromDeviceOrientationChange,
-            boolean fromDisplayDensityChange, boolean hasStackTasks) {
-        this.fromMultiWindow = fromMultiWindow;
-        this.fromDeviceOrientationChange = fromDeviceOrientationChange;
-        this.fromDisplayDensityChange = fromDisplayDensityChange;
-        this.hasStackTasks = hasStackTasks;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DismissRecentsToHomeAnimationStarted.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DismissRecentsToHomeAnimationStarted.java
deleted file mode 100644
index e7be858..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DismissRecentsToHomeAnimationStarted.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the task animation when dismissing Recents starts.
- */
-public class DismissRecentsToHomeAnimationStarted extends EventBus.AnimatedEvent {
-
-    public final boolean animated;
-
-    public DismissRecentsToHomeAnimationStarted(boolean animated) {
-        this.animated = animated;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java
deleted file mode 100644
index 32d9a70..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus.Event;
-
-/**
- * Sent when the window animation has started when docking a task
- */
-public class DockedFirstAnimationFrameEvent extends Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java
deleted file mode 100644
index 9e3ced3..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.activity;
-
-import android.graphics.Rect;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Fires when the user invoked the gesture to dock the top/left task after we called into window
- * manager and before we start recents.
- */
-public class DockedTopTaskEvent extends EventBus.Event {
-
-    public Rect initialRect;
-
-    public DockedTopTaskEvent(Rect initialRect) {
-        this.initialRect = initialRect;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
deleted file mode 100644
index b31f320..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the window animation into Recents completes.  We use this signal to know when
- * we can start in-app animations so that they don't conflict with the window transition into
- * Recents.
- */
-public class EnterRecentsWindowAnimationCompletedEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowLastAnimationFrameEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowLastAnimationFrameEvent.java
deleted file mode 100644
index fd023d8..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowLastAnimationFrameEvent.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-public class EnterRecentsWindowLastAnimationFrameEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ExitRecentsWindowFirstAnimationFrameEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ExitRecentsWindowFirstAnimationFrameEvent.java
deleted file mode 100644
index fa806eb..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ExitRecentsWindowFirstAnimationFrameEvent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Event sent when the exit animation is started.
- *
- * This is sent so parts of UI can synchronize on this event and adjust their appearance. An example
- * of that is hiding the tasks when the launched application window becomes visible.
- */
-public class ExitRecentsWindowFirstAnimationFrameEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideRecentsEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideRecentsEvent.java
deleted file mode 100644
index bf9b421..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideRecentsEvent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the user taps on the Home button or finishes alt-tabbing to hide the Recents
- * activity.
- */
-public class HideRecentsEvent extends EventBus.Event {
-
-    public final boolean triggeredFromAltTab;
-    public final boolean triggeredFromHomeKey;
-
-    public HideRecentsEvent(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
-        this.triggeredFromAltTab = triggeredFromAltTab;
-        this.triggeredFromHomeKey = triggeredFromHomeKey;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideStackActionButtonEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideStackActionButtonEvent.java
deleted file mode 100644
index e4a4f59..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideStackActionButtonEvent.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the stack action button should be hidden.
- */
-public class HideStackActionButtonEvent extends EventBus.Event {
-
-    // Whether or not to translate the stack action button when hiding it
-    public final boolean translate;
-
-    public HideStackActionButtonEvent() {
-        this(true);
-    }
-
-    public HideStackActionButtonEvent(boolean translate) {
-        this.translate = translate;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
deleted file mode 100644
index 24913a4..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This event is sent to request that the most recent task is launched.
- */
-public class LaunchMostRecentTaskRequestEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchNextTaskRequestEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchNextTaskRequestEvent.java
deleted file mode 100644
index 11604b5..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchNextTaskRequestEvent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This event is sent to request that the next task is launched after a double-tap on the Recents
- * button.
- */
-public class LaunchNextTaskRequestEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskEvent.java
deleted file mode 100644
index 2409f39..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskEvent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
-import android.graphics.Rect;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent to request that a particular task is launched.
- */
-public class LaunchTaskEvent extends EventBus.Event {
-
-    public final TaskView taskView;
-    public final Task task;
-    public final Rect targetTaskBounds;
-    public final int targetWindowingMode;
-    public final int targetActivityType;
-    public final boolean screenPinningRequested;
-
-    public LaunchTaskEvent(TaskView taskView, Task task, Rect targetTaskBounds,
-            boolean screenPinningRequested) {
-        this(taskView, task, targetTaskBounds, screenPinningRequested,
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED);
-    }
-
-    public LaunchTaskEvent(TaskView taskView, Task task, Rect targetTaskBounds,
-            boolean screenPinningRequested, int windowingMode, int activityType) {
-        this.taskView = taskView;
-        this.task = task;
-        this.targetTaskBounds = targetTaskBounds;
-        this.targetWindowingMode = windowingMode;
-        this.targetActivityType = activityType;
-        this.screenPinningRequested = screenPinningRequested;
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskFailedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskFailedEvent.java
deleted file mode 100644
index 3a2d58c..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskFailedEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when we fail to launch a task.
- */
-public class LaunchTaskFailedEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskStartedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskStartedEvent.java
deleted file mode 100644
index 3925ab1..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskStartedEvent.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent following {@link LaunchTaskEvent} after the call to the system is made to
- * start the task.
- */
-public class LaunchTaskStartedEvent extends EventBus.AnimatedEvent {
-
-    public final TaskView taskView;
-    public final boolean screenPinningRequested;
-
-    public LaunchTaskStartedEvent(TaskView taskView, boolean screenPinningRequested) {
-        this.taskView = taskView;
-        this.screenPinningRequested = screenPinningRequested;
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskSucceededEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskSucceededEvent.java
deleted file mode 100644
index ec5089f..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchTaskSucceededEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when we successfully launch a task.
- */
-public class LaunchTaskSucceededEvent extends EventBus.Event {
-
-    public final int taskIndexFromStackFront;
-
-    public LaunchTaskSucceededEvent(int taskIndexFromStackFront) {
-        this.taskIndexFromStackFront = taskIndexFromStackFront;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
deleted file mode 100644
index e4972b1..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.TaskStack;
-
-/**
- * This is sent by the activity whenever the multi-window state has changed.
- */
-public class MultiWindowStateChangedEvent extends EventBus.AnimatedEvent {
-
-    public final boolean inMultiWindow;
-    // This flag is only used when undocking a task
-    public final boolean showDeferredAnimation;
-    public final TaskStack stack;
-
-    public MultiWindowStateChangedEvent(boolean inMultiWindow, boolean showDeferredAnimation,
-            TaskStack stack) {
-        this.inMultiWindow = inMultiWindow;
-        this.showDeferredAnimation = showDeferredAnimation;
-        this.stack = stack;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/PackagesChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/PackagesChangedEvent.java
deleted file mode 100644
index 47670e0..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/PackagesChangedEvent.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.views.TaskStackView;
-import com.android.systemui.recents.RecentsActivity;
-
-/**
- * This event is sent by {@link RecentsActivity} when a package on the the system changes.
- * {@link TaskStackView}s listen for this event, and remove the tasks associated with the removed
- * packages.
- */
-public class PackagesChangedEvent extends EventBus.Event {
-
-    public final String packageName;
-    public final int userId;
-
-    public PackagesChangedEvent(String packageName, int userId) {
-        this.packageName = packageName;
-        this.userId = userId;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/RecentsActivityStartingEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/RecentsActivityStartingEvent.java
deleted file mode 100644
index a2ecfe2..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/RecentsActivityStartingEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Called after recents activity is being started, i.e. startActivity has just been called.
- */
-public class RecentsActivityStartingEvent extends EventBus.Event{
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowEmptyViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowEmptyViewEvent.java
deleted file mode 100644
index 75bfd7b..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowEmptyViewEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Sent when the stack should be hidden and the empty view shown.
- */
-public class ShowEmptyViewEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowStackActionButtonEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowStackActionButtonEvent.java
deleted file mode 100644
index d81f89c..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowStackActionButtonEvent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the stack action view button should be shown.
- */
-public class ShowStackActionButtonEvent extends EventBus.Event {
-
-    // Whether or not to translate the stack action button when showing it
-    public final boolean translate;
-
-    public ShowStackActionButtonEvent(boolean translate) {
-        this.translate = translate;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/TaskStackUpdatedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/TaskStackUpdatedEvent.java
deleted file mode 100644
index 51d02b5..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/TaskStackUpdatedEvent.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.TaskStack;
-
-/**
- * This is sent by the activity whenever the task stach has changed.
- */
-public class TaskStackUpdatedEvent extends EventBus.AnimatedEvent {
-
-    /**
-     * A new TaskStack instance representing the latest stack state.
-     */
-    public final TaskStack stack;
-    public final boolean inMultiWindow;
-
-    public TaskStackUpdatedEvent(TaskStack stack, boolean inMultiWindow) {
-        this.stack = stack;
-        this.inMultiWindow = inMultiWindow;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleRecentsEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleRecentsEvent.java
deleted file mode 100644
index 49655b4..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleRecentsEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the user taps on the Overview button to toggle the Recents activity.
- */
-public class ToggleRecentsEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/UndockingTaskEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/UndockingTaskEvent.java
deleted file mode 100644
index d5083a8..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/UndockingTaskEvent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Fires when the user invoked the gesture to undock the task in the docked stack.
- */
-public class UndockingTaskEvent extends EventBus.Event {
-
-    public UndockingTaskEvent() {
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityPinnedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityPinnedEvent.java
deleted file mode 100644
index f4d2fcf..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityPinnedEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.component;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when an activity is pinned.
- */
-public class ActivityPinnedEvent extends EventBus.Event {
-
-    public final int taskId;
-
-    public ActivityPinnedEvent(int taskId) {
-        this.taskId = taskId;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityUnpinnedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityUnpinnedEvent.java
deleted file mode 100644
index 48c5f0b..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/ActivityUnpinnedEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.component;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when an activity is unpinned.
- */
-public class ActivityUnpinnedEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java
deleted file mode 100644
index 37266f6..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/ExpandPipEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.component;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the PiP should be expanded due to being relaunched.
- */
-public class ExpandPipEvent extends EventBus.Event {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/HidePipMenuEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/HidePipMenuEvent.java
deleted file mode 100644
index ce4f207..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/HidePipMenuEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.component;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the PiP menu should be hidden.
- */
-public class HidePipMenuEvent extends EventBus.AnimatedEvent {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/RecentsVisibilityChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/RecentsVisibilityChangedEvent.java
deleted file mode 100644
index 8843eb4..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/RecentsVisibilityChangedEvent.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.component;
-
-import android.content.Context;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the visibility of the RecentsActivity for the current user changes.  Handlers
- * of this event should not alter the UI, as the activity may still be visible.
- */
-public class RecentsVisibilityChangedEvent extends EventBus.Event {
-
-    public final Context applicationContext;
-    public final boolean visible;
-
-    public RecentsVisibilityChangedEvent(Context context, boolean visible) {
-        this.applicationContext = context.getApplicationContext();
-        this.visible = visible;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ScreenPinningRequestEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ScreenPinningRequestEvent.java
deleted file mode 100644
index d460917..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/ScreenPinningRequestEvent.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.component;
-
-import android.content.Context;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when we want to start screen pinning.
- */
-public class ScreenPinningRequestEvent extends EventBus.Event {
-
-    public final Context applicationContext;
-    public final int taskId;
-
-    public ScreenPinningRequestEvent(Context context, int taskId) {
-        this.applicationContext = context.getApplicationContext();
-        this.taskId = taskId;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
deleted file mode 100644
index d9cf5fb..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/SetWaitingForTransitionStartEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.component;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when we are setting/resetting the flag to wait for the transition to start.
- */
-public class SetWaitingForTransitionStartEvent extends EventBus.Event {
-
-    public final boolean waitingForTransitionStart;
-
-    public SetWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
-        this.waitingForTransitionStart = waitingForTransitionStart;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/ShowUserToastEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/ShowUserToastEvent.java
deleted file mode 100644
index e2b39c3..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/component/ShowUserToastEvent.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.component;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when we want to show a toast for the current user.
- */
-public class ShowUserToastEvent extends EventBus.Event {
-
-    public final int msgResId;
-    public final int msgLength;
-
-    public ShowUserToastEvent(int msgResId, int msgLength) {
-        this.msgResId = msgResId;
-        this.msgLength = msgLength;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/AllTaskViewsDismissedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/AllTaskViewsDismissedEvent.java
deleted file mode 100644
index 0352161..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/AllTaskViewsDismissedEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent whenever all the task views in a stack have been dismissed.
- */
-public class AllTaskViewsDismissedEvent extends EventBus.Event {
-
-    public final int msgResId;
-
-    public AllTaskViewsDismissedEvent(int msgResId) {
-        this.msgResId = msgResId;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DeleteTaskDataEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DeleteTaskDataEvent.java
deleted file mode 100644
index b52e83b..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DeleteTaskDataEvent.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-
-/**
- * This is sent when the data associated with a given {@link Task} should be deleted from the
- * system.
- */
-public class DeleteTaskDataEvent extends EventBus.Event {
-
-    public final Task task;
-
-    public DeleteTaskDataEvent(Task task) {
-        this.task = task;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissAllTaskViewsEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissAllTaskViewsEvent.java
deleted file mode 100644
index f8b59c7..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissAllTaskViewsEvent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent to request that all the {@link TaskView}s are dismissed.
- */
-public class DismissAllTaskViewsEvent extends EventBus.AnimatedEvent {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissTaskViewEvent.java
deleted file mode 100644
index 1f8c644..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissTaskViewEvent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent to request that the given {@link TaskView} is dismissed.
- */
-public class DismissTaskViewEvent extends EventBus.AnimatedEvent {
-
-    public final TaskView taskView;
-
-    public DismissTaskViewEvent(TaskView taskView) {
-        this.taskView = taskView;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DraggingInRecentsEndedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DraggingInRecentsEndedEvent.java
deleted file mode 100644
index 9be8eb1..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DraggingInRecentsEndedEvent.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.android.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus.Event;
-
-/**
- * This event is sent when the user finished dragging in recents.
- */
-public class DraggingInRecentsEndedEvent extends Event {
-
-    public final float velocity;
-
-    public DraggingInRecentsEndedEvent(float velocity) {
-        this.velocity = velocity;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DraggingInRecentsEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DraggingInRecentsEvent.java
deleted file mode 100644
index 5e8bfd4..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DraggingInRecentsEvent.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.android.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus.Event;
-
-/**
- * This event is sent when the user changed how far they are dragging in recents.
- */
-public class DraggingInRecentsEvent extends Event {
-
-    public final float distanceFromTop;
-
-    public DraggingInRecentsEvent(float distanceFromTop) {
-        this.distanceFromTop = distanceFromTop;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/HideIncompatibleAppOverlayEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/HideIncompatibleAppOverlayEvent.java
deleted file mode 100644
index d6ef636..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/HideIncompatibleAppOverlayEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when a user stops draggin an incompatible app task.
- */
-public class HideIncompatibleAppOverlayEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsDrawnEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsDrawnEvent.java
deleted file mode 100644
index 5483166..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsDrawnEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Fired when recents was launched and has drawn its first frame.
- */
-public class RecentsDrawnEvent extends EventBus.Event {
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java
deleted file mode 100644
index d9b0027..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Sent when recents is about to grow in multi-window mode when entering recents.
- */
-public class RecentsGrowingEvent extends EventBus.Event {
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/ShowApplicationInfoEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/ShowApplicationInfoEvent.java
deleted file mode 100644
index da19384..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/ShowApplicationInfoEvent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-
-/**
- * This is sent when a user wants to show the application info for a {@link Task}.
- */
-public class ShowApplicationInfoEvent extends EventBus.Event {
-
-    public final Task task;
-
-    public ShowApplicationInfoEvent(Task task) {
-        this.task = task;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/ShowIncompatibleAppOverlayEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/ShowIncompatibleAppOverlayEvent.java
deleted file mode 100644
index 3a4350e..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/ShowIncompatibleAppOverlayEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when a user starts dragging an incompatible app task.
- */
-public class ShowIncompatibleAppOverlayEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/StackViewScrolledEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/StackViewScrolledEvent.java
deleted file mode 100644
index c4b47c0..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/StackViewScrolledEvent.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import android.util.MutableInt;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent whenever a new scroll gesture happens on a stack view.
- */
-public class StackViewScrolledEvent extends EventBus.ReusableEvent {
-
-    public final MutableInt yMovement;
-
-    public StackViewScrolledEvent() {
-        yMovement = new MutableInt(0);
-    }
-
-    public void updateY(int y) {
-        yMovement.value = y;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskSnapshotChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskSnapshotChangedEvent.java
deleted file mode 100644
index f082928..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskSnapshotChangedEvent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-
-/**
- * Sent when a task snapshot has changed.
- */
-public class TaskSnapshotChangedEvent extends EventBus.Event {
-
-    public final int taskId;
-    public final ThumbnailData thumbnailData;
-
-    public TaskSnapshotChangedEvent(int taskId, ThumbnailData thumbnailData) {
-        this.taskId = taskId;
-        this.thumbnailData = thumbnailData;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
deleted file mode 100644
index 881a64a..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent when a {@link TaskView} has been dismissed and is no longer visible.
- */
-public class TaskViewDismissedEvent extends EventBus.Event {
-
-    public final Task task;
-    public final TaskView taskView;
-    public final AnimationProps animation;
-
-    public TaskViewDismissedEvent(Task task, TaskView taskView, AnimationProps animation) {
-        this.task = task;
-        this.taskView = taskView;
-        this.animation = animation;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
deleted file mode 100644
index 39e4c1d..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent whenever the user interacts with the activity.
- */
-public class UserInteractionEvent extends EventBus.ReusableEvent {
-    // Simple Event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragDropTargetChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragDropTargetChangedEvent.java
deleted file mode 100644
index cf61b1e..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragDropTargetChangedEvent.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui.dragndrop;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.views.DropTarget;
-
-/**
- * This event is sent when a user drags in/out of a drop target.
- */
-public class DragDropTargetChangedEvent extends EventBus.AnimatedEvent {
-
-    // The task that is currently being dragged
-    public final Task task;
-    public final DropTarget dropTarget;
-
-    public DragDropTargetChangedEvent(Task task, DropTarget dropTarget) {
-        this.task = task;
-        this.dropTarget = dropTarget;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndCancelledEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndCancelledEvent.java
deleted file mode 100644
index 297afc5..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndCancelledEvent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.events.ui.dragndrop;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent whenever a drag end is cancelled because of an error.
- */
-public class DragEndCancelledEvent extends EventBus.AnimatedEvent {
-
-    public final TaskStack stack;
-    public final Task task;
-    public final TaskView taskView;
-
-    public DragEndCancelledEvent(TaskStack stack, Task task, TaskView taskView) {
-        this.stack = stack;
-        this.task = task;
-        this.taskView = taskView;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndEvent.java
deleted file mode 100644
index 73cbde9..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndEvent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui.dragndrop;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.views.DropTarget;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent whenever a drag ends.
- */
-public class DragEndEvent extends EventBus.AnimatedEvent {
-
-    public final Task task;
-    public final TaskView taskView;
-    public final DropTarget dropTarget;
-
-    public DragEndEvent(Task task, TaskView taskView, DropTarget dropTarget) {
-        this.task = task;
-        this.taskView = taskView;
-        this.dropTarget = dropTarget;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartEvent.java
deleted file mode 100644
index 021be77..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartEvent.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui.dragndrop;
-
-import android.graphics.Point;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent whenever a drag starts.
- */
-public class DragStartEvent extends EventBus.Event {
-
-    public final Task task;
-    public final TaskView taskView;
-    public final Point tlOffset;
-    public final boolean isUserTouchInitiated;
-
-    public DragStartEvent(Task task, TaskView taskView, Point tlOffset) {
-        this(task, taskView, tlOffset, true);
-    }
-
-    public DragStartEvent(Task task, TaskView taskView, Point tlOffset,
-            boolean isUserTouchInitiated) {
-        this.task = task;
-        this.taskView = taskView;
-        this.tlOffset = tlOffset;
-        this.isUserTouchInitiated = isUserTouchInitiated;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartInitializeDropTargetsEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartInitializeDropTargetsEvent.java
deleted file mode 100644
index 64ba574..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragStartInitializeDropTargetsEvent.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui.dragndrop;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.views.RecentsViewTouchHandler;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent by the drag manager when it requires drop targets to register themselves for
- * the current drag gesture.
- */
-public class DragStartInitializeDropTargetsEvent extends EventBus.Event {
-
-    public final Task task;
-    public final TaskView taskView;
-    public final RecentsViewTouchHandler handler;
-
-    public DragStartInitializeDropTargetsEvent(Task task, TaskView taskView,
-            RecentsViewTouchHandler handler) {
-        this.task = task;
-        this.taskView = taskView;
-        this.handler = handler;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/DismissFocusedTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/DismissFocusedTaskViewEvent.java
deleted file mode 100644
index df74018..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/DismissFocusedTaskViewEvent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui.focus;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.views.TaskView;
-
-/**
- * This event is sent to request that the currently focused {@link TaskView} is dismissed.
- */
-public class DismissFocusedTaskViewEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
deleted file mode 100644
index 171ab5e..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui.focus;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Focuses the next task view in the stack.
- */
-public class FocusNextTaskViewEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusPreviousTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusPreviousTaskViewEvent.java
deleted file mode 100644
index 22469e7..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusPreviousTaskViewEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.events.ui.focus;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Focuses the previous task view in the stack.
- */
-public class FocusPreviousTaskViewEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/NavigateTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/NavigateTaskViewEvent.java
deleted file mode 100644
index 5508d26..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/NavigateTaskViewEvent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.events.ui.focus;
-
-import android.view.KeyEvent;
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * Navigates the task view by arrow keys.
- */
-public class NavigateTaskViewEvent extends EventBus.Event {
-    public enum Direction {
-        UNDEFINED, UP, DOWN, LEFT, RIGHT;
-    }
-
-    public Direction direction;
-    public NavigateTaskViewEvent(Direction direction) {
-        this.direction = direction;
-    }
-
-    public static Direction getDirectionFromKeyCode(int keyCode) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_UP:
-                return Direction.UP;
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-                return Direction.DOWN;
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-                return Direction.LEFT;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                return Direction.RIGHT;
-            default:
-                return Direction.UNDEFINED;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java b/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
deleted file mode 100644
index 574ea03..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.misc;
-
-import android.os.Handler;
-import android.view.ViewDebug;
-
-/**
- * A dozer is a class that fires a trigger after it falls asleep.
- * You can occasionally poke the trigger to wake it up, but it will fall asleep if left untouched.
- */
-public class DozeTrigger {
-
-    Handler mHandler;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    boolean mIsDozing;
-    @ViewDebug.ExportedProperty(category="recents")
-    boolean mIsAsleep;
-    @ViewDebug.ExportedProperty(category="recents")
-    int mDozeDurationMilliseconds;
-    Runnable mOnSleepRunnable;
-
-    // Sleep-runnable
-    Runnable mDozeRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mIsDozing = false;
-            mIsAsleep = true;
-            mOnSleepRunnable.run();
-        }
-    };
-
-    public DozeTrigger(int dozeDurationMilliseconds, Runnable onSleepRunnable) {
-        mHandler = new Handler();
-        mDozeDurationMilliseconds = dozeDurationMilliseconds;
-        mOnSleepRunnable = onSleepRunnable;
-    }
-
-    /**
-     * Starts dozing and queues the onSleepRunnable to be called. This also resets the trigger flag.
-     */
-    public void startDozing() {
-        forcePoke();
-        mIsAsleep = false;
-    }
-
-    /**
-     * Stops dozing and prevents the onSleepRunnable from being called.
-     */
-    public void stopDozing() {
-        mHandler.removeCallbacks(mDozeRunnable);
-        mIsDozing = false;
-        mIsAsleep = false;
-    }
-
-    /**
-     * Updates the duration that we have to wait until dozing triggers.
-     */
-    public void setDozeDuration(int duration) {
-        mDozeDurationMilliseconds = duration;
-    }
-
-    /**
-     * Poke this dozer to wake it up if it is dozing, delaying the onSleepRunnable from being
-     * called for a for the doze duration.
-     */
-    public void poke() {
-        if (mIsDozing) {
-            forcePoke();
-        }
-    }
-
-    /**
-     * Poke this dozer to wake it up even if it is not currently dozing.
-     */
-    void forcePoke() {
-        mHandler.removeCallbacks(mDozeRunnable);
-        mHandler.postDelayed(mDozeRunnable, mDozeDurationMilliseconds);
-        mIsDozing = true;
-    }
-
-    /** Returns whether we are dozing or not. */
-    public boolean isDozing() {
-        return mIsDozing;
-    }
-
-    /** Returns whether the trigger has fired at least once. */
-    public boolean isAsleep() {
-        return mIsAsleep;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/FreePathInterpolator.java b/packages/SystemUI/src/com/android/systemui/recents/misc/FreePathInterpolator.java
deleted file mode 100644
index 720c952..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/FreePathInterpolator.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.misc;
-
-import android.graphics.Path;
-import android.view.animation.BaseInterpolator;
-import android.view.animation.Interpolator;
-
-/**
- * An interpolator that can traverse a Path. The x coordinate along the <code>Path</code>
- * is the input value and the output is the y coordinate of the line at that point.
- * This means that the Path must conform to a function <code>y = f(x)</code>.
- *
- * <p>The <code>Path</code> must not have gaps in the x direction and must not
- * loop back on itself such that there can be two points sharing the same x coordinate.
- * It is alright to have a disjoint line in the vertical direction:</p>
- * <p><blockquote><pre>
- *     Path path = new Path();
- *     path.lineTo(0.25f, 0.25f);
- *     path.moveTo(0.25f, 0.5f);
- *     path.lineTo(1f, 1f);
- * </pre></blockquote></p>
- */
-public class FreePathInterpolator extends BaseInterpolator {
-
-    // This governs how accurate the approximation of the Path is.
-    private static final float PRECISION = 0.002f;
-
-    private float[] mX;
-    private float[] mY;
-    private float mArcLength;
-
-    /**
-     * Create an interpolator for an arbitrary <code>Path</code>.
-     *
-     * @param path The <code>Path</code> to use to make the line representing the interpolator.
-     */
-    public FreePathInterpolator(Path path) {
-        initPath(path);
-    }
-
-    private void initPath(Path path) {
-        float[] pointComponents = path.approximate(PRECISION);
-
-        int numPoints = pointComponents.length / 3;
-
-        mX = new float[numPoints];
-        mY = new float[numPoints];
-        mArcLength = 0;
-        float prevX = 0;
-        float prevY = 0;
-        float prevFraction = 0;
-        int componentIndex = 0;
-        for (int i = 0; i < numPoints; i++) {
-            float fraction = pointComponents[componentIndex++];
-            float x = pointComponents[componentIndex++];
-            float y = pointComponents[componentIndex++];
-            if (fraction == prevFraction && x != prevX) {
-                throw new IllegalArgumentException(
-                        "The Path cannot have discontinuity in the X axis.");
-            }
-            if (x < prevX) {
-                throw new IllegalArgumentException("The Path cannot loop back on itself.");
-            }
-            mX[i] = x;
-            mY[i] = y;
-            mArcLength += Math.hypot(x - prevX, y - prevY);
-            prevX = x;
-            prevY = y;
-            prevFraction = fraction;
-        }
-    }
-
-    /**
-     * Using the line in the Path in this interpolator that can be described as
-     * <code>y = f(x)</code>, finds the y coordinate of the line given <code>t</code>
-     * as the x coordinate.
-     *
-     * @param t Treated as the x coordinate along the line.
-     * @return The y coordinate of the Path along the line where x = <code>t</code>.
-     * @see Interpolator#getInterpolation(float)
-     */
-    @Override
-    public float getInterpolation(float t) {
-        int startIndex = 0;
-        int endIndex = mX.length - 1;
-
-        // Return early if out of bounds
-        if (t <= 0) {
-            return mY[startIndex];
-        } else if (t >= 1) {
-            return mY[endIndex];
-        }
-
-        // Do a binary search for the correct x to interpolate between.
-        while (endIndex - startIndex > 1) {
-            int midIndex = (startIndex + endIndex) / 2;
-            if (t < mX[midIndex]) {
-                endIndex = midIndex;
-            } else {
-                startIndex = midIndex;
-            }
-        }
-
-        float xRange = mX[endIndex] - mX[startIndex];
-        if (xRange == 0) {
-            return mY[startIndex];
-        }
-
-        float tInRange = t - mX[startIndex];
-        float fraction = tInRange / xRange;
-
-        float startY = mY[startIndex];
-        float endY = mY[endIndex];
-        return startY + (fraction * (endY - startY));
-    }
-
-    /**
-     * Finds the x that provides the given <code>y = f(x)</code>.
-     *
-     * @param y a value from (0,1) that is in this path.
-     */
-    public float getX(float y) {
-        int startIndex = 0;
-        int endIndex = mY.length - 1;
-
-        // Return early if out of bounds
-        if (y <= 0) {
-            return mX[endIndex];
-        } else if (y >= 1) {
-            return mX[startIndex];
-        }
-
-        // Do a binary search for index that bounds the y
-        while (endIndex - startIndex > 1) {
-            int midIndex = (startIndex + endIndex) / 2;
-            if (y < mY[midIndex]) {
-                startIndex = midIndex;
-            } else {
-                endIndex = midIndex;
-            }
-        }
-
-        float yRange = mY[endIndex] - mY[startIndex];
-        if (yRange == 0) {
-            return mX[startIndex];
-        }
-
-        float tInRange = y - mY[startIndex];
-        float fraction = tInRange / yRange;
-
-        float startX = mX[startIndex];
-        float endX = mX[endIndex];
-        return startX + (fraction * (endX - startX));
-    }
-
-    /**
-     * Returns the arclength of the path we are interpolating.
-     */
-    public float getArcLength() {
-        return mArcLength;
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
deleted file mode 100644
index 2637d88..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.misc;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-
-import java.util.ArrayList;
-
-/**
- * A ref counted trigger that does some logic when the count is first incremented, or last
- * decremented.  Not thread safe as it's not currently needed.
- */
-public class ReferenceCountedTrigger {
-
-    int mCount;
-    ArrayList<Runnable> mFirstIncRunnables = new ArrayList<>();
-    ArrayList<Runnable> mLastDecRunnables = new ArrayList<>();
-    Runnable mErrorRunnable;
-
-    // Convenience runnables
-    Runnable mIncrementRunnable = new Runnable() {
-        @Override
-        public void run() {
-            increment();
-        }
-    };
-    Runnable mDecrementRunnable = new Runnable() {
-        @Override
-        public void run() {
-            decrement();
-        }
-    };
-
-    public ReferenceCountedTrigger() {
-        this(null, null, null);
-    }
-
-    public ReferenceCountedTrigger(Runnable firstIncRunnable, Runnable lastDecRunnable,
-            Runnable errorRunanable) {
-        if (firstIncRunnable != null) mFirstIncRunnables.add(firstIncRunnable);
-        if (lastDecRunnable != null) mLastDecRunnables.add(lastDecRunnable);
-        mErrorRunnable = errorRunanable;
-    }
-
-    /** Increments the ref count */
-    public void increment() {
-        if (mCount == 0 && !mFirstIncRunnables.isEmpty()) {
-            int numRunnables = mFirstIncRunnables.size();
-            for (int i = 0; i < numRunnables; i++) {
-                mFirstIncRunnables.get(i).run();
-            }
-        }
-        mCount++;
-    }
-
-    /** Convenience method to increment this trigger as a runnable */
-    public Runnable incrementAsRunnable() {
-        return mIncrementRunnable;
-    }
-
-    /** Adds a runnable to the last-decrement runnables list. */
-    public void addLastDecrementRunnable(Runnable r) {
-        mLastDecRunnables.add(r);
-    }
-
-    /** Decrements the ref count */
-    public void decrement() {
-        mCount--;
-        if (mCount == 0) {
-            flushLastDecrementRunnables();
-        } else if (mCount < 0) {
-            if (mErrorRunnable != null) {
-                mErrorRunnable.run();
-            } else {
-                throw new RuntimeException("Invalid ref count");
-            }
-        }
-    }
-
-    /**
-     * Runs and clears all the last-decrement runnables now.
-     */
-    public void flushLastDecrementRunnables() {
-        if (!mLastDecRunnables.isEmpty()) {
-            int numRunnables = mLastDecRunnables.size();
-            for (int i = 0; i < numRunnables; i++) {
-                mLastDecRunnables.get(i).run();
-            }
-        }
-        mLastDecRunnables.clear();
-    }
-
-    /**
-     * Convenience method to decrement this trigger as a animator listener.  This listener is
-     * guarded to prevent being called back multiple times, and will trigger a decrement once and
-     * only once.
-     */
-    public Animator.AnimatorListener decrementOnAnimationEnd() {
-        return new AnimatorListenerAdapter() {
-            private boolean hasEnded;
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (hasEnded) return;
-                decrement();
-                hasEnded = true;
-            }
-        };
-    }
-
-    /** Returns the current ref count */
-    public int getCount() {
-        return mCount;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SysUiTaskStackChangeListener.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SysUiTaskStackChangeListener.java
deleted file mode 100644
index 5d7f1ba..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SysUiTaskStackChangeListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.misc;
-
-import android.content.Context;
-
-import com.android.systemui.shared.system.TaskStackChangeListener;
-
-/**
- * An implementation of {@link TaskStackChangeListener}.
- */
-public abstract class SysUiTaskStackChangeListener extends TaskStackChangeListener {
-
-    /**
-     * Checks that the current user matches the user's SystemUI process.
-     */
-    protected final boolean checkCurrentUserId(Context context, boolean debug) {
-        int currentUserId = SystemServicesProxy.getInstance(context).getCurrentUser();
-        return checkCurrentUserId(currentUserId, debug);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
deleted file mode 100644
index 350fe78..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.misc;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.StackInfo;
-import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
-import android.app.AppGlobals;
-import android.app.IActivityManager;
-import android.app.IActivityTaskManager;
-import android.app.WindowConfiguration;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.service.dreams.DreamService;
-import android.service.dreams.IDreamManager;
-import android.util.Log;
-import android.util.MutableBoolean;
-import android.view.Display;
-import android.view.IDockedStackListener;
-import android.view.IWindowManager;
-import android.view.WindowManager;
-import android.view.WindowManager.KeyboardShortcutsReceiver;
-import android.view.WindowManagerGlobal;
-import android.view.accessibility.AccessibilityManager;
-
-import com.android.internal.app.AssistUtils;
-import com.android.internal.os.BackgroundThread;
-import com.android.systemui.Dependency;
-import com.android.systemui.UiOffloadThread;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsImpl;
-import com.android.systemui.statusbar.policy.UserInfoController;
-
-import java.util.List;
-
-/**
- * Acts as a shim around the real system services that we need to access data from, and provides
- * a point of injection when testing UI.
- */
-public class SystemServicesProxy {
-    final static String TAG = "SystemServicesProxy";
-
-    final static BitmapFactory.Options sBitmapOptions;
-    static {
-        sBitmapOptions = new BitmapFactory.Options();
-        sBitmapOptions.inMutable = true;
-        sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
-    }
-
-    private static SystemServicesProxy sSystemServicesProxy;
-
-    AccessibilityManager mAccm;
-    ActivityManager mAm;
-    IActivityManager mIam;
-    IActivityTaskManager mIatm;
-    PackageManager mPm;
-    IPackageManager mIpm;
-    private final IDreamManager mDreamManager;
-    private final Context mContext;
-    AssistUtils mAssistUtils;
-    WindowManager mWm;
-    IWindowManager mIwm;
-    UserManager mUm;
-    Display mDisplay;
-    String mRecentsPackage;
-    private int mCurrentUserId;
-
-    boolean mIsSafeMode;
-
-    int mDummyThumbnailWidth;
-    int mDummyThumbnailHeight;
-    Paint mBgProtectionPaint;
-    Canvas mBgProtectionCanvas;
-
-    private final Runnable mGcRunnable = new Runnable() {
-        @Override
-        public void run() {
-            System.gc();
-            System.runFinalization();
-        }
-    };
-
-    private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
-
-    private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener =
-            (String name, Drawable picture, String userAccount) ->
-                    mCurrentUserId = mAm.getCurrentUser();
-
-    /** Private constructor */
-    private SystemServicesProxy(Context context) {
-        mContext = context.getApplicationContext();
-        mAccm = AccessibilityManager.getInstance(context);
-        mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        mIam = ActivityManager.getService();
-        mIatm = ActivityTaskManager.getService();
-        mPm = context.getPackageManager();
-        mIpm = AppGlobals.getPackageManager();
-        mAssistUtils = new AssistUtils(context);
-        mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        mIwm = WindowManagerGlobal.getWindowManagerService();
-        mUm = UserManager.get(context);
-        mDreamManager = IDreamManager.Stub.asInterface(
-                ServiceManager.checkService(DreamService.DREAM_SERVICE));
-        mDisplay = mWm.getDefaultDisplay();
-        mRecentsPackage = context.getPackageName();
-        mIsSafeMode = mPm.isSafeMode();
-        mCurrentUserId = mAm.getCurrentUser();
-
-        // Get the dummy thumbnail width/heights
-        Resources res = context.getResources();
-        int wId = com.android.internal.R.dimen.thumbnail_width;
-        int hId = com.android.internal.R.dimen.thumbnail_height;
-        mDummyThumbnailWidth = res.getDimensionPixelSize(wId);
-        mDummyThumbnailHeight = res.getDimensionPixelSize(hId);
-
-        // Create the protection paints
-        mBgProtectionPaint = new Paint();
-        mBgProtectionPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
-        mBgProtectionPaint.setColor(0xFFffffff);
-        mBgProtectionCanvas = new Canvas();
-
-        // Since SystemServicesProxy can be accessed from a per-SysUI process component, create a
-        // per-process listener to keep track of the current user id to reduce the number of binder
-        // calls to fetch it.
-        UserInfoController userInfoController = Dependency.get(UserInfoController.class);
-        userInfoController.addCallback(mOnUserInfoChangedListener);
-    }
-
-    /**
-     * Returns the single instance of the {@link SystemServicesProxy}.
-     * This should only be called on the main thread.
-     */
-    public static synchronized SystemServicesProxy getInstance(Context context) {
-        if (sSystemServicesProxy == null) {
-            sSystemServicesProxy = new SystemServicesProxy(context);
-        }
-        return sSystemServicesProxy;
-    }
-
-    /**
-     * Requests a gc() from the background thread.
-     */
-    public void gc() {
-        BackgroundThread.getHandler().post(mGcRunnable);
-    }
-
-    /**
-     * Returns whether the recents activity is currently visible.
-     */
-    public boolean isRecentsActivityVisible() {
-        return isRecentsActivityVisible(null);
-    }
-
-    /**
-     * Returns whether the recents activity is currently visible.
-     *
-     * @param isHomeStackVisible if provided, will return whether the home stack is visible
-     *                           regardless of the recents visibility
-     *
-     * TODO(winsonc): Refactor this check to just use the recents activity lifecycle
-     */
-    public boolean isRecentsActivityVisible(MutableBoolean isHomeStackVisible) {
-        if (mIam == null) return false;
-
-        try {
-            List<StackInfo> stackInfos = mIatm.getAllStackInfos();
-            ActivityManager.StackInfo homeStackInfo = null;
-            ActivityManager.StackInfo fullscreenStackInfo = null;
-            ActivityManager.StackInfo recentsStackInfo = null;
-            for (int i = 0; i < stackInfos.size(); i++) {
-                final StackInfo stackInfo = stackInfos.get(i);
-                final WindowConfiguration winConfig = stackInfo.configuration.windowConfiguration;
-                final int activityType = winConfig.getActivityType();
-                final int windowingMode = winConfig.getWindowingMode();
-                if (homeStackInfo == null && activityType == ACTIVITY_TYPE_HOME) {
-                    homeStackInfo = stackInfo;
-                } else if (fullscreenStackInfo == null && activityType == ACTIVITY_TYPE_STANDARD
-                        && (windowingMode == WINDOWING_MODE_FULLSCREEN
-                            || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY)) {
-                    fullscreenStackInfo = stackInfo;
-                } else if (recentsStackInfo == null && activityType == ACTIVITY_TYPE_RECENTS) {
-                    recentsStackInfo = stackInfo;
-                }
-            }
-            boolean homeStackVisibleNotOccluded = isStackNotOccluded(homeStackInfo,
-                    fullscreenStackInfo);
-            boolean recentsStackVisibleNotOccluded = isStackNotOccluded(recentsStackInfo,
-                    fullscreenStackInfo);
-            if (isHomeStackVisible != null) {
-                isHomeStackVisible.value = homeStackVisibleNotOccluded;
-            }
-            ComponentName topActivity = recentsStackInfo != null ?
-                    recentsStackInfo.topActivity : null;
-            return (recentsStackVisibleNotOccluded && topActivity != null
-                    && topActivity.getPackageName().equals(RecentsImpl.RECENTS_PACKAGE)
-                    && Recents.RECENTS_ACTIVITIES.contains(topActivity.getClassName()));
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    private boolean isStackNotOccluded(ActivityManager.StackInfo stackInfo,
-            ActivityManager.StackInfo fullscreenStackInfo) {
-        boolean stackVisibleNotOccluded = stackInfo == null || stackInfo.visible;
-        if (fullscreenStackInfo != null && stackInfo != null) {
-            boolean isFullscreenStackOccludingg = fullscreenStackInfo.visible &&
-                    fullscreenStackInfo.position > stackInfo.position;
-            stackVisibleNotOccluded &= !isFullscreenStackOccludingg;
-        }
-        return stackVisibleNotOccluded;
-    }
-
-    /**
-     * Returns whether this device is in the safe mode.
-     */
-    public boolean isInSafeMode() {
-        return mIsSafeMode;
-    }
-
-    /** Moves an already resumed task to the side of the screen to initiate split screen. */
-    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
-            Rect initialBounds) {
-        if (mIatm == null) {
-            return false;
-        }
-
-        try {
-            return mIatm.setTaskWindowingModeSplitScreenPrimary(taskId, createMode,
-                    true /* onTop */, false /* animate */, initialBounds, true /* showRecents */);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    public ActivityManager.StackInfo getSplitScreenPrimaryStack() {
-        try {
-            return mIatm.getStackInfo(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * @return whether there are any docked tasks for the current user.
-     */
-    public boolean hasDockedTask() {
-        if (mIam == null) return false;
-
-        ActivityManager.StackInfo stackInfo = getSplitScreenPrimaryStack();
-        if (stackInfo != null) {
-            int userId = getCurrentUser();
-            boolean hasUserTask = false;
-            for (int i = stackInfo.taskUserIds.length - 1; i >= 0 && !hasUserTask; i--) {
-                hasUserTask = (stackInfo.taskUserIds[i] == userId);
-            }
-            return hasUserTask;
-        }
-        return false;
-    }
-
-    /**
-     * Returns whether there is a soft nav bar.
-     */
-    public boolean hasSoftNavigationBar() {
-        try {
-            return mIwm.hasNavigationBar();
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    /**
-     * Returns whether the device has a transposed nav bar (on the right of the screen) in the
-     * current display orientation.
-     */
-    public boolean hasTransposedNavigationBar() {
-        Rect insets = new Rect();
-        getStableInsets(insets);
-        return insets.right > 0;
-    }
-
-    /** Set the task's windowing mode. */
-    public void setTaskWindowingMode(int taskId, int windowingMode) {
-        if (mIatm == null) return;
-
-        try {
-            mIatm.setTaskWindowingMode(taskId, windowingMode, false /* onTop */);
-        } catch (RemoteException | IllegalArgumentException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Returns whether the provided {@param userId} represents the system user.
-     */
-    public boolean isSystemUser(int userId) {
-        return userId == UserHandle.USER_SYSTEM;
-    }
-
-    /**
-     * Returns the current user id.  Used instead of KeyguardUpdateMonitor in SystemUI components
-     * that run in the non-primary SystemUI process.
-     */
-    public int getCurrentUser() {
-        return mCurrentUserId;
-    }
-
-    /**
-     * Returns the processes user id.
-     */
-    public int getProcessUser() {
-        if (mUm == null) return 0;
-        return mUm.getUserHandle();
-    }
-
-    /**
-     * Returns whether touch exploration is currently enabled.
-     */
-    public boolean isTouchExplorationEnabled() {
-        if (mAccm == null) return false;
-
-        return mAccm.isEnabled() && mAccm.isTouchExplorationEnabled();
-    }
-
-    /**
-     * Returns whether the current task is in screen-pinning mode.
-     */
-    public boolean isScreenPinningActive() {
-        if (mIam == null) return false;
-
-        try {
-            return mIatm.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED;
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the smallest width/height.
-     */
-    public int getDeviceSmallestWidth() {
-        if (mDisplay == null) return 0;
-
-        Point smallestSizeRange = new Point();
-        Point largestSizeRange = new Point();
-        mDisplay.getCurrentSizeRange(smallestSizeRange, largestSizeRange);
-        return smallestSizeRange.x;
-    }
-
-    /**
-     * Returns the current display rect in the current display orientation.
-     */
-    public Rect getDisplayRect() {
-        Rect displayRect = new Rect();
-        if (mDisplay == null) return displayRect;
-
-        Point p = new Point();
-        mDisplay.getRealSize(p);
-        displayRect.set(0, 0, p.x, p.y);
-        return displayRect;
-    }
-
-    /**
-     * Returns the window rect for the RecentsActivity, based on the dimensions of the recents stack
-     */
-    public Rect getWindowRect() {
-        Rect windowRect = new Rect();
-        if (mIam == null) return windowRect;
-
-        try {
-            // Use the recents stack bounds, fallback to fullscreen stack if it is null
-            ActivityManager.StackInfo stackInfo =
-                    mIatm.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
-            if (stackInfo == null) {
-                stackInfo = mIatm.getStackInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-            }
-            if (stackInfo != null) {
-                windowRect.set(stackInfo.bounds);
-            }
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        } finally {
-            return windowRect;
-        }
-    }
-
-    public void startActivityAsUserAsync(Intent intent, ActivityOptions opts) {
-        mUiOffloadThread.submit(() -> mContext.startActivityAsUser(intent,
-                opts != null ? opts.toBundle() : null, UserHandle.CURRENT));
-    }
-
-    /** Starts an in-place animation on the front most application windows. */
-    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) {
-        if (mIam == null) return;
-
-        try {
-            mIatm.startInPlaceAnimationOnFrontMostApplication(
-                    opts == null ? null : opts.toBundle());
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void registerDockedStackListener(IDockedStackListener listener) {
-        if (mWm == null) return;
-
-        try {
-            mIwm.registerDockedStackListener(listener);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Calculates the size of the dock divider in the current orientation.
-     */
-    public int getDockedDividerSize(Context context) {
-        Resources res = context.getResources();
-        int dividerWindowWidth = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_divider_thickness);
-        int dividerInsets = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_divider_insets);
-        return dividerWindowWidth - 2 * dividerInsets;
-    }
-
-    public void requestKeyboardShortcuts(
-            Context context, KeyboardShortcutsReceiver receiver, int deviceId) {
-        mWm.requestAppKeyboardShortcuts(receiver, deviceId);
-    }
-
-    public void getStableInsets(Rect outStableInsets) {
-        if (mWm == null) return;
-
-        try {
-            mIwm.getStableInsets(Display.DEFAULT_DISPLAY, outStableInsets);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Updates the visibility of recents.
-     */
-    public void setRecentsVisibility(final boolean visible) {
-        mUiOffloadThread.submit(() -> {
-            try {
-                mIwm.setRecentsVisibility(visible);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to reach window manager", e);
-            }
-        });
-    }
-
-    /**
-     * Updates the visibility of the picture-in-picture.
-     */
-    public void setPipVisibility(final boolean visible) {
-        mUiOffloadThread.submit(() -> {
-            try {
-                mIwm.setPipVisibility(visible);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to reach window manager", e);
-            }
-        });
-    }
-
-    public boolean isDreaming() {
-        try {
-            return mDreamManager.isDreaming();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to query dream manager.", e);
-        }
-        return false;
-    }
-
-    public void awakenDreamsAsync() {
-        mUiOffloadThread.submit(() -> {
-            try {
-                mDreamManager.awaken();
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        });
-    }
-
-    public interface StartActivityFromRecentsResultListener {
-        void onStartActivityResult(boolean succeeded);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/DockState.java b/packages/SystemUI/src/com/android/systemui/recents/views/DockState.java
deleted file mode 100644
index a246141..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/DockState.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.views;
-
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.annotation.IntDef;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
-import android.util.IntProperty;
-import android.view.animation.Interpolator;
-
-import com.android.internal.policy.DockedDividerUtils;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.shared.recents.utilities.Utilities;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-
-/**
- * The various possible dock states when dragging and dropping a task.
- */
-public class DockState implements DropTarget {
-
-    public static final int DOCK_AREA_BG_COLOR = 0xFFffffff;
-    public static final int DOCK_AREA_GRID_BG_COLOR = 0xFF000000;
-
-    // The rotation to apply to the hint text
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({HORIZONTAL, VERTICAL})
-    public @interface TextOrientation {}
-    private static final int HORIZONTAL = 0;
-    private static final int VERTICAL = 1;
-
-    private static final int DOCK_AREA_ALPHA = 80;
-    public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, 255, HORIZONTAL,
-            null, null, null);
-    public static final DockState LEFT = new DockState(DOCKED_LEFT,
-            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA, 0, VERTICAL,
-            new RectF(0, 0, 0.125f, 1), new RectF(0, 0, 0.125f, 1),
-            new RectF(0, 0, 0.5f, 1));
-    public static final DockState TOP = new DockState(DOCKED_TOP,
-            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA, 0, HORIZONTAL,
-            new RectF(0, 0, 1, 0.125f), new RectF(0, 0, 1, 0.125f),
-            new RectF(0, 0, 1, 0.5f));
-    public static final DockState RIGHT = new DockState(DOCKED_RIGHT,
-            SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA, 0, VERTICAL,
-            new RectF(0.875f, 0, 1, 1), new RectF(0.875f, 0, 1, 1),
-            new RectF(0.5f, 0, 1, 1));
-    public static final DockState BOTTOM = new DockState(DOCKED_BOTTOM,
-            SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA, 0, HORIZONTAL,
-            new RectF(0, 0.875f, 1, 1), new RectF(0, 0.875f, 1, 1),
-            new RectF(0, 0.5f, 1, 1));
-
-    @Override
-    public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
-            boolean isCurrentTarget) {
-        if (isCurrentTarget) {
-            getMappedRect(expandedTouchDockArea, width, height, mTmpRect);
-            return mTmpRect.contains(x, y);
-        } else {
-            getMappedRect(touchArea, width, height, mTmpRect);
-            updateBoundsWithSystemInsets(mTmpRect, insets);
-            return mTmpRect.contains(x, y);
-        }
-    }
-
-    // Represents the view state of this dock state
-    public static class ViewState {
-        private static final IntProperty<ViewState> HINT_ALPHA =
-                new IntProperty<ViewState>("drawableAlpha") {
-                    @Override
-                    public void setValue(ViewState object, int alpha) {
-                        object.mHintTextAlpha = alpha;
-                        object.dockAreaOverlay.invalidateSelf();
-                    }
-
-                    @Override
-                    public Integer get(ViewState object) {
-                        return object.mHintTextAlpha;
-                    }
-                };
-
-        public final int dockAreaAlpha;
-        public final ColorDrawable dockAreaOverlay;
-        public final int hintTextAlpha;
-        public final int hintTextOrientation;
-
-        private final int mHintTextResId;
-        private String mHintText;
-        private Paint mHintTextPaint;
-        private Point mHintTextBounds = new Point();
-        private int mHintTextAlpha = 255;
-        private AnimatorSet mDockAreaOverlayAnimator;
-        private Rect mTmpRect = new Rect();
-
-        private ViewState(int areaAlpha, int hintAlpha, @TextOrientation int hintOrientation,
-                int hintTextResId) {
-            dockAreaAlpha = areaAlpha;
-            dockAreaOverlay = new ColorDrawable(Recents.getConfiguration().isGridEnabled
-                    ? DOCK_AREA_GRID_BG_COLOR : DOCK_AREA_BG_COLOR);
-            dockAreaOverlay.setAlpha(0);
-            hintTextAlpha = hintAlpha;
-            hintTextOrientation = hintOrientation;
-            mHintTextResId = hintTextResId;
-            mHintTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-            mHintTextPaint.setColor(Color.WHITE);
-        }
-
-        /**
-         * Updates the view state with the given context.
-         */
-        public void update(Context context) {
-            Resources res = context.getResources();
-            mHintText = context.getString(mHintTextResId);
-            mHintTextPaint.setTextSize(res.getDimensionPixelSize(
-                    R.dimen.recents_drag_hint_text_size));
-            mHintTextPaint.getTextBounds(mHintText, 0, mHintText.length(), mTmpRect);
-            mHintTextBounds.set((int) mHintTextPaint.measureText(mHintText), mTmpRect.height());
-        }
-
-        /**
-         * Draws the current view state.
-         */
-        public void draw(Canvas canvas) {
-            // Draw the overlay background
-            if (dockAreaOverlay.getAlpha() > 0) {
-                dockAreaOverlay.draw(canvas);
-            }
-
-            // Draw the hint text
-            if (mHintTextAlpha > 0) {
-                Rect bounds = dockAreaOverlay.getBounds();
-                int x = bounds.left + (bounds.width() - mHintTextBounds.x) / 2;
-                int y = bounds.top + (bounds.height() + mHintTextBounds.y) / 2;
-                mHintTextPaint.setAlpha(mHintTextAlpha);
-                if (hintTextOrientation == VERTICAL) {
-                    canvas.save();
-                    canvas.rotate(-90f, bounds.centerX(), bounds.centerY());
-                }
-                canvas.drawText(mHintText, x, y, mHintTextPaint);
-                if (hintTextOrientation == VERTICAL) {
-                    canvas.restore();
-                }
-            }
-        }
-
-        /**
-         * Creates a new bounds and alpha animation.
-         */
-        public void startAnimation(Rect bounds, int areaAlpha, int hintAlpha, int duration,
-                Interpolator interpolator, boolean animateAlpha, boolean animateBounds) {
-            if (mDockAreaOverlayAnimator != null) {
-                mDockAreaOverlayAnimator.cancel();
-            }
-
-            ObjectAnimator anim;
-            ArrayList<Animator> animators = new ArrayList<>();
-            if (dockAreaOverlay.getAlpha() != areaAlpha) {
-                if (animateAlpha) {
-                    anim = ObjectAnimator.ofInt(dockAreaOverlay,
-                            Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), areaAlpha);
-                    anim.setDuration(duration);
-                    anim.setInterpolator(interpolator);
-                    animators.add(anim);
-                } else {
-                    dockAreaOverlay.setAlpha(areaAlpha);
-                }
-            }
-            if (mHintTextAlpha != hintAlpha) {
-                if (animateAlpha) {
-                    anim = ObjectAnimator.ofInt(this, HINT_ALPHA, mHintTextAlpha,
-                            hintAlpha);
-                    anim.setDuration(150);
-                    anim.setInterpolator(hintAlpha > mHintTextAlpha
-                            ? Interpolators.ALPHA_IN
-                            : Interpolators.ALPHA_OUT);
-                    animators.add(anim);
-                } else {
-                    mHintTextAlpha = hintAlpha;
-                    dockAreaOverlay.invalidateSelf();
-                }
-            }
-            if (bounds != null && !dockAreaOverlay.getBounds().equals(bounds)) {
-                if (animateBounds) {
-                    PropertyValuesHolder prop = PropertyValuesHolder.ofObject(
-                            Utilities.DRAWABLE_RECT, Utilities.RECT_EVALUATOR,
-                            new Rect(dockAreaOverlay.getBounds()), bounds);
-                    anim = ObjectAnimator.ofPropertyValuesHolder(dockAreaOverlay, prop);
-                    anim.setDuration(duration);
-                    anim.setInterpolator(interpolator);
-                    animators.add(anim);
-                } else {
-                    dockAreaOverlay.setBounds(bounds);
-                }
-            }
-            if (!animators.isEmpty()) {
-                mDockAreaOverlayAnimator = new AnimatorSet();
-                mDockAreaOverlayAnimator.playTogether(animators);
-                mDockAreaOverlayAnimator.start();
-            }
-        }
-    }
-
-    public final int dockSide;
-    public final int createMode;
-    public final ViewState viewState;
-    private final RectF touchArea;
-    private final RectF dockArea;
-    private final RectF expandedTouchDockArea;
-    private static final Rect mTmpRect = new Rect();
-
-    /**
-     * @param createMode used to pass to ActivityManager to dock the task
-     * @param touchArea the area in which touch will initiate this dock state
-     * @param dockArea the visible dock area
-     * @param expandedTouchDockArea the area in which touch will continue to dock after entering
-     *                              the initial touch area.  This is also the new dock area to
-     *                              draw.
-     */
-    DockState(int dockSide, int createMode, int dockAreaAlpha, int hintTextAlpha,
-            @TextOrientation int hintTextOrientation, RectF touchArea, RectF dockArea,
-            RectF expandedTouchDockArea) {
-        this.dockSide = dockSide;
-        this.createMode = createMode;
-        this.viewState = new ViewState(dockAreaAlpha, hintTextAlpha, hintTextOrientation,
-                R.string.recents_drag_hint_message);
-        this.dockArea = dockArea;
-        this.touchArea = touchArea;
-        this.expandedTouchDockArea = expandedTouchDockArea;
-    }
-
-    /**
-     * Updates the dock state with the given context.
-     */
-    public void update(Context context) {
-        viewState.update(context);
-    }
-
-    /**
-     * Returns the docked task bounds with the given {@param width} and {@param height}.
-     */
-    public Rect getPreDockedBounds(int width, int height, Rect insets) {
-        getMappedRect(dockArea, width, height, mTmpRect);
-        return updateBoundsWithSystemInsets(mTmpRect, insets);
-    }
-
-    /**
-     * Returns the expanded docked task bounds with the given {@param width} and
-     * {@param height}.
-     */
-    public Rect getDockedBounds(int width, int height, int dividerSize, Rect insets,
-            Resources res) {
-        // Calculate the docked task bounds
-        boolean isHorizontalDivision =
-                res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
-        int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
-                insets, width, height, dividerSize);
-        Rect newWindowBounds = new Rect();
-        DockedDividerUtils.calculateBoundsForPosition(position, dockSide, newWindowBounds,
-                width, height, dividerSize);
-        return newWindowBounds;
-    }
-
-    /**
-     * Returns the task stack bounds with the given {@param width} and
-     * {@param height}.
-     */
-    public Rect getDockedTaskStackBounds(Rect displayRect, int width, int height,
-            int dividerSize, Rect insets, TaskStackLayoutAlgorithm layoutAlgorithm,
-            Resources res, Rect windowRectOut) {
-        // Calculate the inverse docked task bounds
-        boolean isHorizontalDivision =
-                res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
-        int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
-                insets, width, height, dividerSize);
-        DockedDividerUtils.calculateBoundsForPosition(position,
-                DockedDividerUtils.invertDockSide(dockSide), windowRectOut, width, height,
-                dividerSize);
-
-        // Calculate the task stack bounds from the new window bounds
-        Rect taskStackBounds = new Rect();
-        // If the task stack bounds is specifically under the dock area, then ignore the top
-        // inset
-        int top = dockArea.bottom < 1f
-                ? 0
-                : insets.top;
-        // For now, ignore the left insets since we always dock on the left and show Recents
-        // on the right
-        layoutAlgorithm.getTaskStackBounds(displayRect, windowRectOut, top, 0, insets.right,
-                taskStackBounds);
-        return taskStackBounds;
-    }
-
-    /**
-     * Returns the expanded bounds in certain dock sides such that the bounds account for the
-     * system insets (namely the vertical nav bar).  This call modifies and returns the given
-     * {@param bounds}.
-     */
-    private Rect updateBoundsWithSystemInsets(Rect bounds, Rect insets) {
-        if (dockSide == DOCKED_LEFT) {
-            bounds.right += insets.left;
-        } else if (dockSide == DOCKED_RIGHT) {
-            bounds.left -= insets.right;
-        }
-        return bounds;
-    }
-
-    /**
-     * Returns the mapped rect to the given dimensions.
-     */
-    private void getMappedRect(RectF bounds, int width, int height, Rect out) {
-        out.set((int) (bounds.left * width), (int) (bounds.top * height),
-                (int) (bounds.right * width), (int) (bounds.bottom * height));
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java b/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
deleted file mode 100644
index f2a6310..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.graphics.Rect;
-
-/**
- * Represents a drop target for a drag gesture.
- */
-public interface DropTarget {
-
-    /**
-     * Returns whether this target can accept this drop.  The x,y are relative to the top level
-     * RecentsView, and the width/height are of the RecentsView.
-     */
-    boolean acceptsDrop(int x, int y, int width, int height, Rect insets, boolean isCurrentTarget);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FakeShadowDrawable.java b/packages/SystemUI/src/com/android/systemui/recents/views/FakeShadowDrawable.java
deleted file mode 100644
index 79a774f..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FakeShadowDrawable.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.PixelFormat;
-import android.graphics.RadialGradient;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Shader;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsConfiguration;
-
-/**
- * A rounded rectangle drawable which also includes a shadow around. This is mostly copied from
- * frameworks/support/v7/cardview/eclair-mr1/android/support/v7/widget/
- * RoundRectDrawableWithShadow.java revision c42ba8c000d1e6ce85e152dfc17089a0a69e739f with a few
- * modifications to suit our needs in SystemUI.
- */
-class FakeShadowDrawable extends Drawable {
-    // used to calculate content padding
-    final static double COS_45 = Math.cos(Math.toRadians(45));
-
-    final static float SHADOW_MULTIPLIER = 1.5f;
-
-    final float mInsetShadow; // extra shadow to avoid gaps between card and shadow
-
-    Paint mCornerShadowPaint;
-
-    Paint mEdgeShadowPaint;
-
-    final RectF mCardBounds;
-
-    float mCornerRadius;
-
-    Path mCornerShadowPath;
-
-    // updated value with inset
-    float mMaxShadowSize;
-
-    // actual value set by developer
-    float mRawMaxShadowSize;
-
-    // multiplied value to account for shadow offset
-    float mShadowSize;
-
-    // actual value set by developer
-    float mRawShadowSize;
-
-    private boolean mDirty = true;
-
-    private final int mShadowStartColor;
-
-    private final int mShadowEndColor;
-
-    private boolean mAddPaddingForCorners = true;
-
-    /**
-     * If shadow size is set to a value above max shadow, we print a warning
-     */
-    private boolean mPrintedShadowClipWarning = false;
-
-    public FakeShadowDrawable(Resources resources, RecentsConfiguration config) {
-        mShadowStartColor = resources.getColor(R.color.fake_shadow_start_color);
-        mShadowEndColor = resources.getColor(R.color.fake_shadow_end_color);
-        mInsetShadow = resources.getDimension(R.dimen.fake_shadow_inset);
-        setShadowSize(resources.getDimensionPixelSize(R.dimen.fake_shadow_size),
-                resources.getDimensionPixelSize(R.dimen.fake_shadow_size));
-        mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
-        mCornerShadowPaint.setStyle(Paint.Style.FILL);
-        mCornerShadowPaint.setDither(true);
-        mCornerRadius = Recents.getConfiguration().isGridEnabled ?
-                resources.getDimensionPixelSize(
-                    R.dimen.recents_grid_task_view_rounded_corners_radius) :
-                resources.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
-        mCardBounds = new RectF();
-        mEdgeShadowPaint = new Paint(mCornerShadowPaint);
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        mCornerShadowPaint.setAlpha(alpha);
-        mEdgeShadowPaint.setAlpha(alpha);
-    }
-
-    @Override
-    protected void onBoundsChange(Rect bounds) {
-        super.onBoundsChange(bounds);
-        mDirty = true;
-    }
-
-    void setShadowSize(float shadowSize, float maxShadowSize) {
-        if (shadowSize < 0 || maxShadowSize < 0) {
-            throw new IllegalArgumentException("invalid shadow size");
-        }
-        if (shadowSize > maxShadowSize) {
-            shadowSize = maxShadowSize;
-            if (!mPrintedShadowClipWarning) {
-                Log.w("CardView", "Shadow size is being clipped by the max shadow size. See "
-                        + "{CardView#setMaxCardElevation}.");
-                mPrintedShadowClipWarning = true;
-            }
-        }
-        if (mRawShadowSize == shadowSize && mRawMaxShadowSize == maxShadowSize) {
-            return;
-        }
-        mRawShadowSize = shadowSize;
-        mRawMaxShadowSize = maxShadowSize;
-        mShadowSize = shadowSize * SHADOW_MULTIPLIER + mInsetShadow;
-        mMaxShadowSize = maxShadowSize + mInsetShadow;
-        mDirty = true;
-        invalidateSelf();
-    }
-
-    @Override
-    public boolean getPadding(Rect padding) {
-        int vOffset = (int) Math.ceil(calculateVerticalPadding(mRawMaxShadowSize, mCornerRadius,
-                mAddPaddingForCorners));
-        int hOffset = (int) Math.ceil(calculateHorizontalPadding(mRawMaxShadowSize, mCornerRadius,
-                mAddPaddingForCorners));
-        padding.set(hOffset, vOffset, hOffset, vOffset);
-        return true;
-    }
-
-    static float calculateVerticalPadding(float maxShadowSize, float cornerRadius,
-            boolean addPaddingForCorners) {
-        if (addPaddingForCorners) {
-            return (float) (maxShadowSize * SHADOW_MULTIPLIER + (1 - COS_45) * cornerRadius);
-        } else {
-            return maxShadowSize * SHADOW_MULTIPLIER;
-        }
-    }
-
-    static float calculateHorizontalPadding(float maxShadowSize, float cornerRadius,
-            boolean addPaddingForCorners) {
-        if (addPaddingForCorners) {
-            return (float) (maxShadowSize + (1 - COS_45) * cornerRadius);
-        } else {
-            return maxShadowSize;
-        }
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter colorFilter) {
-        mCornerShadowPaint.setColorFilter(colorFilter);
-        mEdgeShadowPaint.setColorFilter(colorFilter);
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.OPAQUE;
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        if (mDirty) {
-            buildComponents(getBounds());
-            mDirty = false;
-        }
-        canvas.translate(0, mRawShadowSize / 4);
-        drawShadow(canvas);
-        canvas.translate(0, -mRawShadowSize / 4);
-    }
-
-    private void drawShadow(Canvas canvas) {
-        final float edgeShadowTop = -mCornerRadius - mShadowSize;
-        final float inset = mCornerRadius + mInsetShadow + mRawShadowSize / 2;
-        final boolean drawHorizontalEdges = mCardBounds.width() - 2 * inset > 0;
-        final boolean drawVerticalEdges = mCardBounds.height() - 2 * inset > 0;
-        // LT
-        int saved = canvas.save();
-        canvas.translate(mCardBounds.left + inset, mCardBounds.top + inset);
-        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
-        if (drawHorizontalEdges) {
-            canvas.drawRect(0, edgeShadowTop,
-                    mCardBounds.width() - 2 * inset, -mCornerRadius,
-                    mEdgeShadowPaint);
-        }
-        canvas.restoreToCount(saved);
-        // RB
-        saved = canvas.save();
-        canvas.translate(mCardBounds.right - inset, mCardBounds.bottom - inset);
-        canvas.rotate(180f);
-        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
-        if (drawHorizontalEdges) {
-            canvas.drawRect(0, edgeShadowTop,
-                    mCardBounds.width() - 2 * inset, -mCornerRadius + mShadowSize,
-                    mEdgeShadowPaint);
-        }
-        canvas.restoreToCount(saved);
-        // LB
-        saved = canvas.save();
-        canvas.translate(mCardBounds.left + inset, mCardBounds.bottom - inset);
-        canvas.rotate(270f);
-        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
-        if (drawVerticalEdges) {
-            canvas.drawRect(0, edgeShadowTop,
-                    mCardBounds.height() - 2 * inset, -mCornerRadius, mEdgeShadowPaint);
-        }
-        canvas.restoreToCount(saved);
-        // RT
-        saved = canvas.save();
-        canvas.translate(mCardBounds.right - inset, mCardBounds.top + inset);
-        canvas.rotate(90f);
-        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);
-        if (drawVerticalEdges) {
-            canvas.drawRect(0, edgeShadowTop,
-                    mCardBounds.height() - 2 * inset, -mCornerRadius, mEdgeShadowPaint);
-        }
-        canvas.restoreToCount(saved);
-    }
-
-    private void buildShadowCorners() {
-        RectF innerBounds = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius);
-        RectF outerBounds = new RectF(innerBounds);
-        outerBounds.inset(-mShadowSize, -mShadowSize);
-
-        if (mCornerShadowPath == null) {
-            mCornerShadowPath = new Path();
-        } else {
-            mCornerShadowPath.reset();
-        }
-        mCornerShadowPath.setFillType(Path.FillType.EVEN_ODD);
-        mCornerShadowPath.moveTo(-mCornerRadius, 0);
-        mCornerShadowPath.rLineTo(-mShadowSize, 0);
-        // outer arc
-        mCornerShadowPath.arcTo(outerBounds, 180f, 90f, false);
-        // inner arc
-        mCornerShadowPath.arcTo(innerBounds, 270f, -90f, false);
-        mCornerShadowPath.close();
-
-        float startRatio = mCornerRadius / (mCornerRadius + mShadowSize);
-        mCornerShadowPaint.setShader(new RadialGradient(0, 0, mCornerRadius + mShadowSize,
-                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},
-                new float[]{0f, startRatio, 1f}
-                , Shader.TileMode.CLAMP));
-
-        // we offset the content shadowSize/2 pixels up to make it more realistic.
-        // this is why edge shadow shader has some extra space
-        // When drawing bottom edge shadow, we use that extra space.
-        mEdgeShadowPaint.setShader(new LinearGradient(0, -mCornerRadius + mShadowSize, 0,
-                -mCornerRadius - mShadowSize,
-                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},
-                new float[]{0f, .5f, 1f}, Shader.TileMode.CLAMP));
-    }
-
-    private void buildComponents(Rect bounds) {
-        // Card is offset SHADOW_MULTIPLIER * maxShadowSize to account for the shadow shift.
-        // We could have different top-bottom offsets to avoid extra gap above but in that case
-        // center aligning Views inside the CardView would be problematic.
-        final float verticalOffset = mMaxShadowSize * SHADOW_MULTIPLIER;
-        mCardBounds.set(bounds.left + mMaxShadowSize, bounds.top + verticalOffset,
-                bounds.right - mMaxShadowSize, bounds.bottom - verticalOffset);
-        buildShadowCorners();
-    }
-
-    float getMinWidth() {
-        final float content = 2 *
-                Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow + mRawMaxShadowSize / 2);
-        return content + (mRawMaxShadowSize + mInsetShadow) * 2;
-    }
-
-    float getMinHeight() {
-        final float content = 2 * Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow
-                        + mRawMaxShadowSize * SHADOW_MULTIPLIER / 2);
-        return content + (mRawMaxShadowSize * SHADOW_MULTIPLIER + mInsetShadow) * 2;
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java
deleted file mode 100644
index 471df6a..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.views;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-/**
- * This is an optimized FrameLayout whose layout is completely directed by its parent, and as a
- * result, does not propagate <code>requestLayout()</code> up the view hierarchy. Instead, it will
- * relayout its children with the last known layout bounds when a layout is requested from a child
- * view.
- */
-public class FixedSizeFrameLayout extends FrameLayout {
-
-    private final Rect mLayoutBounds = new Rect();
-
-    public FixedSizeFrameLayout(Context context) {
-        super(context);
-    }
-
-    public FixedSizeFrameLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public FixedSizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public FixedSizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        measureContents(MeasureSpec.getSize(widthMeasureSpec),
-                MeasureSpec.getSize(heightMeasureSpec));
-    }
-
-    @Override
-    protected final void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        mLayoutBounds.set(left, top, right, bottom);
-        layoutContents(mLayoutBounds, changed);
-    }
-
-    @Override
-    public final void requestLayout() {
-        // The base ViewGroup constructor attempts to call requestLayout() before this class's
-        // members are initialized so we should just propagate in that case
-        if (mLayoutBounds == null || mLayoutBounds.isEmpty()) {
-            super.requestLayout();
-        } else {
-            // If we are already laid out, then just reuse the same bounds to layout the children
-            // (but not itself)
-            // TODO: Investigate whether we should coalesce these to the next frame if needed
-            measureContents(getMeasuredWidth(), getMeasuredHeight());
-            layoutContents(mLayoutBounds, false);
-        }
-    }
-
-    /**
-     * Measures the contents of this fixed layout.
-     */
-    protected void measureContents(int width, int height) {
-        super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
-                MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
-    }
-
-    /**
-     * Lays out the contents of this fixed layout.
-     */
-    protected void layoutContents(Rect bounds, boolean changed) {
-        super.onLayout(changed, bounds.left, bounds.top, bounds.right, bounds.bottom);
-
-        int width = getMeasuredWidth();
-        int height = getMeasuredHeight();
-        onSizeChanged(width, height, width, height);
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
deleted file mode 100644
index d3b5e47..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.content.Context;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-
-import com.android.systemui.statusbar.AlphaOptimizedImageView;
-
-/**
- * This is an optimized ImageView that does not trigger a <code>requestLayout()</code> or
- * <code>invalidate()</code> when setting the image to <code>null</code>.
- */
-public class FixedSizeImageView extends AlphaOptimizedImageView {
-
-    private boolean mAllowRelayout = true;
-    private boolean mAllowInvalidate = true;
-
-    public FixedSizeImageView(Context context) {
-        this(context, null);
-    }
-
-    public FixedSizeImageView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public FixedSizeImageView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public FixedSizeImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    public void requestLayout() {
-        if (mAllowRelayout) {
-            super.requestLayout();
-        }
-    }
-
-    @Override
-    public void invalidate() {
-        if (mAllowInvalidate) {
-            super.invalidate();
-        }
-    }
-
-    @Override
-    public void setImageDrawable(Drawable drawable) {
-        boolean isNullBitmapDrawable = (drawable instanceof BitmapDrawable) &&
-                (((BitmapDrawable) drawable).getBitmap() == null);
-        if (drawable == null || isNullBitmapDrawable) {
-            mAllowRelayout = false;
-            mAllowInvalidate = false;
-        }
-        super.setImageDrawable(drawable);
-        mAllowRelayout = true;
-        mAllowInvalidate = true;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsEntrancePathInterpolator.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsEntrancePathInterpolator.java
deleted file mode 100644
index e32da2d..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsEntrancePathInterpolator.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.views;
-
-import android.view.animation.PathInterpolator;
-
-/**
- * A helper interpolator to stagger the entrance animation in recents by offsetting the start time
- */
-public class RecentsEntrancePathInterpolator extends PathInterpolator {
-    final float mStartOffsetFraction;
-
-    /**
-     * Create an interpolator for a cubic Bezier curve with an offset play time. The end points
-     * <code>(0, 0)</code> and <code>(1, 1)</code> are assumed.
-     *
-     * @param controlX1 The x coordinate of the first control point of the cubic Bezier.
-     * @param controlY1 The y coordinate of the first control point of the cubic Bezier.
-     * @param controlX2 The x coordinate of the second control point of the cubic Bezier.
-     * @param controlY2 The y coordinate of the second control point of the cubic Bezier.
-     * @param startOffsetFraction The fraction from 0 to 1 to start the animation from
-     */
-    public RecentsEntrancePathInterpolator(float controlX1, float controlY1, float controlX2,
-            float controlY2, float startOffsetFraction) {
-        super(controlX1, controlY1, controlX2, controlY2);
-        mStartOffsetFraction = startOffsetFraction;
-    }
-
-    @Override
-    public float getInterpolation(float t) {
-        return super.getInterpolation(t + mStartOffsetFraction);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionComposer.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionComposer.java
deleted file mode 100644
index 1c47430..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionComposer.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.GraphicBuffer;
-import android.graphics.Rect;
-import android.util.Log;
-
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsDebugFlags;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
-import com.android.systemui.shared.recents.view.RecentsTransition;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A helper class to create the transition app animation specs to/from Recents
- */
-public class RecentsTransitionComposer {
-
-    private static final String TAG = "RecentsTransitionComposer";
-
-    private Context mContext;
-    private TaskViewTransform mTmpTransform = new TaskViewTransform();
-
-    public RecentsTransitionComposer(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Composes a single animation spec for the given {@link TaskView}
-     */
-    private static AppTransitionAnimationSpecCompat composeAnimationSpec(TaskStackView stackView,
-            TaskView taskView, TaskViewTransform transform, boolean addHeaderBitmap) {
-        Bitmap b = null;
-        if (addHeaderBitmap) {
-            b = composeHeaderBitmap(taskView, transform);
-            if (b == null) {
-                return null;
-            }
-        }
-
-        Rect taskRect = new Rect();
-        transform.rect.round(taskRect);
-        // Disable in for low ram devices because each task does in Recents does not have fullscreen
-        // height (stackView height) and when transitioning to fullscreen app, the code below would
-        // force the task thumbnail to full stackView height immediately causing the transition
-        // jarring.
-        if (!Recents.getConfiguration().isLowRamDevice && taskView.getTask() !=
-                stackView.getStack().getFrontMostTask()) {
-            taskRect.bottom = taskRect.top + stackView.getMeasuredHeight();
-        }
-        return new AppTransitionAnimationSpecCompat(taskView.getTask().key.id, b, taskRect);
-    }
-
-    /**
-     * Composes the transition spec when docking a task, which includes a full task bitmap.
-     */
-    public List<AppTransitionAnimationSpecCompat> composeDockAnimationSpec(TaskView taskView,
-            Rect bounds) {
-        mTmpTransform.fillIn(taskView);
-        Task task = taskView.getTask();
-        Bitmap buffer = RecentsTransitionComposer.composeTaskBitmap(taskView, mTmpTransform);
-        return Collections.singletonList(new AppTransitionAnimationSpecCompat(task.key.id, buffer,
-                bounds));
-    }
-
-    /**
-     * Composes the animation specs for all the tasks in the target stack.
-     */
-    public List<AppTransitionAnimationSpecCompat> composeAnimationSpecs(final Task task,
-            final TaskStackView stackView, int windowingMode, int activityType, Rect windowRect) {
-        // Calculate the offscreen task rect (for tasks that are not backed by views)
-        TaskView taskView = stackView.getChildViewForTask(task);
-        TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm();
-        Rect offscreenTaskRect = new Rect();
-        stackLayout.getFrontOfStackTransform().rect.round(offscreenTaskRect);
-
-        // If this is a full screen stack, the transition will be towards the single, full screen
-        // task. We only need the transition spec for this task.
-
-        // TODO: Sometimes targetStackId is not initialized after reboot, so we also have to
-        // check for INVALID_STACK_ID (now WINDOWING_MODE_UNDEFINED)
-        if (windowingMode == WINDOWING_MODE_FULLSCREEN
-                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
-                || activityType == ACTIVITY_TYPE_ASSISTANT
-                || windowingMode == WINDOWING_MODE_UNDEFINED) {
-            List<AppTransitionAnimationSpecCompat> specs = new ArrayList<>();
-            if (taskView == null) {
-                specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
-            } else {
-                mTmpTransform.fillIn(taskView);
-                stackLayout.transformToScreenCoordinates(mTmpTransform, windowRect);
-                AppTransitionAnimationSpecCompat spec = composeAnimationSpec(stackView, taskView,
-                        mTmpTransform, true /* addHeaderBitmap */);
-                if (spec != null) {
-                    specs.add(spec);
-                }
-            }
-            return specs;
-        }
-        return Collections.emptyList();
-    }
-
-    /**
-     * Composes a single animation spec for the given {@link Task}
-     */
-    private static AppTransitionAnimationSpecCompat composeOffscreenAnimationSpec(Task task,
-            Rect taskRect) {
-        return new AppTransitionAnimationSpecCompat(task.key.id, null, taskRect);
-    }
-
-    public static Bitmap composeTaskBitmap(TaskView taskView, TaskViewTransform transform) {
-        float scale = transform.scale;
-        int fromWidth = (int) (transform.rect.width() * scale);
-        int fromHeight = (int) (transform.rect.height() * scale);
-        if (fromWidth == 0 || fromHeight == 0) {
-            Log.e(TAG, "Could not compose thumbnail for task: " + taskView.getTask() +
-                    " at transform: " + transform);
-
-            return RecentsTransition.drawViewIntoHardwareBitmap(1, 1, null, 1f, 0x00ffffff);
-        } else {
-            if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
-                return RecentsTransition.drawViewIntoHardwareBitmap(fromWidth, fromHeight, null, 1f,
-                        0xFFff0000);
-            } else {
-                return RecentsTransition.drawViewIntoHardwareBitmap(fromWidth, fromHeight, taskView,
-                        scale, 0);
-            }
-        }
-    }
-
-    private static Bitmap composeHeaderBitmap(TaskView taskView,
-            TaskViewTransform transform) {
-        float scale = transform.scale;
-        int headerWidth = (int) (transform.rect.width());
-        int headerHeight = (int) (taskView.mHeaderView.getMeasuredHeight() * scale);
-        if (headerWidth == 0 || headerHeight == 0) {
-            return null;
-        }
-
-        if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
-            return RecentsTransition.drawViewIntoHardwareBitmap(headerWidth, headerHeight, null, 1f,
-                    0xFFff0000);
-        } else {
-            return RecentsTransition.drawViewIntoHardwareBitmap(headerWidth, headerHeight,
-                    taskView.mHeaderView, scale, 0);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
deleted file mode 100644
index 5c925fd..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ /dev/null
@@ -1,1078 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-
-import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
-
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.Nullable;
-import android.app.ActivityOptions;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.IRemoteCallback;
-import android.util.ArraySet;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.MathUtils;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewDebug;
-import android.view.ViewPropertyAnimator;
-import android.view.Window;
-import android.view.WindowInsets;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import com.android.internal.colorextraction.ColorExtractor;
-import com.android.internal.colorextraction.drawable.GradientDrawable;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivity;
-import com.android.systemui.recents.RecentsActivityLaunchState;
-import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
-import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
-import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
-import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
-import com.android.systemui.recents.events.activity.ShowEmptyViewEvent;
-import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
-import com.android.systemui.recents.events.component.ExpandPipEvent;
-import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
-import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
-import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
-import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
-import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
-import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.recents.misc.ReferenceCountedTrigger;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
-import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
-import com.android.systemui.shared.recents.view.RecentsTransition;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.ActivityOptionsCompat;
-import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.WindowManagerProxy;
-import com.android.systemui.statusbar.FlingAnimationUtils;
-import com.android.systemui.statusbar.phone.ScrimController;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This view is the the top level layout that contains TaskStacks (which are laid out according
- * to their SpaceNode bounds.
- */
-public class RecentsView extends FrameLayout {
-
-    private static final String TAG = "RecentsView";
-
-    private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
-
-    private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 134;
-    private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
-
-    private static final int BUSY_RECENTS_TASK_COUNT = 3;
-
-    private Handler mHandler;
-    private TaskStackView mTaskStackView;
-    private TextView mStackActionButton;
-    private TextView mEmptyView;
-    private final float mStackButtonShadowRadius;
-    private final PointF mStackButtonShadowDistance;
-    private final int mStackButtonShadowColor;
-
-    private boolean mAwaitingFirstLayout = true;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    Rect mSystemInsets = new Rect();
-    private int mDividerSize;
-
-    private float mBusynessFactor;
-    private GradientDrawable mBackgroundScrim;
-    private ColorDrawable mMultiWindowBackgroundScrim;
-    private ValueAnimator mBackgroundScrimAnimator;
-    private Point mTmpDisplaySize = new Point();
-
-    private final AnimatorUpdateListener mUpdateBackgroundScrimAlpha = (animation) -> {
-        int alpha = (Integer) animation.getAnimatedValue();
-        mBackgroundScrim.setAlpha(alpha);
-        mMultiWindowBackgroundScrim.setAlpha(alpha);
-    };
-
-    private RecentsTransitionComposer mTransitionHelper;
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
-    private RecentsViewTouchHandler mTouchHandler;
-    private final FlingAnimationUtils mFlingAnimationUtils;
-
-    public RecentsView(Context context) {
-        this(context, null);
-    }
-
-    public RecentsView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public RecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public RecentsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        setWillNotDraw(false);
-
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        mHandler = new Handler();
-        mTransitionHelper = new RecentsTransitionComposer(getContext());
-        mDividerSize = ssp.getDockedDividerSize(context);
-        mTouchHandler = new RecentsViewTouchHandler(this);
-        mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
-        mBackgroundScrim = new GradientDrawable(context);
-        mMultiWindowBackgroundScrim = new ColorDrawable();
-
-        LayoutInflater inflater = LayoutInflater.from(context);
-        mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
-        addView(mEmptyView);
-
-        if (mStackActionButton != null) {
-            removeView(mStackActionButton);
-        }
-        mStackActionButton = (TextView) inflater.inflate(Recents.getConfiguration()
-                        .isLowRamDevice
-                    ? R.layout.recents_low_ram_stack_action_button
-                    : R.layout.recents_stack_action_button,
-                this, false);
-
-        mStackButtonShadowRadius = mStackActionButton.getShadowRadius();
-        mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(),
-                mStackActionButton.getShadowDy());
-        mStackButtonShadowColor = mStackActionButton.getShadowColor();
-        addView(mStackActionButton);
-
-        reevaluateStyles();
-    }
-
-    public void reevaluateStyles() {
-        int textColor = Utils.getColorAttrDefaultColor(mContext, R.attr.wallpaperTextColor);
-        boolean usingDarkText = Color.luminance(textColor) < 0.5f;
-
-        mEmptyView.setTextColor(textColor);
-        mEmptyView.setCompoundDrawableTintList(new ColorStateList(new int[][]{
-                {android.R.attr.state_enabled}}, new int[]{textColor}));
-
-        if (mStackActionButton != null) {
-            mStackActionButton.setTextColor(textColor);
-            // Enable/disable shadow if text color is already dark.
-            if (usingDarkText) {
-                mStackActionButton.setShadowLayer(0, 0, 0, 0);
-            } else {
-                mStackActionButton.setShadowLayer(mStackButtonShadowRadius,
-                        mStackButtonShadowDistance.x, mStackButtonShadowDistance.y,
-                        mStackButtonShadowColor);
-            }
-        }
-
-        // Let's also require dark status and nav bars if the text is dark
-        int systemBarsStyle = usingDarkText ? View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
-                View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0;
-
-        setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
-                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
-                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
-                systemBarsStyle);
-    }
-
-    /**
-     * Called from RecentsActivity when it is relaunched.
-     */
-    public void onReload(TaskStack stack, boolean isResumingFromVisible) {
-        final RecentsConfiguration config = Recents.getConfiguration();
-        final RecentsActivityLaunchState launchState = config.getLaunchState();
-        final boolean isTaskStackEmpty = stack.getTaskCount() == 0;
-
-        if (mTaskStackView == null) {
-            isResumingFromVisible = false;
-            mTaskStackView = new TaskStackView(getContext());
-            mTaskStackView.setSystemInsets(mSystemInsets);
-            addView(mTaskStackView);
-        }
-
-        // Reset the state
-        mAwaitingFirstLayout = !isResumingFromVisible;
-
-        // Update the stack
-        mTaskStackView.onReload(isResumingFromVisible);
-        updateStack(stack, true /* setStackViewTasks */);
-        updateBusyness();
-
-        if (isResumingFromVisible) {
-            // If we are already visible, then restore the background scrim
-            animateBackgroundScrim(getOpaqueScrimAlpha(), DEFAULT_UPDATE_SCRIM_DURATION);
-        } else {
-            // If we are already occluded by the app, then set the final background scrim alpha now.
-            // Otherwise, defer until the enter animation completes to animate the scrim alpha with
-            // the tasks for the home animation.
-            if (launchState.launchedViaDockGesture || launchState.launchedFromApp
-                    || isTaskStackEmpty) {
-                mBackgroundScrim.setAlpha((int) (getOpaqueScrimAlpha() * 255));
-            } else {
-                mBackgroundScrim.setAlpha(0);
-            }
-            mMultiWindowBackgroundScrim.setAlpha(mBackgroundScrim.getAlpha());
-        }
-    }
-
-    /**
-     * Called from RecentsActivity when the task stack is updated.
-     */
-    public void updateStack(TaskStack stack, boolean setStackViewTasks) {
-        if (setStackViewTasks) {
-            mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
-        }
-
-        // Update the top level view's visibilities
-        if (stack.getTaskCount() > 0) {
-            hideEmptyView();
-        } else {
-            showEmptyView(R.string.recents_empty_message);
-        }
-    }
-
-    /**
-     * Animates the scrim opacity based on how many tasks are visible.
-     * Called from {@link RecentsActivity} when tasks are dismissed.
-     */
-    public void updateScrimOpacity() {
-        if (updateBusyness()) {
-            animateBackgroundScrim(getOpaqueScrimAlpha(), DEFAULT_UPDATE_SCRIM_DURATION);
-        }
-    }
-
-    /**
-     * Updates the busyness factor.
-     *
-     * @return True if it changed.
-     */
-    private boolean updateBusyness() {
-        final int taskCount = mTaskStackView.getStack().getTaskCount();
-        final float busyness = Math.min(taskCount, BUSY_RECENTS_TASK_COUNT)
-                / (float) BUSY_RECENTS_TASK_COUNT;
-        if (mBusynessFactor == busyness) {
-            return false;
-        } else {
-            mBusynessFactor = busyness;
-            return true;
-        }
-    }
-
-    /**
-     * Returns the current TaskStack.
-     */
-    public TaskStack getStack() {
-        return mTaskStackView.getStack();
-    }
-
-    /**
-     * Returns the window background scrim.
-     */
-    public void updateBackgroundScrim(Window window, boolean isInMultiWindow) {
-        if (isInMultiWindow) {
-            mBackgroundScrim.setCallback(null);
-            window.setBackgroundDrawable(mMultiWindowBackgroundScrim);
-        } else {
-            mMultiWindowBackgroundScrim.setCallback(null);
-            window.setBackgroundDrawable(mBackgroundScrim);
-        }
-    }
-
-    /** Launches the focused task from the first stack if possible */
-    public boolean launchFocusedTask(int logEvent) {
-        if (mTaskStackView != null) {
-            Task task = mTaskStackView.getFocusedTask();
-            if (task != null) {
-                TaskView taskView = mTaskStackView.getChildViewForTask(task);
-                EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null, false));
-
-                if (logEvent != 0) {
-                    MetricsLogger.action(getContext(), logEvent,
-                            task.key.getComponent().toString());
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /** Launches the task that recents was launched from if possible */
-    public boolean launchPreviousTask() {
-        if (Recents.getConfiguration().getLaunchState().launchedFromPipApp) {
-            // If the app auto-entered PiP on the way to Recents, then just re-expand it
-            EventBus.getDefault().send(new ExpandPipEvent());
-            return true;
-        }
-
-        if (mTaskStackView != null) {
-            Task task = getStack().getLaunchTarget();
-            if (task != null) {
-                TaskView taskView = mTaskStackView.getChildViewForTask(task);
-                EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null, false));
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Hides the task stack and shows the empty view.
-     */
-    public void showEmptyView(int msgResId) {
-        mTaskStackView.setVisibility(View.INVISIBLE);
-        mEmptyView.setText(msgResId);
-        mEmptyView.setVisibility(View.VISIBLE);
-        mEmptyView.bringToFront();
-        mStackActionButton.bringToFront();
-    }
-
-    /**
-     * Shows the task stack and hides the empty view.
-     */
-    public void hideEmptyView() {
-        mEmptyView.setVisibility(View.INVISIBLE);
-        mTaskStackView.setVisibility(View.VISIBLE);
-        mTaskStackView.bringToFront();
-        mStackActionButton.bringToFront();
-    }
-
-    /**
-     * Set the color of the scrim.
-     *
-     * @param scrimColors Colors to use.
-     * @param animated Interpolate colors if true.
-     */
-    public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) {
-        mBackgroundScrim.setColors(scrimColors, animated);
-        int alpha = mMultiWindowBackgroundScrim.getAlpha();
-        mMultiWindowBackgroundScrim.setColor(scrimColors.getMainColor());
-        mMultiWindowBackgroundScrim.setAlpha(alpha);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
-        EventBus.getDefault().register(mTouchHandler, RecentsActivity.EVENT_BUS_PRIORITY + 2);
-        super.onAttachedToWindow();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        EventBus.getDefault().unregister(this);
-        EventBus.getDefault().unregister(mTouchHandler);
-    }
-
-    /**
-     * This is called with the full size of the window since we are handling our own insets.
-     */
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-        int height = MeasureSpec.getSize(heightMeasureSpec);
-
-        if (mTaskStackView.getVisibility() != GONE) {
-            mTaskStackView.measure(widthMeasureSpec, heightMeasureSpec);
-        }
-
-        // Measure the empty view to the full size of the screen
-        if (mEmptyView.getVisibility() != GONE) {
-            measureChild(mEmptyView, MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
-                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
-        }
-
-        // Measure the stack action button within the constraints of the space above the stack
-        Rect buttonBounds = mTaskStackView.mLayoutAlgorithm.getStackActionButtonRect();
-        measureChild(mStackActionButton,
-                MeasureSpec.makeMeasureSpec(buttonBounds.width(), MeasureSpec.AT_MOST),
-                MeasureSpec.makeMeasureSpec(buttonBounds.height(), MeasureSpec.AT_MOST));
-
-        setMeasuredDimension(width, height);
-    }
-
-    /**
-     * This is called with the full size of the window since we are handling our own insets.
-     */
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        if (mTaskStackView.getVisibility() != GONE) {
-            mTaskStackView.layout(left, top, left + getMeasuredWidth(), top + getMeasuredHeight());
-        }
-
-        // Layout the empty view
-        if (mEmptyView.getVisibility() != GONE) {
-            int leftRightInsets = mSystemInsets.left + mSystemInsets.right;
-            int topBottomInsets = mSystemInsets.top + mSystemInsets.bottom;
-            int childWidth = mEmptyView.getMeasuredWidth();
-            int childHeight = mEmptyView.getMeasuredHeight();
-            int childLeft = left + mSystemInsets.left +
-                    Math.max(0, (right - left - leftRightInsets - childWidth)) / 2;
-            int childTop = top + mSystemInsets.top +
-                    Math.max(0, (bottom - top - topBottomInsets - childHeight)) / 2;
-            mEmptyView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
-        }
-
-        // Needs to know the screen size since the gradient never scales up or down
-        // even when bounds change.
-        mContext.getDisplay().getRealSize(mTmpDisplaySize);
-        mBackgroundScrim.setScreenSize(mTmpDisplaySize.x, mTmpDisplaySize.y);
-        mBackgroundScrim.setBounds(left, top, right, bottom);
-        mMultiWindowBackgroundScrim.setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
-
-        // Layout the stack action button such that its drawable is start-aligned with the
-        // stack, vertically centered in the available space above the stack
-        Rect buttonBounds = getStackActionButtonBoundsFromStackLayout();
-        mStackActionButton.layout(buttonBounds.left, buttonBounds.top, buttonBounds.right,
-                buttonBounds.bottom);
-
-        if (mAwaitingFirstLayout) {
-            mAwaitingFirstLayout = false;
-            // If launched via dragging from the nav bar, then we should translate the whole view
-            // down offscreen
-            RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-            if (launchState.launchedViaDragGesture) {
-                setTranslationY(getMeasuredHeight());
-            } else {
-                setTranslationY(0f);
-            }
-
-            if (Recents.getConfiguration().isLowRamDevice
-                    && mEmptyView.getVisibility() == View.VISIBLE) {
-                animateEmptyView(true /* show */, null /* postAnimationTrigger */);
-            }
-        }
-    }
-
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        mSystemInsets.set(insets.getSystemWindowInsets());
-        mTaskStackView.setSystemInsets(mSystemInsets);
-        requestLayout();
-        return insets;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        return mTouchHandler.onInterceptTouchEvent(ev);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        return mTouchHandler.onTouchEvent(ev);
-    }
-
-    @Override
-    public void onDrawForeground(Canvas canvas) {
-        super.onDrawForeground(canvas);
-
-        ArrayList<DockState> visDockStates = mTouchHandler.getVisibleDockStates();
-        for (int i = visDockStates.size() - 1; i >= 0; i--) {
-            visDockStates.get(i).viewState.draw(canvas);
-        }
-    }
-
-    @Override
-    protected boolean verifyDrawable(Drawable who) {
-        ArrayList<DockState> visDockStates = mTouchHandler.getVisibleDockStates();
-        for (int i = visDockStates.size() - 1; i >= 0; i--) {
-            Drawable d = visDockStates.get(i).viewState.dockAreaOverlay;
-            if (d == who) {
-                return true;
-            }
-        }
-        return super.verifyDrawable(who);
-    }
-
-    /**** EventBus Events ****/
-
-    public final void onBusEvent(LaunchTaskEvent event) {
-        launchTaskFromRecents(getStack(), event.task, mTaskStackView, event.taskView,
-                event.screenPinningRequested, event.targetWindowingMode, event.targetActivityType);
-        if (Recents.getConfiguration().isLowRamDevice) {
-            EventBus.getDefault().send(new HideStackActionButtonEvent(false /* translate */));
-        }
-    }
-
-    public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
-        int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION;
-        // Hide the stack action button
-        EventBus.getDefault().send(new HideStackActionButtonEvent());
-        animateBackgroundScrim(0f, taskViewExitToHomeDuration);
-
-        if (Recents.getConfiguration().isLowRamDevice) {
-            animateEmptyView(false /* show */, event.getAnimationTrigger());
-        }
-    }
-
-    public final void onBusEvent(DragStartEvent event) {
-        updateVisibleDockRegions(Recents.getConfiguration().getDockStatesForCurrentOrientation(),
-                true /* isDefaultDockState */, DockState.NONE.viewState.dockAreaAlpha,
-                DockState.NONE.viewState.hintTextAlpha,
-                true /* animateAlpha */, false /* animateBounds */);
-
-        // Temporarily hide the stack action button without changing visibility
-        if (mStackActionButton != null) {
-            mStackActionButton.animate()
-                    .alpha(0f)
-                    .setDuration(HIDE_STACK_ACTION_BUTTON_DURATION)
-                    .setInterpolator(Interpolators.ALPHA_OUT)
-                    .start();
-        }
-    }
-
-    public final void onBusEvent(DragDropTargetChangedEvent event) {
-        if (event.dropTarget == null || !(event.dropTarget instanceof DockState)) {
-            updateVisibleDockRegions(
-                    Recents.getConfiguration().getDockStatesForCurrentOrientation(),
-                    true /* isDefaultDockState */, DockState.NONE.viewState.dockAreaAlpha,
-                    DockState.NONE.viewState.hintTextAlpha,
-                    true /* animateAlpha */, true /* animateBounds */);
-        } else {
-            final DockState dockState = (DockState) event.dropTarget;
-            updateVisibleDockRegions(new DockState[] {dockState},
-                    false /* isDefaultDockState */, -1, -1, true /* animateAlpha */,
-                    true /* animateBounds */);
-        }
-        if (mStackActionButton != null) {
-            event.addPostAnimationCallback(new Runnable() {
-                @Override
-                public void run() {
-                    // Move the clear all button to its new position
-                    Rect buttonBounds = getStackActionButtonBoundsFromStackLayout();
-                    mStackActionButton.setLeftTopRightBottom(buttonBounds.left, buttonBounds.top,
-                            buttonBounds.right, buttonBounds.bottom);
-                }
-            });
-        }
-    }
-
-    public final void onBusEvent(final DragEndEvent event) {
-        // Handle the case where we drop onto a dock region
-        if (event.dropTarget instanceof DockState) {
-            final DockState dockState = (DockState) event.dropTarget;
-
-            // Hide the dock region
-            updateVisibleDockRegions(null, false /* isDefaultDockState */, -1, -1,
-                    false /* animateAlpha */, false /* animateBounds */);
-
-            // We translated the view but we need to animate it back from the current layout-space
-            // rect to its final layout-space rect
-            Utilities.setViewFrameFromTranslation(event.taskView);
-
-            final ActivityOptions options = ActivityOptionsCompat.makeSplitScreenOptions(
-                    dockState.createMode == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
-            if (ActivityManagerWrapper.getInstance().startActivityFromRecents(event.task.key.id,
-                    options)) {
-                final Runnable animStartedListener = () -> {
-                    EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
-                    // Remove the task and don't bother relaying out, as all the tasks
-                    // will be relaid out when the stack changes on the multiwindow
-                    // change event
-                    getStack().removeTask(event.task, null, true /* fromDockGesture */);
-                };
-                final Rect taskRect = getTaskRect(event.taskView);
-                AppTransitionAnimationSpecsFuture future = new AppTransitionAnimationSpecsFuture(
-                        getHandler()) {
-                    @Override
-                    public List<AppTransitionAnimationSpecCompat> composeSpecs() {
-                        return mTransitionHelper.composeDockAnimationSpec(event.taskView, taskRect);
-                    }
-                };
-                WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
-                        future, animStartedListener, getHandler(), true /* scaleUp */);
-                MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
-                        event.task.getTopComponent().flattenToShortString());
-            } else {
-                EventBus.getDefault().send(new DragEndCancelledEvent(getStack(), event.task,
-                        event.taskView));
-            }
-        } else {
-            // Animate the overlay alpha back to 0
-            updateVisibleDockRegions(null, true /* isDefaultDockState */, -1, -1,
-                    true /* animateAlpha */, false /* animateBounds */);
-        }
-
-        // Show the stack action button again without changing visibility
-        if (mStackActionButton != null) {
-            mStackActionButton.animate()
-                    .alpha(1f)
-                    .setDuration(SHOW_STACK_ACTION_BUTTON_DURATION)
-                    .setInterpolator(Interpolators.ALPHA_IN)
-                    .start();
-        }
-    }
-
-    public final void onBusEvent(final DragEndCancelledEvent event) {
-        // Animate the overlay alpha back to 0
-        updateVisibleDockRegions(null, true /* isDefaultDockState */, -1, -1,
-                true /* animateAlpha */, false /* animateBounds */);
-    }
-
-    private Rect getTaskRect(TaskView taskView) {
-        int[] location = taskView.getLocationOnScreen();
-        int viewX = location[0];
-        int viewY = location[1];
-        return new Rect(viewX, viewY,
-                (int) (viewX + taskView.getWidth() * taskView.getScaleX()),
-                (int) (viewY + taskView.getHeight() * taskView.getScaleY()));
-    }
-
-    public final void onBusEvent(DraggingInRecentsEvent event) {
-        if (mTaskStackView.getTaskViews().size() > 0) {
-            setTranslationY(event.distanceFromTop - mTaskStackView.getTaskViews().get(0).getY());
-        }
-    }
-
-    public final void onBusEvent(DraggingInRecentsEndedEvent event) {
-        ViewPropertyAnimator animator = animate();
-        if (event.velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
-            animator.translationY(getHeight());
-            animator.withEndAction(new Runnable() {
-                @Override
-                public void run() {
-                    WindowManagerProxy.getInstance().maximizeDockedStack();
-                }
-            });
-            mFlingAnimationUtils.apply(animator, getTranslationY(), getHeight(), event.velocity);
-        } else {
-            animator.translationY(0f);
-            animator.setListener(null);
-            mFlingAnimationUtils.apply(animator, getTranslationY(), 0, event.velocity);
-        }
-        animator.start();
-    }
-
-    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-        if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
-                && getStack().getTaskCount() > 0) {
-            animateBackgroundScrim(getOpaqueScrimAlpha(),
-                    TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
-        }
-    }
-
-    public final void onBusEvent(AllTaskViewsDismissedEvent event) {
-        EventBus.getDefault().send(new HideStackActionButtonEvent());
-    }
-
-    public final void onBusEvent(DismissAllTaskViewsEvent event) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        if (!ssp.hasDockedTask()) {
-            // Animate the background away only if we are dismissing Recents to home
-            animateBackgroundScrim(0f, DEFAULT_UPDATE_SCRIM_DURATION);
-        }
-    }
-
-    public final void onBusEvent(ShowStackActionButtonEvent event) {
-        showStackActionButton(SHOW_STACK_ACTION_BUTTON_DURATION, event.translate);
-    }
-
-    public final void onBusEvent(HideStackActionButtonEvent event) {
-        hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
-    }
-
-    public final void onBusEvent(MultiWindowStateChangedEvent event) {
-        updateStack(event.stack, false /* setStackViewTasks */);
-    }
-
-    public final void onBusEvent(ShowEmptyViewEvent event) {
-        showEmptyView(R.string.recents_empty_message);
-    }
-
-    /**
-     * Shows the stack action button.
-     */
-    private void showStackActionButton(final int duration, final boolean translate) {
-        final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
-        if (mStackActionButton.getVisibility() == View.INVISIBLE) {
-            mStackActionButton.setVisibility(View.VISIBLE);
-            mStackActionButton.setAlpha(0f);
-            if (translate) {
-                mStackActionButton.setTranslationY(mStackActionButton.getMeasuredHeight() *
-                        (Recents.getConfiguration().isLowRamDevice ? 1 : -0.25f));
-            } else {
-                mStackActionButton.setTranslationY(0f);
-            }
-            postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
-                @Override
-                public void run() {
-                    if (translate) {
-                        mStackActionButton.animate()
-                            .translationY(0f);
-                    }
-                    mStackActionButton.animate()
-                            .alpha(1f)
-                            .setDuration(duration)
-                            .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                            .start();
-                }
-            });
-        }
-        postAnimationTrigger.flushLastDecrementRunnables();
-    }
-
-    /**
-     * Hides the stack action button.
-     */
-    private void hideStackActionButton(int duration, boolean translate) {
-        final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
-        hideStackActionButton(duration, translate, postAnimationTrigger);
-        postAnimationTrigger.flushLastDecrementRunnables();
-    }
-
-    /**
-     * Hides the stack action button.
-     */
-    private void hideStackActionButton(int duration, boolean translate,
-                                       final ReferenceCountedTrigger postAnimationTrigger) {
-        if (mStackActionButton.getVisibility() == View.VISIBLE) {
-            if (translate) {
-                mStackActionButton.animate().translationY(mStackActionButton.getMeasuredHeight()
-                        * (Recents.getConfiguration().isLowRamDevice ? 1 : -0.25f));
-            }
-            mStackActionButton.animate()
-                    .alpha(0f)
-                    .setDuration(duration)
-                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                    .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            mStackActionButton.setVisibility(View.INVISIBLE);
-                            postAnimationTrigger.decrement();
-                        }
-                    })
-                    .start();
-            postAnimationTrigger.increment();
-        }
-    }
-
-    /**
-     * Animates a translation in the Y direction and fades in/out for empty view to show or hide it.
-     * @param show whether to translate up and fade in the empty view to the center of the screen
-     * @param postAnimationTrigger to keep track of the animation
-     */
-    private void animateEmptyView(boolean show, ReferenceCountedTrigger postAnimationTrigger) {
-        float start = mTaskStackView.getStackAlgorithm().getTaskRect().height() / 4;
-        mEmptyView.setTranslationY(show ? start : 0);
-        mEmptyView.setAlpha(show ? 0f : 1f);
-        ViewPropertyAnimator animator = mEmptyView.animate()
-                .setDuration(150)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .translationY(show ? 0 : start)
-                .alpha(show ? 1f : 0f);
-
-        if (postAnimationTrigger != null) {
-            animator.setListener(postAnimationTrigger.decrementOnAnimationEnd());
-            postAnimationTrigger.increment();
-        }
-        animator.start();
-    }
-
-    /**
-     * Updates the dock region to match the specified dock state.
-     */
-    private void updateVisibleDockRegions(DockState[] newDockStates,
-            boolean isDefaultDockState, int overrideAreaAlpha, int overrideHintAlpha,
-            boolean animateAlpha, boolean animateBounds) {
-        ArraySet<DockState> newDockStatesSet = Utilities.arrayToSet(newDockStates,
-                new ArraySet<DockState>());
-        ArrayList<DockState> visDockStates = mTouchHandler.getVisibleDockStates();
-        for (int i = visDockStates.size() - 1; i >= 0; i--) {
-            DockState dockState = visDockStates.get(i);
-            DockState.ViewState viewState = dockState.viewState;
-            if (newDockStates == null || !newDockStatesSet.contains(dockState)) {
-                // This is no longer visible, so hide it
-                viewState.startAnimation(null, 0, 0, TaskStackView.SLOW_SYNC_STACK_DURATION,
-                        Interpolators.FAST_OUT_SLOW_IN, animateAlpha, animateBounds);
-            } else {
-                // This state is now visible, update the bounds and show it
-                int areaAlpha = overrideAreaAlpha != -1
-                        ? overrideAreaAlpha
-                        : viewState.dockAreaAlpha;
-                int hintAlpha = overrideHintAlpha != -1
-                        ? overrideHintAlpha
-                        : viewState.hintTextAlpha;
-                Rect bounds = isDefaultDockState
-                        ? dockState.getPreDockedBounds(getMeasuredWidth(), getMeasuredHeight(),
-                                mSystemInsets)
-                        : dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight(),
-                                mDividerSize, mSystemInsets, getResources());
-                if (viewState.dockAreaOverlay.getCallback() != this) {
-                    viewState.dockAreaOverlay.setCallback(this);
-                    viewState.dockAreaOverlay.setBounds(bounds);
-                }
-                viewState.startAnimation(bounds, areaAlpha, hintAlpha,
-                        TaskStackView.SLOW_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN,
-                        animateAlpha, animateBounds);
-            }
-        }
-    }
-
-    /**
-     * Scrim alpha based on how busy recents is:
-     * Scrim will be {@link ScrimController#GRADIENT_SCRIM_ALPHA} when the stack is empty,
-     * and {@link ScrimController#GRADIENT_SCRIM_ALPHA_BUSY} when it's full.
-     *
-     * @return Alpha from 0 to 1.
-     */
-    private float getOpaqueScrimAlpha() {
-        return MathUtils.map(0, 1, ScrimController.GRADIENT_SCRIM_ALPHA,
-                ScrimController.GRADIENT_SCRIM_ALPHA_BUSY, mBusynessFactor);
-    }
-
-    /**
-     * Animates the background scrim to the given {@param alpha}.
-     */
-    private void animateBackgroundScrim(float alpha, int duration) {
-        Utilities.cancelAnimationWithoutCallbacks(mBackgroundScrimAnimator);
-        // Calculate the absolute alpha to animate from
-        final int fromAlpha = mBackgroundScrim.getAlpha();
-        final int toAlpha = (int) (alpha * 255);
-        mBackgroundScrimAnimator = ValueAnimator.ofInt(fromAlpha, toAlpha);
-        mBackgroundScrimAnimator.setDuration(duration);
-        mBackgroundScrimAnimator.setInterpolator(toAlpha > fromAlpha
-                ? Interpolators.ALPHA_IN
-                : Interpolators.ALPHA_OUT);
-        mBackgroundScrimAnimator.addUpdateListener(mUpdateBackgroundScrimAlpha);
-        mBackgroundScrimAnimator.start();
-    }
-
-    /**
-     * @return the bounds of the stack action button.
-     */
-    Rect getStackActionButtonBoundsFromStackLayout() {
-        Rect actionButtonRect = new Rect(
-                mTaskStackView.mLayoutAlgorithm.getStackActionButtonRect());
-        int left, top;
-        if (Recents.getConfiguration().isLowRamDevice) {
-            Rect windowRect = Recents.getSystemServices().getWindowRect();
-            int spaceLeft = windowRect.width() - mSystemInsets.left - mSystemInsets.right;
-            left = (spaceLeft - mStackActionButton.getMeasuredWidth()) / 2 + mSystemInsets.left;
-            top = windowRect.height() - (mStackActionButton.getMeasuredHeight()
-                    + mSystemInsets.bottom + mStackActionButton.getPaddingBottom() / 2);
-        } else {
-            left = isLayoutRtl()
-                ? actionButtonRect.left - mStackActionButton.getPaddingLeft()
-                : actionButtonRect.right + mStackActionButton.getPaddingRight()
-                        - mStackActionButton.getMeasuredWidth();
-            top = actionButtonRect.top +
-                (actionButtonRect.height() - mStackActionButton.getMeasuredHeight()) / 2;
-        }
-        actionButtonRect.set(left, top, left + mStackActionButton.getMeasuredWidth(),
-                top + mStackActionButton.getMeasuredHeight());
-        return actionButtonRect;
-    }
-
-    View getStackActionButton() {
-        return mStackActionButton;
-    }
-
-    /**
-     * Launches the specified {@link Task}.
-     */
-    public void launchTaskFromRecents(final TaskStack stack, @Nullable final Task task,
-            final TaskStackView stackView, final TaskView taskView,
-            final boolean screenPinningRequested, final int windowingMode, final int activityType) {
-
-        final Runnable animStartedListener;
-        final AppTransitionAnimationSpecsFuture transitionFuture;
-        if (taskView != null) {
-
-            // Fetch window rect here already in order not to be blocked on lock contention in WM
-            // when the future calls it.
-            final Rect windowRect = Recents.getSystemServices().getWindowRect();
-            transitionFuture = new AppTransitionAnimationSpecsFuture(stackView.getHandler()) {
-                @Override
-                public List<AppTransitionAnimationSpecCompat> composeSpecs() {
-                    return mTransitionHelper.composeAnimationSpecs(task, stackView, windowingMode,
-                            activityType, windowRect);
-                }
-            };
-            animStartedListener = new Runnable() {
-                private boolean mHandled;
-
-                @Override
-                public void run() {
-                    if (mHandled) {
-                        return;
-                    }
-                    mHandled = true;
-
-                    // If we are launching into another task, cancel the previous task's
-                    // window transition
-                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                    stackView.cancelAllTaskViewAnimations();
-
-                    if (screenPinningRequested) {
-                        // Request screen pinning after the animation runs
-                        mHandler.postDelayed(() -> {
-                            EventBus.getDefault().send(new ScreenPinningRequestEvent(mContext,
-                                    task.key.id));
-                        }, 350);
-                    }
-
-                    if (!Recents.getConfiguration().isLowRamDevice) {
-                        // Reset the state where we are waiting for the transition to start
-                        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
-                    }
-                }
-            };
-        } else {
-            // This is only the case if the task is not on screen (scrolled offscreen for example)
-            transitionFuture = null;
-            animStartedListener = new Runnable() {
-                private boolean mHandled;
-
-                @Override
-                public void run() {
-                    if (mHandled) {
-                        return;
-                    }
-                    mHandled = true;
-
-                    // If we are launching into another task, cancel the previous task's
-                    // window transition
-                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
-                    EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
-                    stackView.cancelAllTaskViewAnimations();
-
-                    if (!Recents.getConfiguration().isLowRamDevice) {
-                        // Reset the state where we are waiting for the transition to start
-                        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
-                    }
-                }
-            };
-        }
-
-        EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(true));
-        final ActivityOptions opts = RecentsTransition.createAspectScaleAnimation(mContext,
-                mHandler, true /* scaleUp */, transitionFuture != null ? transitionFuture : null,
-                animStartedListener);
-        if (taskView == null) {
-            // If there is no task view, then we do not need to worry about animating out occluding
-            // task views, and we can launch immediately
-            startTaskActivity(stack, task, taskView, opts, transitionFuture,
-                    windowingMode, activityType);
-        } else {
-            LaunchTaskStartedEvent launchStartedEvent = new LaunchTaskStartedEvent(taskView,
-                    screenPinningRequested);
-            EventBus.getDefault().send(launchStartedEvent);
-            startTaskActivity(stack, task, taskView, opts, transitionFuture, windowingMode,
-                    activityType);
-        }
-        ActivityManagerWrapper.getInstance().closeSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
-    }
-
-    /**
-     * Starts the activity for the launch task.
-     *
-     * @param taskView this is the {@link TaskView} that we are launching from. This can be null if
-     *                 we are toggling recents and the launch-to task is now offscreen.
-     */
-    private void startTaskActivity(TaskStack stack, Task task, @Nullable TaskView taskView,
-            ActivityOptions opts, AppTransitionAnimationSpecsFuture transitionFuture,
-            int windowingMode, int activityType) {
-        ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(task.key, opts,
-                windowingMode, activityType, succeeded -> {
-            if (succeeded) {
-                // Keep track of the index of the task launch
-                int taskIndexFromFront = 0;
-                int taskIndex = stack.indexOfTask(task);
-                if (taskIndex > -1) {
-                    taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
-                }
-                EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
-            } else {
-                Log.e(TAG, mContext.getString(R.string.recents_launch_error_message, task.title));
-
-                // Dismiss the task if we fail to launch it
-                if (taskView != null) {
-                    taskView.dismissTask();
-                }
-
-                // Keep track of failed launches
-                EventBus.getDefault().send(new LaunchTaskFailedEvent());
-            }
-        }, getHandler());
-        if (transitionFuture != null) {
-            mHandler.post(transitionFuture::composeSpecsSynchronous);
-        }
-    }
-
-    @Override
-    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-        super.requestDisallowInterceptTouchEvent(disallowIntercept);
-        mTouchHandler.cancelStackActionButtonClick();
-    }
-
-    public void dump(String prefix, PrintWriter writer) {
-        String innerPrefix = prefix + "  ";
-        String id = Integer.toHexString(System.identityHashCode(this));
-
-        writer.print(prefix); writer.print(TAG);
-        writer.print(" awaitingFirstLayout="); writer.print(mAwaitingFirstLayout ? "Y" : "N");
-        writer.print(" insets="); writer.print(Utilities.dumpRect(mSystemInsets));
-        writer.print(" [0x"); writer.print(id); writer.print("]");
-        writer.println();
-
-        if (getStack() != null) {
-            getStack().dump(innerPrefix, writer);
-        }
-        if (mTaskStackView != null) {
-            mTaskStackView.dump(innerPrefix, writer);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
deleted file mode 100644
index 53a91e5..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.PointerIcon;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewDebug;
-
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
-import com.android.systemui.recents.events.activity.HideRecentsEvent;
-import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
-import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
-import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragStartInitializeDropTargetsEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.model.Task;
-
-import java.util.ArrayList;
-
-/**
- * Handles touch events for a RecentsView.
- */
-public class RecentsViewTouchHandler {
-
-    private RecentsView mRv;
-
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task")
-    private Task mDragTask;
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task_view_")
-    private TaskView mTaskView;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    private Point mTaskViewOffset = new Point();
-    @ViewDebug.ExportedProperty(category="recents")
-    private Point mDownPos = new Point();
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mDragRequested;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mIsDragging;
-    private float mDragSlop;
-    private int mDeviceId = -1;
-
-    private DropTarget mLastDropTarget;
-    private DividerSnapAlgorithm mDividerSnapAlgorithm;
-    private ArrayList<DropTarget> mDropTargets = new ArrayList<>();
-    private ArrayList<DockState> mVisibleDockStates = new ArrayList<>();
-
-    public RecentsViewTouchHandler(RecentsView rv) {
-        mRv = rv;
-        mDragSlop = ViewConfiguration.get(rv.getContext()).getScaledTouchSlop();
-        updateSnapAlgorithm();
-    }
-
-    private void updateSnapAlgorithm() {
-        Rect insets = new Rect();
-        SystemServicesProxy.getInstance(mRv.getContext()).getStableInsets(insets);
-        mDividerSnapAlgorithm = DividerSnapAlgorithm.create(mRv.getContext(), insets);
-    }
-
-    /**
-     * Registers a new drop target for the current drag only.
-     */
-    public void registerDropTargetForCurrentDrag(DropTarget target) {
-        mDropTargets.add(target);
-    }
-
-    /**
-     * Returns the set of visible dock states for this current drag.
-     */
-    public ArrayList<DockState> getVisibleDockStates() {
-        return mVisibleDockStates;
-    }
-
-    /** Touch preprocessing for handling below */
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        return handleTouchEvent(ev) || mDragRequested;
-    }
-
-    /** Handles touch events once we have intercepted them */
-    public boolean onTouchEvent(MotionEvent ev) {
-        handleTouchEvent(ev);
-        if (ev.getAction() == MotionEvent.ACTION_UP && mRv.getStack().getTaskCount() == 0) {
-            EventBus.getDefault().send(new HideRecentsEvent(false, true));
-        }
-        return true;
-    }
-
-    /**** Events ****/
-
-    public final void onBusEvent(DragStartEvent event) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        mRv.getParent().requestDisallowInterceptTouchEvent(true);
-        mDragRequested = true;
-        // We defer starting the actual drag handling until the user moves past the drag slop
-        mIsDragging = false;
-        mDragTask = event.task;
-        mTaskView = event.taskView;
-        mDropTargets.clear();
-
-        int[] recentsViewLocation = new int[2];
-        mRv.getLocationInWindow(recentsViewLocation);
-        mTaskViewOffset.set(mTaskView.getLeft() - recentsViewLocation[0] + event.tlOffset.x,
-                mTaskView.getTop() - recentsViewLocation[1] + event.tlOffset.y);
-
-        // Change space coordinates relative to the view to RecentsView when user initiates a touch
-        if (event.isUserTouchInitiated) {
-            float x = mDownPos.x - mTaskViewOffset.x;
-            float y = mDownPos.y - mTaskViewOffset.y;
-            mTaskView.setTranslationX(x);
-            mTaskView.setTranslationY(y);
-        }
-
-        mVisibleDockStates.clear();
-        if (ActivityTaskManager.supportsMultiWindow(mRv.getContext()) && !ssp.hasDockedTask()
-                && mDividerSnapAlgorithm.isSplitScreenFeasible()) {
-            Recents.logDockAttempt(mRv.getContext(), event.task.getTopComponent(),
-                    event.task.resizeMode);
-            if (!event.task.isDockable) {
-                EventBus.getDefault().send(new ShowIncompatibleAppOverlayEvent());
-            } else {
-                // Add the dock state drop targets (these take priority)
-                DockState[] dockStates = Recents.getConfiguration()
-                        .getDockStatesForCurrentOrientation();
-                for (DockState dockState : dockStates) {
-                    registerDropTargetForCurrentDrag(dockState);
-                    dockState.update(mRv.getContext());
-                    mVisibleDockStates.add(dockState);
-                }
-            }
-        }
-
-        // Request other drop targets to register themselves
-        EventBus.getDefault().send(new DragStartInitializeDropTargetsEvent(event.task,
-                event.taskView, this));
-        if (mDeviceId != -1) {
-            InputDevice device = InputDevice.getDevice(mDeviceId);
-            if (device != null) {
-                device.setPointerType(PointerIcon.TYPE_GRABBING);
-            }
-        }
-    }
-
-    public final void onBusEvent(DragEndEvent event) {
-        if (!mDragTask.isDockable) {
-            EventBus.getDefault().send(new HideIncompatibleAppOverlayEvent());
-        }
-        mDragRequested = false;
-        mDragTask = null;
-        mTaskView = null;
-        mLastDropTarget = null;
-    }
-
-    public final void onBusEvent(ConfigurationChangedEvent event) {
-        if (event.fromDisplayDensityChange || event.fromDeviceOrientationChange) {
-            updateSnapAlgorithm();
-        }
-    }
-
-    void cancelStackActionButtonClick() {
-        mRv.getStackActionButton().setPressed(false);
-    }
-
-    private boolean isWithinStackActionButton(float x, float y) {
-        Rect rect = mRv.getStackActionButtonBoundsFromStackLayout();
-        return mRv.getStackActionButton().getVisibility() == View.VISIBLE &&
-                mRv.getStackActionButton().pointInView(x - rect.left, y - rect.top, 0 /* slop */);
-    }
-
-    private void changeStackActionButtonDrawableHotspot(float x, float y) {
-        Rect rect = mRv.getStackActionButtonBoundsFromStackLayout();
-        mRv.getStackActionButton().drawableHotspotChanged(x - rect.left, y - rect.top);
-    }
-
-    /**
-     * Handles dragging touch events
-     */
-    private boolean handleTouchEvent(MotionEvent ev) {
-        int action = ev.getActionMasked();
-        boolean consumed = false;
-        float evX = ev.getX();
-        float evY = ev.getY();
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mDownPos.set((int) evX, (int) evY);
-                mDeviceId = ev.getDeviceId();
-
-                if (isWithinStackActionButton(evX, evY)) {
-                    changeStackActionButtonDrawableHotspot(evX, evY);
-                    mRv.getStackActionButton().setPressed(true);
-                }
-                break;
-            case MotionEvent.ACTION_MOVE: {
-                float x = evX - mTaskViewOffset.x;
-                float y = evY - mTaskViewOffset.y;
-
-                if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) {
-                    changeStackActionButtonDrawableHotspot(evX, evY);
-                }
-
-                if (mDragRequested) {
-                    if (!mIsDragging) {
-                        mIsDragging = Math.hypot(evX - mDownPos.x, evY - mDownPos.y) > mDragSlop;
-                    }
-                    if (mIsDragging) {
-                        int width = mRv.getMeasuredWidth();
-                        int height = mRv.getMeasuredHeight();
-
-                        DropTarget currentDropTarget = null;
-
-                        // Give priority to the current drop target to retain the touch handling
-                        if (mLastDropTarget != null) {
-                            if (mLastDropTarget.acceptsDrop((int) evX, (int) evY, width, height,
-                                    mRv.mSystemInsets, true /* isCurrentTarget */)) {
-                                currentDropTarget = mLastDropTarget;
-                            }
-                        }
-
-                        // Otherwise, find the next target to handle this event
-                        if (currentDropTarget == null) {
-                            for (DropTarget target : mDropTargets) {
-                                if (target.acceptsDrop((int) evX, (int) evY, width, height,
-                                        mRv.mSystemInsets, false /* isCurrentTarget */)) {
-                                    currentDropTarget = target;
-                                    break;
-                                }
-                            }
-                        }
-                        if (mLastDropTarget != currentDropTarget) {
-                            mLastDropTarget = currentDropTarget;
-                            EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask,
-                                    currentDropTarget));
-                        }
-                    }
-                    mTaskView.setTranslationX(x);
-                    mTaskView.setTranslationY(y);
-                }
-                break;
-            }
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL: {
-                if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) {
-                    EventBus.getDefault().send(new DismissAllTaskViewsEvent());
-                    consumed = true;
-                }
-                cancelStackActionButtonClick();
-                if (mDragRequested) {
-                    boolean cancelled = action == MotionEvent.ACTION_CANCEL;
-                    if (cancelled) {
-                        EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask, null));
-                    }
-                    EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView,
-                            !cancelled ? mLastDropTarget : null));
-                    break;
-                }
-                mDeviceId = -1;
-            }
-        }
-        return consumed;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
deleted file mode 100644
index 170e39d..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.content.Context;
-import android.view.View;
-
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivity;
-import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
-import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
-import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-
-/** Manages the scrims for the various system bars. */
-public class SystemBarScrimViews {
-
-    private static final int DEFAULT_ANIMATION_DURATION = 150;
-
-    private Context mContext;
-
-    private View mNavBarScrimView;
-
-    private boolean mHasNavBarScrim;
-    private boolean mShouldAnimateNavBarScrim;
-    private boolean mHasTransposedNavBar;
-    private boolean mHasDockedTasks;
-    private int mNavBarScrimEnterDuration;
-
-    public SystemBarScrimViews(RecentsActivity activity) {
-        mContext = activity;
-        mNavBarScrimView = activity.findViewById(R.id.nav_bar_scrim);
-        mNavBarScrimView.forceHasOverlappingRendering(false);
-        mNavBarScrimEnterDuration = activity.getResources().getInteger(
-                R.integer.recents_nav_bar_scrim_enter_duration);
-        mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavigationBar();
-        mHasDockedTasks = Recents.getSystemServices().hasDockedTask();
-    }
-
-    /**
-     * Updates the nav bar scrim.
-     */
-    public void updateNavBarScrim(boolean animateNavBarScrim, boolean hasStackTasks,
-            AnimationProps animation) {
-        prepareEnterRecentsAnimation(isNavBarScrimRequired(hasStackTasks), animateNavBarScrim);
-        if (animateNavBarScrim && animation != null) {
-            animateNavBarScrimVisibility(true, animation);
-        }
-    }
-
-    /**
-     * Prepares the scrim views for animating when entering Recents. This will be called before
-     * the first draw, unless we are updating the scrim on configuration change.
-     */
-    private void prepareEnterRecentsAnimation(boolean hasNavBarScrim, boolean animateNavBarScrim) {
-        mHasNavBarScrim = hasNavBarScrim;
-        mShouldAnimateNavBarScrim = animateNavBarScrim;
-
-        mNavBarScrimView.setVisibility(mHasNavBarScrim && !mShouldAnimateNavBarScrim ?
-                View.VISIBLE : View.INVISIBLE);
-    }
-
-    /**
-     * Animates the nav bar scrim visibility.
-     */
-    private void animateNavBarScrimVisibility(boolean visible, AnimationProps animation) {
-        int toY = 0;
-        if (visible) {
-            mNavBarScrimView.setVisibility(View.VISIBLE);
-            mNavBarScrimView.setTranslationY(mNavBarScrimView.getMeasuredHeight());
-        } else {
-            toY = mNavBarScrimView.getMeasuredHeight();
-        }
-        if (animation != AnimationProps.IMMEDIATE) {
-            mNavBarScrimView.animate()
-                    .translationY(toY)
-                    .setDuration(animation.getDuration(AnimationProps.BOUNDS))
-                    .setInterpolator(animation.getInterpolator(AnimationProps.BOUNDS))
-                    .start();
-        } else {
-            mNavBarScrimView.setTranslationY(toY);
-        }
-    }
-
-    /**
-     * @return Whether to show the nav bar scrim.
-     */
-    private boolean isNavBarScrimRequired(boolean hasStackTasks) {
-        return hasStackTasks && !mHasTransposedNavBar && !mHasDockedTasks;
-    }
-
-    /**** EventBus events ****/
-
-    /**
-     * Starts animating the scrim views when entering Recents.
-     */
-    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
-        if (mHasNavBarScrim) {
-            AnimationProps animation = mShouldAnimateNavBarScrim
-                    ? new AnimationProps()
-                            .setDuration(AnimationProps.BOUNDS, mNavBarScrimEnterDuration)
-                            .setInterpolator(AnimationProps.BOUNDS, Interpolators.DECELERATE_QUINT)
-                    : AnimationProps.IMMEDIATE;
-            animateNavBarScrimVisibility(true, animation);
-        }
-    }
-
-    /**
-     * Starts animating the scrim views when leaving Recents (either via launching a task, or
-     * going home).
-     */
-    public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
-        if (mHasNavBarScrim) {
-            AnimationProps animation = createBoundsAnimation(
-                    TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION);
-            animateNavBarScrimVisibility(false, animation);
-        }
-    }
-
-    public final void onBusEvent(DismissAllTaskViewsEvent event) {
-        if (mHasNavBarScrim) {
-            AnimationProps animation = createBoundsAnimation(
-                    TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION);
-            animateNavBarScrimVisibility(false, animation);
-        }
-    }
-
-    public final void onBusEvent(ConfigurationChangedEvent event) {
-        if (event.fromDeviceOrientationChange) {
-            mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavigationBar();
-        }
-        animateScrimToCurrentNavBarState(event.hasStackTasks);
-    }
-
-    public final void onBusEvent(MultiWindowStateChangedEvent event) {
-        mHasDockedTasks = event.inMultiWindow;
-        animateScrimToCurrentNavBarState(event.stack.getTaskCount() > 0);
-    }
-
-    public final void onBusEvent(final DragEndEvent event) {
-        // Hide the nav bar scrims once we drop to a dock region
-        if (event.dropTarget instanceof DockState) {
-            animateScrimToCurrentNavBarState(false /* hasStackTasks */);
-        }
-    }
-
-    public final void onBusEvent(final DragEndCancelledEvent event) {
-        // Restore the scrims to the normal state
-        animateScrimToCurrentNavBarState(event.stack.getTaskCount() > 0);
-    }
-
-    /**
-     * Animates the scrim to match the state of the current nav bar.
-     */
-    private void animateScrimToCurrentNavBarState(boolean hasStackTasks) {
-        boolean hasNavBarScrim = isNavBarScrimRequired(hasStackTasks);
-        if (mHasNavBarScrim != hasNavBarScrim) {
-            AnimationProps animation = hasNavBarScrim
-                    ? createBoundsAnimation(DEFAULT_ANIMATION_DURATION)
-                    : AnimationProps.IMMEDIATE;
-            animateNavBarScrimVisibility(hasNavBarScrim, animation);
-        }
-        mHasNavBarScrim = hasNavBarScrim;
-    }
-
-    /**
-     * @return a default animation to aniamte the bounds of the scrim.
-     */
-    private AnimationProps createBoundsAnimation(int duration) {
-        return new AnimationProps()
-                .setDuration(AnimationProps.BOUNDS, duration)
-                .setInterpolator(AnimationProps.BOUNDS, Interpolators.FAST_OUT_SLOW_IN);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
deleted file mode 100644
index 67d0978..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2015 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.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.util.Log;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
-
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivityLaunchState;
-import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.RecentsDebugFlags;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
-import com.android.systemui.recents.misc.ReferenceCountedTrigger;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.recents.views.lowram.TaskStackLowRamLayoutAlgorithm;
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A helper class to create task view animations for {@link TaskView}s in a {@link TaskStackView},
- * but not the contents of the {@link TaskView}s.
- */
-public class TaskStackAnimationHelper {
-
-    /**
-     * Callbacks from the helper to coordinate view-content animations with view animations.
-     */
-    public interface Callbacks {
-        /**
-         * Callback to prepare for the start animation for the launch target {@link TaskView}.
-         */
-        void onPrepareLaunchTargetForEnterAnimation();
-
-        /**
-         * Callback to start the animation for the launch target {@link TaskView}.
-         */
-        void onStartLaunchTargetEnterAnimation(TaskViewTransform transform, int duration,
-                boolean screenPinningEnabled, ReferenceCountedTrigger postAnimationTrigger);
-
-        /**
-         * Callback to start the animation for the launch target {@link TaskView} when it is
-         * launched from Recents.
-         */
-        void onStartLaunchTargetLaunchAnimation(int duration, boolean screenPinningRequested,
-                ReferenceCountedTrigger postAnimationTrigger);
-
-        /**
-         * Callback to start the animation for the front {@link TaskView} if there is no launch
-         * target.
-         */
-        void onStartFrontTaskEnterAnimation(boolean screenPinningEnabled);
-    }
-
-    private static final int DOUBLE_FRAME_OFFSET_MS = 33;
-    private static final int FRAME_OFFSET_MS = 16;
-
-    private static final int ENTER_EXIT_NUM_ANIMATING_TASKS = 5;
-
-    private static final int ENTER_FROM_HOME_ALPHA_DURATION = 100;
-    public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 300;
-    private static final Interpolator ENTER_FROM_HOME_ALPHA_INTERPOLATOR = Interpolators.LINEAR;
-
-    public static final int EXIT_TO_HOME_TRANSLATION_DURATION = 200;
-    private static final Interpolator EXIT_TO_HOME_TRANSLATION_INTERPOLATOR =
-            new PathInterpolator(0.4f, 0, 0.6f, 1f);
-
-    private static final int DISMISS_TASK_DURATION = 175;
-    private static final int DISMISS_ALL_TASKS_DURATION = 200;
-    private static final Interpolator DISMISS_ALL_TRANSLATION_INTERPOLATOR =
-            new PathInterpolator(0.4f, 0, 1f, 1f);
-
-    private static final Interpolator FOCUS_NEXT_TASK_INTERPOLATOR =
-            new PathInterpolator(0.4f, 0, 0, 1f);
-    private static final Interpolator FOCUS_IN_FRONT_NEXT_TASK_INTERPOLATOR =
-            new PathInterpolator(0, 0, 0, 1f);
-    private static final Interpolator FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR =
-            Interpolators.LINEAR_OUT_SLOW_IN;
-
-    private static final Interpolator ENTER_WHILE_DOCKING_INTERPOLATOR =
-            Interpolators.LINEAR_OUT_SLOW_IN;
-
-    private final int mEnterAndExitFromHomeTranslationOffset;
-    private TaskStackView mStackView;
-
-    private TaskViewTransform mTmpTransform = new TaskViewTransform();
-    private ArrayList<TaskViewTransform> mTmpCurrentTaskTransforms = new ArrayList<>();
-    private ArrayList<TaskViewTransform> mTmpFinalTaskTransforms = new ArrayList<>();
-
-    public TaskStackAnimationHelper(Context context, TaskStackView stackView) {
-        mStackView = stackView;
-        mEnterAndExitFromHomeTranslationOffset = Recents.getConfiguration().isGridEnabled
-                ? 0 : DOUBLE_FRAME_OFFSET_MS;
-    }
-
-    /**
-     * Prepares the stack views and puts them in their initial animation state while visible, before
-     * the in-app enter animations start (after the window-transition completes).
-     */
-    public void prepareForEnterAnimation() {
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        Resources res = mStackView.getResources();
-        Resources appResources = mStackView.getContext().getApplicationContext().getResources();
-
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-        TaskStackViewScroller stackScroller = mStackView.getScroller();
-        TaskStack stack = mStackView.getStack();
-        Task launchTargetTask = stack.getLaunchTarget();
-
-        // Break early if there are no tasks
-        if (stack.getTaskCount() == 0) {
-            return;
-        }
-
-        int offscreenYOffset = stackLayout.mStackRect.height();
-        int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize(
-                R.dimen.recents_task_stack_animation_affiliate_enter_offset);
-        int launchedWhileDockingOffset = res.getDimensionPixelSize(
-                R.dimen.recents_task_stack_animation_launched_while_docking_offset);
-        boolean isLandscape = appResources.getConfiguration().orientation
-                == Configuration.ORIENTATION_LANDSCAPE;
-
-        float top = 0;
-        final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice;
-        if (isLowRamDevice && launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
-            stackLayout.getStackTransform(launchTargetTask, stackScroller.getStackScroll(),
-                    mTmpTransform, null /* frontTransform */);
-            top = mTmpTransform.rect.top;
-        }
-
-        // Prepare each of the task views for their enter animation from front to back
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        for (int i = taskViews.size() - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            // Get the current transform for the task, which will be used to position it offscreen
-            stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
-                    null);
-
-            if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
-                if (task.isLaunchTarget) {
-                    tv.onPrepareLaunchTargetForEnterAnimation();
-                } else if (isLowRamDevice && i >= taskViews.size() -
-                            (TaskStackLowRamLayoutAlgorithm.MAX_LAYOUT_TASK_COUNT + 1)
-                        && !RecentsDebugFlags.Static.DisableRecentsLowRamEnterExitAnimation) {
-                    // Move the last 2nd and 3rd last tasks in-app animation to match the motion of
-                    // the last task's app transition
-                    stackLayout.getStackTransform(task, stackScroller.getStackScroll(),
-                            mTmpTransform, null);
-                    mTmpTransform.rect.offset(0, -top);
-                    mTmpTransform.alpha = 0f;
-                    mStackView.updateTaskViewToTransform(tv, mTmpTransform,
-                            AnimationProps.IMMEDIATE);
-                    stackLayout.getStackTransform(task, stackScroller.getStackScroll(),
-                            mTmpTransform, null);
-                    mTmpTransform.alpha = 1f;
-                    // Duration see {@link
-                    // com.android.server.wm.AppTransition#DEFAULT_APP_TRANSITION_DURATION}
-                    mStackView.updateTaskViewToTransform(tv, mTmpTransform,
-                            new AnimationProps(336, Interpolators.FAST_OUT_SLOW_IN));
-                }
-            } else if (launchState.launchedFromHome) {
-                if (isLowRamDevice) {
-                    mTmpTransform.rect.offset(0, stackLayout.getTaskRect().height() / 4);
-                } else {
-                    // Move the task view off screen (below) so we can animate it in
-                    mTmpTransform.rect.offset(0, offscreenYOffset);
-                }
-                mTmpTransform.alpha = 0f;
-                mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
-            } else if (launchState.launchedViaDockGesture) {
-                int offset = isLandscape
-                        ? launchedWhileDockingOffset
-                        : (int) (offscreenYOffset * 0.9f);
-                mTmpTransform.rect.offset(0, offset);
-                mTmpTransform.alpha = 0f;
-                mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
-            }
-        }
-    }
-
-    /**
-     * Starts the in-app enter animation, which animates the {@link TaskView}s to their final places
-     * depending on how Recents was triggered.
-     */
-    public void startEnterAnimation(final ReferenceCountedTrigger postAnimationTrigger) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        Resources res = mStackView.getResources();
-        Resources appRes = mStackView.getContext().getApplicationContext().getResources();
-
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-        TaskStackViewScroller stackScroller = mStackView.getScroller();
-        TaskStack stack = mStackView.getStack();
-        Task launchTargetTask = stack.getLaunchTarget();
-
-        // Break early if there are no tasks
-        if (stack.getTaskCount() == 0) {
-            return;
-        }
-
-        final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice;
-        int taskViewEnterFromAppDuration = res.getInteger(
-                R.integer.recents_task_enter_from_app_duration);
-        int taskViewEnterFromAffiliatedAppDuration = res.getInteger(
-                R.integer.recents_task_enter_from_affiliated_app_duration);
-        int dockGestureAnimDuration = appRes.getInteger(
-                R.integer.long_press_dock_anim_duration);
-
-        // Since low ram devices have an animation when entering app -> recents, do not allow
-        // toggle until the animation is complete
-        if (launchState.launchedFromApp && !launchState.launchedViaDockGesture && isLowRamDevice) {
-            postAnimationTrigger.addLastDecrementRunnable(() -> EventBus.getDefault()
-                .send(new SetWaitingForTransitionStartEvent(false)));
-        }
-
-        // Create enter animations for each of the views from front to back
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = taskViewCount - 1; i >= 0; i--) {
-            int taskIndexFromFront = taskViewCount - i - 1;
-            int taskIndexFromBack = i;
-            final TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            // Get the current transform for the task, which will be updated to the final transform
-            // to animate to depending on how recents was invoked
-            stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
-                    null);
-
-            if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
-                if (task.isLaunchTarget) {
-                    tv.onStartLaunchTargetEnterAnimation(mTmpTransform,
-                            taskViewEnterFromAppDuration, mStackView.mScreenPinningEnabled,
-                            postAnimationTrigger);
-                }
-
-            } else if (launchState.launchedFromHome) {
-                // Animate the tasks up, but offset the animations to be relative to the front-most
-                // task animation
-                final float startOffsetFraction = (float) (Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS,
-                        taskIndexFromFront) * mEnterAndExitFromHomeTranslationOffset) /
-                        ENTER_FROM_HOME_TRANSLATION_DURATION;
-                AnimationProps taskAnimation = new AnimationProps()
-                        .setInterpolator(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_INTERPOLATOR)
-                        .setListener(postAnimationTrigger.decrementOnAnimationEnd());
-                if (isLowRamDevice) {
-                    taskAnimation.setInterpolator(AnimationProps.BOUNDS,
-                            Interpolators.FAST_OUT_SLOW_IN)
-                            .setDuration(AnimationProps.BOUNDS, 150)
-                            .setDuration(AnimationProps.ALPHA, 150);
-                } else {
-                    taskAnimation.setStartDelay(AnimationProps.ALPHA,
-                                Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS, taskIndexFromFront) *
-                                        FRAME_OFFSET_MS)
-                            .setInterpolator(AnimationProps.BOUNDS,
-                                new RecentsEntrancePathInterpolator(0f, 0f, 0.2f, 1f,
-                                        startOffsetFraction))
-                            .setDuration(AnimationProps.BOUNDS, ENTER_FROM_HOME_TRANSLATION_DURATION)
-                            .setDuration(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_DURATION);
-                }
-                postAnimationTrigger.increment();
-                mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
-                if (i == taskViewCount - 1) {
-                    tv.onStartFrontTaskEnterAnimation(mStackView.mScreenPinningEnabled);
-                }
-            } else if (launchState.launchedViaDockGesture) {
-                // Animate the tasks up - add some delay to match the divider animation
-                AnimationProps taskAnimation = new AnimationProps()
-                        .setDuration(AnimationProps.BOUNDS, dockGestureAnimDuration +
-                                (taskIndexFromBack * DOUBLE_FRAME_OFFSET_MS))
-                        .setInterpolator(AnimationProps.BOUNDS,
-                                ENTER_WHILE_DOCKING_INTERPOLATOR)
-                        .setStartDelay(AnimationProps.BOUNDS, 48)
-                        .setListener(postAnimationTrigger.decrementOnAnimationEnd());
-                postAnimationTrigger.increment();
-                mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
-            }
-        }
-    }
-
-    /**
-     * Starts an in-app animation to hide all the task views so that we can transition back home.
-     */
-    public void startExitToHomeAnimation(boolean animated,
-            ReferenceCountedTrigger postAnimationTrigger) {
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-        TaskStack stack = mStackView.getStack();
-
-        // Break early if there are no tasks
-        if (stack.getTaskCount() == 0) {
-            return;
-        }
-
-        int offscreenYOffset = stackLayout.mStackRect.height();
-
-        // Create the animations for each of the tasks
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            int taskIndexFromFront = taskViewCount - i - 1;
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            if (mStackView.isIgnoredTask(task)) {
-                continue;
-            }
-
-            // Animate the tasks down
-            AnimationProps taskAnimation;
-            if (animated) {
-                int delay = Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS , taskIndexFromFront) *
-                        mEnterAndExitFromHomeTranslationOffset;
-                taskAnimation = new AnimationProps()
-                        .setDuration(AnimationProps.BOUNDS, EXIT_TO_HOME_TRANSLATION_DURATION)
-                        .setListener(postAnimationTrigger.decrementOnAnimationEnd());
-                if (Recents.getConfiguration().isLowRamDevice) {
-                    taskAnimation.setInterpolator(AnimationProps.BOUNDS,
-                            Interpolators.FAST_OUT_SLOW_IN);
-                } else {
-                    taskAnimation.setStartDelay(AnimationProps.BOUNDS, delay)
-                            .setInterpolator(AnimationProps.BOUNDS,
-                                    EXIT_TO_HOME_TRANSLATION_INTERPOLATOR);
-                }
-                postAnimationTrigger.increment();
-            } else {
-                taskAnimation = AnimationProps.IMMEDIATE;
-            }
-
-            mTmpTransform.fillIn(tv);
-            if (Recents.getConfiguration().isLowRamDevice) {
-                taskAnimation.setInterpolator(AnimationProps.ALPHA,
-                                EXIT_TO_HOME_TRANSLATION_INTERPOLATOR)
-                        .setDuration(AnimationProps.ALPHA, EXIT_TO_HOME_TRANSLATION_DURATION);
-                mTmpTransform.rect.offset(0, stackLayout.mTaskStackLowRamLayoutAlgorithm
-                        .getTaskRect().height() / 4);
-                mTmpTransform.alpha = 0f;
-            } else {
-                mTmpTransform.rect.offset(0, offscreenYOffset);
-            }
-            mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
-        }
-    }
-
-    /**
-     * Starts the animation for the launching task view, hiding any tasks that might occlude the
-     * window transition for the launching task.
-     */
-    public void startLaunchTaskAnimation(TaskView launchingTaskView, boolean screenPinningRequested,
-            final ReferenceCountedTrigger postAnimationTrigger) {
-        Resources res = mStackView.getResources();
-
-        int taskViewExitToAppDuration = res.getInteger(
-                R.integer.recents_task_exit_to_app_duration);
-        int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize(
-                R.dimen.recents_task_stack_animation_affiliate_enter_offset);
-
-        Task launchingTask = launchingTaskView.getTask();
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            if (tv == launchingTaskView) {
-                tv.setClipViewInStack(false);
-                postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
-                    @Override
-                    public void run() {
-                        tv.setClipViewInStack(true);
-                    }
-                });
-                tv.onStartLaunchTargetLaunchAnimation(taskViewExitToAppDuration,
-                        screenPinningRequested, postAnimationTrigger);
-            }
-        }
-    }
-
-    /**
-     * Starts the delete animation for the specified {@link TaskView}.
-     */
-    public void startDeleteTaskAnimation(final TaskView deleteTaskView, boolean gridLayout,
-            final ReferenceCountedTrigger postAnimationTrigger) {
-        if (gridLayout) {
-            startTaskGridDeleteTaskAnimation(deleteTaskView, postAnimationTrigger);
-        } else {
-            startTaskStackDeleteTaskAnimation(deleteTaskView, postAnimationTrigger);
-        }
-    }
-
-    /**
-     * Starts the delete animation for all the {@link TaskView}s.
-     */
-    public void startDeleteAllTasksAnimation(final List<TaskView> taskViews, boolean gridLayout,
-            final ReferenceCountedTrigger postAnimationTrigger) {
-        if (gridLayout) {
-            for (int i = 0; i < taskViews.size(); i++) {
-                startTaskGridDeleteTaskAnimation(taskViews.get(i), postAnimationTrigger);
-            }
-        } else {
-            startTaskStackDeleteAllTasksAnimation(taskViews, postAnimationTrigger);
-        }
-    }
-
-    /**
-     * Starts the animation to focus the next {@link TaskView} when paging through recents.
-     *
-     * @return whether or not this will trigger a scroll in the stack
-     */
-    public boolean startScrollToFocusedTaskAnimation(Task newFocusedTask,
-            boolean requestViewFocus) {
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-        TaskStackViewScroller stackScroller = mStackView.getScroller();
-        TaskStack stack = mStackView.getStack();
-
-        final float curScroll = stackScroller.getStackScroll();
-        final float newScroll = stackScroller.getBoundedStackScroll(
-                stackLayout.getStackScrollForTask(newFocusedTask));
-        boolean willScrollToFront = newScroll > curScroll;
-        boolean willScroll = Float.compare(newScroll, curScroll) != 0;
-
-        // Get the current set of task transforms
-        int taskViewCount = mStackView.getTaskViews().size();
-        ArrayList<Task> stackTasks = stack.getTasks();
-        mStackView.getCurrentTaskTransforms(stackTasks, mTmpCurrentTaskTransforms);
-
-        // Pick up the newly visible views after the scroll
-        mStackView.bindVisibleTaskViews(newScroll);
-
-        // Update the internal state
-        stackLayout.setFocusState(TaskStackLayoutAlgorithm.STATE_FOCUSED);
-        stackScroller.setStackScroll(newScroll, null /* animation */);
-        mStackView.cancelDeferredTaskViewLayoutAnimation();
-
-        // Get the final set of task transforms
-        mStackView.getLayoutTaskTransforms(newScroll, stackLayout.getFocusState(), stackTasks,
-                true /* ignoreTaskOverrides */, mTmpFinalTaskTransforms);
-
-        // Focus the task view
-        TaskView newFocusedTaskView = mStackView.getChildViewForTask(newFocusedTask);
-        if (newFocusedTaskView == null) {
-            // Log the error if we have no task view, and skip the animation
-            Log.e("TaskStackAnimationHelper", "b/27389156 null-task-view prebind:" + taskViewCount +
-                    " postbind:" + mStackView.getTaskViews().size() + " prescroll:" + curScroll +
-                    " postscroll: " + newScroll);
-            return false;
-        }
-        newFocusedTaskView.setFocusedState(true, requestViewFocus);
-
-        // Setup the end listener to return all the hidden views to the view pool after the
-        // focus animation
-        ReferenceCountedTrigger postAnimTrigger = new ReferenceCountedTrigger();
-        postAnimTrigger.addLastDecrementRunnable(new Runnable() {
-            @Override
-            public void run() {
-                mStackView.bindVisibleTaskViews(newScroll);
-            }
-        });
-
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        taskViewCount = taskViews.size();
-        int newFocusTaskViewIndex = taskViews.indexOf(newFocusedTaskView);
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            if (mStackView.isIgnoredTask(task)) {
-                continue;
-            }
-
-            int taskIndex = stackTasks.indexOf(task);
-            TaskViewTransform fromTransform = mTmpCurrentTaskTransforms.get(taskIndex);
-            TaskViewTransform toTransform = mTmpFinalTaskTransforms.get(taskIndex);
-
-            // Update the task to the initial state (for the newly picked up tasks)
-            mStackView.updateTaskViewToTransform(tv, fromTransform, AnimationProps.IMMEDIATE);
-
-            int duration;
-            Interpolator interpolator;
-            if (willScrollToFront) {
-                duration = calculateStaggeredAnimDuration(i);
-                interpolator = FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR;
-            } else {
-                if (i < newFocusTaskViewIndex) {
-                    duration = 150 + ((newFocusTaskViewIndex - i - 1) * 50);
-                    interpolator = FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR;
-                } else if (i > newFocusTaskViewIndex) {
-                    duration = Math.max(100, 150 - ((i - newFocusTaskViewIndex - 1) * 50));
-                    interpolator = FOCUS_IN_FRONT_NEXT_TASK_INTERPOLATOR;
-                } else {
-                    duration = 200;
-                    interpolator = FOCUS_NEXT_TASK_INTERPOLATOR;
-                }
-            }
-
-            AnimationProps anim = new AnimationProps()
-                    .setDuration(AnimationProps.BOUNDS, duration)
-                    .setInterpolator(AnimationProps.BOUNDS, interpolator)
-                    .setListener(postAnimTrigger.decrementOnAnimationEnd());
-            postAnimTrigger.increment();
-            mStackView.updateTaskViewToTransform(tv, toTransform, anim);
-        }
-        return willScroll;
-    }
-
-    /**
-     * Starts the animation to go to the initial stack layout with a task focused.  In addition, the
-     * previous task will be animated in after the scroll completes.
-     */
-    public void startNewStackScrollAnimation(TaskStack newStack,
-            ReferenceCountedTrigger animationTrigger) {
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-        TaskStackViewScroller stackScroller = mStackView.getScroller();
-
-        // Get the current set of task transforms
-        ArrayList<Task> stackTasks = newStack.getTasks();
-        mStackView.getCurrentTaskTransforms(stackTasks, mTmpCurrentTaskTransforms);
-
-        // Update the stack
-        mStackView.setTasks(newStack, false /* allowNotifyStackChanges */);
-        mStackView.updateLayoutAlgorithm(false /* boundScroll */);
-
-        // Pick up the newly visible views after the scroll
-        final float newScroll = stackLayout.mInitialScrollP;
-        mStackView.bindVisibleTaskViews(newScroll);
-
-        // Update the internal state
-        stackLayout.setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
-        stackLayout.setTaskOverridesForInitialState(newStack, true /* ignoreScrollToFront */);
-        stackScroller.setStackScroll(newScroll);
-        mStackView.cancelDeferredTaskViewLayoutAnimation();
-
-        // Get the final set of task transforms
-        mStackView.getLayoutTaskTransforms(newScroll, stackLayout.getFocusState(), stackTasks,
-                false /* ignoreTaskOverrides */, mTmpFinalTaskTransforms);
-
-        // Hide the front most task view until the scroll is complete
-        Task frontMostTask = newStack.getFrontMostTask();
-        final TaskView frontMostTaskView = mStackView.getChildViewForTask(frontMostTask);
-        final TaskViewTransform frontMostTransform = mTmpFinalTaskTransforms.get(
-                stackTasks.indexOf(frontMostTask));
-        if (frontMostTaskView != null) {
-            mStackView.updateTaskViewToTransform(frontMostTaskView,
-                    stackLayout.getFrontOfStackTransform(), AnimationProps.IMMEDIATE);
-        }
-
-        // Setup the end listener to return all the hidden views to the view pool after the
-        // focus animation
-        animationTrigger.addLastDecrementRunnable(new Runnable() {
-            @Override
-            public void run() {
-                mStackView.bindVisibleTaskViews(newScroll);
-
-                // Now, animate in the front-most task
-                if (frontMostTaskView != null) {
-                    mStackView.updateTaskViewToTransform(frontMostTaskView, frontMostTransform,
-                            new AnimationProps(75, 250, FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR));
-                }
-            }
-        });
-
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            if (mStackView.isIgnoredTask(task)) {
-                continue;
-            }
-            if (task == frontMostTask && frontMostTaskView != null) {
-                continue;
-            }
-
-            int taskIndex = stackTasks.indexOf(task);
-            TaskViewTransform fromTransform = mTmpCurrentTaskTransforms.get(taskIndex);
-            TaskViewTransform toTransform = mTmpFinalTaskTransforms.get(taskIndex);
-
-            // Update the task to the initial state (for the newly picked up tasks)
-            mStackView.updateTaskViewToTransform(tv, fromTransform, AnimationProps.IMMEDIATE);
-
-            int duration = calculateStaggeredAnimDuration(i);
-            Interpolator interpolator = FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR;
-
-            AnimationProps anim = new AnimationProps()
-                    .setDuration(AnimationProps.BOUNDS, duration)
-                    .setInterpolator(AnimationProps.BOUNDS, interpolator)
-                    .setListener(animationTrigger.decrementOnAnimationEnd());
-            animationTrigger.increment();
-            mStackView.updateTaskViewToTransform(tv, toTransform, anim);
-        }
-    }
-
-    /**
-     * Caclulates a staggered duration for {@link #startScrollToFocusedTaskAnimation} and
-     * {@link #startNewStackScrollAnimation}.
-     */
-    private int calculateStaggeredAnimDuration(int i) {
-        return Math.max(100, 100 + ((i - 1) * 50));
-    }
-
-    private void startTaskGridDeleteTaskAnimation(final TaskView deleteTaskView,
-            final ReferenceCountedTrigger postAnimationTrigger) {
-        postAnimationTrigger.increment();
-        postAnimationTrigger.addLastDecrementRunnable(() -> {
-            mStackView.getTouchHandler().onChildDismissed(deleteTaskView);
-        });
-        deleteTaskView.animate().setDuration(300).scaleX(0.9f).scaleY(0.9f).alpha(0).setListener(
-                new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        postAnimationTrigger.decrement();
-                    }}).start();
-    }
-
-    private void startTaskStackDeleteTaskAnimation(final TaskView deleteTaskView,
-            final ReferenceCountedTrigger postAnimationTrigger) {
-        TaskStackViewTouchHandler touchHandler = mStackView.getTouchHandler();
-        touchHandler.onBeginManualDrag(deleteTaskView);
-
-        postAnimationTrigger.increment();
-        postAnimationTrigger.addLastDecrementRunnable(() -> {
-            touchHandler.onChildDismissed(deleteTaskView);
-        });
-
-        final float dismissSize = touchHandler.getScaledDismissSize();
-        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
-        animator.setDuration(400);
-        animator.addUpdateListener((animation) -> {
-            float progress = (Float) animation.getAnimatedValue();
-            deleteTaskView.setTranslationX(progress * dismissSize);
-            touchHandler.updateSwipeProgress(deleteTaskView, true, progress);
-        });
-        animator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                postAnimationTrigger.decrement();
-            }
-        });
-        animator.start();
-    }
-
-    private void startTaskStackDeleteAllTasksAnimation(final List<TaskView> taskViews,
-            final ReferenceCountedTrigger postAnimationTrigger) {
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-
-        int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.getTaskRect().left;
-
-        int taskViewCount = taskViews.size();
-        for (int i = taskViewCount - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
-            int taskIndexFromFront = taskViewCount - i - 1;
-            int startDelay = taskIndexFromFront * DOUBLE_FRAME_OFFSET_MS;
-
-            // Disabling clipping with the stack while the view is animating away
-            tv.setClipViewInStack(false);
-
-            // Compose the new animation and transform and star the animation
-            AnimationProps taskAnimation = new AnimationProps(startDelay,
-                    DISMISS_ALL_TASKS_DURATION, DISMISS_ALL_TRANSLATION_INTERPOLATOR,
-                    new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            postAnimationTrigger.decrement();
-
-                            // Re-enable clipping with the stack (we will reuse this view)
-                            tv.setClipViewInStack(true);
-                        }
-                    });
-            postAnimationTrigger.increment();
-
-            mTmpTransform.fillIn(tv);
-            mTmpTransform.rect.offset(offscreenXOffset, 0);
-            mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
deleted file mode 100644
index d9f79bb..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ /dev/null
@@ -1,1280 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Path;
-import android.graphics.Rect;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-import android.view.ViewDebug;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivityLaunchState;
-import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.RecentsDebugFlags;
-import com.android.systemui.recents.misc.FreePathInterpolator;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.recents.views.lowram.TaskStackLowRamLayoutAlgorithm;
-import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
-
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Used to describe a visible range that can be normalized to [0, 1].
- */
-class Range {
-    final float relativeMin;
-    final float relativeMax;
-    float origin;
-    float min;
-    float max;
-
-    public Range(float relMin, float relMax) {
-        min = relativeMin = relMin;
-        max = relativeMax = relMax;
-    }
-
-    /**
-     * Offsets this range to a given absolute position.
-     */
-    public void offset(float x) {
-        this.origin = x;
-        min = x + relativeMin;
-        max = x + relativeMax;
-    }
-
-    /**
-     * Returns x normalized to the range 0 to 1 such that 0 = min, 0.5 = origin and 1 = max
-     *
-     * @param x is an absolute value in the same domain as origin
-     */
-    public float getNormalizedX(float x) {
-        if (x < origin) {
-            return 0.5f + 0.5f * (x - origin) / -relativeMin;
-        } else {
-            return 0.5f + 0.5f * (x - origin) / relativeMax;
-        }
-    }
-
-    /**
-     * Given a normalized {@param x} value in this range, projected onto the full range to get an
-     * absolute value about the given {@param origin}.
-     */
-    public float getAbsoluteX(float normX) {
-        if (normX < 0.5f) {
-            return (normX - 0.5f) / 0.5f * -relativeMin;
-        } else {
-            return (normX - 0.5f) / 0.5f * relativeMax;
-        }
-    }
-
-    /**
-     * Returns whether a value at an absolute x would be within range.
-     */
-    public boolean isInRange(float absX) {
-        return (absX >= Math.floor(min)) && (absX <= Math.ceil(max));
-    }
-}
-
-/**
- * The layout logic for a TaskStackView.  This layout needs to be able to calculate the stack layout
- * without an activity-specific context only with the information passed in.  This layout can have
- * two states focused and unfocused, and in the focused state, there is a task that is displayed
- * more prominently in the stack.
- */
-public class TaskStackLayoutAlgorithm {
-
-    private static final String TAG = "TaskStackLayoutAlgorithm";
-
-    // The distribution of view bounds alpha
-    // XXX: This is a hack because you can currently set the max alpha to be > 1f
-    public static final float OUTLINE_ALPHA_MIN_VALUE = 0f;
-    public static final float OUTLINE_ALPHA_MAX_VALUE = 2f;
-
-    // The medium/maximum dim on the tasks
-    private static final float MED_DIM = 0.15f;
-    private static final float MAX_DIM = 0.25f;
-
-    // The various focus states
-    public static final int STATE_FOCUSED = 1;
-    public static final int STATE_UNFOCUSED = 0;
-
-    // The side that an offset is anchored
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({FROM_TOP, FROM_BOTTOM})
-    public @interface AnchorSide {}
-    private static final int FROM_TOP = 0;
-    private static final int FROM_BOTTOM = 1;
-
-    // The extent that we care about when calculating fractions
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({WIDTH, HEIGHT})
-    public @interface Extent {}
-    private static final int WIDTH = 0;
-    private static final int HEIGHT = 1;
-
-    public interface TaskStackLayoutAlgorithmCallbacks {
-        void onFocusStateChanged(int prevFocusState, int curFocusState);
-    }
-
-    /**
-     * @return True if we should use the grid layout.
-     */
-    boolean useGridLayout() {
-        return Recents.getConfiguration().isGridEnabled;
-    }
-
-    // A report of the visibility state of the stack
-    public static class VisibilityReport {
-        public int numVisibleTasks;
-        public int numVisibleThumbnails;
-
-        public VisibilityReport(int tasks, int thumbnails) {
-            numVisibleTasks = tasks;
-            numVisibleThumbnails = thumbnails;
-        }
-    }
-
-    Context mContext;
-    private TaskStackLayoutAlgorithmCallbacks mCb;
-
-    // The task bounds (untransformed) for layout.  This rect is anchored at mTaskRoot.
-    @ViewDebug.ExportedProperty(category="recents")
-    public Rect mTaskRect = new Rect();
-    // The stack bounds, inset from the top system insets, and runs to the bottom of the screen
-    @ViewDebug.ExportedProperty(category="recents")
-    public Rect mStackRect = new Rect();
-    // This is the current system insets
-    @ViewDebug.ExportedProperty(category="recents")
-    public Rect mSystemInsets = new Rect();
-
-    // The visible ranges when the stack is focused and unfocused
-    private Range mUnfocusedRange;
-    private Range mFocusedRange;
-
-    // This is the bounds of the stack action above the stack rect
-    @ViewDebug.ExportedProperty(category="recents")
-    private Rect mStackActionButtonRect = new Rect();
-    // The base top margin for the stack from the system insets
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mBaseTopMargin;
-    // The base side margin for the stack from the system insets
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mBaseSideMargin;
-    // The base bottom margin for the stack from the system insets
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mBaseBottomMargin;
-    private int mMinMargin;
-
-    // The initial offset that the focused task is from the top
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mInitialTopOffset;
-    private int mBaseInitialTopOffset;
-    // The initial offset that the launch-from task is from the bottom
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mInitialBottomOffset;
-    private int mBaseInitialBottomOffset;
-
-    // The height between the top margin and the top of the focused task
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mFocusedTopPeekHeight;
-    // The height between the bottom margin and the top of task in front of the focused task
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mFocusedBottomPeekHeight;
-
-    // The offset from the bottom of the stack to the bottom of the bounds when the stack is
-    // scrolled to the front
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mStackBottomOffset;
-
-    /** The height, in pixels, of each task view's title bar. */
-    private int mTitleBarHeight;
-
-    // The paths defining the motion of the tasks when the stack is focused and unfocused
-    private Path mUnfocusedCurve;
-    private Path mFocusedCurve;
-    private FreePathInterpolator mUnfocusedCurveInterpolator;
-    private FreePathInterpolator mFocusedCurveInterpolator;
-
-    // The paths defining the distribution of the dim to apply to tasks in the stack when focused
-    // and unfocused
-    private Path mUnfocusedDimCurve;
-    private Path mFocusedDimCurve;
-    private FreePathInterpolator mUnfocusedDimCurveInterpolator;
-    private FreePathInterpolator mFocusedDimCurveInterpolator;
-
-    // The state of the stack focus (0..1), which controls the transition of the stack from the
-    // focused to non-focused state
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mFocusState;
-
-    // The smallest scroll progress, at this value, the back most task will be visible
-    @ViewDebug.ExportedProperty(category="recents")
-    float mMinScrollP;
-    // The largest scroll progress, at this value, the front most task will be visible above the
-    // navigation bar
-    @ViewDebug.ExportedProperty(category="recents")
-    float mMaxScrollP;
-    // The initial progress that the scroller is set when you first enter recents
-    @ViewDebug.ExportedProperty(category="recents")
-    float mInitialScrollP;
-    // The task progress for the front-most task in the stack
-    @ViewDebug.ExportedProperty(category="recents")
-    float mFrontMostTaskP;
-
-    // The last computed task counts
-    @ViewDebug.ExportedProperty(category="recents")
-    int mNumStackTasks;
-
-    // The min/max z translations
-    @ViewDebug.ExportedProperty(category="recents")
-    int mMinTranslationZ;
-    @ViewDebug.ExportedProperty(category="recents")
-    public int mMaxTranslationZ;
-
-    // Optimization, allows for quick lookup of task -> index
-    private SparseIntArray mTaskIndexMap = new SparseIntArray();
-    private SparseArray<Float> mTaskIndexOverrideMap = new SparseArray<>();
-
-    TaskGridLayoutAlgorithm mTaskGridLayoutAlgorithm;
-    TaskStackLowRamLayoutAlgorithm mTaskStackLowRamLayoutAlgorithm;
-
-    // The transform to place TaskViews at the front and back of the stack respectively
-    TaskViewTransform mBackOfStackTransform = new TaskViewTransform();
-    TaskViewTransform mFrontOfStackTransform = new TaskViewTransform();
-
-    public TaskStackLayoutAlgorithm(Context context, TaskStackLayoutAlgorithmCallbacks cb) {
-        mContext = context;
-        mCb = cb;
-        mTaskGridLayoutAlgorithm = new TaskGridLayoutAlgorithm(context);
-        mTaskStackLowRamLayoutAlgorithm = new TaskStackLowRamLayoutAlgorithm(context);
-        reloadOnConfigurationChange(context);
-    }
-
-    /**
-     * Reloads the layout for the current configuration.
-     */
-    public void reloadOnConfigurationChange(Context context) {
-        Resources res = context.getResources();
-        mFocusedRange = new Range(res.getFloat(R.integer.recents_layout_focused_range_min),
-                res.getFloat(R.integer.recents_layout_focused_range_max));
-        mUnfocusedRange = new Range(res.getFloat(R.integer.recents_layout_unfocused_range_min),
-                res.getFloat(R.integer.recents_layout_unfocused_range_max));
-        mFocusState = getInitialFocusState();
-        mFocusedTopPeekHeight = res.getDimensionPixelSize(R.dimen.recents_layout_top_peek_size);
-        mFocusedBottomPeekHeight =
-                res.getDimensionPixelSize(R.dimen.recents_layout_bottom_peek_size);
-        mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_layout_z_min);
-        mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_layout_z_max);
-        mBaseInitialTopOffset = getDimensionForDevice(context,
-                R.dimen.recents_layout_initial_top_offset_phone_port,
-                R.dimen.recents_layout_initial_top_offset_phone_land,
-                R.dimen.recents_layout_initial_top_offset_tablet,
-                R.dimen.recents_layout_initial_top_offset_tablet,
-                R.dimen.recents_layout_initial_top_offset_tablet,
-                R.dimen.recents_layout_initial_top_offset_tablet,
-                R.dimen.recents_layout_initial_top_offset_tablet);
-        mBaseInitialBottomOffset = getDimensionForDevice(context,
-                R.dimen.recents_layout_initial_bottom_offset_phone_port,
-                R.dimen.recents_layout_initial_bottom_offset_phone_land,
-                R.dimen.recents_layout_initial_bottom_offset_tablet,
-                R.dimen.recents_layout_initial_bottom_offset_tablet,
-                R.dimen.recents_layout_initial_bottom_offset_tablet,
-                R.dimen.recents_layout_initial_bottom_offset_tablet,
-                R.dimen.recents_layout_initial_bottom_offset_tablet);
-        mTaskGridLayoutAlgorithm.reloadOnConfigurationChange(context);
-        mTaskStackLowRamLayoutAlgorithm.reloadOnConfigurationChange(context);
-        mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
-        mBaseTopMargin = getDimensionForDevice(context,
-                R.dimen.recents_layout_top_margin_phone,
-                R.dimen.recents_layout_top_margin_tablet,
-                R.dimen.recents_layout_top_margin_tablet_xlarge,
-                R.dimen.recents_layout_top_margin_tablet);
-        mBaseSideMargin = getDimensionForDevice(context,
-                R.dimen.recents_layout_side_margin_phone,
-                R.dimen.recents_layout_side_margin_tablet,
-                R.dimen.recents_layout_side_margin_tablet_xlarge,
-                R.dimen.recents_layout_side_margin_tablet);
-        mBaseBottomMargin = res.getDimensionPixelSize(R.dimen.recents_layout_bottom_margin);
-        mTitleBarHeight = getDimensionForDevice(mContext,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height_tablet_land,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height_tablet_land,
-                R.dimen.recents_grid_task_view_header_height);
-    }
-
-    /**
-     * Resets this layout when the stack view is reset.
-     */
-    public void reset() {
-        mTaskIndexOverrideMap.clear();
-        setFocusState(getInitialFocusState());
-    }
-
-    /**
-     * Sets the system insets.
-     */
-    public boolean setSystemInsets(Rect systemInsets) {
-        boolean changed = !mSystemInsets.equals(systemInsets);
-        mSystemInsets.set(systemInsets);
-        mTaskGridLayoutAlgorithm.setSystemInsets(systemInsets);
-        mTaskStackLowRamLayoutAlgorithm.setSystemInsets(systemInsets);
-        return changed;
-    }
-
-    /**
-     * Sets the focused state.
-     */
-    public void setFocusState(int focusState) {
-        int prevFocusState = mFocusState;
-        mFocusState = focusState;
-        updateFrontBackTransforms();
-        if (mCb != null) {
-            mCb.onFocusStateChanged(prevFocusState, focusState);
-        }
-    }
-
-    /**
-     * Gets the focused state.
-     */
-    public int getFocusState() {
-        return mFocusState;
-    }
-
-    /**
-     * Computes the stack and task rects.  The given task stack bounds already has the top/right
-     * insets and left/right padding already applied.
-     */
-    public void initialize(Rect displayRect, Rect windowRect, Rect taskStackBounds) {
-        Rect lastStackRect = new Rect(mStackRect);
-
-        int topMargin = getScaleForExtent(windowRect, displayRect, mBaseTopMargin, mMinMargin, HEIGHT);
-        int bottomMargin = getScaleForExtent(windowRect, displayRect, mBaseBottomMargin, mMinMargin,
-                HEIGHT);
-        mInitialTopOffset = getScaleForExtent(windowRect, displayRect, mBaseInitialTopOffset,
-                mMinMargin, HEIGHT);
-        mInitialBottomOffset = mBaseInitialBottomOffset;
-
-        // Compute the stack bounds
-        mStackBottomOffset = mSystemInsets.bottom + bottomMargin;
-        mStackRect.set(taskStackBounds);
-        mStackRect.top += topMargin;
-
-        // The stack action button will take the full un-padded header space above the stack
-        mStackActionButtonRect.set(mStackRect.left, mStackRect.top - topMargin,
-                mStackRect.right, mStackRect.top + mFocusedTopPeekHeight);
-
-        // Anchor the task rect top aligned to the stack rect
-        int height = mStackRect.height() - mInitialTopOffset - mStackBottomOffset;
-        mTaskRect.set(mStackRect.left, mStackRect.top, mStackRect.right, mStackRect.top + height);
-
-        if (mTaskRect.width() <= 0 || mTaskRect.height() <= 0) {
-            // Logging for b/36654830
-            Log.e(TAG, "Invalid task rect: taskRect=" + mTaskRect + " stackRect=" + mStackRect
-                    + " displayRect=" + displayRect + " windowRect=" + windowRect
-                    + " taskStackBounds=" + taskStackBounds);
-        }
-
-        // Short circuit here if the stack rects haven't changed so we don't do all the work below
-        if (!lastStackRect.equals(mStackRect)) {
-            // Reinitialize the focused and unfocused curves
-            mUnfocusedCurve = constructUnfocusedCurve();
-            mUnfocusedCurveInterpolator = new FreePathInterpolator(mUnfocusedCurve);
-            mFocusedCurve = constructFocusedCurve();
-            mFocusedCurveInterpolator = new FreePathInterpolator(mFocusedCurve);
-            mUnfocusedDimCurve = constructUnfocusedDimCurve();
-            mUnfocusedDimCurveInterpolator = new FreePathInterpolator(mUnfocusedDimCurve);
-            mFocusedDimCurve = constructFocusedDimCurve();
-            mFocusedDimCurveInterpolator = new FreePathInterpolator(mFocusedDimCurve);
-
-            updateFrontBackTransforms();
-        }
-
-        // Initialize the grid layout
-        mTaskGridLayoutAlgorithm.initialize(windowRect);
-        mTaskStackLowRamLayoutAlgorithm.initialize(windowRect);
-    }
-
-    /**
-     * Computes the minimum and maximum scroll progress values and the progress values for each task
-     * in the stack.
-     */
-    public void update(TaskStack stack, ArraySet<Task.TaskKey> ignoreTasksSet,
-            RecentsActivityLaunchState launchState, float lastScrollPPercent) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-
-        // Clear the progress map
-        mTaskIndexMap.clear();
-
-        // Return early if we have no tasks
-        ArrayList<Task> tasks = stack.getTasks();
-        if (tasks.isEmpty()) {
-            mFrontMostTaskP = 0;
-            mMinScrollP = mMaxScrollP = mInitialScrollP = 0;
-            mNumStackTasks = 0;
-            return;
-        }
-
-        // Filter the set of stack tasks
-        ArrayList<Task> stackTasks = new ArrayList<>();
-        for (int i = 0; i < tasks.size(); i++) {
-            Task task = tasks.get(i);
-            if (ignoreTasksSet.contains(task.key)) {
-                continue;
-            }
-            stackTasks.add(task);
-        }
-        mNumStackTasks = stackTasks.size();
-
-        // Put each of the tasks in the progress map at a fixed index (does not need to actually
-        // map to a scroll position, just by index)
-        int taskCount = stackTasks.size();
-        for (int i = 0; i < taskCount; i++) {
-            Task task = stackTasks.get(i);
-            mTaskIndexMap.put(task.key.id, i);
-        }
-
-        // Calculate the min/max/initial scroll
-        Task launchTask = stack.getLaunchTarget();
-        int launchTaskIndex = launchTask != null
-                ? stack.indexOfTask(launchTask)
-                : mNumStackTasks - 1;
-        if (getInitialFocusState() == STATE_FOCUSED) {
-            int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
-            float maxBottomNormX = getNormalizedXFromFocusedY(maxBottomOffset, FROM_BOTTOM);
-            mFocusedRange.offset(0f);
-            mMinScrollP = 0;
-            mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
-                    Math.max(0, mFocusedRange.getAbsoluteX(maxBottomNormX)));
-            if (launchState.launchedFromHome || launchState.launchedFromPipApp
-                    || launchState.launchedWithNextPipApp) {
-                mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
-            } else {
-                mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP, mMaxScrollP);
-            }
-        } else if (mNumStackTasks == 1) {
-            // If there is one stack task, ignore the min/max/initial scroll positions
-            mMinScrollP = 0;
-            mMaxScrollP = 0;
-            mInitialScrollP = 0;
-        } else {
-            // Set the max scroll to be the point where the front most task is visible with the
-            // stack bottom offset
-            int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
-            float maxBottomNormX = getNormalizedXFromUnfocusedY(maxBottomOffset, FROM_BOTTOM);
-            mUnfocusedRange.offset(0f);
-            mMinScrollP = Recents.getConfiguration().isLowRamDevice
-                    ? mTaskStackLowRamLayoutAlgorithm.getMinScrollP()
-                    : 0;
-            mMaxScrollP = Recents.getConfiguration().isLowRamDevice
-                    ? mTaskStackLowRamLayoutAlgorithm.getMaxScrollP(taskCount)
-                    : Math.max(mMinScrollP, (mNumStackTasks - 1) -
-                    Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX)));
-            boolean scrollToFront = launchState.launchedFromHome || launchState.launchedFromPipApp
-                    || launchState.launchedWithNextPipApp || launchState.launchedViaDockGesture;
-
-            if (launchState.launchedWithAltTab) {
-                mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
-            } else if (0 <= lastScrollPPercent && lastScrollPPercent <= 1) {
-                mInitialScrollP = Utilities.mapRange(lastScrollPPercent, mMinScrollP, mMaxScrollP);
-            } else if (Recents.getConfiguration().isLowRamDevice) {
-                mInitialScrollP = mTaskStackLowRamLayoutAlgorithm.getInitialScrollP(mNumStackTasks,
-                        scrollToFront);
-            } else if (scrollToFront) {
-                mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
-            } else {
-                // We are overriding the initial two task positions, so set the initial scroll
-                // position to match the second task (aka focused task) position
-                float initialTopNormX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
-                mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2))
-                        - Math.max(0, mUnfocusedRange.getAbsoluteX(initialTopNormX)));
-            }
-        }
-    }
-
-    /**
-     * Creates task overrides to ensure the initial stack layout if necessary.
-     */
-    public void setTaskOverridesForInitialState(TaskStack stack, boolean ignoreScrollToFront) {
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-
-        mTaskIndexOverrideMap.clear();
-
-        boolean scrollToFront = launchState.launchedFromHome ||
-                launchState.launchedFromPipApp ||
-                launchState.launchedWithNextPipApp ||
-                launchState.launchedViaDockGesture;
-        if (getInitialFocusState() == STATE_UNFOCUSED && mNumStackTasks > 1) {
-            if (ignoreScrollToFront || (!launchState.launchedWithAltTab && !scrollToFront)) {
-                // Set the initial scroll to the predefined state (which differs from the stack)
-                float [] initialNormX = null;
-                float minBottomTaskNormX = getNormalizedXFromUnfocusedY(mSystemInsets.bottom +
-                        mInitialBottomOffset, FROM_BOTTOM);
-                float maxBottomTaskNormX = getNormalizedXFromUnfocusedY(mFocusedTopPeekHeight +
-                        mTaskRect.height() - mMinMargin, FROM_TOP);
-                if (mNumStackTasks <= 2) {
-                    // For small stacks, position the tasks so that they are top aligned to under
-                    // the action button, but ensure that it is at least a certain offset from the
-                    // bottom of the stack
-                    initialNormX = new float[] {
-                            Math.min(maxBottomTaskNormX, minBottomTaskNormX),
-                            getNormalizedXFromUnfocusedY(mFocusedTopPeekHeight, FROM_TOP)
-                    };
-                } else {
-                    initialNormX = new float[] {
-                            minBottomTaskNormX,
-                            getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP)
-                    };
-                }
-
-                mUnfocusedRange.offset(0f);
-                List<Task> tasks = stack.getTasks();
-                int taskCount = tasks.size();
-                for (int i = taskCount - 1; i >= 0; i--) {
-                    int indexFromFront = taskCount - i - 1;
-                    if (indexFromFront >= initialNormX.length) {
-                        break;
-                    }
-                    float newTaskProgress = mInitialScrollP +
-                            mUnfocusedRange.getAbsoluteX(initialNormX[indexFromFront]);
-                    mTaskIndexOverrideMap.put(tasks.get(i).key.id, newTaskProgress);
-                }
-            }
-        }
-    }
-
-    /**
-     * Adds and override task progress for the given task when transitioning from focused to
-     * unfocused state.
-     */
-    public void addUnfocusedTaskOverride(Task task, float stackScroll) {
-        if (mFocusState != STATE_UNFOCUSED) {
-            mFocusedRange.offset(stackScroll);
-            mUnfocusedRange.offset(stackScroll);
-            float focusedRangeX = mFocusedRange.getNormalizedX(mTaskIndexMap.get(task.key.id));
-            float focusedY = mFocusedCurveInterpolator.getInterpolation(focusedRangeX);
-            float unfocusedRangeX = mUnfocusedCurveInterpolator.getX(focusedY);
-            float unfocusedTaskProgress = stackScroll + mUnfocusedRange.getAbsoluteX(unfocusedRangeX);
-            if (Float.compare(focusedRangeX, unfocusedRangeX) != 0) {
-                mTaskIndexOverrideMap.put(task.key.id, unfocusedTaskProgress);
-            }
-        }
-    }
-
-    /**
-     * Adds and override task progress for the given task when transitioning from focused to
-     * unfocused state.
-     */
-    public void addUnfocusedTaskOverride(TaskView taskView, float stackScroll) {
-        mFocusedRange.offset(stackScroll);
-        mUnfocusedRange.offset(stackScroll);
-
-        Task task = taskView.getTask();
-        int top = taskView.getTop() - mTaskRect.top;
-        float focusedRangeX = getNormalizedXFromFocusedY(top, FROM_TOP);
-        float unfocusedRangeX = getNormalizedXFromUnfocusedY(top, FROM_TOP);
-        float unfocusedTaskProgress = stackScroll + mUnfocusedRange.getAbsoluteX(unfocusedRangeX);
-        if (Float.compare(focusedRangeX, unfocusedRangeX) != 0) {
-            mTaskIndexOverrideMap.put(task.key.id, unfocusedTaskProgress);
-        }
-    }
-
-    public void clearUnfocusedTaskOverrides() {
-        mTaskIndexOverrideMap.clear();
-    }
-
-    /**
-     * Updates this stack when a scroll happens.
-     *
-     */
-    public float updateFocusStateOnScroll(float lastTargetStackScroll, float targetStackScroll,
-            float lastStackScroll) {
-        if (targetStackScroll == lastStackScroll || Recents.getConfiguration().isLowRamDevice) {
-            return targetStackScroll;
-        }
-
-        float deltaScroll = targetStackScroll - lastStackScroll;
-        float deltaTargetScroll = targetStackScroll - lastTargetStackScroll;
-        float newScroll = targetStackScroll;
-        mUnfocusedRange.offset(targetStackScroll);
-        for (int i = mTaskIndexOverrideMap.size() - 1; i >= 0; i--) {
-            int taskId = mTaskIndexOverrideMap.keyAt(i);
-            float x = mTaskIndexMap.get(taskId);
-            float overrideX = mTaskIndexOverrideMap.get(taskId, 0f);
-            float newOverrideX = overrideX + deltaScroll;
-            if (isInvalidOverrideX(x, overrideX, newOverrideX)) {
-                // Remove the override once we reach the original task index
-                mTaskIndexOverrideMap.removeAt(i);
-            } else if ((overrideX >= x && deltaScroll <= 0f) ||
-                    (overrideX <= x && deltaScroll >= 0f)) {
-                // Scrolling from override x towards x, then lock the task in place
-                mTaskIndexOverrideMap.put(taskId, newOverrideX);
-            } else {
-                // Scrolling override x away from x, we should still move the scroll towards x
-                newScroll = lastStackScroll;
-                newOverrideX = overrideX - deltaTargetScroll;
-                if (isInvalidOverrideX(x, overrideX, newOverrideX)) {
-                    mTaskIndexOverrideMap.removeAt(i);
-                } else{
-                    mTaskIndexOverrideMap.put(taskId, newOverrideX);
-                }
-            }
-        }
-        return newScroll;
-    }
-
-    private boolean isInvalidOverrideX(float x, float overrideX, float newOverrideX) {
-        boolean outOfBounds = mUnfocusedRange.getNormalizedX(newOverrideX) < 0f ||
-                mUnfocusedRange.getNormalizedX(newOverrideX) > 1f;
-        return outOfBounds || (overrideX >= x && x >= newOverrideX) ||
-                (overrideX <= x && x <= newOverrideX);
-    }
-
-    /**
-     * Returns the default focus state.
-     */
-    public int getInitialFocusState() {
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-        RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-        if (launchState.launchedWithAltTab) {
-            return STATE_FOCUSED;
-        } else {
-            return STATE_UNFOCUSED;
-        }
-    }
-
-    public Rect getStackActionButtonRect() {
-        return useGridLayout()
-                ? mTaskGridLayoutAlgorithm.getStackActionButtonRect() : mStackActionButtonRect;
-    }
-
-    /**
-     * Returns the TaskViewTransform that would put the task just off the back of the stack.
-     */
-    public TaskViewTransform getBackOfStackTransform() {
-        return mBackOfStackTransform;
-    }
-
-    /**
-     * Returns the TaskViewTransform that would put the task just off the front of the stack.
-     */
-    public TaskViewTransform getFrontOfStackTransform() {
-        return mFrontOfStackTransform;
-    }
-
-    /**
-     * Returns whether this stack layout has been initialized.
-     */
-    public boolean isInitialized() {
-        return !mStackRect.isEmpty();
-    }
-
-    /**
-     * Computes the maximum number of visible tasks and thumbnails when the scroll is at the initial
-     * stack scroll.  Requires that update() is called first.
-     */
-    public VisibilityReport computeStackVisibilityReport(ArrayList<Task> tasks) {
-        if (useGridLayout()) {
-            return mTaskGridLayoutAlgorithm.computeStackVisibilityReport(tasks);
-        }
-
-        if (Recents.getConfiguration().isLowRamDevice) {
-            return mTaskStackLowRamLayoutAlgorithm.computeStackVisibilityReport(tasks);
-        }
-
-        // Ensure minimum visibility count
-        if (tasks.size() <= 1) {
-            return new VisibilityReport(1, 1);
-        }
-
-        // Otherwise, walk backwards in the stack and count the number of tasks and visible
-        // thumbnails and add that to the total task count
-        TaskViewTransform tmpTransform = new TaskViewTransform();
-        Range currentRange = getInitialFocusState() > 0f ? mFocusedRange : mUnfocusedRange;
-        currentRange.offset(mInitialScrollP);
-        int taskBarHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.recents_task_view_header_height);
-        int numVisibleTasks = 0;
-        int numVisibleThumbnails = 0;
-        float prevScreenY = Integer.MAX_VALUE;
-        for (int i = tasks.size() - 1; i >= 0; i--) {
-            Task task = tasks.get(i);
-
-            // Skip invisible
-            float taskProgress = getStackScrollForTask(task);
-            if (!currentRange.isInRange(taskProgress)) {
-                continue;
-            }
-
-            getStackTransform(taskProgress, taskProgress, mInitialScrollP, mFocusState,
-                    tmpTransform, null, false /* ignoreSingleTaskCase */, false /* forceUpdate */);
-            float screenY = tmpTransform.rect.top;
-            boolean hasVisibleThumbnail = (prevScreenY - screenY) > taskBarHeight;
-            if (hasVisibleThumbnail) {
-                numVisibleThumbnails++;
-                numVisibleTasks++;
-                prevScreenY = screenY;
-            } else {
-                // Once we hit the next front most task that does not have a visible thumbnail,
-                // walk through remaining visible set
-                for (int j = i; j >= 0; j--) {
-                    taskProgress = getStackScrollForTask(tasks.get(j));
-                    if (!currentRange.isInRange(taskProgress)) {
-                        break;
-                    }
-                    numVisibleTasks++;
-                }
-                break;
-            }
-        }
-        return new VisibilityReport(numVisibleTasks, numVisibleThumbnails);
-    }
-
-    /**
-     * Returns the transform for the given task.  This transform is relative to the mTaskRect, which
-     * is what the view is measured and laid out with.
-     */
-    public TaskViewTransform getStackTransform(Task task, float stackScroll,
-            TaskViewTransform transformOut, TaskViewTransform frontTransform) {
-        return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
-                false /* forceUpdate */, false /* ignoreTaskOverrides */);
-    }
-
-    public TaskViewTransform getStackTransform(Task task, float stackScroll,
-            TaskViewTransform transformOut, TaskViewTransform frontTransform,
-            boolean ignoreTaskOverrides) {
-        return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
-                false /* forceUpdate */, ignoreTaskOverrides);
-    }
-
-    public TaskViewTransform getStackTransform(Task task, float stackScroll, int focusState,
-            TaskViewTransform transformOut, TaskViewTransform frontTransform, boolean forceUpdate,
-            boolean ignoreTaskOverrides) {
-        if (useGridLayout()) {
-            int taskIndex = mTaskIndexMap.get(task.key.id);
-            int taskCount = mTaskIndexMap.size();
-            mTaskGridLayoutAlgorithm.getTransform(taskIndex, taskCount, transformOut, this);
-            return transformOut;
-        } else if (Recents.getConfiguration().isLowRamDevice) {
-            if (task == null) {
-                transformOut.reset();
-                return transformOut;
-            }
-            int taskIndex = mTaskIndexMap.get(task.key.id);
-            mTaskStackLowRamLayoutAlgorithm.getTransform(taskIndex, stackScroll, transformOut,
-                    mNumStackTasks, this);
-            return transformOut;
-        } else {
-            // Return early if we have an invalid index
-            int nonOverrideTaskProgress = mTaskIndexMap.get(task.key.id, -1);
-            if (task == null || nonOverrideTaskProgress == -1) {
-                transformOut.reset();
-                return transformOut;
-            }
-            float taskProgress = ignoreTaskOverrides
-                    ? nonOverrideTaskProgress
-                    : getStackScrollForTask(task);
-
-            getStackTransform(taskProgress, nonOverrideTaskProgress, stackScroll, focusState,
-                    transformOut, frontTransform, false /* ignoreSingleTaskCase */, forceUpdate);
-            return transformOut;
-        }
-    }
-
-    /**
-     * Like {@link #getStackTransform}, but in screen coordinates
-     */
-    public TaskViewTransform getStackTransformScreenCoordinates(Task task, float stackScroll,
-            TaskViewTransform transformOut, TaskViewTransform frontTransform,
-            Rect windowOverrideRect) {
-        TaskViewTransform transform = getStackTransform(task, stackScroll, mFocusState,
-                transformOut, frontTransform, true /* forceUpdate */,
-                false /* ignoreTaskOverrides */);
-        return transformToScreenCoordinates(transform, windowOverrideRect);
-    }
-
-    /**
-     * Transforms the given {@param transformOut} to the screen coordinates, overriding the current
-     * window rectangle with {@param windowOverrideRect} if non-null.
-     */
-    TaskViewTransform transformToScreenCoordinates(TaskViewTransform transformOut,
-            Rect windowOverrideRect) {
-        Rect windowRect = windowOverrideRect != null
-                ? windowOverrideRect
-                : Recents.getSystemServices().getWindowRect();
-        transformOut.rect.offset(windowRect.left, windowRect.top);
-        if (useGridLayout()) {
-            // Draw the thumbnail a little lower to perfectly coincide with the view we are
-            // transitioning to, where the header bar has already been drawn.
-            transformOut.rect.offset(0, mTitleBarHeight);
-        }
-        return transformOut;
-    }
-
-    /**
-     * Update/get the transform.
-     *
-     * @param ignoreSingleTaskCase When set, will ensure that the transform computed does not take
-     *                             into account the special single-task case.  This is only used
-     *                             internally to ensure that we can calculate the transform for any
-     *                             position in the stack.
-     */
-    public void getStackTransform(float taskProgress, float nonOverrideTaskProgress,
-            float stackScroll, int focusState, TaskViewTransform transformOut,
-            TaskViewTransform frontTransform, boolean ignoreSingleTaskCase, boolean forceUpdate) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-
-        // Ensure that the task is in range
-        mUnfocusedRange.offset(stackScroll);
-        mFocusedRange.offset(stackScroll);
-        boolean unfocusedVisible = mUnfocusedRange.isInRange(taskProgress);
-        boolean focusedVisible = mFocusedRange.isInRange(taskProgress);
-
-        // Skip if the task is not visible
-        if (!forceUpdate && !unfocusedVisible && !focusedVisible) {
-            transformOut.reset();
-            return;
-        }
-
-        // Map the absolute task progress to the normalized x at the stack scroll.  We use this to
-        // calculate positions along the curve.
-        mUnfocusedRange.offset(stackScroll);
-        mFocusedRange.offset(stackScroll);
-        float unfocusedRangeX = mUnfocusedRange.getNormalizedX(taskProgress);
-        float focusedRangeX = mFocusedRange.getNormalizedX(taskProgress);
-
-        // Map the absolute task progress to the normalized x at the bounded stack scroll.  We use
-        // this to calculate bounded properties, like translationZ and outline alpha.
-        float boundedStackScroll = Utilities.clamp(stackScroll, mMinScrollP, mMaxScrollP);
-        mUnfocusedRange.offset(boundedStackScroll);
-        mFocusedRange.offset(boundedStackScroll);
-        float boundedScrollUnfocusedRangeX = mUnfocusedRange.getNormalizedX(taskProgress);
-        float boundedScrollUnfocusedNonOverrideRangeX =
-                mUnfocusedRange.getNormalizedX(nonOverrideTaskProgress);
-
-        // Map the absolute task progress to the normalized x at the upper bounded stack scroll.
-        // We use this to calculate the dim, which is bounded only on one end.
-        float lowerBoundedStackScroll = Utilities.clamp(stackScroll, -Float.MAX_VALUE, mMaxScrollP);
-        mUnfocusedRange.offset(lowerBoundedStackScroll);
-        mFocusedRange.offset(lowerBoundedStackScroll);
-        float lowerBoundedUnfocusedRangeX = mUnfocusedRange.getNormalizedX(taskProgress);
-        float lowerBoundedFocusedRangeX = mFocusedRange.getNormalizedX(taskProgress);
-
-        int x = (mStackRect.width() - mTaskRect.width()) / 2;
-        int y;
-        float z;
-        float dimAlpha;
-        float viewOutlineAlpha;
-        if (mNumStackTasks == 1 && !ignoreSingleTaskCase) {
-            // When there is exactly one task, then decouple the task from the stack and just move
-            // in screen space
-            float tmpP = (mMinScrollP - stackScroll) / mNumStackTasks;
-            int centerYOffset = (mStackRect.top - mTaskRect.top) +
-                    (mStackRect.height() - mSystemInsets.bottom - mTaskRect.height()) / 2;
-            y = centerYOffset + getYForDeltaP(tmpP, 0);
-            z = mMaxTranslationZ;
-            dimAlpha = 0f;
-            viewOutlineAlpha = OUTLINE_ALPHA_MIN_VALUE +
-                    (OUTLINE_ALPHA_MAX_VALUE - OUTLINE_ALPHA_MIN_VALUE) / 2f;
-
-        } else {
-            // Otherwise, update the task to the stack layout
-            int unfocusedY = (int) ((1f - mUnfocusedCurveInterpolator.getInterpolation(
-                    unfocusedRangeX)) * mStackRect.height());
-            int focusedY = (int) ((1f - mFocusedCurveInterpolator.getInterpolation(
-                    focusedRangeX)) * mStackRect.height());
-            float unfocusedDim = mUnfocusedDimCurveInterpolator.getInterpolation(
-                    lowerBoundedUnfocusedRangeX);
-            float focusedDim = mFocusedDimCurveInterpolator.getInterpolation(
-                    lowerBoundedFocusedRangeX);
-
-            // Special case, because we override the initial task positions differently for small
-            // stacks, we clamp the dim to 0 in the initial position, and then only modulate the
-            // dim when the task is scrolled back towards the top of the screen
-            if (mNumStackTasks <= 2 && nonOverrideTaskProgress == 0f) {
-                if (boundedScrollUnfocusedRangeX >= 0.5f) {
-                    unfocusedDim = 0f;
-                } else {
-                    float offset = mUnfocusedDimCurveInterpolator.getInterpolation(0.5f);
-                    unfocusedDim -= offset;
-                    unfocusedDim *= MAX_DIM / (MAX_DIM - offset);
-                }
-            }
-            y = (mStackRect.top - mTaskRect.top) +
-                    (int) Utilities.mapRange(focusState, unfocusedY, focusedY);
-            z = Utilities.mapRange(Utilities.clamp01(boundedScrollUnfocusedNonOverrideRangeX),
-                    mMinTranslationZ, mMaxTranslationZ);
-            dimAlpha = Utilities.mapRange(focusState, unfocusedDim, focusedDim);
-            viewOutlineAlpha = Utilities.mapRange(Utilities.clamp01(boundedScrollUnfocusedRangeX),
-                    OUTLINE_ALPHA_MIN_VALUE, OUTLINE_ALPHA_MAX_VALUE);
-        }
-
-        // Fill out the transform
-        transformOut.scale = 1f;
-        transformOut.alpha = 1f;
-        transformOut.translationZ = z;
-        transformOut.dimAlpha = dimAlpha;
-        transformOut.viewOutlineAlpha = viewOutlineAlpha;
-        transformOut.rect.set(mTaskRect);
-        transformOut.rect.offset(x, y);
-        Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
-        transformOut.visible = (transformOut.rect.top < mStackRect.bottom) &&
-                (frontTransform == null || transformOut.rect.top != frontTransform.rect.top);
-    }
-
-    /**
-     * Returns the untransformed task view bounds.
-     */
-    public Rect getUntransformedTaskViewBounds() {
-        return new Rect(mTaskRect);
-    }
-
-    /**
-     * Returns the scroll progress to scroll to such that the top of the task is at the top of the
-     * stack.
-     */
-    float getStackScrollForTask(Task t) {
-        Float overrideP = mTaskIndexOverrideMap.get(t.key.id, null);
-        if (Recents.getConfiguration().isLowRamDevice || overrideP == null) {
-            return (float) mTaskIndexMap.get(t.key.id, 0);
-        }
-        return overrideP;
-    }
-
-    /**
-     * Returns the original scroll progress to scroll to such that the top of the task is at the top
-     * of the stack.
-     */
-    float getStackScrollForTaskIgnoreOverrides(Task t) {
-        return (float) mTaskIndexMap.get(t.key.id, 0);
-    }
-
-    /**
-     * Returns the scroll progress to scroll to such that the top of the task at the initial top
-     * offset (which is at the task's brightest point).
-     */
-    float getStackScrollForTaskAtInitialOffset(Task t) {
-        if (Recents.getConfiguration().isLowRamDevice) {
-            RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-            return mTaskStackLowRamLayoutAlgorithm.getInitialScrollP(mNumStackTasks,
-                    launchState.launchedFromHome || launchState.launchedFromPipApp
-                            || launchState.launchedWithNextPipApp);
-        }
-        float normX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
-        mUnfocusedRange.offset(0f);
-        return Utilities.clamp((float) mTaskIndexMap.get(t.key.id, 0) - Math.max(0,
-                mUnfocusedRange.getAbsoluteX(normX)), mMinScrollP, mMaxScrollP);
-    }
-
-    /**
-     * Maps a movement in screen y, relative to {@param downY}, to a movement in along the arc
-     * length of the curve.  We know the curve is mostly flat, so we just map the length of the
-     * screen along the arc-length proportionally (1/arclength).
-     */
-    public float getDeltaPForY(int downY, int y) {
-        if (Recents.getConfiguration().isLowRamDevice) {
-            return mTaskStackLowRamLayoutAlgorithm.scrollToPercentage(downY - y);
-        }
-        float deltaP = (float) (y - downY) / mStackRect.height() *
-                mUnfocusedCurveInterpolator.getArcLength();
-        return -deltaP;
-    }
-
-    /**
-     * This is the inverse of {@link #getDeltaPForY}.  Given a movement along the arc length
-     * of the curve, map back to the screen y.
-     */
-    public int getYForDeltaP(float downScrollP, float p) {
-        if (Recents.getConfiguration().isLowRamDevice) {
-            return mTaskStackLowRamLayoutAlgorithm.percentageToScroll(downScrollP - p);
-        }
-        int y = (int) ((p - downScrollP) * mStackRect.height() *
-                (1f / mUnfocusedCurveInterpolator.getArcLength()));
-        return -y;
-    }
-
-    /**
-     * Returns the task stack bounds in the current orientation.  This rect takes into account the
-     * top and right system insets (but not the bottom inset) and left/right paddings, but _not_
-     * the top/bottom padding or insets.
-     */
-    public void getTaskStackBounds(Rect displayRect, Rect windowRect, int topInset, int leftInset,
-            int rightInset, Rect taskStackBounds) {
-        taskStackBounds.set(windowRect.left + leftInset, windowRect.top + topInset,
-                windowRect.right - rightInset, windowRect.bottom);
-
-        // Ensure that the new width is at most the smaller display edge size
-        int sideMargin = getScaleForExtent(windowRect, displayRect, mBaseSideMargin, mMinMargin,
-                WIDTH);
-        int targetStackWidth = taskStackBounds.width() - 2 * sideMargin;
-        if (Utilities.getAppConfiguration(mContext).orientation
-                == Configuration.ORIENTATION_LANDSCAPE) {
-            // If we are in landscape, calculate the width of the stack in portrait and ensure that
-            // we are not larger than that size
-            Rect portraitDisplayRect = new Rect(0, 0,
-                    Math.min(displayRect.width(), displayRect.height()),
-                    Math.max(displayRect.width(), displayRect.height()));
-            int portraitSideMargin = getScaleForExtent(portraitDisplayRect, portraitDisplayRect,
-                    mBaseSideMargin, mMinMargin, WIDTH);
-            targetStackWidth = Math.min(targetStackWidth,
-                    portraitDisplayRect.width() - 2 * portraitSideMargin);
-        }
-        taskStackBounds.inset((taskStackBounds.width() - targetStackWidth) / 2, 0);
-    }
-
-    /**
-     * Retrieves resources that are constant regardless of the current configuration of the device.
-     */
-    public static int getDimensionForDevice(Context ctx, int phoneResId,
-            int tabletResId, int xlargeTabletResId, int gridLayoutResId) {
-        return getDimensionForDevice(ctx, phoneResId, phoneResId, tabletResId, tabletResId,
-                xlargeTabletResId, xlargeTabletResId, gridLayoutResId);
-    }
-
-    /**
-     * Retrieves resources that are constant regardless of the current configuration of the device.
-     */
-    public static int getDimensionForDevice(Context ctx, int phonePortResId, int phoneLandResId,
-            int tabletPortResId, int tabletLandResId, int xlargeTabletPortResId,
-            int xlargeTabletLandResId, int gridLayoutResId) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        Resources res = ctx.getResources();
-        boolean isLandscape = Utilities.getAppConfiguration(ctx).orientation ==
-                Configuration.ORIENTATION_LANDSCAPE;
-        if (config.isGridEnabled) {
-            return res.getDimensionPixelSize(gridLayoutResId);
-        } else if (config.isXLargeScreen) {
-            return res.getDimensionPixelSize(isLandscape
-                    ? xlargeTabletLandResId
-                    : xlargeTabletPortResId);
-        } else if (config.isLargeScreen) {
-            return res.getDimensionPixelSize(isLandscape
-                    ? tabletLandResId
-                    : tabletPortResId);
-        } else {
-            return res.getDimensionPixelSize(isLandscape
-                    ? phoneLandResId
-                    : phonePortResId);
-        }
-    }
-
-    /**
-     * Returns the normalized x on the unfocused curve given an absolute Y position (relative to the
-     * stack height).
-     */
-    private float getNormalizedXFromUnfocusedY(float y, @AnchorSide int fromSide) {
-        float offset = (fromSide == FROM_TOP)
-                ? mStackRect.height() - y
-                : y;
-        float offsetPct = offset / mStackRect.height();
-        return mUnfocusedCurveInterpolator.getX(offsetPct);
-    }
-
-    /**
-     * Returns the normalized x on the focused curve given an absolute Y position (relative to the
-     * stack height).
-     */
-    private float getNormalizedXFromFocusedY(float y, @AnchorSide int fromSide) {
-        float offset = (fromSide == FROM_TOP)
-                ? mStackRect.height() - y
-                : y;
-        float offsetPct = offset / mStackRect.height();
-        return mFocusedCurveInterpolator.getX(offsetPct);
-    }
-
-    /**
-     * Creates a new path for the focused curve.
-     */
-    private Path constructFocusedCurve() {
-        // Initialize the focused curve. This curve is a piecewise curve composed of several
-        // linear pieces that goes from (0,1) through (0.5, peek height offset),
-        // (0.5, bottom task offsets), and (1,0).
-        float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
-        float bottomPeekHeightPct = (float) (mStackBottomOffset + mFocusedBottomPeekHeight) /
-                mStackRect.height();
-        float minBottomPeekHeightPct = (float) (mFocusedTopPeekHeight + mTaskRect.height() -
-                mMinMargin) / mStackRect.height();
-        Path p = new Path();
-        p.moveTo(0f, 1f);
-        p.lineTo(0.5f, 1f - topPeekHeightPct);
-        p.lineTo(1f - (0.5f / mFocusedRange.relativeMax), Math.max(1f - minBottomPeekHeightPct,
-                bottomPeekHeightPct));
-        p.lineTo(1f, 0f);
-        return p;
-    }
-
-    /**
-     * Creates a new path for the unfocused curve.
-     */
-    private Path constructUnfocusedCurve() {
-        // Initialize the unfocused curve. This curve is a piecewise curve composed of two quadradic
-        // beziers that goes from (0,1) through (0.5, peek height offset) and ends at (1,0).  This
-        // ensures that we match the range, at which 0.5 represents the stack scroll at the current
-        // task progress.  Because the height offset can change depending on a resource, we compute
-        // the control point of the second bezier such that between it and a first known point,
-        // there is a tangent at (0.5, peek height offset).
-        float cpoint1X = 0.4f;
-        float cpoint1Y = 0.975f;
-        float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
-        float slope = ((1f - topPeekHeightPct) - cpoint1Y) / (0.5f - cpoint1X);
-        float b = 1f - slope * cpoint1X;
-        float cpoint2X = 0.65f;
-        float cpoint2Y = slope * cpoint2X + b;
-        Path p = new Path();
-        p.moveTo(0f, 1f);
-        p.cubicTo(0f, 1f, cpoint1X, cpoint1Y, 0.5f, 1f - topPeekHeightPct);
-        p.cubicTo(0.5f, 1f - topPeekHeightPct, cpoint2X, cpoint2Y, 1f, 0f);
-        return p;
-    }
-
-    /**
-     * Creates a new path for the focused dim curve.
-     */
-    private Path constructFocusedDimCurve() {
-        Path p = new Path();
-        // The focused dim interpolator starts at max dim, reduces to zero at 0.5 (the focused
-        // task), then goes back to max dim at the next task
-        p.moveTo(0f, MAX_DIM);
-        p.lineTo(0.5f, 0f);
-        p.lineTo(0.5f + (0.5f / mFocusedRange.relativeMax), MAX_DIM);
-        p.lineTo(1f, MAX_DIM);
-        return p;
-    }
-
-    /**
-     * Creates a new path for the unfocused dim curve.
-     */
-    private Path constructUnfocusedDimCurve() {
-        float focusX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
-        float cpoint2X = focusX + (1f - focusX) / 2;
-        Path p = new Path();
-        // The unfocused dim interpolator starts at max dim, reduces to zero at 0.5 (the focused
-        // task), then goes back to max dim towards the front of the stack
-        p.moveTo(0f, MAX_DIM);
-        p.cubicTo(focusX * 0.5f, MAX_DIM, focusX * 0.75f, MAX_DIM * 0.75f, focusX, 0f);
-        p.cubicTo(cpoint2X, 0f, cpoint2X, MED_DIM, 1f, MED_DIM);
-        return p;
-    }
-
-    /**
-     * Scales the given {@param value} to the scale of the {@param instance} rect relative to the
-     * {@param other} rect in the {@param extent} side.
-     */
-    private int getScaleForExtent(Rect instance, Rect other, int value, int minValue,
-                                  @Extent int extent) {
-        if (extent == WIDTH) {
-            float scale = Utilities.clamp01((float) instance.width() / other.width());
-            return Math.max(minValue, (int) (scale * value));
-        } else if (extent == HEIGHT) {
-            float scale = Utilities.clamp01((float) instance.height() / other.height());
-            return Math.max(minValue, (int) (scale * value));
-        }
-        return value;
-    }
-
-    /**
-     * Updates the current transforms that would put a TaskView at the front and back of the stack.
-     */
-    private void updateFrontBackTransforms() {
-        // Return early if we have not yet initialized
-        if (mStackRect.isEmpty()) {
-            return;
-        }
-        if (Recents.getConfiguration().isLowRamDevice) {
-            mTaskStackLowRamLayoutAlgorithm.getBackOfStackTransform(mBackOfStackTransform, this);
-            mTaskStackLowRamLayoutAlgorithm.getFrontOfStackTransform(mFrontOfStackTransform, this);
-            return;
-        }
-
-        float min = Utilities.mapRange(mFocusState, mUnfocusedRange.relativeMin,
-                mFocusedRange.relativeMin);
-        float max = Utilities.mapRange(mFocusState, mUnfocusedRange.relativeMax,
-                mFocusedRange.relativeMax);
-        getStackTransform(min, min, 0f, mFocusState, mBackOfStackTransform, null,
-                true /* ignoreSingleTaskCase */, true /* forceUpdate */);
-        getStackTransform(max, max, 0f, mFocusState, mFrontOfStackTransform, null,
-                true /* ignoreSingleTaskCase */, true /* forceUpdate */);
-        mBackOfStackTransform.visible = true;
-        mFrontOfStackTransform.visible = true;
-    }
-
-    /**
-     * Returns the proper task rectangle according to the current grid state.
-     */
-    public Rect getTaskRect() {
-        if (Recents.getConfiguration().isLowRamDevice) {
-            return mTaskStackLowRamLayoutAlgorithm.getTaskRect();
-        }
-        return useGridLayout() ? mTaskGridLayoutAlgorithm.getTaskGridRect() : mTaskRect;
-    }
-
-    public void dump(String prefix, PrintWriter writer) {
-        String innerPrefix = prefix + "  ";
-
-        writer.print(prefix); writer.print(TAG);
-        writer.write(" numStackTasks="); writer.print(mNumStackTasks);
-        writer.println();
-
-        writer.print(innerPrefix);
-        writer.print("insets="); writer.print(Utilities.dumpRect(mSystemInsets));
-        writer.print(" stack="); writer.print(Utilities.dumpRect(mStackRect));
-        writer.print(" task="); writer.print(Utilities.dumpRect(mTaskRect));
-        writer.print(" actionButton="); writer.print(Utilities.dumpRect(mStackActionButtonRect));
-        writer.println();
-
-        writer.print(innerPrefix);
-        writer.print("minScroll="); writer.print(mMinScrollP);
-        writer.print(" maxScroll="); writer.print(mMaxScrollP);
-        writer.print(" initialScroll="); writer.print(mInitialScrollP);
-        writer.println();
-
-        writer.print(innerPrefix);
-        writer.print("focusState="); writer.print(mFocusState);
-        writer.println();
-
-        if (mTaskIndexOverrideMap.size() > 0) {
-            for (int i = mTaskIndexOverrideMap.size() - 1; i >= 0; i--) {
-                int taskId = mTaskIndexOverrideMap.keyAt(i);
-                float x = mTaskIndexMap.get(taskId);
-                float overrideX = mTaskIndexOverrideMap.get(taskId, 0f);
-
-                writer.print(innerPrefix);
-                writer.print("taskId= "); writer.print(taskId);
-                writer.print(" x= "); writer.print(x);
-                writer.print(" overrideX= "); writer.print(overrideX);
-                writer.println();
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
deleted file mode 100644
index 89288d8..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ /dev/null
@@ -1,2286 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.IntDef;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.MutableBoolean;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewDebug;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.FrameLayout;
-import android.widget.ScrollView;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivity;
-import com.android.systemui.recents.RecentsActivityLaunchState;
-import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.RecentsDebugFlags;
-import com.android.systemui.recents.RecentsImpl;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
-import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
-import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
-import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.HideRecentsEvent;
-import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
-import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
-import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskEvent;
-import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
-import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
-import com.android.systemui.recents.events.activity.PackagesChangedEvent;
-import com.android.systemui.recents.events.activity.ShowEmptyViewEvent;
-import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
-import com.android.systemui.recents.events.component.ActivityPinnedEvent;
-import com.android.systemui.recents.events.component.ExpandPipEvent;
-import com.android.systemui.recents.events.component.HidePipMenuEvent;
-import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
-import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
-import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
-import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
-import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
-import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
-import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
-import com.android.systemui.recents.events.ui.UserInteractionEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
-import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
-import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
-import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
-import com.android.systemui.recents.misc.DozeTrigger;
-import com.android.systemui.recents.misc.ReferenceCountedTrigger;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.recents.views.grid.GridTaskView;
-import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
-import com.android.systemui.recents.views.grid.TaskViewFocusFrame;
-
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/* The visual representation of a task stack view */
-public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks,
-        TaskView.TaskViewCallbacks, TaskStackViewScroller.TaskStackViewScrollerCallbacks,
-        TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks,
-        ViewPool.ViewPoolConsumer<TaskView, Task> {
-
-    private static final String TAG = "TaskStackView";
-
-    // The thresholds at which to show/hide the stack action button.
-    private static final float SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f;
-    private static final float HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f;
-
-    public static final int DEFAULT_SYNC_STACK_DURATION = 200;
-    public static final int SLOW_SYNC_STACK_DURATION = 250;
-    private static final int DRAG_SCALE_DURATION = 175;
-    static final float DRAG_SCALE_FACTOR = 1.05f;
-
-    private static final int LAUNCH_NEXT_SCROLL_BASE_DURATION = 216;
-    private static final int LAUNCH_NEXT_SCROLL_INCR_DURATION = 32;
-
-    // The actions to perform when resetting to initial state,
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({INITIAL_STATE_UPDATE_NONE, INITIAL_STATE_UPDATE_ALL, INITIAL_STATE_UPDATE_LAYOUT_ONLY})
-    public @interface InitialStateAction {}
-    /** Do not update the stack and layout to the initial state. */
-    private static final int INITIAL_STATE_UPDATE_NONE = 0;
-    /** Update both the stack and layout to the initial state. */
-    private static final int INITIAL_STATE_UPDATE_ALL = 1;
-    /** Update only the layout to the initial state. */
-    private static final int INITIAL_STATE_UPDATE_LAYOUT_ONLY = 2;
-
-    private LayoutInflater mInflater;
-    private TaskStack mStack = new TaskStack();
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
-    TaskStackLayoutAlgorithm mLayoutAlgorithm;
-    // The stable layout algorithm is only used to calculate the task rect with the stable bounds
-    private TaskStackLayoutAlgorithm mStableLayoutAlgorithm;
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_")
-    private TaskStackViewScroller mStackScroller;
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
-    private TaskStackViewTouchHandler mTouchHandler;
-    private TaskStackAnimationHelper mAnimationHelper;
-    private ViewPool<TaskView, Task> mViewPool;
-
-    private ArrayList<TaskView> mTaskViews = new ArrayList<>();
-    private ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
-    private ArraySet<Task.TaskKey> mIgnoreTasks = new ArraySet<>();
-    private AnimationProps mDeferredTaskViewLayoutAnimation = null;
-
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="doze_")
-    private DozeTrigger mUIDozeTrigger;
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="focused_task_")
-    private Task mFocusedTask;
-
-    private int mTaskCornerRadiusPx;
-    private int mDividerSize;
-    private int mStartTimerIndicatorDuration;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mTaskViewsClipDirty = true;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mEnterAnimationComplete = false;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mStackReloaded = false;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mFinishedLayoutAfterStackReload = false;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mLaunchNextAfterFirstMeasure = false;
-    @ViewDebug.ExportedProperty(category="recents")
-    @InitialStateAction
-    private int mInitialState = INITIAL_STATE_UPDATE_ALL;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mInMeasureLayout = false;
-    @ViewDebug.ExportedProperty(category="recents")
-    boolean mTouchExplorationEnabled;
-    @ViewDebug.ExportedProperty(category="recents")
-    boolean mScreenPinningEnabled;
-
-    // The stable stack bounds are the full bounds that we were measured with from RecentsView
-    @ViewDebug.ExportedProperty(category="recents")
-    private Rect mStableStackBounds = new Rect();
-    // The current stack bounds are dynamic and may change as the user drags and drops
-    @ViewDebug.ExportedProperty(category="recents")
-    private Rect mStackBounds = new Rect();
-    // The current window bounds at the point we were measured
-    @ViewDebug.ExportedProperty(category="recents")
-    private Rect mStableWindowRect = new Rect();
-    // The current window bounds are dynamic and may change as the user drags and drops
-    @ViewDebug.ExportedProperty(category="recents")
-    private Rect mWindowRect = new Rect();
-    // The current display bounds
-    @ViewDebug.ExportedProperty(category="recents")
-    private Rect mDisplayRect = new Rect();
-    // The current display orientation
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mDisplayOrientation = Configuration.ORIENTATION_UNDEFINED;
-
-    private Rect mTmpRect = new Rect();
-    private ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
-    private List<TaskView> mTmpTaskViews = new ArrayList<>();
-    private TaskViewTransform mTmpTransform = new TaskViewTransform();
-    private int[] mTmpIntPair = new int[2];
-    private boolean mResetToInitialStateWhenResized;
-    private int mLastWidth;
-    private int mLastHeight;
-    private boolean mStackActionButtonVisible;
-
-    // Percentage of last ScrollP from the min to max scrollP that lives after configuration changes
-    private float mLastScrollPPercent = -1;
-
-    // We keep track of the task view focused by user interaction and draw a frame around it in the
-    // grid layout.
-    private TaskViewFocusFrame mTaskViewFocusFrame;
-
-    private Task mPrefetchingTask;
-    private final float mFastFlingVelocity;
-
-    // A convenience update listener to request updating clipping of tasks
-    private ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener =
-            new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    if (!mTaskViewsClipDirty) {
-                        mTaskViewsClipDirty = true;
-                        invalidate();
-                    }
-                }
-            };
-
-    private DropTarget mStackDropTarget = new DropTarget() {
-        @Override
-        public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
-                boolean isCurrentTarget) {
-            // This drop target has a fixed bounds and should be checked last, so just fall through
-            // if it is the current target
-            if (!isCurrentTarget) {
-                return mLayoutAlgorithm.mStackRect.contains(x, y);
-            }
-            return false;
-        }
-    };
-
-    public TaskStackView(Context context) {
-        super(context);
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        Resources res = context.getResources();
-
-        // Set the stack first
-        mStack.setCallbacks(this);
-        mViewPool = new ViewPool<>(context, this);
-        mInflater = LayoutInflater.from(context);
-        mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
-        mStableLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null);
-        mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
-        mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
-        mAnimationHelper = new TaskStackAnimationHelper(context, this);
-        mTaskCornerRadiusPx = Recents.getConfiguration().isGridEnabled ?
-                res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) :
-                res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
-        mFastFlingVelocity = res.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
-        mDividerSize = ssp.getDockedDividerSize(context);
-        mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
-        mDisplayRect = ssp.getDisplayRect();
-        mStackActionButtonVisible = false;
-
-        // Create a frame to draw around the focused task view
-        if (Recents.getConfiguration().isGridEnabled) {
-            mTaskViewFocusFrame = new TaskViewFocusFrame(mContext, this,
-                mLayoutAlgorithm.mTaskGridLayoutAlgorithm);
-            addView(mTaskViewFocusFrame);
-            getViewTreeObserver().addOnGlobalFocusChangeListener(mTaskViewFocusFrame);
-        }
-
-        int taskBarDismissDozeDelaySeconds = getResources().getInteger(
-                R.integer.recents_task_bar_dismiss_delay_seconds);
-        mUIDozeTrigger = new DozeTrigger(taskBarDismissDozeDelaySeconds, new Runnable() {
-            @Override
-            public void run() {
-                // Show the task bar dismiss buttons
-                List<TaskView> taskViews = getTaskViews();
-                int taskViewCount = taskViews.size();
-                for (int i = 0; i < taskViewCount; i++) {
-                    TaskView tv = taskViews.get(i);
-                    tv.startNoUserInteractionAnimation();
-                }
-            }
-        });
-        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
-        super.onAttachedToWindow();
-        readSystemFlags();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        EventBus.getDefault().unregister(this);
-    }
-
-    /**
-     * Called from RecentsActivity when it is relaunched.
-     */
-    void onReload(boolean isResumingFromVisible) {
-        if (!isResumingFromVisible) {
-            // Reset the focused task
-            resetFocusedTask(getFocusedTask());
-        }
-
-        // Reset the state of each of the task views
-        List<TaskView> taskViews = new ArrayList<>();
-        taskViews.addAll(getTaskViews());
-        taskViews.addAll(mViewPool.getViews());
-        for (int i = taskViews.size() - 1; i >= 0; i--) {
-            taskViews.get(i).onReload(isResumingFromVisible);
-        }
-
-        // Reset the stack state
-        readSystemFlags();
-        mTaskViewsClipDirty = true;
-        mUIDozeTrigger.stopDozing();
-        if (!isResumingFromVisible) {
-            mStackScroller.reset();
-            mStableLayoutAlgorithm.reset();
-            mLayoutAlgorithm.reset();
-            mLastScrollPPercent = -1;
-        }
-
-        // Since we always animate to the same place in (the initial state), always reset the stack
-        // to the initial state when resuming
-        mStackReloaded = true;
-        mFinishedLayoutAfterStackReload = false;
-        mLaunchNextAfterFirstMeasure = false;
-        mInitialState = INITIAL_STATE_UPDATE_ALL;
-        requestLayout();
-    }
-
-    /**
-     * Sets the stack tasks of this TaskStackView from the given TaskStack.
-     */
-    public void setTasks(TaskStack stack, boolean allowNotifyStackChanges) {
-        boolean isInitialized = mLayoutAlgorithm.isInitialized();
-
-        // Only notify if we are already initialized, otherwise, everything will pick up all the
-        // new and old tasks when we next layout
-        mStack.setTasks(stack, allowNotifyStackChanges && isInitialized);
-    }
-
-    /** Returns the task stack. */
-    public TaskStack getStack() {
-        return mStack;
-    }
-
-    /**
-     * Updates this TaskStackView to the initial state.
-     */
-    public void updateToInitialState() {
-        mStackScroller.setStackScrollToInitialState();
-        mLayoutAlgorithm.setTaskOverridesForInitialState(mStack, false /* ignoreScrollToFront */);
-    }
-
-    /** Updates the list of task views */
-    void updateTaskViewsList() {
-        mTaskViews.clear();
-        int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View v = getChildAt(i);
-            if (v instanceof TaskView) {
-                mTaskViews.add((TaskView) v);
-            }
-        }
-    }
-
-    /** Gets the list of task views */
-    List<TaskView> getTaskViews() {
-        return mTaskViews;
-    }
-
-    /**
-     * Returns the front most task view.
-     */
-    private TaskView getFrontMostTaskView() {
-        List<TaskView> taskViews = getTaskViews();
-        if (taskViews.isEmpty()) {
-            return null;
-        }
-        return taskViews.get(taskViews.size() - 1);
-    }
-
-    /**
-     * Finds the child view given a specific {@param task}.
-     */
-    public TaskView getChildViewForTask(Task t) {
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            if (tv.getTask() == t) {
-                return tv;
-            }
-        }
-        return null;
-    }
-
-    /** Returns the stack algorithm for this task stack. */
-    public TaskStackLayoutAlgorithm getStackAlgorithm() {
-        return mLayoutAlgorithm;
-    }
-
-    /** Returns the grid algorithm for this task stack. */
-    public TaskGridLayoutAlgorithm getGridAlgorithm() {
-        return mLayoutAlgorithm.mTaskGridLayoutAlgorithm;
-    }
-
-    /**
-     * Returns the touch handler for this task stack.
-     */
-    public TaskStackViewTouchHandler getTouchHandler() {
-        return mTouchHandler;
-    }
-
-    /**
-     * Adds a task to the ignored set.
-     */
-    void addIgnoreTask(Task task) {
-        mIgnoreTasks.add(task.key);
-    }
-
-    /**
-     * Removes a task from the ignored set.
-     */
-    void removeIgnoreTask(Task task) {
-        mIgnoreTasks.remove(task.key);
-    }
-
-    /**
-     * Returns whether the specified {@param task} is ignored.
-     */
-    boolean isIgnoredTask(Task task) {
-        return mIgnoreTasks.contains(task.key);
-    }
-
-    /**
-     * Computes the task transforms at the current stack scroll for all visible tasks. If a valid
-     * target stack scroll is provided (ie. is different than {@param curStackScroll}), then the
-     * visible range includes all tasks at the target stack scroll. This is useful for ensure that
-     * all views necessary for a transition or animation will be visible at the start.
-     *
-     * @param taskTransforms The set of task view transforms to reuse, this list will be sized to
-     *                       match the size of {@param tasks}
-     * @param tasks The set of tasks for which to generate transforms
-     * @param curStackScroll The current stack scroll
-     * @param targetStackScroll The stack scroll that we anticipate we are going to be scrolling to.
-     *                          The range of the union of the visible views at the current and
-     *                          target stack scrolls will be returned.
-     * @param ignoreTasksSet The set of tasks to skip for purposes of calculaing the visible range.
-     *                       Transforms will still be calculated for the ignore tasks.
-     * @return the front and back most visible task indices (there may be non visible tasks in
-     *         between this range)
-     */
-    int[] computeVisibleTaskTransforms(ArrayList<TaskViewTransform> taskTransforms,
-            ArrayList<Task> tasks, float curStackScroll, float targetStackScroll,
-            ArraySet<Task.TaskKey> ignoreTasksSet, boolean ignoreTaskOverrides) {
-        int taskCount = tasks.size();
-        int[] visibleTaskRange = mTmpIntPair;
-        visibleTaskRange[0] = -1;
-        visibleTaskRange[1] = -1;
-        boolean useTargetStackScroll = Float.compare(curStackScroll, targetStackScroll) != 0;
-
-        // We can reuse the task transforms where possible to reduce object allocation
-        matchTaskListSize(tasks, taskTransforms);
-
-        // Update the stack transforms
-        TaskViewTransform frontTransform = null;
-        TaskViewTransform frontTransformAtTarget = null;
-        TaskViewTransform transform = null;
-        TaskViewTransform transformAtTarget = null;
-        for (int i = taskCount - 1; i >= 0; i--) {
-            Task task = tasks.get(i);
-
-            // Calculate the current and (if necessary) the target transform for the task
-            transform = mLayoutAlgorithm.getStackTransform(task, curStackScroll,
-                    taskTransforms.get(i), frontTransform, ignoreTaskOverrides);
-            if (useTargetStackScroll && !transform.visible) {
-                // If we have a target stack scroll and the task is not currently visible, then we
-                // just update the transform at the new scroll
-                // TODO: Optimize this
-                transformAtTarget = mLayoutAlgorithm.getStackTransform(task, targetStackScroll,
-                    new TaskViewTransform(), frontTransformAtTarget);
-                if (transformAtTarget.visible) {
-                    transform.copyFrom(transformAtTarget);
-                }
-            }
-
-            // For ignore tasks, only calculate the stack transform and skip the calculation of the
-            // visible stack indices
-            if (ignoreTasksSet.contains(task.key)) {
-                continue;
-            }
-
-            frontTransform = transform;
-            frontTransformAtTarget = transformAtTarget;
-            if (transform.visible) {
-                if (visibleTaskRange[0] < 0) {
-                    visibleTaskRange[0] = i;
-                }
-                visibleTaskRange[1] = i;
-            }
-        }
-        return visibleTaskRange;
-    }
-
-    /**
-     * Binds the visible {@link TaskView}s at the given target scroll.
-     */
-    void bindVisibleTaskViews(float targetStackScroll) {
-        bindVisibleTaskViews(targetStackScroll, false /* ignoreTaskOverrides */);
-    }
-
-    /**
-     * Synchronizes the set of children {@link TaskView}s to match the visible set of tasks in the
-     * current {@link TaskStack}. This call does not continue on to update their position to the
-     * computed {@link TaskViewTransform}s of the visible range, but only ensures that they will
-     * be added/removed from the view hierarchy and placed in the correct Z order and initial
-     * position (if not currently on screen).
-     *
-     * @param targetStackScroll If provided, will ensure that the set of visible {@link TaskView}s
-     *                          includes those visible at the current stack scroll, and all at the
-     *                          target stack scroll.
-     * @param ignoreTaskOverrides If set, the visible task computation will get the transforms for
-     *                            tasks at their non-overridden task progress
-     */
-    void bindVisibleTaskViews(float targetStackScroll, boolean ignoreTaskOverrides) {
-        // Get all the task transforms
-        ArrayList<Task> tasks = mStack.getTasks();
-        int[] visibleTaskRange = computeVisibleTaskTransforms(mCurrentTaskTransforms, tasks,
-                mStackScroller.getStackScroll(), targetStackScroll, mIgnoreTasks,
-                ignoreTaskOverrides);
-
-        // Return all the invisible children to the pool
-        mTmpTaskViewMap.clear();
-        List<TaskView> taskViews = getTaskViews();
-        int lastFocusedTaskIndex = -1;
-        int taskViewCount = taskViews.size();
-        for (int i = taskViewCount - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            // Skip ignored tasks
-            if (mIgnoreTasks.contains(task.key)) {
-                continue;
-            }
-
-            // It is possible for the set of lingering TaskViews to differ from the stack if the
-            // stack was updated before the relayout.  If the task view is no longer in the stack,
-            // then just return it back to the view pool.
-            int taskIndex = mStack.indexOfTask(task);
-            TaskViewTransform transform = null;
-            if (taskIndex != -1) {
-                transform = mCurrentTaskTransforms.get(taskIndex);
-            }
-
-            if (transform != null && transform.visible) {
-                mTmpTaskViewMap.put(task.key, tv);
-            } else {
-                if (mTouchExplorationEnabled && Utilities.isDescendentAccessibilityFocused(tv)) {
-                    lastFocusedTaskIndex = taskIndex;
-                    resetFocusedTask(task);
-                }
-                mViewPool.returnViewToPool(tv);
-            }
-        }
-
-        // Pick up all the newly visible children
-        for (int i = tasks.size() - 1; i >= 0; i--) {
-            Task task = tasks.get(i);
-            TaskViewTransform transform = mCurrentTaskTransforms.get(i);
-
-            // Skip ignored tasks
-            if (mIgnoreTasks.contains(task.key)) {
-                continue;
-            }
-
-            // Skip the invisible stack tasks
-            if (!transform.visible) {
-                continue;
-            }
-
-            TaskView tv = mTmpTaskViewMap.get(task.key);
-            if (tv == null) {
-                tv = mViewPool.pickUpViewFromPool(task, task);
-                if (transform.rect.top <= mLayoutAlgorithm.mStackRect.top) {
-                    updateTaskViewToTransform(tv, mLayoutAlgorithm.getBackOfStackTransform(),
-                            AnimationProps.IMMEDIATE);
-                } else {
-                    updateTaskViewToTransform(tv, mLayoutAlgorithm.getFrontOfStackTransform(),
-                            AnimationProps.IMMEDIATE);
-                }
-            } else {
-                // Reattach it in the right z order
-                final int taskIndex = mStack.indexOfTask(task);
-                final int insertIndex = findTaskViewInsertIndex(task, taskIndex);
-                if (insertIndex != getTaskViews().indexOf(tv)){
-                    detachViewFromParent(tv);
-                    attachViewToParent(tv, insertIndex, tv.getLayoutParams());
-                    updateTaskViewsList();
-                }
-            }
-        }
-
-        updatePrefetchingTask(tasks, visibleTaskRange[0], visibleTaskRange[1]);
-
-        // Update the focus if the previous focused task was returned to the view pool
-        if (lastFocusedTaskIndex != -1) {
-            int newFocusedTaskIndex = (lastFocusedTaskIndex < visibleTaskRange[1])
-                    ? visibleTaskRange[1]
-                    : visibleTaskRange[0];
-            setFocusedTask(newFocusedTaskIndex, false /* scrollToTask */,
-                    true /* requestViewFocus */);
-            TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
-            if (focusedTaskView != null) {
-                focusedTaskView.requestAccessibilityFocus();
-            }
-        }
-    }
-
-    /**
-     * @see #relayoutTaskViews(AnimationProps, ArrayMap<Task, AnimationProps>, boolean)
-     */
-    public void relayoutTaskViews(AnimationProps animation) {
-        relayoutTaskViews(animation, null /* animationOverrides */,
-                false /* ignoreTaskOverrides */);
-    }
-
-    /**
-     * Relayout the the visible {@link TaskView}s to their current transforms as specified by the
-     * {@link TaskStackLayoutAlgorithm} with the given {@param animation}. This call cancels any
-     * animations that are current running on those task views, and will ensure that the children
-     * {@link TaskView}s will match the set of visible tasks in the stack.  If a {@link Task} has
-     * an animation provided in {@param animationOverrides}, that will be used instead.
-     */
-    private void relayoutTaskViews(AnimationProps animation,
-            ArrayMap<Task, AnimationProps> animationOverrides, boolean ignoreTaskOverrides) {
-        // If we had a deferred animation, cancel that
-        cancelDeferredTaskViewLayoutAnimation();
-
-        // Synchronize the current set of TaskViews
-        bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTaskOverrides);
-
-        // Animate them to their final transforms with the given animation
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            if (mIgnoreTasks.contains(task.key)) {
-                continue;
-            }
-
-            int taskIndex = mStack.indexOfTask(task);
-            TaskViewTransform transform = mCurrentTaskTransforms.get(taskIndex);
-            if (animationOverrides != null && animationOverrides.containsKey(task)) {
-                animation = animationOverrides.get(task);
-            }
-
-            updateTaskViewToTransform(tv, transform, animation);
-        }
-    }
-
-    /**
-     * Posts an update to synchronize the {@link TaskView}s with the stack on the next frame.
-     */
-    void relayoutTaskViewsOnNextFrame(AnimationProps animation) {
-        mDeferredTaskViewLayoutAnimation = animation;
-        invalidate();
-    }
-
-    /**
-     * Called to update a specific {@link TaskView} to a given {@link TaskViewTransform} with a
-     * given set of {@link AnimationProps} properties.
-     */
-    public void updateTaskViewToTransform(TaskView taskView, TaskViewTransform transform,
-            AnimationProps animation) {
-        if (taskView.isAnimatingTo(transform)) {
-            return;
-        }
-        taskView.cancelTransformAnimation();
-        taskView.updateViewPropertiesToTaskTransform(transform, animation,
-                mRequestUpdateClippingListener);
-    }
-
-    /**
-     * Returns the current task transforms of all tasks, falling back to the stack layout if there
-     * is no {@link TaskView} for the task.
-     */
-    public void getCurrentTaskTransforms(ArrayList<Task> tasks,
-            ArrayList<TaskViewTransform> transformsOut) {
-        matchTaskListSize(tasks, transformsOut);
-        int focusState = mLayoutAlgorithm.getFocusState();
-        for (int i = tasks.size() - 1; i >= 0; i--) {
-            Task task = tasks.get(i);
-            TaskViewTransform transform = transformsOut.get(i);
-            TaskView tv = getChildViewForTask(task);
-            if (tv != null) {
-                transform.fillIn(tv);
-            } else {
-                mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(),
-                        focusState, transform, null, true /* forceUpdate */,
-                        false /* ignoreTaskOverrides */);
-            }
-            transform.visible = true;
-        }
-    }
-
-    /**
-     * Returns the task transforms for all the tasks in the stack if the stack was at the given
-     * {@param stackScroll} and {@param focusState}.
-     */
-    public void getLayoutTaskTransforms(float stackScroll, int focusState, ArrayList<Task> tasks,
-            boolean ignoreTaskOverrides, ArrayList<TaskViewTransform> transformsOut) {
-        matchTaskListSize(tasks, transformsOut);
-        for (int i = tasks.size() - 1; i >= 0; i--) {
-            Task task = tasks.get(i);
-            TaskViewTransform transform = transformsOut.get(i);
-            mLayoutAlgorithm.getStackTransform(task, stackScroll, focusState, transform, null,
-                    true /* forceUpdate */, ignoreTaskOverrides);
-            transform.visible = true;
-        }
-    }
-
-    /**
-     * Cancels the next deferred task view layout.
-     */
-    void cancelDeferredTaskViewLayoutAnimation() {
-        mDeferredTaskViewLayoutAnimation = null;
-    }
-
-    /**
-     * Cancels all {@link TaskView} animations.
-     */
-    void cancelAllTaskViewAnimations() {
-        List<TaskView> taskViews = getTaskViews();
-        for (int i = taskViews.size() - 1; i >= 0; i--) {
-            final TaskView tv = taskViews.get(i);
-            if (!mIgnoreTasks.contains(tv.getTask().key)) {
-                tv.cancelTransformAnimation();
-            }
-        }
-    }
-
-    /**
-     * Updates the clip for each of the task views from back to front.
-     */
-    private void clipTaskViews() {
-        // We never clip task views in grid layout
-        if (Recents.getConfiguration().isGridEnabled) {
-            return;
-        }
-
-        // Update the clip on each task child
-        List<TaskView> taskViews = getTaskViews();
-        TaskView tmpTv = null;
-        TaskView prevVisibleTv = null;
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            TaskView frontTv = null;
-            int clipBottom = 0;
-
-            if (isIgnoredTask(tv.getTask())) {
-                // For each of the ignore tasks, update the translationZ of its TaskView to be
-                // between the translationZ of the tasks immediately underneath it
-                if (prevVisibleTv != null) {
-                    tv.setTranslationZ(Math.max(tv.getTranslationZ(),
-                            prevVisibleTv.getTranslationZ() + 0.1f));
-                }
-            }
-
-            if (i < (taskViewCount - 1) && tv.shouldClipViewInStack()) {
-                // Find the next view to clip against
-                for (int j = i + 1; j < taskViewCount; j++) {
-                    tmpTv = taskViews.get(j);
-
-                    if (tmpTv.shouldClipViewInStack()) {
-                        frontTv = tmpTv;
-                        break;
-                    }
-                }
-
-                // Clip against the next view, this is just an approximation since we are
-                // stacked and we can make assumptions about the visibility of the this
-                // task relative to the ones in front of it.
-                if (frontTv != null) {
-                    float taskBottom = tv.getBottom();
-                    float frontTaskTop = frontTv.getTop();
-                    if (frontTaskTop < taskBottom) {
-                        // Map the stack view space coordinate (the rects) to view space
-                        clipBottom = (int) (taskBottom - frontTaskTop) - mTaskCornerRadiusPx;
-                    }
-                }
-            }
-            tv.getViewBounds().setClipBottom(clipBottom);
-            tv.mThumbnailView.updateThumbnailVisibility(clipBottom - tv.getPaddingBottom());
-            prevVisibleTv = tv;
-        }
-        mTaskViewsClipDirty = false;
-    }
-
-    public void updateLayoutAlgorithm(boolean boundScrollToNewMinMax) {
-        updateLayoutAlgorithm(boundScrollToNewMinMax, Recents.getConfiguration().getLaunchState());
-    }
-
-    /**
-     * Updates the layout algorithm min and max virtual scroll bounds.
-     */
-   public void updateLayoutAlgorithm(boolean boundScrollToNewMinMax,
-           RecentsActivityLaunchState launchState) {
-        // Compute the min and max scroll values
-        mLayoutAlgorithm.update(mStack, mIgnoreTasks, launchState, mLastScrollPPercent);
-
-        if (boundScrollToNewMinMax) {
-            mStackScroller.boundScroll();
-        }
-    }
-
-    /**
-     * Updates the stack layout to its stable places.
-     */
-    private void updateLayoutToStableBounds() {
-        mWindowRect.set(mStableWindowRect);
-        mStackBounds.set(mStableStackBounds);
-        mLayoutAlgorithm.setSystemInsets(mStableLayoutAlgorithm.mSystemInsets);
-        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
-        updateLayoutAlgorithm(true /* boundScroll */);
-    }
-
-    /** Returns the scroller. */
-    public TaskStackViewScroller getScroller() {
-        return mStackScroller;
-    }
-
-    /**
-     * Sets the focused task to the provided (bounded taskIndex).
-     *
-     * @return whether or not the stack will scroll as a part of this focus change
-     */
-    public boolean setFocusedTask(int taskIndex, boolean scrollToTask,
-            final boolean requestViewFocus) {
-        return setFocusedTask(taskIndex, scrollToTask, requestViewFocus, 0);
-    }
-
-    /**
-     * Sets the focused task to the provided (bounded focusTaskIndex).
-     *
-     * @return whether or not the stack will scroll as a part of this focus change
-     */
-    public boolean setFocusedTask(int focusTaskIndex, boolean scrollToTask,
-            boolean requestViewFocus, int timerIndicatorDuration) {
-        // Find the next task to focus
-        int newFocusedTaskIndex = mStack.getTaskCount() > 0 ?
-                Utilities.clamp(focusTaskIndex, 0, mStack.getTaskCount() - 1) : -1;
-        final Task newFocusedTask = (newFocusedTaskIndex != -1) ?
-                mStack.getTasks().get(newFocusedTaskIndex) : null;
-
-        // Reset the last focused task state if changed
-        if (mFocusedTask != null) {
-            // Cancel the timer indicator, if applicable
-            if (timerIndicatorDuration > 0) {
-                final TaskView tv = getChildViewForTask(mFocusedTask);
-                if (tv != null) {
-                    tv.getHeaderView().cancelFocusTimerIndicator();
-                }
-            }
-
-            resetFocusedTask(mFocusedTask);
-        }
-
-        boolean willScroll = false;
-        mFocusedTask = newFocusedTask;
-
-        if (newFocusedTask != null) {
-            // Start the timer indicator, if applicable
-            if (timerIndicatorDuration > 0) {
-                final TaskView tv = getChildViewForTask(mFocusedTask);
-                if (tv != null) {
-                    tv.getHeaderView().startFocusTimerIndicator(timerIndicatorDuration);
-                } else {
-                    // The view is null; set a flag for later
-                    mStartTimerIndicatorDuration = timerIndicatorDuration;
-                }
-            }
-
-            if (scrollToTask) {
-                // Cancel any running enter animations at this point when we scroll or change focus
-                if (!mEnterAnimationComplete) {
-                    cancelAllTaskViewAnimations();
-                }
-
-                mLayoutAlgorithm.clearUnfocusedTaskOverrides();
-                willScroll = mAnimationHelper.startScrollToFocusedTaskAnimation(newFocusedTask,
-                        requestViewFocus);
-                if (willScroll) {
-                    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
-                }
-            } else {
-                // Focus the task view
-                TaskView newFocusedTaskView = getChildViewForTask(newFocusedTask);
-                if (newFocusedTaskView != null) {
-                    newFocusedTaskView.setFocusedState(true, requestViewFocus);
-                }
-            }
-            // Any time a task view gets the focus, we move the focus frame around it.
-            if (mTaskViewFocusFrame != null) {
-                mTaskViewFocusFrame.moveGridTaskViewFocus(getChildViewForTask(newFocusedTask));
-            }
-        }
-        return willScroll;
-    }
-
-    /**
-     * Sets the focused task relative to the currently focused task.
-     *
-     * @param forward whether to go to the next task in the stack (along the curve) or the previous
-     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
-     *                       if the currently focused task is not a stack task, will set the focus
-     *                       to the first visible stack task
-     * @param animated determines whether to actually draw the highlight along with the change in
-     *                            focus.
-     */
-    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated) {
-        setRelativeFocusedTask(forward, stackTasksOnly, animated, false, 0);
-    }
-
-    /**
-     * Sets the focused task relative to the currently focused task.
-     *
-     * @param forward whether to go to the next task in the stack (along the curve) or the previous
-     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
-     *                       if the currently focused task is not a stack task, will set the focus
-     *                       to the first visible stack task
-     * @param animated determines whether to actually draw the highlight along with the change in
-     *                            focus.
-     * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scroll
-     *                               happens.
-     * @param timerIndicatorDuration the duration to initialize the auto-advance timer indicator
-     */
-    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
-                                       boolean cancelWindowAnimations, int timerIndicatorDuration) {
-        Task focusedTask = getFocusedTask();
-        int newIndex = mStack.indexOfTask(focusedTask);
-        if (focusedTask != null) {
-            if (stackTasksOnly) {
-                List<Task> tasks =  mStack.getTasks();
-                // Try the next task if it is a stack task
-                int tmpNewIndex = newIndex + (forward ? -1 : 1);
-                if (0 <= tmpNewIndex && tmpNewIndex < tasks.size()) {
-                    newIndex = tmpNewIndex;
-                }
-            } else {
-                // No restrictions, lets just move to the new task (looping forward/backwards if
-                // necessary)
-                int taskCount = mStack.getTaskCount();
-                newIndex = (newIndex + (forward ? -1 : 1) + taskCount) % taskCount;
-            }
-        } else {
-            // We don't have a focused task
-            float stackScroll = mStackScroller.getStackScroll();
-            ArrayList<Task> tasks = mStack.getTasks();
-            int taskCount = tasks.size();
-            if (useGridLayout()) {
-                // For the grid layout, we directly set focus to the most recently used task
-                // no matter we're moving forwards or backwards.
-                newIndex = taskCount - 1;
-            } else {
-                // For the grid layout we pick a proper task to focus, according to the current
-                // stack scroll.
-                if (forward) {
-                    // Walk backwards and focus the next task smaller than the current stack scroll
-                    for (newIndex = taskCount - 1; newIndex >= 0; newIndex--) {
-                        float taskP = mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
-                        if (Float.compare(taskP, stackScroll) <= 0) {
-                            break;
-                        }
-                    }
-                } else {
-                    // Walk forwards and focus the next task larger than the current stack scroll
-                    for (newIndex = 0; newIndex < taskCount; newIndex++) {
-                        float taskP = mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
-                        if (Float.compare(taskP, stackScroll) >= 0) {
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-        if (newIndex != -1) {
-            boolean willScroll = setFocusedTask(newIndex, true /* scrollToTask */,
-                    true /* requestViewFocus */, timerIndicatorDuration);
-            if (willScroll && cancelWindowAnimations) {
-                // As we iterate to the next/previous task, cancel any current/lagging window
-                // transition animations
-                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
-            }
-        }
-    }
-
-    /**
-     * Resets the focused task.
-     */
-    public void resetFocusedTask(Task task) {
-        if (task != null) {
-            TaskView tv = getChildViewForTask(task);
-            if (tv != null) {
-                tv.setFocusedState(false, false /* requestViewFocus */);
-            }
-        }
-        if (mTaskViewFocusFrame != null) {
-            mTaskViewFocusFrame.moveGridTaskViewFocus(null);
-        }
-        mFocusedTask = null;
-    }
-
-    /**
-     * Returns the focused task.
-     */
-    public Task getFocusedTask() {
-        return mFocusedTask;
-    }
-
-    /**
-     * Returns the accessibility focused task.
-     */
-    Task getAccessibilityFocusedTask() {
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            if (Utilities.isDescendentAccessibilityFocused(tv)) {
-                return tv.getTask();
-            }
-        }
-        TaskView frontTv = getFrontMostTaskView();
-        if (frontTv != null) {
-            return frontTv.getTask();
-        }
-        return null;
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        if (taskViewCount > 0) {
-            TaskView backMostTask = taskViews.get(0);
-            TaskView frontMostTask = taskViews.get(taskViewCount - 1);
-            event.setFromIndex(mStack.indexOfTask(backMostTask.getTask()));
-            event.setToIndex(mStack.indexOfTask(frontMostTask.getTask()));
-            event.setContentDescription(frontMostTask.getTask().title);
-        }
-        event.setItemCount(mStack.getTaskCount());
-
-        int stackHeight = mLayoutAlgorithm.mStackRect.height();
-        event.setScrollY((int) (mStackScroller.getStackScroll() * stackHeight));
-        event.setMaxScrollY((int) (mLayoutAlgorithm.mMaxScrollP * stackHeight));
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        if (taskViewCount > 1) {
-            // Find the accessibility focused task
-            Task focusedTask = getAccessibilityFocusedTask();
-            info.setScrollable(true);
-            int focusedTaskIndex = mStack.indexOfTask(focusedTask);
-            if (focusedTaskIndex > 0 || !mStackActionButtonVisible) {
-                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
-            }
-            if (0 <= focusedTaskIndex && focusedTaskIndex < mStack.getTaskCount() - 1) {
-                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
-            }
-        }
-    }
-
-    @Override
-    public CharSequence getAccessibilityClassName() {
-        return ScrollView.class.getName();
-    }
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        if (super.performAccessibilityAction(action, arguments)) {
-            return true;
-        }
-        Task focusedTask = getAccessibilityFocusedTask();
-        int taskIndex = mStack.indexOfTask(focusedTask);
-        if (0 <= taskIndex && taskIndex < mStack.getTaskCount()) {
-            switch (action) {
-                case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
-                    setFocusedTask(taskIndex + 1, true /* scrollToTask */, true /* requestViewFocus */,
-                            0);
-                    return true;
-                }
-                case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
-                    setFocusedTask(taskIndex - 1, true /* scrollToTask */, true /* requestViewFocus */,
-                            0);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        return mTouchHandler.onInterceptTouchEvent(ev);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        return mTouchHandler.onTouchEvent(ev);
-    }
-
-    @Override
-    public boolean onGenericMotionEvent(MotionEvent ev) {
-        return mTouchHandler.onGenericMotionEvent(ev);
-    }
-
-    @Override
-    public void computeScroll() {
-        if (mStackScroller.computeScroll()) {
-            // Notify accessibility
-            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
-            Recents.getTaskLoader().getHighResThumbnailLoader().setFlingingFast(
-                    mStackScroller.getScrollVelocity() > mFastFlingVelocity);
-        }
-        if (mDeferredTaskViewLayoutAnimation != null) {
-            relayoutTaskViews(mDeferredTaskViewLayoutAnimation);
-            mTaskViewsClipDirty = true;
-            mDeferredTaskViewLayoutAnimation = null;
-        }
-        if (mTaskViewsClipDirty) {
-            clipTaskViews();
-        }
-        mLastScrollPPercent = Utilities.clamp(Utilities.unmapRange(mStackScroller.getStackScroll(),
-            mLayoutAlgorithm.mMinScrollP, mLayoutAlgorithm.mMaxScrollP), 0, 1);
-    }
-
-    /**
-     * Computes the maximum number of visible tasks and thumbnails. Requires that
-     * updateLayoutForStack() is called first.
-     */
-    public TaskStackLayoutAlgorithm.VisibilityReport computeStackVisibilityReport() {
-        return mLayoutAlgorithm.computeStackVisibilityReport(mStack.getTasks());
-    }
-
-    /**
-     * Updates the system insets.
-     */
-    public void setSystemInsets(Rect systemInsets) {
-        boolean changed = false;
-        changed |= mStableLayoutAlgorithm.setSystemInsets(systemInsets);
-        changed |= mLayoutAlgorithm.setSystemInsets(systemInsets);
-        if (changed) {
-            requestLayout();
-        }
-    }
-
-    /**
-     * This is called with the full window width and height to allow stack view children to
-     * perform the full screen transition down.
-     */
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        mInMeasureLayout = true;
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-        int height = MeasureSpec.getSize(heightMeasureSpec);
-
-        // Update the stable stack bounds, but only update the current stack bounds if the stable
-        // bounds have changed.  This is because we may get spurious measures while dragging where
-        // our current stack bounds reflect the target drop region.
-        mLayoutAlgorithm.getTaskStackBounds(mDisplayRect, new Rect(0, 0, width, height),
-                mLayoutAlgorithm.mSystemInsets.top, mLayoutAlgorithm.mSystemInsets.left,
-                mLayoutAlgorithm.mSystemInsets.right, mTmpRect);
-        if (!mTmpRect.equals(mStableStackBounds)) {
-            mStableStackBounds.set(mTmpRect);
-            mStackBounds.set(mTmpRect);
-            mStableWindowRect.set(0, 0, width, height);
-            mWindowRect.set(0, 0, width, height);
-        }
-
-        // Compute the rects in the stack algorithm
-        mStableLayoutAlgorithm.initialize(mDisplayRect, mStableWindowRect, mStableStackBounds);
-        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
-        updateLayoutAlgorithm(false /* boundScroll */);
-
-        // If this is the first layout, then scroll to the front of the stack, then update the
-        // TaskViews with the stack so that we can lay them out
-        boolean resetToInitialState = (width != mLastWidth || height != mLastHeight)
-                && mResetToInitialStateWhenResized;
-        if (!mFinishedLayoutAfterStackReload || mInitialState != INITIAL_STATE_UPDATE_NONE
-                || resetToInitialState) {
-            if (mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY || resetToInitialState) {
-                updateToInitialState();
-                mResetToInitialStateWhenResized = false;
-            }
-            if (mFinishedLayoutAfterStackReload) {
-                mInitialState = INITIAL_STATE_UPDATE_NONE;
-            }
-        }
-        // If we got the launch-next event before the first layout pass, then re-send it after the
-        // initial state has been updated
-        if (mLaunchNextAfterFirstMeasure) {
-            mLaunchNextAfterFirstMeasure = false;
-            EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
-        }
-
-        // Rebind all the views, including the ignore ones
-        bindVisibleTaskViews(mStackScroller.getStackScroll(), false /* ignoreTaskOverrides */);
-
-        // Measure each of the TaskViews
-        mTmpTaskViews.clear();
-        mTmpTaskViews.addAll(getTaskViews());
-        mTmpTaskViews.addAll(mViewPool.getViews());
-        int taskViewCount = mTmpTaskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            measureTaskView(mTmpTaskViews.get(i));
-        }
-        if (mTaskViewFocusFrame != null) {
-            mTaskViewFocusFrame.measure();
-        }
-
-        setMeasuredDimension(width, height);
-        mLastWidth = width;
-        mLastHeight = height;
-        mInMeasureLayout = false;
-    }
-
-    /**
-     * Measures a TaskView.
-     */
-    private void measureTaskView(TaskView tv) {
-        Rect padding = new Rect();
-        if (tv.getBackground() != null) {
-            tv.getBackground().getPadding(padding);
-        }
-        mTmpRect.set(mStableLayoutAlgorithm.getTaskRect());
-        mTmpRect.union(mLayoutAlgorithm.getTaskRect());
-        tv.measure(
-                MeasureSpec.makeMeasureSpec(mTmpRect.width() + padding.left + padding.right,
-                        MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(mTmpRect.height() + padding.top + padding.bottom,
-                        MeasureSpec.EXACTLY));
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        // Layout each of the TaskViews
-        mTmpTaskViews.clear();
-        mTmpTaskViews.addAll(getTaskViews());
-        mTmpTaskViews.addAll(mViewPool.getViews());
-        int taskViewCount = mTmpTaskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            layoutTaskView(changed, mTmpTaskViews.get(i));
-        }
-        if (mTaskViewFocusFrame != null) {
-            mTaskViewFocusFrame.layout();
-        }
-
-        if (changed) {
-            if (mStackScroller.isScrollOutOfBounds()) {
-                mStackScroller.boundScroll();
-            }
-        }
-
-        // Relayout all of the task views including the ignored ones
-        relayoutTaskViews(AnimationProps.IMMEDIATE);
-        clipTaskViews();
-
-        if (!mFinishedLayoutAfterStackReload) {
-            // Prepare the task enter animations (this can be called numerous times)
-            mInitialState = INITIAL_STATE_UPDATE_NONE;
-            onFirstLayout();
-
-            if (mStackReloaded) {
-                mFinishedLayoutAfterStackReload = true;
-                tryStartEnterAnimation();
-            }
-        }
-    }
-
-    /**
-     * Lays out a TaskView.
-     */
-    private void layoutTaskView(boolean changed, TaskView tv) {
-        if (changed) {
-            Rect padding = new Rect();
-            if (tv.getBackground() != null) {
-                tv.getBackground().getPadding(padding);
-            }
-            mTmpRect.set(mStableLayoutAlgorithm.getTaskRect());
-            mTmpRect.union(mLayoutAlgorithm.getTaskRect());
-            tv.cancelTransformAnimation();
-            tv.layout(mTmpRect.left - padding.left, mTmpRect.top - padding.top,
-                    mTmpRect.right + padding.right, mTmpRect.bottom + padding.bottom);
-        } else {
-            // If the layout has not changed, then just lay it out again in-place
-            tv.layout(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
-        }
-    }
-
-    /** Handler for the first layout. */
-    void onFirstLayout() {
-        // Setup the view for the enter animation
-        mAnimationHelper.prepareForEnterAnimation();
-
-        // Set the task focused state without requesting view focus, and leave the focus animations
-        // until after the enter-animation
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-
-        // We set the initial focused task view iff the following conditions are satisfied:
-        // 1. Recents is showing task views in stack layout.
-        // 2. Recents is launched with ALT + TAB.
-        boolean setFocusOnFirstLayout = !useGridLayout() || launchState.launchedWithAltTab;
-        if (setFocusOnFirstLayout) {
-            int focusedTaskIndex = getInitialFocusTaskIndex(launchState, mStack.getTaskCount(),
-                useGridLayout());
-            if (focusedTaskIndex != -1) {
-                setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
-                        false /* requestViewFocus */);
-            }
-        }
-        updateStackActionButtonVisibility();
-    }
-
-    public boolean isTouchPointInView(float x, float y, TaskView tv) {
-        mTmpRect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
-        mTmpRect.offset((int) tv.getTranslationX(), (int) tv.getTranslationY());
-        return mTmpRect.contains((int) x, (int) y);
-    }
-
-    /**
-     * Returns a non-ignored task in the {@param tasks} list that can be used as an achor when
-     * calculating the scroll position before and after a layout change.
-     */
-    public Task findAnchorTask(List<Task> tasks, MutableBoolean isFrontMostTask) {
-        for (int i = tasks.size() - 1; i >= 0; i--) {
-            Task task = tasks.get(i);
-
-            // Ignore deleting tasks
-            if (isIgnoredTask(task)) {
-                if (i == tasks.size() - 1) {
-                    isFrontMostTask.value = true;
-                }
-                continue;
-            }
-            return task;
-        }
-        return null;
-    }
-
-    /**** TaskStackCallbacks Implementation ****/
-
-    @Override
-    public void onStackTaskAdded(TaskStack stack, Task newTask) {
-        // Update the min/max scroll and animate other task views into their new positions
-        updateLayoutAlgorithm(true /* boundScroll */);
-
-        // Animate all the tasks into place
-        relayoutTaskViews(!mFinishedLayoutAfterStackReload
-                ? AnimationProps.IMMEDIATE
-                : new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN));
-    }
-
-    /**
-     * We expect that the {@link TaskView} associated with the removed task is already hidden.
-     */
-    @Override
-    public void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask,
-            AnimationProps animation, boolean fromDockGesture, boolean dismissRecentsIfAllRemoved) {
-        if (mFocusedTask == removedTask) {
-            resetFocusedTask(removedTask);
-        }
-
-        // Remove the view associated with this task, we can't rely on updateTransforms
-        // to work here because the task is no longer in the list
-        TaskView tv = getChildViewForTask(removedTask);
-        if (tv != null) {
-            mViewPool.returnViewToPool(tv);
-        }
-
-        // Remove the task from the ignored set
-        removeIgnoreTask(removedTask);
-
-        // If requested, relayout with the given animation
-        if (animation != null) {
-            updateLayoutAlgorithm(true /* boundScroll */);
-            relayoutTaskViews(animation);
-        }
-
-        // Update the new front most task's action button
-        if (mScreenPinningEnabled && newFrontMostTask != null) {
-            TaskView frontTv = getChildViewForTask(newFrontMostTask);
-            if (frontTv != null) {
-                frontTv.showActionButton(true /* fadeIn */, DEFAULT_SYNC_STACK_DURATION);
-            }
-        }
-
-        // If there are no remaining tasks, then just close recents
-        if (mStack.getTaskCount() == 0) {
-            if (dismissRecentsIfAllRemoved) {
-                EventBus.getDefault().send(new AllTaskViewsDismissedEvent(fromDockGesture
-                        ? R.string.recents_empty_message
-                        : R.string.recents_empty_message_dismissed_all));
-            } else {
-                EventBus.getDefault().send(new ShowEmptyViewEvent());
-            }
-        }
-    }
-
-    @Override
-    public void onStackTasksRemoved(TaskStack stack) {
-        // Reset the focused task
-        resetFocusedTask(getFocusedTask());
-
-        // Return all the views to the pool
-        List<TaskView> taskViews = new ArrayList<>();
-        taskViews.addAll(getTaskViews());
-        for (int i = taskViews.size() - 1; i >= 0; i--) {
-            mViewPool.returnViewToPool(taskViews.get(i));
-        }
-
-        // Remove all the ignore tasks
-        mIgnoreTasks.clear();
-
-        // If there are no remaining tasks, then just close recents
-        EventBus.getDefault().send(new AllTaskViewsDismissedEvent(
-                R.string.recents_empty_message_dismissed_all));
-    }
-
-    @Override
-    public void onStackTasksUpdated(TaskStack stack) {
-        if (!mFinishedLayoutAfterStackReload) {
-            return;
-        }
-
-        // Update the layout and immediately layout
-        updateLayoutAlgorithm(false /* boundScroll */);
-        relayoutTaskViews(AnimationProps.IMMEDIATE);
-
-        // Rebind all the task views.  This will not trigger new resources to be loaded
-        // unless they have actually changed
-        List<TaskView> taskViews = getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            bindTaskView(tv, tv.getTask());
-        }
-    }
-
-    /**** ViewPoolConsumer Implementation ****/
-
-    @Override
-    public TaskView createView(Context context) {
-        if (Recents.getConfiguration().isGridEnabled) {
-            return (GridTaskView) mInflater.inflate(R.layout.recents_grid_task_view, this, false);
-        } else {
-            return (TaskView) mInflater.inflate(R.layout.recents_task_view, this, false);
-        }
-    }
-
-    @Override
-    public void onReturnViewToPool(TaskView tv) {
-        final Task task = tv.getTask();
-
-        // Unbind the task from the task view
-        unbindTaskView(tv, task);
-
-        // Reset the view properties and view state
-        tv.clearAccessibilityFocus();
-        tv.resetViewProperties();
-        tv.setFocusedState(false, false /* requestViewFocus */);
-        tv.setClipViewInStack(false);
-        if (mScreenPinningEnabled) {
-            tv.hideActionButton(false /* fadeOut */, 0 /* duration */, false /* scaleDown */, null);
-        }
-
-        // Detach the view from the hierarchy
-        detachViewFromParent(tv);
-        // Update the task views list after removing the task view
-        updateTaskViewsList();
-    }
-
-    @Override
-    public void onPickUpViewFromPool(TaskView tv, Task task, boolean isNewView) {
-        // Find the index where this task should be placed in the stack
-        int taskIndex = mStack.indexOfTask(task);
-        int insertIndex = findTaskViewInsertIndex(task, taskIndex);
-
-        // Add/attach the view to the hierarchy
-        if (isNewView) {
-            if (mInMeasureLayout) {
-                // If we are measuring the layout, then just add the view normally as it will be
-                // laid out during the layout pass
-                addView(tv, insertIndex);
-            } else {
-                // Otherwise, this is from a bindVisibleTaskViews() call outside the measure/layout
-                // pass, and we should layout the new child ourselves
-                ViewGroup.LayoutParams params = tv.getLayoutParams();
-                if (params == null) {
-                    params = generateDefaultLayoutParams();
-                }
-                addViewInLayout(tv, insertIndex, params, true /* preventRequestLayout */);
-                measureTaskView(tv);
-                layoutTaskView(true /* changed */, tv);
-            }
-        } else {
-            attachViewToParent(tv, insertIndex, tv.getLayoutParams());
-        }
-        // Update the task views list after adding the new task view
-        updateTaskViewsList();
-
-        // Bind the task view to the new task
-        bindTaskView(tv, task);
-
-        // Set the new state for this view, including the callbacks and view clipping
-        tv.setCallbacks(this);
-        tv.setTouchEnabled(true);
-        tv.setClipViewInStack(true);
-        if (mFocusedTask == task) {
-            tv.setFocusedState(true, false /* requestViewFocus */);
-            if (mStartTimerIndicatorDuration > 0) {
-                // The timer indicator couldn't be started before, so start it now
-                tv.getHeaderView().startFocusTimerIndicator(mStartTimerIndicatorDuration);
-                mStartTimerIndicatorDuration = 0;
-            }
-        }
-
-        // Restore the action button visibility if it is the front most task view
-        if (mScreenPinningEnabled && tv.getTask() == mStack.getFrontMostTask()) {
-            tv.showActionButton(false /* fadeIn */, 0 /* fadeInDuration */);
-        }
-    }
-
-    @Override
-    public boolean hasPreferredData(TaskView tv, Task preferredData) {
-        return (tv.getTask() == preferredData);
-    }
-
-    private void bindTaskView(TaskView tv, Task task) {
-        // Rebind the task and request that this task's data be filled into the TaskView
-        tv.onTaskBound(task, mTouchExplorationEnabled, mDisplayOrientation, mDisplayRect);
-
-        // If the doze trigger has already fired, then update the state for this task view
-        if (mUIDozeTrigger.isAsleep() ||
-                useGridLayout() || Recents.getConfiguration().isLowRamDevice) {
-            tv.setNoUserInteractionState();
-        }
-
-        if (task == mPrefetchingTask) {
-            task.notifyTaskDataLoaded(task.thumbnail, task.icon);
-        } else {
-            // Load the task data
-            Recents.getTaskLoader().loadTaskData(task);
-        }
-        Recents.getTaskLoader().getHighResThumbnailLoader().onTaskVisible(task);
-    }
-
-    private void unbindTaskView(TaskView tv, Task task) {
-        if (task != mPrefetchingTask) {
-            // Report that this task's data is no longer being used
-            Recents.getTaskLoader().unloadTaskData(task);
-        }
-        Recents.getTaskLoader().getHighResThumbnailLoader().onTaskInvisible(task);
-    }
-
-    private void updatePrefetchingTask(ArrayList<Task> tasks, int frontIndex, int backIndex) {
-        Task t = null;
-        boolean somethingVisible = frontIndex != -1 && backIndex != -1;
-        if (somethingVisible && frontIndex < tasks.size() - 1) {
-            t = tasks.get(frontIndex + 1);
-        }
-        if (mPrefetchingTask != t) {
-            if (mPrefetchingTask != null) {
-                int index = tasks.indexOf(mPrefetchingTask);
-                if (index < backIndex || index > frontIndex) {
-                    Recents.getTaskLoader().unloadTaskData(mPrefetchingTask);
-                }
-            }
-            mPrefetchingTask = t;
-            if (t != null) {
-                Recents.getTaskLoader().loadTaskData(t);
-            }
-        }
-    }
-
-    private void clearPrefetchingTask() {
-        if (mPrefetchingTask != null) {
-            Recents.getTaskLoader().unloadTaskData(mPrefetchingTask);
-        }
-        mPrefetchingTask = null;
-    }
-
-    /**** TaskViewCallbacks Implementation ****/
-
-    @Override
-    public void onTaskViewClipStateChanged(TaskView tv) {
-        if (!mTaskViewsClipDirty) {
-            mTaskViewsClipDirty = true;
-            invalidate();
-        }
-    }
-
-    /**** TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks ****/
-
-    @Override
-    public void onFocusStateChanged(int prevFocusState, int curFocusState) {
-        if (mDeferredTaskViewLayoutAnimation == null) {
-            mUIDozeTrigger.poke();
-            relayoutTaskViewsOnNextFrame(AnimationProps.IMMEDIATE);
-        }
-    }
-
-    /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/
-
-    @Override
-    public void onStackScrollChanged(float prevScroll, float curScroll, AnimationProps animation) {
-        mUIDozeTrigger.poke();
-        if (animation != null) {
-            relayoutTaskViewsOnNextFrame(animation);
-        }
-
-        // In grid layout, the stack action button always remains visible.
-        if (mEnterAnimationComplete && !useGridLayout()) {
-            if (Recents.getConfiguration().isLowRamDevice) {
-                // Show stack button when user drags down to show older tasks on low ram devices
-                if (mStack.getTaskCount() > 0 && !mStackActionButtonVisible
-                        && mTouchHandler.mIsScrolling && curScroll - prevScroll < 0) {
-                    // Going up
-                    EventBus.getDefault().send(
-                            new ShowStackActionButtonEvent(true /* translate */));
-                }
-                return;
-            }
-            if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
-                    curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
-                    mStack.getTaskCount() > 0) {
-                EventBus.getDefault().send(new ShowStackActionButtonEvent(true /* translate */));
-            } else if (prevScroll < HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
-                    curScroll >= HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
-                EventBus.getDefault().send(new HideStackActionButtonEvent());
-            }
-        }
-    }
-
-    /**** EventBus Events ****/
-
-    public final void onBusEvent(PackagesChangedEvent event) {
-        // Compute which components need to be removed
-        ArraySet<ComponentName> removedComponents = mStack.computeComponentsRemoved(
-                event.packageName, event.userId);
-
-        // For other tasks, just remove them directly if they no longer exist
-        ArrayList<Task> tasks = mStack.getTasks();
-        for (int i = tasks.size() - 1; i >= 0; i--) {
-            final Task t = tasks.get(i);
-            if (removedComponents.contains(t.key.getComponent())) {
-                final TaskView tv = getChildViewForTask(t);
-                if (tv != null) {
-                    // For visible children, defer removing the task until after the animation
-                    tv.dismissTask();
-                } else {
-                    // Otherwise, remove the task from the stack immediately
-                    mStack.removeTask(t, AnimationProps.IMMEDIATE, false /* fromDockGesture */);
-                }
-            }
-        }
-    }
-
-    public final void onBusEvent(LaunchTaskEvent event) {
-        // Cancel any doze triggers once a task is launched
-        mUIDozeTrigger.stopDozing();
-    }
-
-    public final void onBusEvent(LaunchMostRecentTaskRequestEvent event) {
-        if (mStack.getTaskCount() > 0) {
-            Task mostRecentTask = mStack.getFrontMostTask();
-            launchTask(mostRecentTask);
-        }
-    }
-
-    public final void onBusEvent(ShowStackActionButtonEvent event) {
-        mStackActionButtonVisible = true;
-    }
-
-    public final void onBusEvent(HideStackActionButtonEvent event) {
-        mStackActionButtonVisible = false;
-    }
-
-    public final void onBusEvent(LaunchNextTaskRequestEvent event) {
-        if (!mFinishedLayoutAfterStackReload) {
-            mLaunchNextAfterFirstMeasure = true;
-            return;
-        }
-
-        if (mStack.getTaskCount() == 0) {
-            if (RecentsImpl.getLastPipTime() != -1) {
-                EventBus.getDefault().send(new ExpandPipEvent());
-                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
-                        "pip");
-            } else {
-                // If there are no tasks, then just hide recents back to home.
-                EventBus.getDefault().send(new HideRecentsEvent(false, true));
-            }
-            return;
-        }
-
-        if (!Recents.getConfiguration().getLaunchState().launchedFromPipApp
-                && mStack.isNextLaunchTargetPip(RecentsImpl.getLastPipTime())) {
-            // If the launch task is in the pinned stack, then expand the PiP now
-            EventBus.getDefault().send(new ExpandPipEvent());
-            MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK, "pip");
-        } else {
-            final Task launchTask = mStack.getNextLaunchTarget();
-            if (launchTask != null) {
-                // Defer launching the task until the PiP menu has been dismissed (if it is
-                // showing at all)
-                HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
-                hideMenuEvent.addPostAnimationCallback(() -> {
-                    launchTask(launchTask);
-                });
-                EventBus.getDefault().send(hideMenuEvent);
-                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
-                        launchTask.key.getComponent().toString());
-            }
-        }
-    }
-
-    public final void onBusEvent(LaunchTaskStartedEvent event) {
-        mAnimationHelper.startLaunchTaskAnimation(event.taskView, event.screenPinningRequested,
-                event.getAnimationTrigger());
-    }
-
-    public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
-        // Stop any scrolling
-        mTouchHandler.cancelNonDismissTaskAnimations();
-        mStackScroller.stopScroller();
-        mStackScroller.stopBoundScrollAnimation();
-        cancelDeferredTaskViewLayoutAnimation();
-
-        // Start the task animations
-        mAnimationHelper.startExitToHomeAnimation(event.animated, event.getAnimationTrigger());
-
-        // Dismiss the grid task view focus frame
-        if (mTaskViewFocusFrame != null) {
-            mTaskViewFocusFrame.moveGridTaskViewFocus(null);
-        }
-    }
-
-    public final void onBusEvent(DismissFocusedTaskViewEvent event) {
-        if (mFocusedTask != null) {
-            if (mTaskViewFocusFrame != null) {
-                mTaskViewFocusFrame.moveGridTaskViewFocus(null);
-            }
-            TaskView tv = getChildViewForTask(mFocusedTask);
-            if (tv != null) {
-                tv.dismissTask();
-            }
-            resetFocusedTask(mFocusedTask);
-        }
-    }
-
-    public final void onBusEvent(DismissTaskViewEvent event) {
-        // For visible children, defer removing the task until after the animation
-        mAnimationHelper.startDeleteTaskAnimation(
-                event.taskView, useGridLayout(), event.getAnimationTrigger());
-    }
-
-    public final void onBusEvent(final DismissAllTaskViewsEvent event) {
-        // Keep track of the tasks which will have their data removed
-        ArrayList<Task> tasks = new ArrayList<>(mStack.getTasks());
-        mAnimationHelper.startDeleteAllTasksAnimation(
-                getTaskViews(), useGridLayout(), event.getAnimationTrigger());
-        event.addPostAnimationCallback(new Runnable() {
-            @Override
-            public void run() {
-                // Announce for accessibility
-                announceForAccessibility(getContext().getString(
-                        R.string.accessibility_recents_all_items_dismissed));
-
-                // Remove all tasks and delete the task data for all tasks
-                mStack.removeAllTasks(true /* notifyStackChanges */);
-                for (int i = tasks.size() - 1; i >= 0; i--) {
-                    EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i)));
-                }
-
-                MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS_ALL);
-            }
-        });
-
-    }
-
-    public final void onBusEvent(TaskViewDismissedEvent event) {
-        // Announce for accessibility
-        announceForAccessibility(getContext().getString(
-                R.string.accessibility_recents_item_dismissed, event.task.title));
-
-        if (useGridLayout() && event.animation != null) {
-            event.animation.setListener(new AnimatorListenerAdapter() {
-                public void onAnimationEnd(Animator animator) {
-                    if (mTaskViewFocusFrame != null) {
-                        // Resize the grid layout task view focus frame
-                        mTaskViewFocusFrame.resize();
-                    }
-                }
-            });
-        }
-
-        // Remove the task from the stack
-        mStack.removeTask(event.task, event.animation, false /* fromDockGesture */);
-        EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
-        if (mStack.getTaskCount() > 0 && Recents.getConfiguration().isLowRamDevice) {
-            EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
-        }
-
-        MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
-                event.task.key.getComponent().toString());
-    }
-
-    public final void onBusEvent(FocusNextTaskViewEvent event) {
-        // Stop any scrolling
-        mStackScroller.stopScroller();
-        mStackScroller.stopBoundScrollAnimation();
-
-        setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */, false, 0);
-    }
-
-    public final void onBusEvent(FocusPreviousTaskViewEvent event) {
-        // Stop any scrolling
-        mStackScroller.stopScroller();
-        mStackScroller.stopBoundScrollAnimation();
-
-        setRelativeFocusedTask(false, false /* stackTasksOnly */, true /* animated */);
-    }
-
-    public final void onBusEvent(NavigateTaskViewEvent event) {
-        if (useGridLayout()) {
-            final int taskCount = mStack.getTaskCount();
-            final int currentIndex = mStack.indexOfTask(getFocusedTask());
-            final int nextIndex = mLayoutAlgorithm.mTaskGridLayoutAlgorithm.navigateFocus(taskCount,
-                    currentIndex, event.direction);
-            setFocusedTask(nextIndex, false, true);
-        } else {
-            switch (event.direction) {
-                case UP:
-                    EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
-                    break;
-                case DOWN:
-                    EventBus.getDefault().send(new FocusNextTaskViewEvent());
-                    break;
-            }
-        }
-    }
-
-    public final void onBusEvent(UserInteractionEvent event) {
-        // Poke the doze trigger on user interaction
-        mUIDozeTrigger.poke();
-
-        RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-        if (mFocusedTask != null) {
-            TaskView tv = getChildViewForTask(mFocusedTask);
-            if (tv != null) {
-                tv.getHeaderView().cancelFocusTimerIndicator();
-            }
-        }
-    }
-
-    public final void onBusEvent(DragStartEvent event) {
-        // Ensure that the drag task is not animated
-        addIgnoreTask(event.task);
-
-        // Enlarge the dragged view slightly
-        float finalScale = event.taskView.getScaleX() * DRAG_SCALE_FACTOR;
-        mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
-                mTmpTransform, null);
-        mTmpTransform.scale = finalScale;
-        mTmpTransform.translationZ = mLayoutAlgorithm.mMaxTranslationZ + 1;
-        mTmpTransform.dimAlpha = 0f;
-        updateTaskViewToTransform(event.taskView, mTmpTransform,
-                new AnimationProps(DRAG_SCALE_DURATION, Interpolators.FAST_OUT_SLOW_IN));
-    }
-
-    public final void onBusEvent(DragDropTargetChangedEvent event) {
-        AnimationProps animation = new AnimationProps(SLOW_SYNC_STACK_DURATION,
-                Interpolators.FAST_OUT_SLOW_IN);
-        boolean ignoreTaskOverrides = false;
-        if (event.dropTarget instanceof DockState) {
-            // Calculate the new task stack bounds that matches the window size that Recents will
-            // have after the drop
-            final DockState dockState = (DockState) event.dropTarget;
-            Rect systemInsets = new Rect(mStableLayoutAlgorithm.mSystemInsets);
-            // When docked, the nav bar insets are consumed and the activity is measured without
-            // insets.  However, the window bounds include the insets, so we need to subtract them
-            // here to make them identical.
-            int height = getMeasuredHeight();
-            height -= systemInsets.bottom;
-            systemInsets.bottom = 0;
-            mStackBounds.set(dockState.getDockedTaskStackBounds(mDisplayRect, getMeasuredWidth(),
-                    height, mDividerSize, systemInsets,
-                    mLayoutAlgorithm, getResources(), mWindowRect));
-            mLayoutAlgorithm.setSystemInsets(systemInsets);
-            mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds);
-            updateLayoutAlgorithm(true /* boundScroll */);
-            ignoreTaskOverrides = true;
-        } else {
-            // Restore the pre-drag task stack bounds, but ensure that we don't layout the dragging
-            // task view, so add it back to the ignore set after updating the layout
-            removeIgnoreTask(event.task);
-            updateLayoutToStableBounds();
-            addIgnoreTask(event.task);
-        }
-        relayoutTaskViews(animation, null /* animationOverrides */, ignoreTaskOverrides);
-    }
-
-    public final void onBusEvent(final DragEndEvent event) {
-        // We don't handle drops on the dock regions
-        if (event.dropTarget instanceof DockState) {
-            // However, we do need to reset the overrides, since the last state of this task stack
-            // view layout was ignoring task overrides (see DragDropTargetChangedEvent handler)
-            mLayoutAlgorithm.clearUnfocusedTaskOverrides();
-            return;
-        }
-
-        // Restore the task, so that relayout will apply to it below
-        removeIgnoreTask(event.task);
-
-        // Convert the dragging task view back to its final layout-space rect
-        Utilities.setViewFrameFromTranslation(event.taskView);
-
-        // Animate all the tasks into place
-        ArrayMap<Task, AnimationProps> animationOverrides = new ArrayMap<>();
-        animationOverrides.put(event.task, new AnimationProps(SLOW_SYNC_STACK_DURATION,
-                Interpolators.FAST_OUT_SLOW_IN,
-                event.getAnimationTrigger().decrementOnAnimationEnd()));
-        relayoutTaskViews(new AnimationProps(SLOW_SYNC_STACK_DURATION,
-                Interpolators.FAST_OUT_SLOW_IN));
-        event.getAnimationTrigger().increment();
-    }
-
-    public final void onBusEvent(final DragEndCancelledEvent event) {
-        // Restore the pre-drag task stack bounds, including the dragging task view
-        removeIgnoreTask(event.task);
-        updateLayoutToStableBounds();
-
-        // Convert the dragging task view back to its final layout-space rect
-        Utilities.setViewFrameFromTranslation(event.taskView);
-
-        // Animate all the tasks into place
-        ArrayMap<Task, AnimationProps> animationOverrides = new ArrayMap<>();
-        animationOverrides.put(event.task, new AnimationProps(SLOW_SYNC_STACK_DURATION,
-                Interpolators.FAST_OUT_SLOW_IN,
-                event.getAnimationTrigger().decrementOnAnimationEnd()));
-        relayoutTaskViews(new AnimationProps(SLOW_SYNC_STACK_DURATION,
-                Interpolators.FAST_OUT_SLOW_IN));
-        event.getAnimationTrigger().increment();
-    }
-
-    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
-        mEnterAnimationComplete = true;
-        tryStartEnterAnimation();
-    }
-
-    private void tryStartEnterAnimation() {
-        if (!mStackReloaded || !mFinishedLayoutAfterStackReload || !mEnterAnimationComplete) {
-            return;
-        }
-
-        if (mStack.getTaskCount() > 0) {
-            // Start the task enter animations
-            ReferenceCountedTrigger trigger = new ReferenceCountedTrigger();
-            mAnimationHelper.startEnterAnimation(trigger);
-
-            // Add a runnable to the post animation ref counter to clear all the views
-            trigger.addLastDecrementRunnable(() -> {
-                // Start the dozer to trigger to trigger any UI that shows after a timeout
-                mUIDozeTrigger.startDozing();
-
-                // Update the focused state here -- since we only set the focused task without
-                // requesting view focus in onFirstLayout(), actually request view focus and
-                // animate the focused state if we are alt-tabbing now, after the window enter
-                // animation is completed
-                if (mFocusedTask != null) {
-                    RecentsConfiguration config = Recents.getConfiguration();
-                    RecentsActivityLaunchState launchState = config.getLaunchState();
-                    setFocusedTask(mStack.indexOfTask(mFocusedTask),
-                            false /* scrollToTask */, launchState.launchedWithAltTab);
-                    TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
-                    if (mTouchExplorationEnabled && focusedTaskView != null) {
-                        focusedTaskView.requestAccessibilityFocus();
-                    }
-                }
-            });
-        }
-
-        // This flag is only used to choreograph the enter animation, so we can reset it here
-        mStackReloaded = false;
-    }
-
-    public final void onBusEvent(final MultiWindowStateChangedEvent event) {
-        if (event.inMultiWindow || !event.showDeferredAnimation) {
-            setTasks(event.stack, true /* allowNotifyStackChanges */);
-        } else {
-            // Reset the launch state before handling the multiwindow change
-            RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-            launchState.reset();
-
-            // Defer until the next frame to ensure that we have received all the system insets, and
-            // initial layout updates
-            event.getAnimationTrigger().increment();
-            post(new Runnable() {
-                @Override
-                public void run() {
-                    // Scroll the stack to the front to see the undocked task
-                    mAnimationHelper.startNewStackScrollAnimation(event.stack,
-                            event.getAnimationTrigger());
-                    event.getAnimationTrigger().decrement();
-                }
-            });
-        }
-    }
-
-    public final void onBusEvent(ConfigurationChangedEvent event) {
-        if (event.fromDeviceOrientationChange) {
-            mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
-            mDisplayRect = Recents.getSystemServices().getDisplayRect();
-
-            // Always stop the scroller, otherwise, we may continue setting the stack scroll to the
-            // wrong bounds in the new layout
-            mStackScroller.stopScroller();
-        }
-        reloadOnConfigurationChange();
-
-        // Notify the task views of the configuration change so they can reload their resources
-        if (!event.fromMultiWindow) {
-            mTmpTaskViews.clear();
-            mTmpTaskViews.addAll(getTaskViews());
-            mTmpTaskViews.addAll(mViewPool.getViews());
-            int taskViewCount = mTmpTaskViews.size();
-            for (int i = 0; i < taskViewCount; i++) {
-                mTmpTaskViews.get(i).onConfigurationChanged();
-            }
-        }
-
-        // Update the Clear All button in case we're switching in or out of grid layout.
-        updateStackActionButtonVisibility();
-
-        // Trigger a new layout and update to the initial state if necessary. When entering split
-        // screen, the multi-window configuration change event can happen after the stack is already
-        // reloaded (but pending measure/layout), in this case, do not override the intiial state
-        // and just wait for the upcoming measure/layout pass.
-        if (event.fromMultiWindow && mInitialState == INITIAL_STATE_UPDATE_NONE) {
-            mInitialState = INITIAL_STATE_UPDATE_LAYOUT_ONLY;
-            requestLayout();
-        } else if (event.fromDeviceOrientationChange) {
-            mInitialState = INITIAL_STATE_UPDATE_ALL;
-            requestLayout();
-        }
-    }
-
-    public final void onBusEvent(RecentsGrowingEvent event) {
-        mResetToInitialStateWhenResized = true;
-    }
-
-    public final void onBusEvent(RecentsVisibilityChangedEvent event) {
-        if (!event.visible) {
-            if (mTaskViewFocusFrame != null) {
-                mTaskViewFocusFrame.moveGridTaskViewFocus(null);
-            }
-
-            List<TaskView> taskViews = new ArrayList<>(getTaskViews());
-            for (int i = 0; i < taskViews.size(); i++) {
-                mViewPool.returnViewToPool(taskViews.get(i));
-            }
-            clearPrefetchingTask();
-
-            // We can not reset mEnterAnimationComplete in onReload() because when docking the top
-            // task, we can receive the enter animation callback before onReload(), so reset it
-            // here onces Recents is not visible
-            mEnterAnimationComplete = false;
-        }
-    }
-
-    public final void onBusEvent(ActivityPinnedEvent event) {
-        // If an activity enters PiP while Recents is open, remove the stack task associated with
-        // the new PiP task
-        Task removeTask = mStack.findTaskWithId(event.taskId);
-        if (removeTask != null) {
-            // In this case, we remove the task, but if the last task is removed, don't dismiss
-            // Recents to home
-            mStack.removeTask(removeTask, AnimationProps.IMMEDIATE, false /* fromDockGesture */,
-                    false /* dismissRecentsIfAllRemoved */);
-        }
-        updateLayoutAlgorithm(false /* boundScroll */);
-        updateToInitialState();
-    }
-
-    public void reloadOnConfigurationChange() {
-        mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
-        mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
-    }
-
-    /**
-     * Returns the insert index for the task in the current set of task views. If the given task
-     * is already in the task view list, then this method returns the insert index assuming it
-     * is first removed at the previous index.
-     *
-     * @param task the task we are finding the index for
-     * @param taskIndex the index of the task in the stack
-     */
-    private int findTaskViewInsertIndex(Task task, int taskIndex) {
-        if (taskIndex != -1) {
-            List<TaskView> taskViews = getTaskViews();
-            boolean foundTaskView = false;
-            int taskViewCount = taskViews.size();
-            for (int i = 0; i < taskViewCount; i++) {
-                Task tvTask = taskViews.get(i).getTask();
-                if (tvTask == task) {
-                    foundTaskView = true;
-                } else if (taskIndex < mStack.indexOfTask(tvTask)) {
-                    if (foundTaskView) {
-                        return i - 1;
-                    } else {
-                        return i;
-                    }
-                }
-            }
-        }
-        return -1;
-    }
-
-    private void launchTask(Task task) {
-        // Stop all animations
-        cancelAllTaskViewAnimations();
-
-        float curScroll = mStackScroller.getStackScroll();
-        float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(task);
-        float absScrollDiff = Math.abs(targetScroll - curScroll);
-        if (getChildViewForTask(task) == null || absScrollDiff > 0.35f) {
-            int duration = (int) (LAUNCH_NEXT_SCROLL_BASE_DURATION +
-                    absScrollDiff * LAUNCH_NEXT_SCROLL_INCR_DURATION);
-            mStackScroller.animateScroll(targetScroll,
-                    duration, new Runnable() {
-                        @Override
-                        public void run() {
-                            EventBus.getDefault().send(new LaunchTaskEvent(
-                                    getChildViewForTask(task), task, null,
-                                    false /* screenPinningRequested */));
-                        }
-                    });
-        } else {
-            EventBus.getDefault().send(new LaunchTaskEvent(getChildViewForTask(task), task, null,
-                    false /* screenPinningRequested */));
-        }
-    }
-
-    /**
-     * Check whether we should use the grid layout.
-     */
-    public boolean useGridLayout() {
-        return mLayoutAlgorithm.useGridLayout();
-    }
-
-    /**
-     * Reads current system flags related to accessibility and screen pinning.
-     */
-    private void readSystemFlags() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
-        mScreenPinningEnabled = ActivityManagerWrapper.getInstance().isScreenPinningEnabled()
-                && !ActivityManagerWrapper.getInstance().isLockToAppActive();
-    }
-
-    private void updateStackActionButtonVisibility() {
-        if (Recents.getConfiguration().isLowRamDevice) {
-            return;
-        }
-
-        // Always show the button in grid layout.
-        if (useGridLayout() ||
-                (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
-                        mStack.getTaskCount() > 0)) {
-            EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
-        } else {
-            EventBus.getDefault().send(new HideStackActionButtonEvent());
-        }
-    }
-
-    /**
-     * Returns the task to focus given the current launch state.
-     */
-    private int getInitialFocusTaskIndex(RecentsActivityLaunchState launchState, int numTasks,
-            boolean useGridLayout) {
-        if (launchState.launchedFromApp) {
-            if (useGridLayout) {
-                // If coming from another app to the grid layout, focus the front most task
-                return numTasks - 1;
-            }
-
-            // If coming from another app, focus the next task
-            return Math.max(0, numTasks - 2);
-        } else {
-            // If coming from home, focus the front most task
-            return numTasks - 1;
-        }
-    }
-
-    /**
-     * Updates {@param transforms} to be the same size as {@param tasks}.
-     */
-    private void matchTaskListSize(List<Task> tasks, List<TaskViewTransform> transforms) {
-        // We can reuse the task transforms where possible to reduce object allocation
-        int taskTransformCount = transforms.size();
-        int taskCount = tasks.size();
-        if (taskTransformCount < taskCount) {
-            // If there are less transforms than tasks, then add as many transforms as necessary
-            for (int i = taskTransformCount; i < taskCount; i++) {
-                transforms.add(new TaskViewTransform());
-            }
-        } else if (taskTransformCount > taskCount) {
-            // If there are more transforms than tasks, then just subset the transform list
-            transforms.subList(taskCount, taskTransformCount).clear();
-        }
-    }
-
-    public void dump(String prefix, PrintWriter writer) {
-        String innerPrefix = prefix + "  ";
-        String id = Integer.toHexString(System.identityHashCode(this));
-
-        writer.print(prefix); writer.print(TAG);
-        writer.print(" hasDefRelayout=");
-        writer.print(mDeferredTaskViewLayoutAnimation != null ? "Y" : "N");
-        writer.print(" clipDirty="); writer.print(mTaskViewsClipDirty ? "Y" : "N");
-        writer.print(" awaitingStackReload="); writer.print(mFinishedLayoutAfterStackReload ? "Y" : "N");
-        writer.print(" initialState="); writer.print(mInitialState);
-        writer.print(" inMeasureLayout="); writer.print(mInMeasureLayout ? "Y" : "N");
-        writer.print(" enterAnimCompleted="); writer.print(mEnterAnimationComplete ? "Y" : "N");
-        writer.print(" touchExplorationOn="); writer.print(mTouchExplorationEnabled ? "Y" : "N");
-        writer.print(" screenPinningOn="); writer.print(mScreenPinningEnabled ? "Y" : "N");
-        writer.print(" numIgnoreTasks="); writer.print(mIgnoreTasks.size());
-        writer.print(" numViewPool="); writer.print(mViewPool.getViews().size());
-        writer.print(" stableStackBounds="); writer.print(Utilities.dumpRect(mStableStackBounds));
-        writer.print(" stackBounds="); writer.print(Utilities.dumpRect(mStackBounds));
-        writer.print(" stableWindow="); writer.print(Utilities.dumpRect(mStableWindowRect));
-        writer.print(" window="); writer.print(Utilities.dumpRect(mWindowRect));
-        writer.print(" display="); writer.print(Utilities.dumpRect(mDisplayRect));
-        writer.print(" orientation="); writer.print(mDisplayOrientation);
-        writer.print(" [0x"); writer.print(id); writer.print("]");
-        writer.println();
-
-        if (mFocusedTask != null) {
-            writer.print(innerPrefix);
-            writer.print("Focused task: ");
-            mFocusedTask.dump("", writer);
-        }
-
-        int numTaskViews = mTaskViews.size();
-        for (int i = 0; i < numTaskViews; i++) {
-            mTaskViews.get(i).dump(innerPrefix, writer);
-        }
-
-        mLayoutAlgorithm.dump(innerPrefix, writer);
-        mStackScroller.dump(innerPrefix, writer);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
deleted file mode 100644
index 6b23977..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.util.FloatProperty;
-import android.util.Log;
-import android.util.Property;
-import android.view.ViewConfiguration;
-import android.view.ViewDebug;
-import android.widget.OverScroller;
-
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.recents.views.lowram.TaskStackLowRamLayoutAlgorithm;
-import com.android.systemui.statusbar.FlingAnimationUtils;
-
-import java.io.PrintWriter;
-
-/* The scrolling logic for a TaskStackView */
-public class TaskStackViewScroller {
-
-    private static final String TAG = "TaskStackViewScroller";
-    private static final boolean DEBUG = false;
-
-    public interface TaskStackViewScrollerCallbacks {
-        void onStackScrollChanged(float prevScroll, float curScroll, AnimationProps animation);
-    }
-
-    /**
-     * A Property wrapper around the <code>stackScroll</code> functionality handled by the
-     * {@link #setStackScroll(float)} and
-     * {@link #getStackScroll()} methods.
-     */
-    private static final Property<TaskStackViewScroller, Float> STACK_SCROLL =
-            new FloatProperty<TaskStackViewScroller>("stackScroll") {
-                @Override
-                public void setValue(TaskStackViewScroller object, float value) {
-                    object.setStackScroll(value);
-                }
-
-                @Override
-                public Float get(TaskStackViewScroller object) {
-                    return object.getStackScroll();
-                }
-            };
-
-    Context mContext;
-    TaskStackLayoutAlgorithm mLayoutAlgorithm;
-    TaskStackViewScrollerCallbacks mCb;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    float mStackScrollP;
-    @ViewDebug.ExportedProperty(category="recents")
-    float mLastDeltaP = 0f;
-    float mFlingDownScrollP;
-    int mFlingDownY;
-
-    OverScroller mScroller;
-    ObjectAnimator mScrollAnimator;
-    float mFinalAnimatedScroll;
-
-    final FlingAnimationUtils mFlingAnimationUtils;
-
-    public TaskStackViewScroller(Context context, TaskStackViewScrollerCallbacks cb,
-            TaskStackLayoutAlgorithm layoutAlgorithm) {
-        mContext = context;
-        mCb = cb;
-        mScroller = new OverScroller(context);
-        if (Recents.getConfiguration().isLowRamDevice) {
-            mScroller.setFriction(0.06f);
-        }
-        mLayoutAlgorithm = layoutAlgorithm;
-        mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
-    }
-
-    /** Resets the task scroller. */
-    void reset() {
-        mStackScrollP = 0f;
-        mLastDeltaP = 0f;
-    }
-
-    void resetDeltaScroll() {
-        mLastDeltaP = 0f;
-    }
-
-    /** Gets the current stack scroll */
-    public float getStackScroll() {
-        return mStackScrollP;
-    }
-
-    /**
-     * Sets the current stack scroll immediately.
-     */
-    public void setStackScroll(float s) {
-        setStackScroll(s, AnimationProps.IMMEDIATE);
-    }
-
-    /**
-     * Sets the current stack scroll immediately, and returns the difference between the target
-     * scroll and the actual scroll after accounting for the effect on the focus state.
-     */
-    public float setDeltaStackScroll(float downP, float deltaP) {
-        float targetScroll = downP + deltaP;
-        float newScroll = mLayoutAlgorithm.updateFocusStateOnScroll(downP + mLastDeltaP, targetScroll,
-                mStackScrollP);
-        setStackScroll(newScroll, AnimationProps.IMMEDIATE);
-        mLastDeltaP = deltaP;
-        return newScroll - targetScroll;
-    }
-
-    /**
-     * Sets the current stack scroll, but indicates to the callback the preferred animation to
-     * update to this new scroll.
-     */
-    public void setStackScroll(float newScroll, AnimationProps animation) {
-        float prevScroll = mStackScrollP;
-        mStackScrollP = newScroll;
-        if (mCb != null) {
-            mCb.onStackScrollChanged(prevScroll, mStackScrollP, animation);
-        }
-    }
-
-    /**
-     * Sets the current stack scroll to the initial state when you first enter recents.
-     * @return whether the stack progress changed.
-     */
-    public boolean setStackScrollToInitialState() {
-        float prevScroll = mStackScrollP;
-        setStackScroll(mLayoutAlgorithm.mInitialScrollP);
-        return Float.compare(prevScroll, mStackScrollP) != 0;
-    }
-
-    /**
-     * Starts a fling that is coordinated with the {@link TaskStackViewTouchHandler}.
-     */
-    public void fling(float downScrollP, int downY, int y, int velY, int minY, int maxY,
-            int overscroll) {
-        if (DEBUG) {
-            Log.d(TAG, "fling: " + downScrollP + ", downY: " + downY + ", y: " + y +
-                    ", velY: " + velY + ", minY: " + minY + ", maxY: " + maxY);
-        }
-        mFlingDownScrollP = downScrollP;
-        mFlingDownY = downY;
-        mScroller.fling(0, y, 0, velY, 0, 0, minY, maxY, 0, overscroll);
-    }
-
-    /** Bounds the current scroll if necessary */
-    public boolean boundScroll() {
-        float curScroll = getStackScroll();
-        float newScroll = getBoundedStackScroll(curScroll);
-        if (Float.compare(newScroll, curScroll) != 0) {
-            setStackScroll(newScroll);
-            return true;
-        }
-        return false;
-    }
-
-    /** Returns the bounded stack scroll */
-    float getBoundedStackScroll(float scroll) {
-        return Utilities.clamp(scroll, mLayoutAlgorithm.mMinScrollP, mLayoutAlgorithm.mMaxScrollP);
-    }
-
-    /** Returns the amount that the absolute value of how much the scroll is out of bounds. */
-    float getScrollAmountOutOfBounds(float scroll) {
-        if (scroll < mLayoutAlgorithm.mMinScrollP) {
-            return Math.abs(scroll - mLayoutAlgorithm.mMinScrollP);
-        } else if (scroll > mLayoutAlgorithm.mMaxScrollP) {
-            return Math.abs(scroll - mLayoutAlgorithm.mMaxScrollP);
-        }
-        return 0f;
-    }
-
-    /** Returns whether the specified scroll is out of bounds */
-    boolean isScrollOutOfBounds() {
-        return Float.compare(getScrollAmountOutOfBounds(mStackScrollP), 0f) != 0;
-    }
-
-    /**
-     * Scrolls the closest task and snaps into place. Only used in recents for low ram devices.
-     * @param velocity of scroll
-     */
-    void scrollToClosestTask(int velocity) {
-        float stackScroll = getStackScroll();
-
-        // Skip if not in low ram layout and if the scroll is out of min and max bounds
-        if (!Recents.getConfiguration().isLowRamDevice || stackScroll < mLayoutAlgorithm.mMinScrollP
-                || stackScroll > mLayoutAlgorithm.mMaxScrollP) {
-            return;
-        }
-        TaskStackLowRamLayoutAlgorithm algorithm = mLayoutAlgorithm.mTaskStackLowRamLayoutAlgorithm;
-
-        float flingThreshold = ViewConfiguration.get(mContext).getScaledMinimumFlingVelocity();
-        if (Math.abs(velocity) > flingThreshold) {
-            int minY = algorithm.percentageToScroll(mLayoutAlgorithm.mMinScrollP);
-            int maxY = algorithm.percentageToScroll(mLayoutAlgorithm.mMaxScrollP);
-
-            // Calculate the fling and snap to closest task from final y position, computeScroll()
-            // never runs when cancelled with animateScroll() and the overscroll is not calculated
-            // here
-            fling(0 /* downScrollP */, 0 /* downY */, algorithm.percentageToScroll(stackScroll),
-                    -velocity, minY, maxY, 0 /* overscroll */);
-            float pos = algorithm.scrollToPercentage(mScroller.getFinalY());
-
-            float newScrollP = algorithm.getClosestTaskP(pos, mLayoutAlgorithm.mNumStackTasks,
-                    velocity);
-            ValueAnimator animator = ObjectAnimator.ofFloat(stackScroll, newScrollP);
-            mFlingAnimationUtils.apply(animator, algorithm.percentageToScroll(stackScroll),
-                    algorithm.percentageToScroll(newScrollP), velocity);
-            animateScroll(newScrollP, (int) animator.getDuration(), animator.getInterpolator(),
-                    null /* postRunnable */);
-        } else {
-            float newScrollP = algorithm.getClosestTaskP(stackScroll,
-                    mLayoutAlgorithm.mNumStackTasks, velocity);
-            animateScroll(newScrollP, 300, Interpolators.ACCELERATE_DECELERATE,
-                    null /* postRunnable */);
-        }
-    }
-
-    /** Animates the stack scroll into bounds */
-    ObjectAnimator animateBoundScroll() {
-        // TODO: Take duration for snap back
-        float curScroll = getStackScroll();
-        float newScroll = getBoundedStackScroll(curScroll);
-        if (Float.compare(newScroll, curScroll) != 0) {
-            // Start a new scroll animation
-            animateScroll(newScroll, null /* postScrollRunnable */);
-        }
-        return mScrollAnimator;
-    }
-
-    /** Animates the stack scroll */
-    void animateScroll(float newScroll, final Runnable postRunnable) {
-        int duration = mContext.getResources().getInteger(
-                R.integer.recents_animate_task_stack_scroll_duration);
-        animateScroll(newScroll, duration, postRunnable);
-    }
-
-    /** Animates the stack scroll */
-    void animateScroll(float newScroll, int duration, final Runnable postRunnable) {
-        animateScroll(newScroll, duration, Interpolators.LINEAR_OUT_SLOW_IN, postRunnable);
-    }
-
-    /** Animates the stack scroll with time interpolator */
-    void animateScroll(float newScroll, int duration, TimeInterpolator interpolator,
-            final Runnable postRunnable) {
-        ObjectAnimator an = ObjectAnimator.ofFloat(this, STACK_SCROLL, getStackScroll(), newScroll);
-        an.setDuration(duration);
-        an.setInterpolator(interpolator);
-        animateScroll(newScroll, an, postRunnable);
-    }
-
-    /** Animates the stack scroll with animator */
-    private void animateScroll(float newScroll, ObjectAnimator animator,
-            final Runnable postRunnable) {
-        // Finish any current scrolling animations
-        if (mScrollAnimator != null && mScrollAnimator.isRunning()) {
-            setStackScroll(mFinalAnimatedScroll);
-            mScroller.forceFinished(true);
-        }
-        stopScroller();
-        stopBoundScrollAnimation();
-
-        if (Float.compare(mStackScrollP, newScroll) != 0) {
-            mFinalAnimatedScroll = newScroll;
-            mScrollAnimator = animator;
-            mScrollAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    if (postRunnable != null) {
-                        postRunnable.run();
-                    }
-                    mScrollAnimator.removeAllListeners();
-                }
-            });
-            mScrollAnimator.start();
-        } else {
-            if (postRunnable != null) {
-                postRunnable.run();
-            }
-        }
-    }
-
-    /** Aborts any current stack scrolls */
-    void stopBoundScrollAnimation() {
-        Utilities.cancelAnimationWithoutCallbacks(mScrollAnimator);
-    }
-
-    /**** OverScroller ****/
-
-    /** Called from the view draw, computes the next scroll. */
-    boolean computeScroll() {
-        if (mScroller.computeScrollOffset()) {
-            float deltaP = mLayoutAlgorithm.getDeltaPForY(mFlingDownY, mScroller.getCurrY());
-            mFlingDownScrollP += setDeltaStackScroll(mFlingDownScrollP, deltaP);
-            if (DEBUG) {
-                Log.d(TAG, "computeScroll: " + (mFlingDownScrollP + deltaP));
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /** Returns whether the overscroller is scrolling. */
-    boolean isScrolling() {
-        return !mScroller.isFinished();
-    }
-
-    float getScrollVelocity() {
-        return mScroller.getCurrVelocity();
-    }
-
-    /** Stops the scroller and any current fling. */
-    void stopScroller() {
-        if (!mScroller.isFinished()) {
-            mScroller.abortAnimation();
-        }
-    }
-
-    public void dump(String prefix, PrintWriter writer) {
-        writer.print(prefix); writer.print(TAG);
-        writer.print(" stackScroll:"); writer.print(mStackScrollP);
-        writer.println();
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
deleted file mode 100644
index c91cdfc..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Path;
-import android.util.ArrayMap;
-import android.util.MutableBoolean;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewDebug;
-import android.view.ViewParent;
-import android.view.animation.Interpolator;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.SwipeHelper;
-import com.android.systemui.recents.Constants;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.HideRecentsEvent;
-import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
-import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
-import com.android.systemui.recents.misc.FreePathInterpolator;
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.statusbar.FlingAnimationUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Handles touch events for a TaskStackView.
- */
-class TaskStackViewTouchHandler implements SwipeHelper.Callback {
-
-    private static final int INACTIVE_POINTER_ID = -1;
-    private static final float CHALLENGING_SWIPE_ESCAPE_VELOCITY = 800f; // dp/sec
-    // The min overscroll is the amount of task progress overscroll we want / the max overscroll
-    // curve value below
-    private static final float MAX_OVERSCROLL = 0.7f / 0.3f;
-    private static final Interpolator OVERSCROLL_INTERP;
-    static {
-        Path OVERSCROLL_PATH = new Path();
-        OVERSCROLL_PATH.moveTo(0, 0);
-        OVERSCROLL_PATH.cubicTo(0.2f, 0.175f, 0.25f, 0.3f, 1f, 0.3f);
-        OVERSCROLL_INTERP = new FreePathInterpolator(OVERSCROLL_PATH);
-    }
-
-    Context mContext;
-    TaskStackView mSv;
-    TaskStackViewScroller mScroller;
-    VelocityTracker mVelocityTracker;
-    FlingAnimationUtils mFlingAnimUtils;
-    ValueAnimator mScrollFlingAnimator;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    boolean mIsScrolling;
-    float mDownScrollP;
-    int mDownX, mDownY;
-    int mLastY;
-    int mActivePointerId = INACTIVE_POINTER_ID;
-    int mOverscrollSize;
-    TaskView mActiveTaskView = null;
-
-    int mMinimumVelocity;
-    int mMaximumVelocity;
-    // The scroll touch slop is used to calculate when we start scrolling
-    int mScrollTouchSlop;
-    // Used to calculate when a tap is outside a task view rectangle.
-    final int mWindowTouchSlop;
-
-    private final StackViewScrolledEvent mStackViewScrolledEvent = new StackViewScrolledEvent();
-
-    // The current and final set of task transforms, sized to match the list of tasks in the stack
-    private ArrayList<Task> mCurrentTasks = new ArrayList<>();
-    private ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
-    private ArrayList<TaskViewTransform> mFinalTaskTransforms = new ArrayList<>();
-    private ArrayMap<View, Animator> mSwipeHelperAnimations = new ArrayMap<>();
-    private TaskViewTransform mTmpTransform = new TaskViewTransform();
-    private float mTargetStackScroll;
-
-    SwipeHelper mSwipeHelper;
-    boolean mInterceptedBySwipeHelper;
-
-    public TaskStackViewTouchHandler(Context context, TaskStackView sv,
-            TaskStackViewScroller scroller) {
-        Resources res = context.getResources();
-        ViewConfiguration configuration = ViewConfiguration.get(context);
-        mContext = context;
-        mSv = sv;
-        mScroller = scroller;
-        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
-        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
-        mScrollTouchSlop = configuration.getScaledTouchSlop();
-        mWindowTouchSlop = configuration.getScaledWindowTouchSlop();
-        mFlingAnimUtils = new FlingAnimationUtils(context, 0.2f);
-        mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_fling_overscroll_distance);
-        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) {
-            @Override
-            protected float getSize(View v) {
-                return getScaledDismissSize();
-            }
-
-            @Override
-            protected void prepareDismissAnimation(View v, Animator anim) {
-                mSwipeHelperAnimations.put(v, anim);
-            }
-
-            @Override
-            protected void prepareSnapBackAnimation(View v, Animator anim) {
-                anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-                mSwipeHelperAnimations.put(v, anim);
-            }
-
-            @Override
-            protected float getUnscaledEscapeVelocity() {
-                return CHALLENGING_SWIPE_ESCAPE_VELOCITY;
-            }
-
-            @Override
-            protected long getMaxEscapeAnimDuration() {
-                return 700;
-            }
-        };
-        mSwipeHelper.setDisableHardwareLayers(true);
-    }
-
-    /** Velocity tracker helpers */
-    void initOrResetVelocityTracker() {
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        } else {
-            mVelocityTracker.clear();
-        }
-    }
-    void recycleVelocityTracker() {
-        if (mVelocityTracker != null) {
-            mVelocityTracker.recycle();
-            mVelocityTracker = null;
-        }
-    }
-
-    /** Touch preprocessing for handling below */
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // Pass through to swipe helper if we are swiping
-        mInterceptedBySwipeHelper = isSwipingEnabled() && mSwipeHelper.onInterceptTouchEvent(ev);
-        if (mInterceptedBySwipeHelper) {
-            return true;
-        }
-
-        return handleTouchEvent(ev);
-    }
-
-    /** Handles touch events once we have intercepted them */
-    public boolean onTouchEvent(MotionEvent ev) {
-        // Pass through to swipe helper if we are swiping
-        if (mInterceptedBySwipeHelper && mSwipeHelper.onTouchEvent(ev)) {
-            return true;
-        }
-
-        handleTouchEvent(ev);
-        return true;
-    }
-
-    /**
-     * Finishes all scroll-fling and non-dismissing animations currently running.
-     */
-    public void cancelNonDismissTaskAnimations() {
-        Utilities.cancelAnimationWithoutCallbacks(mScrollFlingAnimator);
-        if (!mSwipeHelperAnimations.isEmpty()) {
-            // For the non-dismissing tasks, freeze the position into the task overrides
-            List<TaskView> taskViews = mSv.getTaskViews();
-            for (int i = taskViews.size() - 1; i >= 0; i--) {
-                TaskView tv = taskViews.get(i);
-
-                if (mSv.isIgnoredTask(tv.getTask())) {
-                    continue;
-                }
-
-                tv.cancelTransformAnimation();
-                mSv.getStackAlgorithm().addUnfocusedTaskOverride(tv, mTargetStackScroll);
-            }
-            mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
-            // Update the scroll to the final scroll position from onBeginDrag()
-            mSv.getScroller().setStackScroll(mTargetStackScroll, null);
-
-            mSwipeHelperAnimations.clear();
-        }
-        mActiveTaskView = null;
-    }
-
-    private boolean handleTouchEvent(MotionEvent ev) {
-        // Short circuit if we have no children
-        if (mSv.getTaskViews().size() == 0) {
-            return false;
-        }
-
-        final TaskStackLayoutAlgorithm layoutAlgorithm = mSv.mLayoutAlgorithm;
-        int action = ev.getAction();
-        switch (action & MotionEvent.ACTION_MASK) {
-            case MotionEvent.ACTION_DOWN: {
-                // Stop the current scroll if it is still flinging
-                mScroller.stopScroller();
-                mScroller.stopBoundScrollAnimation();
-                mScroller.resetDeltaScroll();
-                cancelNonDismissTaskAnimations();
-                mSv.cancelDeferredTaskViewLayoutAnimation();
-
-                // Save the touch down info
-                mDownX = (int) ev.getX();
-                mDownY = (int) ev.getY();
-                mLastY = mDownY;
-                mDownScrollP = mScroller.getStackScroll();
-                mActivePointerId = ev.getPointerId(0);
-                mActiveTaskView = findViewAtPoint(mDownX, mDownY);
-
-                // Initialize the velocity tracker
-                initOrResetVelocityTracker();
-                mVelocityTracker.addMovement(ev);
-                break;
-            }
-            case MotionEvent.ACTION_POINTER_DOWN: {
-                final int index = ev.getActionIndex();
-                mActivePointerId = ev.getPointerId(index);
-                mDownX = (int) ev.getX(index);
-                mDownY = (int) ev.getY(index);
-                mLastY = mDownY;
-                mDownScrollP = mScroller.getStackScroll();
-                mScroller.resetDeltaScroll();
-                mVelocityTracker.addMovement(ev);
-                break;
-            }
-            case MotionEvent.ACTION_MOVE: {
-                int activePointerIndex = ev.findPointerIndex(mActivePointerId);
-                if (activePointerIndex == -1) {
-                    break;
-                }
-                int y = (int) ev.getY(activePointerIndex);
-                int x = (int) ev.getX(activePointerIndex);
-                if (!mIsScrolling) {
-                    int yDiff = Math.abs(y - mDownY);
-                    int xDiff = Math.abs(x - mDownX);
-                    if (Math.abs(y - mDownY) > mScrollTouchSlop && yDiff > xDiff) {
-                        mIsScrolling = true;
-                        float stackScroll = mScroller.getStackScroll();
-                        List<TaskView> taskViews = mSv.getTaskViews();
-                        for (int i = taskViews.size() - 1; i >= 0; i--) {
-                            layoutAlgorithm.addUnfocusedTaskOverride(taskViews.get(i).getTask(),
-                                    stackScroll);
-                        }
-                        layoutAlgorithm.setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
-
-                        // Disallow parents from intercepting touch events
-                        final ViewParent parent = mSv.getParent();
-                        if (parent != null) {
-                            parent.requestDisallowInterceptTouchEvent(true);
-                        }
-
-                        MetricsLogger.action(mSv.getContext(), MetricsEvent.OVERVIEW_SCROLL);
-                        mLastY = mDownY = y;
-                    }
-                }
-                if (mIsScrolling) {
-                    // If we just move linearly on the screen, then that would map to 1/arclength
-                    // of the curve, so just move the scroll proportional to that
-                    float deltaP = layoutAlgorithm.getDeltaPForY(mDownY, y);
-
-                    // Modulate the overscroll to prevent users from pulling the stack too far
-                    float minScrollP = layoutAlgorithm.mMinScrollP;
-                    float maxScrollP = layoutAlgorithm.mMaxScrollP;
-                    float curScrollP = mDownScrollP + deltaP;
-                    if (curScrollP < minScrollP || curScrollP > maxScrollP) {
-                        float clampedScrollP = Utilities.clamp(curScrollP, minScrollP, maxScrollP);
-                        float overscrollP = (curScrollP - clampedScrollP);
-                        float maxOverscroll = Recents.getConfiguration().isLowRamDevice
-                                ? layoutAlgorithm.mTaskStackLowRamLayoutAlgorithm.getMaxOverscroll()
-                                : MAX_OVERSCROLL;
-                        float overscrollX = Math.abs(overscrollP) / maxOverscroll;
-                        float interpX = OVERSCROLL_INTERP.getInterpolation(overscrollX);
-                        curScrollP = clampedScrollP + Math.signum(overscrollP) *
-                                (interpX * maxOverscroll);
-                    }
-                    mDownScrollP += mScroller.setDeltaStackScroll(mDownScrollP,
-                            curScrollP - mDownScrollP);
-                    mStackViewScrolledEvent.updateY(y - mLastY);
-                    EventBus.getDefault().send(mStackViewScrolledEvent);
-                }
-
-                mLastY = y;
-                mVelocityTracker.addMovement(ev);
-                break;
-            }
-            case MotionEvent.ACTION_POINTER_UP: {
-                int pointerIndex = ev.getActionIndex();
-                int pointerId = ev.getPointerId(pointerIndex);
-                if (pointerId == mActivePointerId) {
-                    // Select a new active pointer id and reset the motion state
-                    final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
-                    mActivePointerId = ev.getPointerId(newPointerIndex);
-                    mDownX = (int) ev.getX(pointerIndex);
-                    mDownY = (int) ev.getY(pointerIndex);
-                    mLastY = mDownY;
-                    mDownScrollP = mScroller.getStackScroll();
-                }
-                mVelocityTracker.addMovement(ev);
-                break;
-            }
-            case MotionEvent.ACTION_UP: {
-                mVelocityTracker.addMovement(ev);
-                mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                int activePointerIndex = ev.findPointerIndex(mActivePointerId);
-                int y = (int) ev.getY(activePointerIndex);
-                int velocity = (int) mVelocityTracker.getYVelocity(mActivePointerId);
-                if (mIsScrolling) {
-                    if (mScroller.isScrollOutOfBounds()) {
-                        mScroller.animateBoundScroll();
-                    } else if (Math.abs(velocity) > mMinimumVelocity &&
-                            !Recents.getConfiguration().isLowRamDevice) {
-                        float minY = mDownY + layoutAlgorithm.getYForDeltaP(mDownScrollP,
-                                layoutAlgorithm.mMaxScrollP);
-                        float maxY = mDownY + layoutAlgorithm.getYForDeltaP(mDownScrollP,
-                                layoutAlgorithm.mMinScrollP);
-                        mScroller.fling(mDownScrollP, mDownY, y, velocity, (int) minY, (int) maxY,
-                                mOverscrollSize);
-                        mSv.invalidate();
-                    }
-
-                    // Reset the focused task after the user has scrolled, but we have no scrolling
-                    // in grid layout and therefore we don't want to reset the focus there.
-                    if (!mSv.mTouchExplorationEnabled && !mSv.useGridLayout()) {
-                        if (Recents.getConfiguration().isLowRamDevice) {
-                            mScroller.scrollToClosestTask(velocity);
-                        } else {
-                            mSv.resetFocusedTask(mSv.getFocusedTask());
-                        }
-                    }
-                } else if (mActiveTaskView == null) {
-                    // This tap didn't start on a task.
-                    maybeHideRecentsFromBackgroundTap((int) ev.getX(), (int) ev.getY());
-                }
-
-                mActivePointerId = INACTIVE_POINTER_ID;
-                mIsScrolling = false;
-                recycleVelocityTracker();
-                break;
-            }
-            case MotionEvent.ACTION_CANCEL: {
-                mActivePointerId = INACTIVE_POINTER_ID;
-                mIsScrolling = false;
-                recycleVelocityTracker();
-                break;
-            }
-        }
-        return mIsScrolling;
-    }
-
-    /** Hides recents if the up event at (x, y) is a tap on the background area. */
-    void maybeHideRecentsFromBackgroundTap(int x, int y) {
-        // Ignore the up event if it's too far from its start position. The user might have been
-        // trying to scroll or swipe.
-        int dx = Math.abs(mDownX - x);
-        int dy = Math.abs(mDownY - y);
-        if (dx > mScrollTouchSlop || dy > mScrollTouchSlop) {
-            return;
-        }
-
-        // Shift the tap position toward the center of the task stack and check to see if it would
-        // have hit a view. The user might have tried to tap on a task and missed slightly.
-        int shiftedX = x;
-        if (x > (mSv.getRight() - mSv.getLeft()) / 2) {
-            shiftedX -= mWindowTouchSlop;
-        } else {
-            shiftedX += mWindowTouchSlop;
-        }
-        if (findViewAtPoint(shiftedX, y) != null) {
-            return;
-        }
-
-        // Disallow tapping above and below the stack to dismiss recents
-        if (x > mSv.mLayoutAlgorithm.mStackRect.left && x < mSv.mLayoutAlgorithm.mStackRect.right) {
-            return;
-        }
-
-        // The user intentionally tapped on the background, which is like a tap on the "desktop".
-        // Hide recents and transition to the launcher.
-        EventBus.getDefault().send(new HideRecentsEvent(false, true));
-    }
-
-    /** Handles generic motion events */
-    public boolean onGenericMotionEvent(MotionEvent ev) {
-        if ((ev.getSource() & InputDevice.SOURCE_CLASS_POINTER) ==
-                InputDevice.SOURCE_CLASS_POINTER) {
-            int action = ev.getAction();
-            switch (action & MotionEvent.ACTION_MASK) {
-                case MotionEvent.ACTION_SCROLL:
-                    // Find the front most task and scroll the next task to the front
-                    float vScroll = ev.getAxisValue(MotionEvent.AXIS_VSCROLL);
-                    if (vScroll > 0) {
-                        mSv.setRelativeFocusedTask(true, true /* stackTasksOnly */,
-                                false /* animated */);
-                    } else {
-                        mSv.setRelativeFocusedTask(false, true /* stackTasksOnly */,
-                                false /* animated */);
-                    }
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    /**** SwipeHelper Implementation ****/
-
-    @Override
-    public View getChildAtPosition(MotionEvent ev) {
-        TaskView tv = findViewAtPoint((int) ev.getX(), (int) ev.getY());
-        if (tv != null && canChildBeDismissed(tv)) {
-            return tv;
-        }
-        return null;
-    }
-
-    @Override
-    public boolean canChildBeDismissed(View v) {
-        // Disallow dismissing an already dismissed task
-        TaskView tv = (TaskView) v;
-        Task task = tv.getTask();
-        return !mSwipeHelperAnimations.containsKey(v) &&
-                (mSv.getStack().indexOfTask(task) != -1);
-    }
-
-    /**
-     * Starts a manual drag that goes through the same swipe helper path.
-     */
-    public void onBeginManualDrag(TaskView v) {
-        mActiveTaskView = v;
-        mSwipeHelperAnimations.put(v, null);
-        onBeginDrag(v);
-    }
-
-    @Override
-    public void onBeginDrag(View v) {
-        TaskView tv = (TaskView) v;
-
-        // Disable clipping with the stack while we are swiping
-        tv.setClipViewInStack(false);
-        // Disallow touch events from this task view
-        tv.setTouchEnabled(false);
-        // Disallow parents from intercepting touch events
-        final ViewParent parent = mSv.getParent();
-        if (parent != null) {
-            parent.requestDisallowInterceptTouchEvent(true);
-        }
-
-        // Add this task to the set of tasks we are deleting
-        mSv.addIgnoreTask(tv.getTask());
-
-        // Determine if we are animating the other tasks while dismissing this task
-        mCurrentTasks = new ArrayList<Task>(mSv.getStack().getTasks());
-        MutableBoolean isFrontMostTask = new MutableBoolean(false);
-        Task anchorTask = mSv.findAnchorTask(mCurrentTasks, isFrontMostTask);
-        TaskStackLayoutAlgorithm layoutAlgorithm = mSv.getStackAlgorithm();
-        TaskStackViewScroller stackScroller = mSv.getScroller();
-        if (anchorTask != null) {
-            // Get the current set of task transforms
-            mSv.getCurrentTaskTransforms(mCurrentTasks, mCurrentTaskTransforms);
-
-            // Get the stack scroll of the task to anchor to (since we are removing something, the
-            // front most task will be our anchor task)
-            float prevAnchorTaskScroll = 0;
-            boolean pullStackForward = mCurrentTasks.size() > 0;
-            if (pullStackForward) {
-                if (Recents.getConfiguration().isLowRamDevice) {
-                    float index = layoutAlgorithm.getStackScrollForTask(anchorTask);
-                    prevAnchorTaskScroll = mSv.getStackAlgorithm().mTaskStackLowRamLayoutAlgorithm
-                            .getScrollPForTask((int) index);
-                } else {
-                    prevAnchorTaskScroll = layoutAlgorithm.getStackScrollForTask(anchorTask);
-                }
-            }
-
-            // Calculate where the views would be without the deleting tasks
-            mSv.updateLayoutAlgorithm(false /* boundScroll */);
-
-            float newStackScroll = stackScroller.getStackScroll();
-            if (isFrontMostTask.value) {
-                // Bound the stack scroll to pull tasks forward if necessary
-                newStackScroll = stackScroller.getBoundedStackScroll(newStackScroll);
-            } else if (pullStackForward) {
-                // Otherwise, offset the scroll by the movement of the anchor task
-                float anchorTaskScroll =
-                        layoutAlgorithm.getStackScrollForTaskIgnoreOverrides(anchorTask);
-                if (Recents.getConfiguration().isLowRamDevice) {
-                    float index = layoutAlgorithm.getStackScrollForTask(anchorTask);
-                    anchorTaskScroll = mSv.getStackAlgorithm().mTaskStackLowRamLayoutAlgorithm
-                            .getScrollPForTask((int) index);
-                }
-                float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
-                if (layoutAlgorithm.getFocusState() != TaskStackLayoutAlgorithm.STATE_FOCUSED
-                        && !Recents.getConfiguration().isLowRamDevice) {
-                    // If we are focused, we don't want the front task to move, but otherwise, we
-                    // allow the back task to move up, and the front task to move back
-                    stackScrollOffset *= 0.75f;
-                }
-                newStackScroll = stackScroller.getBoundedStackScroll(stackScroller.getStackScroll()
-                        + stackScrollOffset);
-            }
-
-            // Pick up the newly visible views, not including the deleting tasks
-            mSv.bindVisibleTaskViews(newStackScroll, true /* ignoreTaskOverrides */);
-
-            // Get the final set of task transforms (with task removed)
-            mSv.getLayoutTaskTransforms(newStackScroll, TaskStackLayoutAlgorithm.STATE_UNFOCUSED,
-                    mCurrentTasks, true /* ignoreTaskOverrides */, mFinalTaskTransforms);
-
-            // Set the target to scroll towards upon dismissal
-            mTargetStackScroll = newStackScroll;
-
-            /*
-             * Post condition: All views that will be visible as a part of the gesture are retrieved
-             *                 and at their initial positions.  The stack is still at the current
-             *                 scroll, but the layout is updated without the task currently being
-             *                 dismissed.  The final layout is in the unfocused stack state, which
-             *                 will be applied when the current task is dismissed.
-             */
-        }
-    }
-
-    @Override
-    public boolean updateSwipeProgress(View v, boolean dismissable, float swipeProgress) {
-        // Only update the swipe progress for the surrounding tasks if the dismiss animation was not
-        // preempted from a call to cancelNonDismissTaskAnimations
-        if ((mActiveTaskView == v || mSwipeHelperAnimations.containsKey(v)) &&
-                !Recents.getConfiguration().isLowRamDevice) {
-            updateTaskViewTransforms(
-                    Interpolators.FAST_OUT_SLOW_IN.getInterpolation(swipeProgress));
-        }
-        return true;
-    }
-
-    /**
-     * Called after the {@link TaskView} is finished animating away.
-     */
-    @Override
-    public void onChildDismissed(View v) {
-        TaskView tv = (TaskView) v;
-
-        // Re-enable clipping with the stack (we will reuse this view)
-        tv.setClipViewInStack(true);
-        // Re-enable touch events from this task view
-        tv.setTouchEnabled(true);
-        // Update the scroll to the final scroll position before laying out the tasks during dismiss
-        if (mSwipeHelperAnimations.containsKey(v)) {
-            mSv.getScroller().setStackScroll(mTargetStackScroll, null);
-        }
-        // Remove the task view from the stack, ignoring the animation if we've started dragging
-        // again
-        EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv,
-                mSwipeHelperAnimations.containsKey(v)
-                    ? new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
-                        Interpolators.FAST_OUT_SLOW_IN)
-                    : null));
-        // Only update the final scroll and layout state (set in onBeginDrag()) if the dismiss
-        // animation was not preempted from a call to cancelNonDismissTaskAnimations
-        if (mSwipeHelperAnimations.containsKey(v)) {
-            // Update the focus state to the final focus state
-            mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
-            mSv.getStackAlgorithm().clearUnfocusedTaskOverrides();
-            // Stop tracking this deletion animation
-            mSwipeHelperAnimations.remove(v);
-        }
-        // Keep track of deletions by keyboard
-        MetricsLogger.histogram(tv.getContext(), "overview_task_dismissed_source",
-                Constants.Metrics.DismissSourceSwipeGesture);
-    }
-
-    /**
-     * Called after the {@link TaskView} is finished animating back into the list.
-     * onChildDismissed() calls.
-     */
-    @Override
-    public void onChildSnappedBack(View v, float targetLeft) {
-        TaskView tv = (TaskView) v;
-
-        // Re-enable clipping with the stack
-        tv.setClipViewInStack(true);
-        // Re-enable touch events from this task view
-        tv.setTouchEnabled(true);
-
-        // Stop tracking this deleting task, and update the layout to include this task again.  The
-        // stack scroll does not need to be reset, since the scroll has not actually changed in
-        // onBeginDrag().
-        mSv.removeIgnoreTask(tv.getTask());
-        mSv.updateLayoutAlgorithm(false /* boundScroll */);
-        mSv.relayoutTaskViews(AnimationProps.IMMEDIATE);
-        mSwipeHelperAnimations.remove(v);
-    }
-
-    @Override
-    public void onDragCancelled(View v) {
-        // Do nothing
-    }
-
-    @Override
-    public boolean isAntiFalsingNeeded() {
-        return false;
-    }
-
-    @Override
-    public float getFalsingThresholdFactor() {
-        return 0;
-    }
-
-    /**
-     * Interpolates the non-deleting tasks to their final transforms from their current transforms.
-     */
-    private void updateTaskViewTransforms(float dismissFraction) {
-        List<TaskView> taskViews = mSv.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = 0; i < taskViewCount; i++) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-
-            if (mSv.isIgnoredTask(task)) {
-                continue;
-            }
-
-            int taskIndex = mCurrentTasks.indexOf(task);
-            if (taskIndex == -1) {
-                // If a task was added to the stack view after the start of the dismiss gesture,
-                // just ignore it
-                continue;
-            }
-
-            TaskViewTransform fromTransform = mCurrentTaskTransforms.get(taskIndex);
-            TaskViewTransform toTransform = mFinalTaskTransforms.get(taskIndex);
-
-            mTmpTransform.copyFrom(fromTransform);
-            // We only really need to interpolate the bounds, progress and translation
-            mTmpTransform.rect.set(Utilities.RECTF_EVALUATOR.evaluate(dismissFraction,
-                    fromTransform.rect, toTransform.rect));
-            mTmpTransform.dimAlpha = fromTransform.dimAlpha + (toTransform.dimAlpha -
-                    fromTransform.dimAlpha) * dismissFraction;
-            mTmpTransform.viewOutlineAlpha = fromTransform.viewOutlineAlpha +
-                    (toTransform.viewOutlineAlpha - fromTransform.viewOutlineAlpha) *
-                            dismissFraction;
-            mTmpTransform.translationZ = fromTransform.translationZ +
-                    (toTransform.translationZ - fromTransform.translationZ) * dismissFraction;
-
-            mSv.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
-        }
-    }
-
-    /** Returns the view at the specified coordinates */
-    private TaskView findViewAtPoint(int x, int y) {
-        List<Task> tasks = mSv.getStack().getTasks();
-        int taskCount = tasks.size();
-        for (int i = taskCount - 1; i >= 0; i--) {
-            TaskView tv = mSv.getChildViewForTask(tasks.get(i));
-            if (tv != null && tv.getVisibility() == View.VISIBLE) {
-                if (mSv.isTouchPointInView(x, y, tv)) {
-                    return tv;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the scaled size used to calculate the dismiss fraction.
-     */
-    public float getScaledDismissSize() {
-        return 1.5f * Math.max(mSv.getWidth(), mSv.getHeight());
-    }
-
-    /**
-     * Returns whether swiping is enabled.
-     */
-    private boolean isSwipingEnabled() {
-        return !mSv.useGridLayout();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
deleted file mode 100644
index f0278a6..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ /dev/null
@@ -1,738 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Outline;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.FloatProperty;
-import android.util.Property;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewDebug;
-import android.view.ViewOutlineProvider;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivity;
-import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.LaunchTaskEvent;
-import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
-import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.recents.misc.ReferenceCountedTrigger;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.recents.view.AnimateableViewBounds;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * A {@link TaskView} represents a fixed view of a task. Because the TaskView's layout is directed
- * solely by the {@link TaskStackView}, we make it a fixed size layout which allows relayouts down
- * the view hierarchy, but not upwards from any of its children (the TaskView will relayout itself
- * with the previous bounds if any child requests layout).
- */
-public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks,
-        TaskStackAnimationHelper.Callbacks, View.OnClickListener, View.OnLongClickListener {
-
-    /** The TaskView callbacks */
-    interface TaskViewCallbacks {
-        void onTaskViewClipStateChanged(TaskView tv);
-    }
-
-    /**
-     * The dim overlay is generally calculated from the task progress, but occasionally (like when
-     * launching) needs to be animated independently of the task progress.  This call is only used
-     * when animating the task into Recents, when the header dim is already applied
-     */
-    public static final Property<TaskView, Float> DIM_ALPHA_WITHOUT_HEADER =
-            new FloatProperty<TaskView>("dimAlphaWithoutHeader") {
-                @Override
-                public void setValue(TaskView tv, float dimAlpha) {
-                    tv.setDimAlphaWithoutHeader(dimAlpha);
-                }
-
-                @Override
-                public Float get(TaskView tv) {
-                    return tv.getDimAlpha();
-                }
-            };
-
-    /**
-     * The dim overlay is generally calculated from the task progress, but occasionally (like when
-     * launching) needs to be animated independently of the task progress.
-     */
-    public static final Property<TaskView, Float> DIM_ALPHA =
-            new FloatProperty<TaskView>("dimAlpha") {
-                @Override
-                public void setValue(TaskView tv, float dimAlpha) {
-                    tv.setDimAlpha(dimAlpha);
-                }
-
-                @Override
-                public Float get(TaskView tv) {
-                    return tv.getDimAlpha();
-                }
-            };
-
-    /**
-     * The dim overlay is generally calculated from the task progress, but occasionally (like when
-     * launching) needs to be animated independently of the task progress.
-     */
-    public static final Property<TaskView, Float> VIEW_OUTLINE_ALPHA =
-            new FloatProperty<TaskView>("viewOutlineAlpha") {
-                @Override
-                public void setValue(TaskView tv, float alpha) {
-                    tv.getViewBounds().setAlpha(alpha);
-                }
-
-                @Override
-                public Float get(TaskView tv) {
-                    return tv.getViewBounds().getAlpha();
-                }
-            };
-
-    @ViewDebug.ExportedProperty(category="recents")
-    private float mDimAlpha;
-    private float mActionButtonTranslationZ;
-
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="task_")
-    private Task mTask;
-    private boolean mTaskBound;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mClipViewInStack = true;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mTouchExplorationEnabled;
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mIsDisabledInSafeMode;
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="view_bounds_")
-    private AnimateableViewBounds mViewBounds;
-
-    private AnimatorSet mTransformAnimation;
-    private ObjectAnimator mDimAnimator;
-    private ObjectAnimator mOutlineAnimator;
-    private final TaskViewTransform mTargetAnimationTransform = new TaskViewTransform();
-    private ArrayList<Animator> mTmpAnimators = new ArrayList<>();
-
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="thumbnail_")
-    protected TaskViewThumbnail mThumbnailView;
-    @ViewDebug.ExportedProperty(deepExport=true, prefix="header_")
-    protected TaskViewHeader mHeaderView;
-    private View mActionButtonView;
-    private View mIncompatibleAppToastView;
-    private TaskViewCallbacks mCb;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    private Point mDownTouchPos = new Point();
-
-    private Toast mDisabledAppToast;
-
-    public TaskView(Context context) {
-        this(context, null);
-    }
-
-    public TaskView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        RecentsConfiguration config = Recents.getConfiguration();
-        Resources res = context.getResources();
-        mViewBounds = createOutlineProvider();
-        if (config.fakeShadows) {
-            setBackground(new FakeShadowDrawable(res, config));
-        }
-        setOutlineProvider(mViewBounds);
-        setOnLongClickListener(this);
-        setAccessibilityDelegate(new TaskViewAccessibilityDelegate(this));
-    }
-
-    /** Set callback */
-    void setCallbacks(TaskViewCallbacks cb) {
-        mCb = cb;
-    }
-
-    /**
-     * Called from RecentsActivity when it is relaunched.
-     */
-    void onReload(boolean isResumingFromVisible) {
-        resetNoUserInteractionState();
-        if (!isResumingFromVisible) {
-            resetViewProperties();
-        }
-    }
-
-    /** Gets the task */
-    public Task getTask() {
-        return mTask;
-    }
-
-    /* Create an outline provider to clip and outline the view */
-    protected AnimateableViewBounds createOutlineProvider() {
-        return new AnimateableViewBounds(this, mContext.getResources().getDimensionPixelSize(
-            R.dimen.recents_task_view_shadow_rounded_corners_radius));
-    }
-
-    /** Returns the view bounds. */
-    AnimateableViewBounds getViewBounds() {
-        return mViewBounds;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        // Bind the views
-        mHeaderView = findViewById(R.id.task_view_bar);
-        mThumbnailView = findViewById(R.id.task_view_thumbnail);
-        mThumbnailView.updateClipToTaskBar(mHeaderView);
-        mActionButtonView = findViewById(R.id.lock_to_app_fab);
-        mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
-            @Override
-            public void getOutline(View view, Outline outline) {
-                // Set the outline to match the FAB background
-                outline.setOval(0, 0, mActionButtonView.getWidth(), mActionButtonView.getHeight());
-                outline.setAlpha(0.35f);
-            }
-        });
-        mActionButtonView.setOnClickListener(this);
-        mActionButtonTranslationZ = mActionButtonView.getTranslationZ();
-    }
-
-    /**
-     * Update the task view when the configuration changes.
-     */
-    protected void onConfigurationChanged() {
-        mHeaderView.onConfigurationChanged();
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        if (w > 0 && h > 0) {
-            mHeaderView.onTaskViewSizeChanged(w, h);
-            mThumbnailView.onTaskViewSizeChanged(w, h);
-
-            mActionButtonView.setTranslationX(w - getMeasuredWidth());
-            mActionButtonView.setTranslationY(h - getMeasuredHeight());
-        }
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            mDownTouchPos.set((int) (ev.getX() * getScaleX()), (int) (ev.getY() * getScaleY()));
-        }
-        return super.onInterceptTouchEvent(ev);
-    }
-
-    @Override
-    protected void measureContents(int width, int height) {
-        int widthWithoutPadding = width - mPaddingLeft - mPaddingRight;
-        int heightWithoutPadding = height - mPaddingTop - mPaddingBottom;
-        int widthSpec = MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY);
-        int heightSpec = MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.EXACTLY);
-
-        // Measure the content
-        measureChildren(widthSpec, heightSpec);
-
-        setMeasuredDimension(width, height);
-    }
-
-    void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform,
-            AnimationProps toAnimation, ValueAnimator.AnimatorUpdateListener updateCallback) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        cancelTransformAnimation();
-
-        // Compose the animations for the transform
-        mTmpAnimators.clear();
-        toTransform.applyToTaskView(this, mTmpAnimators, toAnimation, !config.fakeShadows);
-        if (toAnimation.isImmediate()) {
-            if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
-                setDimAlpha(toTransform.dimAlpha);
-            }
-            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
-                mViewBounds.setAlpha(toTransform.viewOutlineAlpha);
-            }
-            // Manually call back to the animator listener and update callback
-            if (toAnimation.getListener() != null) {
-                toAnimation.getListener().onAnimationEnd(null);
-            }
-            if (updateCallback != null) {
-                updateCallback.onAnimationUpdate(null);
-            }
-        } else {
-            // Both the progress and the update are a function of the bounds movement of the task
-            if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
-                mDimAnimator = ObjectAnimator.ofFloat(this, DIM_ALPHA, getDimAlpha(),
-                        toTransform.dimAlpha);
-                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mDimAnimator));
-            }
-            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
-                mOutlineAnimator = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
-                        mViewBounds.getAlpha(), toTransform.viewOutlineAlpha);
-                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, mOutlineAnimator));
-            }
-            if (updateCallback != null) {
-                ValueAnimator updateCallbackAnim = ValueAnimator.ofInt(0, 1);
-                updateCallbackAnim.addUpdateListener(updateCallback);
-                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, updateCallbackAnim));
-            }
-
-            // Create the animator
-            mTransformAnimation = toAnimation.createAnimator(mTmpAnimators);
-            mTransformAnimation.start();
-            mTargetAnimationTransform.copyFrom(toTransform);
-        }
-    }
-
-    /** Resets this view's properties */
-    void resetViewProperties() {
-        cancelTransformAnimation();
-        setDimAlpha(0);
-        setVisibility(View.VISIBLE);
-        getViewBounds().reset();
-        getHeaderView().reset();
-        TaskViewTransform.reset(this);
-
-        mActionButtonView.setScaleX(1f);
-        mActionButtonView.setScaleY(1f);
-        mActionButtonView.setAlpha(0f);
-        mActionButtonView.setTranslationX(0f);
-        mActionButtonView.setTranslationY(0f);
-        mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
-        if (mIncompatibleAppToastView != null) {
-            mIncompatibleAppToastView.setVisibility(View.INVISIBLE);
-        }
-    }
-
-    /**
-     * @return whether we are animating towards {@param transform}
-     */
-    boolean isAnimatingTo(TaskViewTransform transform) {
-        return mTransformAnimation != null && mTransformAnimation.isStarted()
-                && mTargetAnimationTransform.isSame(transform);
-    }
-
-    /**
-     * Cancels any current transform animations.
-     */
-    public void cancelTransformAnimation() {
-        cancelDimAnimationIfExists();
-        Utilities.cancelAnimationWithoutCallbacks(mTransformAnimation);
-        Utilities.cancelAnimationWithoutCallbacks(mOutlineAnimator);
-    }
-
-    private void cancelDimAnimationIfExists() {
-        if (mDimAnimator != null) {
-            mDimAnimator.cancel();
-        }
-    }
-
-    /** Enables/disables handling touch on this task view. */
-    public void setTouchEnabled(boolean enabled) {
-        setOnClickListener(enabled ? this : null);
-    }
-
-    /** Animates this task view if the user does not interact with the stack after a certain time. */
-    public void startNoUserInteractionAnimation() {
-        mHeaderView.startNoUserInteractionAnimation();
-    }
-
-    /** Mark this task view that the user does has not interacted with the stack after a certain time. */
-    void setNoUserInteractionState() {
-        mHeaderView.setNoUserInteractionState();
-    }
-
-    /** Resets the state tracking that the user has not interacted with the stack after a certain time. */
-    void resetNoUserInteractionState() {
-        mHeaderView.resetNoUserInteractionState();
-    }
-
-    /** Dismisses this task. */
-    void dismissTask() {
-        // Animate out the view and call the callback
-        final TaskView tv = this;
-        DismissTaskViewEvent dismissEvent = new DismissTaskViewEvent(tv);
-        dismissEvent.addPostAnimationCallback(new Runnable() {
-            @Override
-            public void run() {
-                EventBus.getDefault().send(new TaskViewDismissedEvent(mTask, tv,
-                        new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
-                                Interpolators.FAST_OUT_SLOW_IN)));
-            }
-        });
-        EventBus.getDefault().send(dismissEvent);
-    }
-
-    /**
-     * Returns whether this view should be clipped, or any views below should clip against this
-     * view.
-     */
-    boolean shouldClipViewInStack() {
-        if (getVisibility() != View.VISIBLE || Recents.getConfiguration().isLowRamDevice) {
-            return false;
-        }
-        return mClipViewInStack;
-    }
-
-    /** Sets whether this view should be clipped, or clipped against. */
-    void setClipViewInStack(boolean clip) {
-        if (clip != mClipViewInStack) {
-            mClipViewInStack = clip;
-            if (mCb != null) {
-                mCb.onTaskViewClipStateChanged(this);
-            }
-        }
-    }
-
-    public TaskViewHeader getHeaderView() {
-        return mHeaderView;
-    }
-
-    /**
-     * Sets the current dim.
-     */
-    public void setDimAlpha(float dimAlpha) {
-        mDimAlpha = dimAlpha;
-        mThumbnailView.setDimAlpha(dimAlpha);
-        mHeaderView.setDimAlpha(dimAlpha);
-    }
-
-    /**
-     * Sets the current dim without updating the header's dim.
-     */
-    public void setDimAlphaWithoutHeader(float dimAlpha) {
-        mDimAlpha = dimAlpha;
-        mThumbnailView.setDimAlpha(dimAlpha);
-    }
-
-    /**
-     * Returns the current dim.
-     */
-    public float getDimAlpha() {
-        return mDimAlpha;
-    }
-
-    /**
-     * Explicitly sets the focused state of this task.
-     */
-    public void setFocusedState(boolean isFocused, boolean requestViewFocus) {
-        if (isFocused) {
-            if (requestViewFocus && !isFocused()) {
-                requestFocus();
-            }
-        } else {
-            if (isAccessibilityFocused() && mTouchExplorationEnabled) {
-                clearAccessibilityFocus();
-            }
-        }
-    }
-
-    /**
-     * Shows the action button.
-     * @param fadeIn whether or not to animate the action button in.
-     * @param fadeInDuration the duration of the action button animation, only used if
-     *                       {@param fadeIn} is true.
-     */
-    public void showActionButton(boolean fadeIn, int fadeInDuration) {
-        mActionButtonView.setVisibility(View.VISIBLE);
-
-        if (fadeIn && mActionButtonView.getAlpha() < 1f) {
-            mActionButtonView.animate()
-                    .alpha(1f)
-                    .scaleX(1f)
-                    .scaleY(1f)
-                    .setDuration(fadeInDuration)
-                    .setInterpolator(Interpolators.ALPHA_IN)
-                    .start();
-        } else {
-            mActionButtonView.setScaleX(1f);
-            mActionButtonView.setScaleY(1f);
-            mActionButtonView.setAlpha(1f);
-            mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
-        }
-    }
-
-    /**
-     * Immediately hides the action button.
-     *
-     * @param fadeOut whether or not to animate the action button out.
-     */
-    public void hideActionButton(boolean fadeOut, int fadeOutDuration, boolean scaleDown,
-            final Animator.AnimatorListener animListener) {
-        if (fadeOut && mActionButtonView.getAlpha() > 0f) {
-            if (scaleDown) {
-                float toScale = 0.9f;
-                mActionButtonView.animate()
-                        .scaleX(toScale)
-                        .scaleY(toScale);
-            }
-            mActionButtonView.animate()
-                    .alpha(0f)
-                    .setDuration(fadeOutDuration)
-                    .setInterpolator(Interpolators.ALPHA_OUT)
-                    .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            if (animListener != null) {
-                                animListener.onAnimationEnd(null);
-                            }
-                            mActionButtonView.setVisibility(View.INVISIBLE);
-                        }
-                    })
-                    .start();
-        } else {
-            mActionButtonView.setAlpha(0f);
-            mActionButtonView.setVisibility(View.INVISIBLE);
-            if (animListener != null) {
-                animListener.onAnimationEnd(null);
-            }
-        }
-    }
-
-    /**** TaskStackAnimationHelper.Callbacks Implementation ****/
-
-    @Override
-    public void onPrepareLaunchTargetForEnterAnimation() {
-        // These values will be animated in when onStartLaunchTargetEnterAnimation() is called
-        setDimAlphaWithoutHeader(0);
-        mActionButtonView.setAlpha(0f);
-        if (mIncompatibleAppToastView != null &&
-                mIncompatibleAppToastView.getVisibility() == View.VISIBLE) {
-            mIncompatibleAppToastView.setAlpha(0f);
-        }
-    }
-
-    @Override
-    public void onStartLaunchTargetEnterAnimation(TaskViewTransform transform, int duration,
-            boolean screenPinningEnabled, ReferenceCountedTrigger postAnimationTrigger) {
-        cancelDimAnimationIfExists();
-
-        // Dim the view after the app window transitions down into recents
-        postAnimationTrigger.increment();
-        AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
-        mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
-                DIM_ALPHA_WITHOUT_HEADER, getDimAlpha(), transform.dimAlpha));
-        mDimAnimator.addListener(postAnimationTrigger.decrementOnAnimationEnd());
-        mDimAnimator.start();
-
-        if (screenPinningEnabled) {
-            showActionButton(true /* fadeIn */, duration /* fadeInDuration */);
-        }
-
-        if (mIncompatibleAppToastView != null &&
-                mIncompatibleAppToastView.getVisibility() == View.VISIBLE) {
-            mIncompatibleAppToastView.animate()
-                    .alpha(1f)
-                    .setDuration(duration)
-                    .setInterpolator(Interpolators.ALPHA_IN)
-                    .start();
-        }
-    }
-
-    @Override
-    public void onStartLaunchTargetLaunchAnimation(int duration, boolean screenPinningRequested,
-            ReferenceCountedTrigger postAnimationTrigger) {
-        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
-
-        // Un-dim the view before/while launching the target
-        AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
-        mDimAnimator = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
-                DIM_ALPHA, getDimAlpha(), 0));
-        mDimAnimator.start();
-
-        postAnimationTrigger.increment();
-        hideActionButton(true /* fadeOut */, duration,
-                !screenPinningRequested /* scaleDown */,
-                postAnimationTrigger.decrementOnAnimationEnd());
-    }
-
-    @Override
-    public void onStartFrontTaskEnterAnimation(boolean screenPinningEnabled) {
-        if (screenPinningEnabled) {
-            showActionButton(false /* fadeIn */, 0 /* fadeInDuration */);
-        }
-    }
-
-    /**** TaskCallbacks Implementation ****/
-
-    public void onTaskBound(Task t, boolean touchExplorationEnabled, int displayOrientation,
-            Rect displayRect) {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        mTouchExplorationEnabled = touchExplorationEnabled;
-        mTask = t;
-        mTaskBound = true;
-        mTask.addCallback(this);
-        mIsDisabledInSafeMode = !mTask.isSystemApp && ssp.isInSafeMode();
-        mThumbnailView.bindToTask(mTask, mIsDisabledInSafeMode, displayOrientation, displayRect);
-        mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
-
-        if (!t.isDockable && ssp.hasDockedTask()) {
-            if (mIncompatibleAppToastView == null) {
-                mIncompatibleAppToastView = Utilities.findViewStubById(this,
-                        R.id.incompatible_app_toast_stub).inflate();
-                TextView msg = findViewById(com.android.internal.R.id.message);
-                msg.setText(R.string.dock_non_resizeble_failed_to_dock_text);
-            }
-            mIncompatibleAppToastView.setVisibility(View.VISIBLE);
-        } else if (mIncompatibleAppToastView != null) {
-            mIncompatibleAppToastView.setVisibility(View.INVISIBLE);
-        }
-    }
-
-    @Override
-    public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData) {
-        if (mTaskBound) {
-            // Update each of the views to the new task data
-            mThumbnailView.onTaskDataLoaded(thumbnailData);
-            mHeaderView.onTaskDataLoaded();
-        }
-    }
-
-    @Override
-    public void onTaskDataUnloaded() {
-        // Unbind each of the views from the task and remove the task callback
-        mTask.removeCallback(this);
-        mThumbnailView.unbindFromTask();
-        mHeaderView.unbindFromTask(mTouchExplorationEnabled);
-        mTaskBound = false;
-    }
-
-    @Override
-    public void onTaskWindowingModeChanged() {
-        // Force rebind the header, the thumbnail does not change due to stack changes
-        mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
-        mHeaderView.onTaskDataLoaded();
-    }
-
-    /**** View.OnClickListener Implementation ****/
-
-    @Override
-     public void onClick(final View v) {
-        if (mIsDisabledInSafeMode) {
-            Context context = getContext();
-            String msg = context.getString(R.string.recents_launch_disabled_message, mTask.title);
-            if (mDisabledAppToast != null) {
-                mDisabledAppToast.cancel();
-            }
-            mDisabledAppToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
-            mDisabledAppToast.show();
-            return;
-        }
-
-        boolean screenPinningRequested = false;
-        if (v == mActionButtonView) {
-            // Reset the translation of the action button before we animate it out
-            mActionButtonView.setTranslationZ(0f);
-            screenPinningRequested = true;
-        }
-        EventBus.getDefault().send(new LaunchTaskEvent(this, mTask, null, screenPinningRequested));
-
-        MetricsLogger.action(v.getContext(), MetricsEvent.ACTION_OVERVIEW_SELECT,
-                mTask.key.getComponent().toString());
-    }
-
-    /**** View.OnLongClickListener Implementation ****/
-
-    @Override
-    public boolean onLongClick(View v) {
-        if (!Recents.getConfiguration().dragToSplitEnabled) {
-            return false;
-        }
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        boolean inBounds = false;
-        Rect clipBounds = new Rect(mViewBounds.getClipBounds());
-        if (!clipBounds.isEmpty()) {
-            // If we are clipping the view to the bounds, manually do the hit test.
-            clipBounds.scale(getScaleX());
-            inBounds = clipBounds.contains(mDownTouchPos.x, mDownTouchPos.y);
-        } else {
-            // Otherwise just make sure we're within the view's bounds.
-            inBounds = mDownTouchPos.x <= getWidth() && mDownTouchPos.y <= getHeight();
-        }
-        if (v == this && inBounds && !ssp.hasDockedTask()) {
-            // Start listening for drag events
-            setClipViewInStack(false);
-
-            mDownTouchPos.x += ((1f - getScaleX()) * getWidth()) / 2;
-            mDownTouchPos.y += ((1f - getScaleY()) * getHeight()) / 2;
-
-            EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
-            EventBus.getDefault().send(new DragStartEvent(mTask, this, mDownTouchPos));
-            return true;
-        }
-        return false;
-    }
-
-    /**** Events ****/
-
-    public final void onBusEvent(DragEndEvent event) {
-        if (!(event.dropTarget instanceof DockState)) {
-            event.addPostAnimationCallback(() -> {
-                // Reset the clip state for the drag view after the end animation completes
-                setClipViewInStack(true);
-            });
-        }
-        EventBus.getDefault().unregister(this);
-    }
-
-    public final void onBusEvent(DragEndCancelledEvent event) {
-        // Reset the clip state for the drag view after the cancel animation completes
-        event.addPostAnimationCallback(() -> {
-            setClipViewInStack(true);
-        });
-    }
-
-    public void dump(String prefix, PrintWriter writer) {
-        String innerPrefix = prefix + "  ";
-
-        writer.print(prefix); writer.print("TaskView");
-        writer.print(" mTask="); writer.print(mTask.key.id);
-        writer.println();
-
-        mThumbnailView.dump(innerPrefix, writer);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
deleted file mode 100644
index 5bb5b2d..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.views;
-
-import android.app.ActivityTaskManager;
-import android.content.Context;
-import android.graphics.Point;
-import android.os.Bundle;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-
-public class TaskViewAccessibilityDelegate extends View.AccessibilityDelegate {
-    private static final String TAG = "TaskViewAccessibilityDelegate";
-
-    private final TaskView mTaskView;
-
-    protected static final int SPLIT_TASK_TOP = R.id.action_split_task_to_top;
-    protected static final int SPLIT_TASK_LEFT = R.id.action_split_task_to_left;
-    protected static final int SPLIT_TASK_RIGHT = R.id.action_split_task_to_right;
-
-    protected final SparseArray<AccessibilityAction> mActions = new SparseArray<>();
-
-    public TaskViewAccessibilityDelegate(TaskView taskView) {
-        mTaskView = taskView;
-        Context context = taskView.getContext();
-        mActions.put(SPLIT_TASK_TOP, new AccessibilityAction(SPLIT_TASK_TOP,
-                context.getString(R.string.recents_accessibility_split_screen_top)));
-        mActions.put(SPLIT_TASK_LEFT, new AccessibilityAction(SPLIT_TASK_LEFT,
-                context.getString(R.string.recents_accessibility_split_screen_left)));
-        mActions.put(SPLIT_TASK_RIGHT, new AccessibilityAction(SPLIT_TASK_RIGHT,
-                context.getString(R.string.recents_accessibility_split_screen_right)));
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(host, info);
-        if (ActivityTaskManager.supportsSplitScreenMultiWindow(mTaskView.getContext())
-                && !Recents.getSystemServices().hasDockedTask()) {
-            DockState[] dockStates = Recents.getConfiguration()
-                    .getDockStatesForCurrentOrientation();
-            for (DockState dockState: dockStates) {
-                if (dockState == DockState.TOP) {
-                    info.addAction(mActions.get(SPLIT_TASK_TOP));
-                } else if (dockState == DockState.LEFT) {
-                    info.addAction(mActions.get(SPLIT_TASK_LEFT));
-                } else if (dockState == DockState.RIGHT) {
-                    info.addAction(mActions.get(SPLIT_TASK_RIGHT));
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean performAccessibilityAction(View host, int action, Bundle args) {
-        if (action == SPLIT_TASK_TOP) {
-            simulateDragIntoMultiwindow(DockState.TOP);
-        } else if (action == SPLIT_TASK_LEFT) {
-            simulateDragIntoMultiwindow(DockState.LEFT);
-        } else if (action == SPLIT_TASK_RIGHT) {
-            simulateDragIntoMultiwindow(DockState.RIGHT);
-        } else {
-            return super.performAccessibilityAction(host, action, args);
-        }
-        return true;
-    }
-
-    /** Simulate a user drag event to split the screen to the respected side */
-    private void simulateDragIntoMultiwindow(DockState dockState) {
-        EventBus.getDefault().send(new DragStartEvent(mTaskView.getTask(), mTaskView,
-                new Point(0,0), false /* isUserTouchInitiated */));
-        EventBus.getDefault().send(new DragEndEvent(mTaskView.getTask(), mTaskView, dockState));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
deleted file mode 100644
index de42914..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.annotation.Nullable;
-import android.app.AppGlobals;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.RippleDrawable;
-import android.os.CountDownTimer;
-import androidx.core.graphics.ColorUtils;
-import android.util.AttributeSet;
-import android.util.IconDrawableFactory;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewAnimationUtils;
-import android.view.ViewDebug;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Constants;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.LaunchTaskEvent;
-import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.PackageManagerWrapper;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-
-/* The task bar view */
-public class TaskViewHeader extends FrameLayout
-        implements View.OnClickListener, View.OnLongClickListener {
-
-    private static IconDrawableFactory sDrawableFactory;
-
-    private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.075f;
-    private static final float OVERLAY_LIGHTNESS_INCREMENT = -0.0625f;
-    private static final int OVERLAY_REVEAL_DURATION = 250;
-    private static final long FOCUS_INDICATOR_INTERVAL_MS = 30;
-
-    /**
-     * A color drawable that draws a slight highlight at the top to help it stand out.
-     */
-    private class HighlightColorDrawable extends Drawable {
-
-        private Paint mHighlightPaint = new Paint();
-        private Paint mBackgroundPaint = new Paint();
-        private int mColor;
-        private float mDimAlpha;
-
-        public HighlightColorDrawable() {
-            mBackgroundPaint.setColor(Color.argb(255, 0, 0, 0));
-            mBackgroundPaint.setAntiAlias(true);
-            mHighlightPaint.setColor(Color.argb(255, 255, 255, 255));
-            mHighlightPaint.setAntiAlias(true);
-        }
-
-        public void setColorAndDim(int color, float dimAlpha) {
-            if (mColor != color || Float.compare(mDimAlpha, dimAlpha) != 0) {
-                mColor = color;
-                mDimAlpha = dimAlpha;
-                if (mShouldDarkenBackgroundColor) {
-                    color = getSecondaryColor(color, false /* useLightOverlayColor */);
-                }
-                mBackgroundPaint.setColor(color);
-
-                ColorUtils.colorToHSL(color, mTmpHSL);
-                // TODO: Consider using the saturation of the color to adjust the lightness as well
-                mTmpHSL[2] = Math.min(1f,
-                        mTmpHSL[2] + HIGHLIGHT_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
-                mHighlightPaint.setColor(ColorUtils.HSLToColor(mTmpHSL));
-
-                invalidateSelf();
-            }
-        }
-
-        @Override
-        public void setColorFilter(@Nullable ColorFilter colorFilter) {
-            // Do nothing
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-            // Do nothing
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            // Draw the highlight at the top edge (but put the bottom edge just out of view)
-            canvas.drawRoundRect(0, 0, mTaskViewRect.width(),
-                    2 * Math.max(mHighlightHeight, mCornerRadius),
-                    mCornerRadius, mCornerRadius, mHighlightPaint);
-
-            // Draw the background with the rounded corners
-            canvas.drawRoundRect(0, mHighlightHeight, mTaskViewRect.width(),
-                    getHeight() + mCornerRadius,
-                    mCornerRadius, mCornerRadius, mBackgroundPaint);
-        }
-
-        @Override
-        public int getOpacity() {
-            return PixelFormat.OPAQUE;
-        }
-
-        public int getColor() {
-            return mColor;
-        }
-    }
-
-    Task mTask;
-
-    // Header views
-    ImageView mIconView;
-    TextView mTitleView;
-    ImageView mMoveTaskButton;
-    ImageView mDismissButton;
-    FrameLayout mAppOverlayView;
-    ImageView mAppIconView;
-    ImageView mAppInfoView;
-    TextView mAppTitleView;
-    ProgressBar mFocusTimerIndicator;
-
-    // Header drawables
-    @ViewDebug.ExportedProperty(category="recents")
-    Rect mTaskViewRect = new Rect();
-    int mHeaderBarHeight;
-    int mHeaderButtonPadding;
-    int mCornerRadius;
-    int mHighlightHeight;
-    @ViewDebug.ExportedProperty(category="recents")
-    float mDimAlpha;
-    Drawable mLightDismissDrawable;
-    Drawable mDarkDismissDrawable;
-    Drawable mLightFullscreenIcon;
-    Drawable mDarkFullscreenIcon;
-    Drawable mLightInfoIcon;
-    Drawable mDarkInfoIcon;
-    int mTaskBarViewLightTextColor;
-    int mTaskBarViewDarkTextColor;
-    int mDisabledTaskBarBackgroundColor;
-    String mDismissDescFormat;
-    String mAppInfoDescFormat;
-    int mTaskWindowingMode = WINDOWING_MODE_UNDEFINED;
-
-    // Header background
-    private HighlightColorDrawable mBackground;
-    private HighlightColorDrawable mOverlayBackground;
-    private float[] mTmpHSL = new float[3];
-
-    // Header dim, which is only used when task view hardware layers are not used
-    private Paint mDimLayerPaint = new Paint();
-
-    // Whether the background color should be darkened to differentiate from the primary color.
-    // Used in grid layout.
-    private boolean mShouldDarkenBackgroundColor = false;
-
-    private CountDownTimer mFocusTimerCountDown;
-
-    public TaskViewHeader(Context context) {
-        this(context, null);
-    }
-
-    public TaskViewHeader(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        setWillNotDraw(false);
-
-        // Load the dismiss resources
-        Resources res = context.getResources();
-        mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
-        mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
-        mCornerRadius = Recents.getConfiguration().isGridEnabled ?
-                res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) :
-                res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
-        mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
-        mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
-        mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
-        mLightFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_light);
-        mDarkFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_dark);
-        mLightInfoIcon = context.getDrawable(R.drawable.recents_info_light);
-        mDarkInfoIcon = context.getDrawable(R.drawable.recents_info_dark);
-        mDisabledTaskBarBackgroundColor =
-                context.getColor(R.color.recents_task_bar_disabled_background_color);
-        mDismissDescFormat = mContext.getString(
-                R.string.accessibility_recents_item_will_be_dismissed);
-        mAppInfoDescFormat = mContext.getString(R.string.accessibility_recents_item_open_app_info);
-
-        // Configure the background and dim
-        mBackground = new HighlightColorDrawable();
-        mBackground.setColorAndDim(Color.argb(255, 0, 0, 0), 0f);
-        setBackground(mBackground);
-        mOverlayBackground = new HighlightColorDrawable();
-        mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
-        mDimLayerPaint.setAntiAlias(true);
-    }
-
-    /**
-     * Resets this header along with the TaskView.
-     */
-    public void reset() {
-        hideAppOverlay(true /* immediate */);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        SystemServicesProxy ssp = Recents.getSystemServices();
-
-        // Initialize the icon and description views
-        mIconView = findViewById(R.id.icon);
-        mIconView.setOnLongClickListener(this);
-        mTitleView = findViewById(R.id.title);
-        mDismissButton = findViewById(R.id.dismiss_task);
-
-        onConfigurationChanged();
-    }
-
-    /**
-     * Programmatically sets the layout params for a header bar layout.  This is necessary because
-     * we can't get resources based on the current configuration, but instead need to get them
-     * based on the device configuration.
-     */
-    private void updateLayoutParams(View icon, View title, View secondaryButton, View button) {
-        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, mHeaderBarHeight, Gravity.TOP);
-        setLayoutParams(lp);
-        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.START);
-        icon.setLayoutParams(lp);
-        lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
-        lp.setMarginStart(mHeaderBarHeight);
-        lp.setMarginEnd(mMoveTaskButton != null
-                ? 2 * mHeaderBarHeight
-                : mHeaderBarHeight);
-        title.setLayoutParams(lp);
-        if (secondaryButton != null) {
-            lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
-            lp.setMarginEnd(mHeaderBarHeight);
-            secondaryButton.setLayoutParams(lp);
-            secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
-                    mHeaderButtonPadding, mHeaderButtonPadding);
-        }
-        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
-        button.setLayoutParams(lp);
-        button.setPadding(mHeaderButtonPadding, mHeaderButtonPadding, mHeaderButtonPadding,
-                mHeaderButtonPadding);
-    }
-
-    /**
-     * Update the header view when the configuration changes.
-     */
-    public void onConfigurationChanged() {
-        // Update the dimensions of everything in the header. We do this because we need to use
-        // resources for the display, and not the current configuration.
-        Resources res = getResources();
-        int headerBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height_tablet_land,
-                R.dimen.recents_task_view_header_height,
-                R.dimen.recents_task_view_header_height_tablet_land,
-                R.dimen.recents_grid_task_view_header_height);
-        int headerButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
-                R.dimen.recents_task_view_header_button_padding,
-                R.dimen.recents_task_view_header_button_padding,
-                R.dimen.recents_task_view_header_button_padding,
-                R.dimen.recents_task_view_header_button_padding_tablet_land,
-                R.dimen.recents_task_view_header_button_padding,
-                R.dimen.recents_task_view_header_button_padding_tablet_land,
-                R.dimen.recents_grid_task_view_header_button_padding);
-        if (headerBarHeight != mHeaderBarHeight || headerButtonPadding != mHeaderButtonPadding) {
-            mHeaderBarHeight = headerBarHeight;
-            mHeaderButtonPadding = headerButtonPadding;
-            updateLayoutParams(mIconView, mTitleView, mMoveTaskButton, mDismissButton);
-            if (mAppOverlayView != null) {
-                updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
-            }
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-
-        // Since we update the position of children based on the width of the parent and this view
-        // recompute these changes with the new view size
-        onTaskViewSizeChanged(mTaskViewRect.width(), mTaskViewRect.height());
-    }
-
-    /**
-     * Called when the task view frame changes, allowing us to move the contents of the header
-     * to match the frame changes.
-     */
-    public void onTaskViewSizeChanged(int width, int height) {
-        mTaskViewRect.set(0, 0, width, height);
-
-        boolean showTitle = true;
-        boolean showMoveIcon = true;
-        boolean showDismissIcon = true;
-        int rightInset = width - getMeasuredWidth();
-
-        mTitleView.setVisibility(showTitle ? View.VISIBLE : View.INVISIBLE);
-        if (mMoveTaskButton != null) {
-            mMoveTaskButton.setVisibility(showMoveIcon ? View.VISIBLE : View.INVISIBLE);
-            mMoveTaskButton.setTranslationX(rightInset);
-        }
-        mDismissButton.setVisibility(showDismissIcon ? View.VISIBLE : View.INVISIBLE);
-        mDismissButton.setTranslationX(rightInset);
-
-        setLeftTopRightBottom(0, 0, width, getMeasuredHeight());
-    }
-
-    @Override
-    public void onDrawForeground(Canvas canvas) {
-        super.onDrawForeground(canvas);
-
-        // Draw the dim layer with the rounded corners
-        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight() + mCornerRadius,
-                mCornerRadius, mCornerRadius, mDimLayerPaint);
-    }
-
-    /** Starts the focus timer. */
-    public void startFocusTimerIndicator(int duration) {
-        if (mFocusTimerIndicator == null) {
-            return;
-        }
-
-        mFocusTimerIndicator.setVisibility(View.VISIBLE);
-        mFocusTimerIndicator.setMax(duration);
-        mFocusTimerIndicator.setProgress(duration);
-        if (mFocusTimerCountDown != null) {
-            mFocusTimerCountDown.cancel();
-        }
-        mFocusTimerCountDown = new CountDownTimer(duration,
-                FOCUS_INDICATOR_INTERVAL_MS) {
-            public void onTick(long millisUntilFinished) {
-                mFocusTimerIndicator.setProgress((int) millisUntilFinished);
-            }
-
-            public void onFinish() {
-                // Do nothing
-            }
-        }.start();
-    }
-
-    /** Cancels the focus timer. */
-    public void cancelFocusTimerIndicator() {
-        if (mFocusTimerIndicator == null) {
-            return;
-        }
-
-        if (mFocusTimerCountDown != null) {
-            mFocusTimerCountDown.cancel();
-            mFocusTimerIndicator.setProgress(0);
-            mFocusTimerIndicator.setVisibility(View.INVISIBLE);
-        }
-    }
-
-    /** Only exposed for the workaround for b/27815919. */
-    public ImageView getIconView() {
-        return mIconView;
-    }
-
-    /** Returns the secondary color for a primary color. */
-    int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) {
-        int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK;
-        return Utilities.getColorWithOverlay(primaryColor, overlayColor, 0.8f);
-    }
-
-    /**
-     * Sets the dim alpha, only used when we are not using hardware layers.
-     * (see RecentsConfiguration.useHardwareLayers)
-     */
-    public void setDimAlpha(float dimAlpha) {
-        if (Float.compare(mDimAlpha, dimAlpha) != 0) {
-            mDimAlpha = dimAlpha;
-            mTitleView.setAlpha(1f - dimAlpha);
-            updateBackgroundColor(mBackground.getColor(), dimAlpha);
-        }
-    }
-
-    /**
-     * Updates the background and highlight colors for this header.
-     */
-    private void updateBackgroundColor(int color, float dimAlpha) {
-        if (mTask != null) {
-            mBackground.setColorAndDim(color, dimAlpha);
-            // TODO: Consider using the saturation of the color to adjust the lightness as well
-            ColorUtils.colorToHSL(color, mTmpHSL);
-            mTmpHSL[2] = Math.min(1f, mTmpHSL[2] + OVERLAY_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
-            mOverlayBackground.setColorAndDim(ColorUtils.HSLToColor(mTmpHSL), dimAlpha);
-            mDimLayerPaint.setAlpha((int) (dimAlpha * 255));
-            invalidate();
-        }
-    }
-
-    /**
-     * Sets whether the background color should be darkened to differentiate from the primary color.
-     */
-    public void setShouldDarkenBackgroundColor(boolean flag) {
-        mShouldDarkenBackgroundColor = flag;
-    }
-
-    /**
-     * Binds the bar view to the task.
-     */
-    public void bindToTask(Task t, boolean touchExplorationEnabled, boolean disabledInSafeMode) {
-        mTask = t;
-
-        int primaryColor = disabledInSafeMode
-                ? mDisabledTaskBarBackgroundColor
-                : t.colorPrimary;
-        if (mBackground.getColor() != primaryColor) {
-            updateBackgroundColor(primaryColor, mDimAlpha);
-        }
-        if (!mTitleView.getText().toString().equals(t.title)) {
-            mTitleView.setText(t.title);
-        }
-        mTitleView.setContentDescription(t.titleDescription);
-        mTitleView.setTextColor(t.useLightOnPrimaryColor ?
-                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
-        mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
-                mLightDismissDrawable : mDarkDismissDrawable);
-        mDismissButton.setContentDescription(String.format(mDismissDescFormat, t.titleDescription));
-        mDismissButton.setOnClickListener(this);
-        mDismissButton.setClickable(false);
-        ((RippleDrawable) mDismissButton.getBackground()).setForceSoftware(true);
-
-        // In accessibility, a single click on the focused app info button will show it
-        if (touchExplorationEnabled) {
-            mIconView.setContentDescription(String.format(mAppInfoDescFormat, t.titleDescription));
-            mIconView.setOnClickListener(this);
-            mIconView.setClickable(true);
-        }
-    }
-
-    /**
-     * Called when the bound task's data has loaded and this view should update to reflect the
-     * changes.
-     */
-    public void onTaskDataLoaded() {
-        if (mTask != null && mTask.icon != null) {
-            mIconView.setImageDrawable(mTask.icon);
-        }
-    }
-
-    /** Unbinds the bar view from the task */
-    void unbindFromTask(boolean touchExplorationEnabled) {
-        mTask = null;
-        mIconView.setImageDrawable(null);
-        if (touchExplorationEnabled) {
-            mIconView.setClickable(false);
-        }
-    }
-
-    /** Animates this task bar if the user does not interact with the stack after a certain time. */
-    void startNoUserInteractionAnimation() {
-        int duration = getResources().getInteger(R.integer.recents_task_enter_from_app_duration);
-        mDismissButton.setVisibility(View.VISIBLE);
-        mDismissButton.setClickable(true);
-        if (mDismissButton.getVisibility() == VISIBLE) {
-            mDismissButton.animate()
-                    .alpha(1f)
-                    .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
-                    .setDuration(duration)
-                    .start();
-        } else {
-            mDismissButton.setAlpha(1f);
-        }
-        if (mMoveTaskButton != null) {
-            if (mMoveTaskButton.getVisibility() == VISIBLE) {
-                mMoveTaskButton.setVisibility(View.VISIBLE);
-                mMoveTaskButton.setClickable(true);
-                mMoveTaskButton.animate()
-                        .alpha(1f)
-                        .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
-                        .setDuration(duration)
-                        .start();
-            } else {
-                mMoveTaskButton.setAlpha(1f);
-            }
-        }
-    }
-
-    /**
-     * Mark this task view that the user does has not interacted with the stack after a certain
-     * time.
-     */
-    public void setNoUserInteractionState() {
-        mDismissButton.setVisibility(View.VISIBLE);
-        mDismissButton.animate().cancel();
-        mDismissButton.setAlpha(1f);
-        mDismissButton.setClickable(true);
-        if (mMoveTaskButton != null) {
-            mMoveTaskButton.setVisibility(View.VISIBLE);
-            mMoveTaskButton.animate().cancel();
-            mMoveTaskButton.setAlpha(1f);
-            mMoveTaskButton.setClickable(true);
-        }
-    }
-
-    /**
-     * Resets the state tracking that the user has not interacted with the stack after a certain
-     * time.
-     */
-    void resetNoUserInteractionState() {
-        mDismissButton.setVisibility(View.INVISIBLE);
-        mDismissButton.setAlpha(0f);
-        mDismissButton.setClickable(false);
-        if (mMoveTaskButton != null) {
-            mMoveTaskButton.setVisibility(View.INVISIBLE);
-            mMoveTaskButton.setAlpha(0f);
-            mMoveTaskButton.setClickable(false);
-        }
-    }
-
-    @Override
-    protected int[] onCreateDrawableState(int extraSpace) {
-
-        // Don't forward our state to the drawable - we do it manually in onTaskViewFocusChanged.
-        // This is to prevent layer trashing when the view is pressed.
-        return new int[] {};
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (v == mIconView) {
-            // In accessibility, a single click on the focused app info button will show it
-            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
-        } else if (v == mDismissButton) {
-            TaskView tv = Utilities.findParent(this, TaskView.class);
-            tv.dismissTask();
-
-            // Keep track of deletions by the dismiss button
-            MetricsLogger.histogram(getContext(), "overview_task_dismissed_source",
-                    Constants.Metrics.DismissSourceHeaderButton);
-        } else if (v == mMoveTaskButton) {
-            TaskView tv = Utilities.findParent(this, TaskView.class);
-            EventBus.getDefault().send(new LaunchTaskEvent(tv, mTask, null, false,
-                    mTaskWindowingMode, ACTIVITY_TYPE_UNDEFINED));
-        } else if (v == mAppInfoView) {
-            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
-        } else if (v == mAppIconView) {
-            hideAppOverlay(false /* immediate */);
-        }
-    }
-
-    @Override
-    public boolean onLongClick(View v) {
-        if (v == mIconView) {
-            showAppOverlay();
-            return true;
-        } else if (v == mAppIconView) {
-            hideAppOverlay(false /* immediate */);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Shows the application overlay.
-     */
-    private void showAppOverlay() {
-        // Skip early if the task is invalid
-        SystemServicesProxy ssp = Recents.getSystemServices();
-        ComponentName cn = mTask.key.getComponent();
-        int userId = mTask.key.userId;
-        ActivityInfo activityInfo = PackageManagerWrapper.getInstance().getActivityInfo(cn, userId);
-        if (activityInfo == null) {
-            return;
-        }
-
-        // Inflate the overlay if necessary
-        if (mAppOverlayView == null) {
-            mAppOverlayView = (FrameLayout) Utilities.findViewStubById(this,
-                    R.id.app_overlay_stub).inflate();
-            mAppOverlayView.setBackground(mOverlayBackground);
-            mAppIconView = (ImageView) mAppOverlayView.findViewById(R.id.app_icon);
-            mAppIconView.setOnClickListener(this);
-            mAppIconView.setOnLongClickListener(this);
-            mAppInfoView = (ImageView) mAppOverlayView.findViewById(R.id.app_info);
-            mAppInfoView.setOnClickListener(this);
-            mAppTitleView = (TextView) mAppOverlayView.findViewById(R.id.app_title);
-            updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
-        }
-
-        // Update the overlay contents for the current app
-        mAppTitleView.setText(ActivityManagerWrapper.getInstance().getBadgedApplicationLabel(
-                activityInfo.applicationInfo, userId));
-        mAppTitleView.setTextColor(mTask.useLightOnPrimaryColor ?
-                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
-        mAppIconView.setImageDrawable(getIconDrawableFactory().getBadgedIcon(
-                activityInfo.applicationInfo, userId));
-        mAppInfoView.setImageDrawable(mTask.useLightOnPrimaryColor
-                ? mLightInfoIcon
-                : mDarkInfoIcon);
-        mAppOverlayView.setVisibility(View.VISIBLE);
-
-        int x = mIconView.getLeft() + mIconView.getWidth() / 2;
-        int y = mIconView.getTop() + mIconView.getHeight() / 2;
-        Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y, 0,
-                getWidth());
-        revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
-        revealAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-        revealAnim.start();
-    }
-
-    /**
-     * Hide the application overlay.
-     */
-    private void hideAppOverlay(boolean immediate) {
-        // Skip if we haven't even loaded the overlay yet
-        if (mAppOverlayView == null) {
-            return;
-        }
-
-        if (immediate) {
-            mAppOverlayView.setVisibility(View.GONE);
-        } else {
-            int x = mIconView.getLeft() + mIconView.getWidth() / 2;
-            int y = mIconView.getTop() + mIconView.getHeight() / 2;
-            Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y,
-                    getWidth(), 0);
-            revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
-            revealAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-            revealAnim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mAppOverlayView.setVisibility(View.GONE);
-                }
-            });
-            revealAnim.start();
-        }
-    }
-
-    private static IconDrawableFactory getIconDrawableFactory() {
-        if (sDrawableFactory == null) {
-            sDrawableFactory = IconDrawableFactory.newInstance(AppGlobals.getInitialApplication());
-        }
-        return sDrawableFactory;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
deleted file mode 100644
index 4152b05..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.LightingColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.Shader;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewDebug;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.ui.TaskSnapshotChangedEvent;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-import java.io.PrintWriter;
-
-
-/**
- * The task thumbnail view.  It implements an image view that allows for animating the dim and
- * alpha of the thumbnail image.
- */
-public class TaskViewThumbnail extends View {
-
-    private static final ColorMatrix TMP_FILTER_COLOR_MATRIX = new ColorMatrix();
-    private static final ColorMatrix TMP_BRIGHTNESS_COLOR_MATRIX = new ColorMatrix();
-
-    private Task mTask;
-
-    private int mDisplayOrientation = Configuration.ORIENTATION_UNDEFINED;
-    private Rect mDisplayRect = new Rect();
-
-    // Drawing
-    @ViewDebug.ExportedProperty(category="recents")
-    protected Rect mTaskViewRect = new Rect();
-    @ViewDebug.ExportedProperty(category="recents")
-    protected Rect mThumbnailRect = new Rect();
-    @ViewDebug.ExportedProperty(category="recents")
-    protected float mThumbnailScale;
-    private float mFullscreenThumbnailScale = 1f;
-    /** The height, in pixels, of the task view's title bar. */
-    private int mTitleBarHeight;
-    private boolean mSizeToFit = false;
-    private boolean mOverlayHeaderOnThumbnailActionBar = true;
-    private ThumbnailData mThumbnailData;
-
-    protected int mCornerRadius;
-    @ViewDebug.ExportedProperty(category="recents")
-    private float mDimAlpha;
-    private Matrix mMatrix = new Matrix();
-    private Paint mDrawPaint = new Paint();
-    protected Paint mLockedPaint = new Paint();
-    protected Paint mBgFillPaint = new Paint();
-    protected BitmapShader mBitmapShader;
-    protected boolean mUserLocked = false;
-    private LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0);
-
-    // Clip the top of the thumbnail against the opaque header bar that overlaps this view
-    private View mTaskBar;
-
-    // Visibility optimization, if the thumbnail height is less than the height of the header
-    // bar for the task view, then just mark this thumbnail view as invisible
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mInvisible;
-
-    @ViewDebug.ExportedProperty(category="recents")
-    private boolean mDisabledInSafeMode;
-
-    public TaskViewThumbnail(Context context) {
-        this(context, null);
-    }
-
-    public TaskViewThumbnail(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public TaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public TaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        mDrawPaint.setColorFilter(mLightingColorFilter);
-        mDrawPaint.setFilterBitmap(true);
-        mDrawPaint.setAntiAlias(true);
-        Resources res = getResources();
-        mCornerRadius = res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
-        mBgFillPaint.setColor(Color.WHITE);
-        mLockedPaint.setColor(Color.WHITE);
-        mTitleBarHeight = res.getDimensionPixelSize(R.dimen.recents_grid_task_view_header_height);
-    }
-
-    /**
-     * Called when the task view frame changes, allowing us to move the contents of the header
-     * to match the frame changes.
-     */
-    public void onTaskViewSizeChanged(int width, int height) {
-        // Return early if the bounds have not changed
-        if (mTaskViewRect.width() == width && mTaskViewRect.height() == height) {
-            return;
-        }
-
-        mTaskViewRect.set(0, 0, width, height);
-        setLeftTopRightBottom(0, 0, width, height);
-        updateThumbnailMatrix();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        if (mInvisible) {
-            return;
-        }
-
-        int viewWidth = mTaskViewRect.width();
-        int viewHeight = mTaskViewRect.height();
-        int thumbnailWidth = Math.min(viewWidth,
-                (int) (mThumbnailRect.width() * mThumbnailScale));
-        int thumbnailHeight = Math.min(viewHeight,
-                (int) (mThumbnailRect.height() * mThumbnailScale));
-
-        if (mUserLocked) {
-            canvas.drawRoundRect(0, 0, viewWidth, viewHeight, mCornerRadius, mCornerRadius,
-                    mLockedPaint);
-        } else if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
-            int topOffset = 0;
-            if (mTaskBar != null && mOverlayHeaderOnThumbnailActionBar) {
-                topOffset = mTaskBar.getHeight() - mCornerRadius;
-            }
-
-            // Draw the background, there will be some small overdraw with the thumbnail
-            if (thumbnailWidth < viewWidth) {
-                // Portrait thumbnail on a landscape task view
-                canvas.drawRoundRect(Math.max(0, thumbnailWidth - mCornerRadius), topOffset,
-                        viewWidth, viewHeight,
-                        mCornerRadius, mCornerRadius, mBgFillPaint);
-            }
-            if (thumbnailHeight < viewHeight) {
-                // Landscape thumbnail on a portrait task view
-                canvas.drawRoundRect(0, Math.max(topOffset, thumbnailHeight - mCornerRadius),
-                        viewWidth, viewHeight,
-                        mCornerRadius, mCornerRadius, mBgFillPaint);
-            }
-
-            // Draw the thumbnail
-            canvas.drawRoundRect(0, topOffset, thumbnailWidth, thumbnailHeight,
-                    mCornerRadius, mCornerRadius, mDrawPaint);
-        } else {
-            canvas.drawRoundRect(0, 0, viewWidth, viewHeight, mCornerRadius, mCornerRadius,
-                    mBgFillPaint);
-        }
-    }
-
-    /** Sets the thumbnail to a given bitmap. */
-    void setThumbnail(ThumbnailData thumbnailData) {
-        if (thumbnailData != null && thumbnailData.thumbnail != null) {
-            Bitmap bm = thumbnailData.thumbnail;
-            bm.prepareToDraw();
-            mFullscreenThumbnailScale = thumbnailData.scale;
-            mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
-            mDrawPaint.setShader(mBitmapShader);
-            mThumbnailRect.set(0, 0,
-                    bm.getWidth() - thumbnailData.insets.left - thumbnailData.insets.right,
-                    bm.getHeight() - thumbnailData.insets.top - thumbnailData.insets.bottom);
-            mThumbnailData = thumbnailData;
-            updateThumbnailMatrix();
-            updateThumbnailPaintFilter();
-        } else {
-            mBitmapShader = null;
-            mDrawPaint.setShader(null);
-            mThumbnailRect.setEmpty();
-            mThumbnailData = null;
-        }
-    }
-
-    /** Updates the paint to draw the thumbnail. */
-    void updateThumbnailPaintFilter() {
-        if (mInvisible) {
-            return;
-        }
-        int mul = (int) ((1.0f - mDimAlpha) * 255);
-        if (mBitmapShader != null) {
-            if (mDisabledInSafeMode) {
-                // Brightness: C-new = C-old*(1-amount) + amount
-                TMP_FILTER_COLOR_MATRIX.setSaturation(0);
-                float scale = 1f - mDimAlpha;
-                float[] mat = TMP_BRIGHTNESS_COLOR_MATRIX.getArray();
-                mat[0] = scale;
-                mat[6] = scale;
-                mat[12] = scale;
-                mat[4] = mDimAlpha * 255f;
-                mat[9] = mDimAlpha * 255f;
-                mat[14] = mDimAlpha * 255f;
-                TMP_FILTER_COLOR_MATRIX.preConcat(TMP_BRIGHTNESS_COLOR_MATRIX);
-                ColorMatrixColorFilter filter = new ColorMatrixColorFilter(TMP_FILTER_COLOR_MATRIX);
-                mDrawPaint.setColorFilter(filter);
-                mBgFillPaint.setColorFilter(filter);
-                mLockedPaint.setColorFilter(filter);
-            } else {
-                mLightingColorFilter.setColorMultiply(Color.argb(255, mul, mul, mul));
-                mDrawPaint.setColorFilter(mLightingColorFilter);
-                mDrawPaint.setColor(0xFFffffff);
-                mBgFillPaint.setColorFilter(mLightingColorFilter);
-                mLockedPaint.setColorFilter(mLightingColorFilter);
-            }
-        } else {
-            int grey = mul;
-            mDrawPaint.setColorFilter(null);
-            mDrawPaint.setColor(Color.argb(255, grey, grey, grey));
-        }
-        if (!mInvisible) {
-            invalidate();
-        }
-    }
-
-    /**
-     * Updates the scale of the bitmap relative to this view.
-     */
-    public void updateThumbnailMatrix() {
-        mThumbnailScale = 1f;
-        if (mBitmapShader != null && mThumbnailData != null) {
-            if (mTaskViewRect.isEmpty()) {
-                // If we haven't measured , skip the thumbnail drawing and only draw the background
-                // color
-                mThumbnailScale = 0f;
-            } else if (mSizeToFit) {
-                // Make sure we fill the entire space regardless of the orientation.
-                float viewAspectRatio = (float) mTaskViewRect.width() /
-                        (float) (mTaskViewRect.height() - mTitleBarHeight);
-                float thumbnailAspectRatio =
-                        (float) mThumbnailRect.width() / (float) mThumbnailRect.height();
-                if (viewAspectRatio > thumbnailAspectRatio) {
-                    mThumbnailScale =
-                            (float) mTaskViewRect.width() / (float) mThumbnailRect.width();
-                } else {
-                    mThumbnailScale = (float) (mTaskViewRect.height() - mTitleBarHeight)
-                            / (float) mThumbnailRect.height();
-                }
-            } else {
-                float invThumbnailScale = 1f / mFullscreenThumbnailScale;
-                if (mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT) {
-                    if (mThumbnailData.orientation == Configuration.ORIENTATION_PORTRAIT) {
-                        // If we are in the same orientation as the screenshot, just scale it to the
-                        // width of the task view
-                        mThumbnailScale = (float) mTaskViewRect.width() / mThumbnailRect.width();
-                    } else {
-                        // Scale the landscape thumbnail up to app size, then scale that to the task
-                        // view size to match other portrait screenshots
-                        mThumbnailScale = invThumbnailScale *
-                                ((float) mTaskViewRect.width() / mDisplayRect.width());
-                    }
-                } else {
-                    // Otherwise, scale the screenshot to fit 1:1 in the current orientation
-                    mThumbnailScale = invThumbnailScale;
-                }
-            }
-            mMatrix.setTranslate(-mThumbnailData.insets.left * mFullscreenThumbnailScale,
-                    -mThumbnailData.insets.top * mFullscreenThumbnailScale);
-            mMatrix.postScale(mThumbnailScale, mThumbnailScale);
-            mBitmapShader.setLocalMatrix(mMatrix);
-        }
-        if (!mInvisible) {
-            invalidate();
-        }
-    }
-
-    /** Sets whether the thumbnail should be resized to fit the task view in all orientations. */
-    public void setSizeToFit(boolean flag) {
-        mSizeToFit = flag;
-    }
-
-    /**
-     * Sets whether the header should overlap (and hide) the action bar in the thumbnail, or
-     * be stacked just above it.
-     */
-    public void setOverlayHeaderOnThumbnailActionBar(boolean flag) {
-        mOverlayHeaderOnThumbnailActionBar = flag;
-    }
-
-    /** Updates the clip rect based on the given task bar. */
-    void updateClipToTaskBar(View taskBar) {
-        mTaskBar = taskBar;
-        invalidate();
-    }
-
-    /** Updates the visibility of the the thumbnail. */
-    void updateThumbnailVisibility(int clipBottom) {
-        boolean invisible = mTaskBar != null && (getHeight() - clipBottom) <= mTaskBar.getHeight();
-        if (invisible != mInvisible) {
-            mInvisible = invisible;
-            if (!mInvisible) {
-                updateThumbnailPaintFilter();
-            }
-        }
-    }
-
-    /**
-     * Sets the dim alpha, only used when we are not using hardware layers.
-     * (see RecentsConfiguration.useHardwareLayers)
-     */
-    public void setDimAlpha(float dimAlpha) {
-        mDimAlpha = dimAlpha;
-        updateThumbnailPaintFilter();
-    }
-
-    /**
-     * Returns the {@link Paint} used to draw a task screenshot, or {@link #mLockedPaint} if the
-     * thumbnail shouldn't be drawn because it belongs to a locked user.
-     */
-    protected Paint getDrawPaint() {
-        if (mUserLocked) {
-            return mLockedPaint;
-        }
-        return mDrawPaint;
-    }
-
-    /**
-     * Binds the thumbnail view to the task.
-     */
-    void bindToTask(Task t, boolean disabledInSafeMode, int displayOrientation, Rect displayRect) {
-        mTask = t;
-        mDisabledInSafeMode = disabledInSafeMode;
-        mDisplayOrientation = displayOrientation;
-        mDisplayRect.set(displayRect);
-        if (t.colorBackground != 0) {
-            mBgFillPaint.setColor(t.colorBackground);
-        }
-        if (t.colorPrimary != 0) {
-            mLockedPaint.setColor(t.colorPrimary);
-        }
-        mUserLocked = t.isLocked;
-        EventBus.getDefault().register(this);
-    }
-
-    /**
-     * Called when the bound task's data has loaded and this view should update to reflect the
-     * changes.
-     */
-    void onTaskDataLoaded(ThumbnailData thumbnailData) {
-        setThumbnail(thumbnailData);
-    }
-
-    /** Unbinds the thumbnail view from the task */
-    void unbindFromTask() {
-        mTask = null;
-        setThumbnail(null);
-        EventBus.getDefault().unregister(this);
-    }
-
-    public final void onBusEvent(TaskSnapshotChangedEvent event) {
-        if (mTask == null || event.taskId != mTask.key.id || event.thumbnailData == null
-                || event.thumbnailData.thumbnail == null) {
-            return;
-        }
-        setThumbnail(event.thumbnailData);
-    }
-
-    public void dump(String prefix, PrintWriter writer) {
-        writer.print(prefix); writer.print("TaskViewThumbnail");
-        writer.print(" mTaskViewRect="); writer.print(Utilities.dumpRect(mTaskViewRect));
-        writer.print(" mThumbnailRect="); writer.print(Utilities.dumpRect(mThumbnailRect));
-        writer.print(" mThumbnailScale="); writer.print(mThumbnailScale);
-        writer.print(" mDimAlpha="); writer.print(mDimAlpha);
-        writer.println();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
deleted file mode 100644
index 9b717e0..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.util.Property;
-import android.view.View;
-
-import com.android.systemui.shared.recents.utilities.AnimationProps;
-import com.android.systemui.shared.recents.utilities.Utilities;
-
-import java.util.ArrayList;
-
-/**
- * The visual properties for a {@link TaskView}.
- */
-public class TaskViewTransform {
-
-    public static final Property<View, Rect> LTRB =
-            new Property<View, Rect>(Rect.class, "leftTopRightBottom") {
-
-                private Rect mTmpRect = new Rect();
-
-                @Override
-                public void set(View v, Rect ltrb) {
-                    v.setLeftTopRightBottom(ltrb.left, ltrb.top, ltrb.right, ltrb.bottom);
-                }
-
-                @Override
-                public Rect get(View v) {
-                    mTmpRect.set(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
-                    return mTmpRect;
-                }
-            };
-
-    public float translationZ = 0;
-    public float scale = 1f;
-    public float alpha = 1f;
-    public float dimAlpha = 0f;
-    public float viewOutlineAlpha = 0f;
-
-    public boolean visible = false;
-
-    // This is a window-space rect used for positioning the task in the stack
-    public RectF rect = new RectF();
-
-    /**
-     * Fills int this transform from the state of the given TaskView.
-     */
-    public void fillIn(TaskView tv) {
-        translationZ = tv.getTranslationZ();
-        scale = tv.getScaleX();
-        alpha = tv.getAlpha();
-        visible = true;
-        dimAlpha = tv.getDimAlpha();
-        viewOutlineAlpha = tv.getViewBounds().getAlpha();
-        rect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
-    }
-
-    /**
-     * Copies the transform state from another {@link TaskViewTransform}.
-     */
-    public void copyFrom(TaskViewTransform other) {
-        translationZ = other.translationZ;
-        scale = other.scale;
-        alpha = other.alpha;
-        visible = other.visible;
-        dimAlpha = other.dimAlpha;
-        viewOutlineAlpha = other.viewOutlineAlpha;
-        rect.set(other.rect);
-    }
-
-    /**
-     * @return whether {@param other} is the same transform as this
-     */
-    public boolean isSame(TaskViewTransform other) {
-        return translationZ == other.translationZ
-                && scale == other.scale
-                && other.alpha == alpha
-                && dimAlpha == other.dimAlpha
-                && visible == other.visible
-                && rect.equals(other.rect);
-    }
-
-    /**
-     * Resets the current transform.
-     */
-    public void reset() {
-        translationZ = 0;
-        scale = 1f;
-        alpha = 1f;
-        dimAlpha = 0f;
-        viewOutlineAlpha = 0f;
-        visible = false;
-        rect.setEmpty();
-    }
-
-    /** Convenience functions to compare against current property values */
-    public boolean hasAlphaChangedFrom(float v) {
-        return (Float.compare(alpha, v) != 0);
-    }
-
-    public boolean hasScaleChangedFrom(float v) {
-        return (Float.compare(scale, v) != 0);
-    }
-
-    public boolean hasTranslationZChangedFrom(float v) {
-        return (Float.compare(translationZ, v) != 0);
-    }
-
-    public boolean hasRectChangedFrom(View v) {
-        return ((int) rect.left != v.getLeft()) || ((int) rect.right != v.getRight()) ||
-                ((int) rect.top != v.getTop()) || ((int) rect.bottom != v.getBottom());
-    }
-
-    /**
-     * Applies this transform to a view.
-     */
-    public void applyToTaskView(TaskView v, ArrayList<Animator> animators,
-            AnimationProps animation, boolean allowShadows) {
-        // Return early if not visible
-        if (!visible) {
-            return;
-        }
-
-        if (animation.isImmediate()) {
-            if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
-                v.setTranslationZ(translationZ);
-            }
-            if (hasScaleChangedFrom(v.getScaleX())) {
-                v.setScaleX(scale);
-                v.setScaleY(scale);
-            }
-            if (hasAlphaChangedFrom(v.getAlpha())) {
-                v.setAlpha(alpha);
-            }
-            if (hasRectChangedFrom(v)) {
-                v.setLeftTopRightBottom((int) rect.left, (int) rect.top, (int) rect.right,
-                        (int) rect.bottom);
-            }
-        } else {
-            if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
-                ObjectAnimator anim = ObjectAnimator.ofFloat(v, View.TRANSLATION_Z,
-                        v.getTranslationZ(), translationZ);
-                animators.add(animation.apply(AnimationProps.TRANSLATION_Z, anim));
-            }
-            if (hasScaleChangedFrom(v.getScaleX())) {
-                ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(v,
-                        PropertyValuesHolder.ofFloat(View.SCALE_X, v.getScaleX(), scale),
-                        PropertyValuesHolder.ofFloat(View.SCALE_Y, v.getScaleX(), scale));
-                animators.add(animation.apply(AnimationProps.SCALE, anim));
-            }
-            if (hasAlphaChangedFrom(v.getAlpha())) {
-                ObjectAnimator anim = ObjectAnimator.ofFloat(v, View.ALPHA, v.getAlpha(), alpha);
-                animators.add(animation.apply(AnimationProps.ALPHA, anim));
-            }
-            if (hasRectChangedFrom(v)) {
-                Rect fromViewRect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
-                Rect toViewRect = new Rect();
-                rect.round(toViewRect);
-                ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(v,
-                        PropertyValuesHolder.ofObject(LTRB, Utilities.RECT_EVALUATOR,
-                                fromViewRect, toViewRect));
-                animators.add(animation.apply(AnimationProps.BOUNDS, anim));
-            }
-        }
-    }
-
-    /** Reset the transform on a view. */
-    public static void reset(TaskView v) {
-        v.setTranslationX(0f);
-        v.setTranslationY(0f);
-        v.setTranslationZ(0f);
-        v.setScaleX(1f);
-        v.setScaleY(1f);
-        v.setAlpha(1f);
-        v.getViewBounds().setClipBottom(0);
-        v.setLeftTopRightBottom(0, 0, 0, 0);
-    }
-
-    @Override
-    public String toString() {
-        return "R: " + rect + " V: " + visible;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
deleted file mode 100644
index a287fe6..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.recents.views;
-
-import android.content.Context;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-
-/* A view pool to manage more views than we can visibly handle */
-public class ViewPool<V, T> {
-
-    /* An interface to the consumer of a view pool */
-    public interface ViewPoolConsumer<V, T> {
-        public V createView(Context context);
-        public void onReturnViewToPool(V v);
-        public void onPickUpViewFromPool(V v, T prepareData, boolean isNewView);
-        public boolean hasPreferredData(V v, T preferredData);
-    }
-
-    Context mContext;
-    ViewPoolConsumer<V, T> mViewCreator;
-    LinkedList<V> mPool = new LinkedList<V>();
-
-    /** Initializes the pool with a fixed predetermined pool size */
-    public ViewPool(Context context, ViewPoolConsumer<V, T> viewCreator) {
-        mContext = context;
-        mViewCreator = viewCreator;
-    }
-
-    /** Returns a view into the pool */
-    void returnViewToPool(V v) {
-        mViewCreator.onReturnViewToPool(v);
-        mPool.push(v);
-    }
-
-    /** Gets a view from the pool and prepares it */
-    V pickUpViewFromPool(T preferredData, T prepareData) {
-        V v = null;
-        boolean isNewView = false;
-        if (mPool.isEmpty()) {
-            v = mViewCreator.createView(mContext);
-            isNewView = true;
-        } else {
-            // Try and find a preferred view
-            Iterator<V> iter = mPool.iterator();
-            while (iter.hasNext()) {
-                V vpv = iter.next();
-                if (mViewCreator.hasPreferredData(vpv, preferredData)) {
-                    v = vpv;
-                    iter.remove();
-                    break;
-                }
-            }
-            // Otherwise, just grab the first view
-            if (v == null) {
-                v = mPool.pop();
-            }
-        }
-        mViewCreator.onPickUpViewFromPool(v, prepareData, isNewView);
-        return v;
-    }
-
-    /**
-     * Returns the list of views in the pool.
-     */
-    List<V> getViews() {
-        return mPool;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/grid/AnimateableGridViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/grid/AnimateableGridViewBounds.java
deleted file mode 100644
index 3bdad31..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/grid/AnimateableGridViewBounds.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.views.grid;
-
-import android.view.View;
-import com.android.systemui.shared.recents.view.AnimateableViewBounds;
-
-/* An outline provider for grid-based task views. */
-class AnimateableGridViewBounds extends AnimateableViewBounds {
-
-    public AnimateableGridViewBounds(View source, int cornerRadius) {
-        super(source, cornerRadius);
-    }
-
-    @Override
-    protected void updateClipBounds() {
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java
deleted file mode 100644
index 0d51154..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.views.grid;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import com.android.systemui.R;
-import com.android.systemui.shared.recents.view.AnimateableViewBounds;
-import com.android.systemui.recents.views.TaskView;
-
-public class GridTaskView extends TaskView {
-
-    /** The height, in pixels, of the header view. */
-    private int mHeaderHeight;
-
-    public GridTaskView(Context context) {
-        this(context, null);
-    }
-
-    public GridTaskView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public GridTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public GridTaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        mHeaderHeight = context.getResources().getDimensionPixelSize(
-                R.dimen.recents_grid_task_view_header_height);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        // Show the full thumbnail and don't overlap with the header.
-        mThumbnailView.setSizeToFit(true);
-        mThumbnailView.setOverlayHeaderOnThumbnailActionBar(false);
-        mThumbnailView.updateThumbnailMatrix();
-        mThumbnailView.setTranslationY(mHeaderHeight);
-        mHeaderView.setShouldDarkenBackgroundColor(true);
-    }
-
-    @Override
-    protected AnimateableViewBounds createOutlineProvider() {
-        return new AnimateableGridViewBounds(this, mContext.getResources().getDimensionPixelSize(
-            R.dimen.recents_task_view_shadow_rounded_corners_radius));
-    }
-
-    @Override
-    protected void onConfigurationChanged() {
-        super.onConfigurationChanged();
-        mHeaderHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.recents_grid_task_view_header_height);
-        mThumbnailView.setTranslationY(mHeaderHeight);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskViewThumbnail.java
deleted file mode 100644
index 2d7cfb1..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskViewThumbnail.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.views.grid;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Path;
-import android.util.AttributeSet;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.views.TaskViewThumbnail;
-
-public class GridTaskViewThumbnail extends TaskViewThumbnail {
-
-    private final Path mThumbnailOutline = new Path();
-    private final Path mRestBackgroundOutline = new Path();
-    // True if either this view's size or thumbnail scale has changed and mThumbnailOutline should
-    // be updated.
-    private boolean mUpdateThumbnailOutline = true;
-
-    public GridTaskViewThumbnail(Context context) {
-        this(context, null);
-    }
-
-    public GridTaskViewThumbnail(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public GridTaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public GridTaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr,
-        int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        mCornerRadius = getResources().getDimensionPixelSize(
-                R.dimen.recents_grid_task_view_rounded_corners_radius);
-    }
-
-    /**
-     * Called when the task view frame changes, allowing us to move the contents of the header
-     * to match the frame changes.
-     */
-    public void onTaskViewSizeChanged(int width, int height) {
-        mUpdateThumbnailOutline = true;
-        super.onTaskViewSizeChanged(width, height);
-    }
-
-    /**
-     * Updates the scale of the bitmap relative to this view.
-     */
-    public void updateThumbnailMatrix() {
-        mUpdateThumbnailOutline = true;
-        super.updateThumbnailMatrix();
-    }
-
-    private void updateThumbnailOutline() {
-        final int titleHeight = getResources().getDimensionPixelSize(
-            R.dimen.recents_grid_task_view_header_height);
-        final int viewWidth = mTaskViewRect.width();
-        final int viewHeight = mTaskViewRect.height() - titleHeight;
-        final int thumbnailWidth = Math.min(viewWidth,
-            (int) (mThumbnailRect.width() * mThumbnailScale));
-        final int thumbnailHeight = Math.min(viewHeight,
-            (int) (mThumbnailRect.height() * mThumbnailScale));
-
-        if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
-            // Draw the thumbnail, we only round the bottom corners:
-            //
-            // outerLeft                outerRight
-            //    <----------------------->            mRestBackgroundOutline
-            //    _________________________            (thumbnailWidth < viewWidth)
-            //    |_______________________| outerTop     A ____ B
-            //    |                       |    ↑           |  |
-            //    |                       |    |           |  |
-            //    |                       |    |           |  |
-            //    |                       |    |           |  | C
-            //    \_______________________/    ↓           |__/
-            //  mCornerRadius             outerBottom    E    D
-            //
-            //  mRestBackgroundOutline (thumbnailHeight < viewHeight)
-            //  A _________________________ B
-            //    |                       | C
-            //  F \_______________________/
-            //    E                       D
-            final int outerLeft = 0;
-            final int outerTop = 0;
-            final int outerRight = outerLeft + thumbnailWidth;
-            final int outerBottom = outerTop + thumbnailHeight;
-            createThumbnailPath(outerLeft, outerTop, outerRight, outerBottom, mThumbnailOutline);
-
-            if (thumbnailWidth < viewWidth) {
-                final int l = Math.max(0, outerRight - mCornerRadius);
-                final int r = outerRight;
-                final int t = outerTop;
-                final int b = outerBottom;
-                mRestBackgroundOutline.reset();
-                mRestBackgroundOutline.moveTo(l, t); // A
-                mRestBackgroundOutline.lineTo(r, t); // B
-                mRestBackgroundOutline.lineTo(r, b - mCornerRadius); // C
-                mRestBackgroundOutline.arcTo(r -  2 * mCornerRadius, b - 2 * mCornerRadius, r, b,
-                        0, 90, false); // D
-                mRestBackgroundOutline.lineTo(l, b); // E
-                mRestBackgroundOutline.lineTo(l, t); // A
-                mRestBackgroundOutline.close();
-
-            }
-            if (thumbnailHeight < viewHeight) {
-                final int l = outerLeft;
-                final int r = outerRight;
-                final int t = Math.max(0, thumbnailHeight - mCornerRadius);
-                final int b = outerBottom;
-                mRestBackgroundOutline.reset();
-                mRestBackgroundOutline.moveTo(l, t); // A
-                mRestBackgroundOutline.lineTo(r, t); // B
-                mRestBackgroundOutline.lineTo(r, b - mCornerRadius); // C
-                mRestBackgroundOutline.arcTo(r -  2 * mCornerRadius, b - 2 * mCornerRadius, r, b,
-                        0, 90, false); // D
-                mRestBackgroundOutline.lineTo(l + mCornerRadius, b); // E
-                mRestBackgroundOutline.arcTo(l, b - 2 * mCornerRadius, l + 2 * mCornerRadius, b,
-                        90, 90, false); // F
-                mRestBackgroundOutline.lineTo(l, t); // A
-                mRestBackgroundOutline.close();
-            }
-        } else {
-            createThumbnailPath(0, 0, viewWidth, viewHeight, mThumbnailOutline);
-        }
-    }
-
-    private void createThumbnailPath(int outerLeft, int outerTop, int outerRight, int outerBottom,
-            Path outPath) {
-        outPath.reset();
-        outPath.moveTo(outerLeft, outerTop);
-        outPath.lineTo(outerRight, outerTop);
-        outPath.lineTo(outerRight, outerBottom - mCornerRadius);
-        outPath.arcTo(outerRight -  2 * mCornerRadius, outerBottom - 2 * mCornerRadius, outerRight,
-                outerBottom, 0, 90, false);
-        outPath.lineTo(outerLeft + mCornerRadius, outerBottom);
-        outPath.arcTo(outerLeft, outerBottom - 2 * mCornerRadius, outerLeft + 2 * mCornerRadius,
-                outerBottom, 90, 90, false);
-        outPath.lineTo(outerLeft, outerTop);
-        outPath.close();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        final int titleHeight = getResources().getDimensionPixelSize(
-            R.dimen.recents_grid_task_view_header_height);
-        final int viewWidth = mTaskViewRect.width();
-        final int viewHeight = mTaskViewRect.height() - titleHeight;
-        final int thumbnailWidth = Math.min(viewWidth,
-            (int) (mThumbnailRect.width() * mThumbnailScale));
-        final int thumbnailHeight = Math.min(viewHeight,
-            (int) (mThumbnailRect.height() * mThumbnailScale));
-
-        if (mUpdateThumbnailOutline) {
-            updateThumbnailOutline();
-            mUpdateThumbnailOutline = false;
-        }
-
-        if (mUserLocked) {
-            canvas.drawPath(mThumbnailOutline, mLockedPaint);
-        } else if (mBitmapShader != null && thumbnailWidth > 0 && thumbnailHeight > 0) {
-            // Draw the background, there will be some small overdraw with the thumbnail
-            if (thumbnailWidth < viewWidth) {
-                // Portrait thumbnail on a landscape task view
-                canvas.drawPath(mRestBackgroundOutline, mBgFillPaint);
-            }
-            if (thumbnailHeight < viewHeight) {
-                // Landscape thumbnail on a portrait task view
-                canvas.drawPath(mRestBackgroundOutline, mBgFillPaint);
-            }
-            canvas.drawPath(mThumbnailOutline, getDrawPaint());
-        } else {
-            canvas.drawPath(mThumbnailOutline, mBgFillPaint);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/grid/TaskGridLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/grid/TaskGridLayoutAlgorithm.java
deleted file mode 100644
index ccda4b5..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/grid/TaskGridLayoutAlgorithm.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.recents.views.grid;
-
-import static com.android.systemui.recents.views.TaskStackLayoutAlgorithm.*;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.WindowManager;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
-import com.android.systemui.recents.views.TaskViewTransform;
-
-import java.util.ArrayList;
-
-public class TaskGridLayoutAlgorithm  {
-
-    private final String TAG = "TaskGridLayoutAlgorithm";
-    public static final int MAX_LAYOUT_TASK_COUNT = 8;
-
-    /** The horizontal padding around the whole recents view. */
-    private int mPaddingLeftRight;
-    /** The vertical padding around the whole recents view. */
-    private int mPaddingTopBottom;
-    /** The padding between task views. */
-    private int mPaddingTaskView;
-
-    private Rect mWindowRect;
-    private Point mScreenSize = new Point();
-
-    private Rect mTaskGridRect;
-
-    /** The height, in pixels, of each task view's title bar. */
-    private int mTitleBarHeight;
-
-    /** The aspect ratio of each task thumbnail, without the title bar. */
-    private float mAppAspectRatio;
-    private Rect mSystemInsets = new Rect();
-
-    /** The thickness of the focused task view frame. */
-    private int mFocusedFrameThickness;
-
-    /**
-     * When the amount of tasks is determined, the size and position of every task view can be
-     * decided. Each instance of TaskGridRectInfo store the task view information for a certain
-     * amount of tasks.
-     */
-    class TaskGridRectInfo {
-        Rect size;
-        int[] xOffsets;
-        int[] yOffsets;
-        int tasksPerLine;
-        int lines;
-
-        TaskGridRectInfo(int taskCount) {
-            size = new Rect();
-            xOffsets = new int[taskCount];
-            yOffsets = new int[taskCount];
-
-            int layoutTaskCount = Math.min(MAX_LAYOUT_TASK_COUNT, taskCount);
-            tasksPerLine = getTasksPerLine(layoutTaskCount);
-            lines = layoutTaskCount < 4 ? 1 : 2;
-
-            // A couple of special cases.
-            boolean landscapeWindow = mWindowRect.width() > mWindowRect.height();
-            boolean landscapeTaskView = mAppAspectRatio > 1;
-            // If we're in portrait but task views are landscape, show more lines of fewer tasks.
-            if (!landscapeWindow && landscapeTaskView) {
-                tasksPerLine = layoutTaskCount < 2 ? 1 : 2;
-                lines = layoutTaskCount < 3 ? 1 : (
-                        layoutTaskCount < 5 ? 2 : (
-                                layoutTaskCount < 7 ? 3 : 4));
-            }
-            // If we're in landscape but task views are portrait, show fewer lines of more tasks.
-            if (landscapeWindow && !landscapeTaskView) {
-                tasksPerLine = layoutTaskCount < 7 ? layoutTaskCount : 6;
-                lines = layoutTaskCount < 7 ? 1 : 2;
-            }
-
-            int taskWidth, taskHeight;
-            int maxTaskWidth = (mWindowRect.width() - 2 * mPaddingLeftRight
-                - (tasksPerLine - 1) * mPaddingTaskView) / tasksPerLine;
-            int maxTaskHeight = (mWindowRect.height() - 2 * mPaddingTopBottom
-                - (lines - 1) * mPaddingTaskView) / lines;
-
-            if (maxTaskHeight >= maxTaskWidth / mAppAspectRatio + mTitleBarHeight) {
-                // Width bound.
-                taskWidth = maxTaskWidth;
-                // Here we should round the height to the nearest integer.
-                taskHeight = (int) (maxTaskWidth / mAppAspectRatio + mTitleBarHeight + 0.5);
-            } else {
-                // Height bound.
-                taskHeight = maxTaskHeight;
-                // Here we should round the width to the nearest integer.
-                taskWidth = (int) ((taskHeight - mTitleBarHeight) * mAppAspectRatio + 0.5);
-            }
-            size.set(0, 0, taskWidth, taskHeight);
-
-            int emptySpaceX = mWindowRect.width() - 2 * mPaddingLeftRight
-                - (tasksPerLine * taskWidth) - (tasksPerLine - 1) * mPaddingTaskView;
-            int emptySpaceY = mWindowRect.height() - 2 * mPaddingTopBottom
-                - (lines * taskHeight) - (lines - 1) * mPaddingTaskView;
-            for (int taskIndex = 0; taskIndex < taskCount; taskIndex++) {
-                // We also need to invert the index in order to display the most recent tasks first.
-                int taskLayoutIndex = taskCount - taskIndex - 1;
-
-                int xIndex = taskLayoutIndex % tasksPerLine;
-                int yIndex = taskLayoutIndex / tasksPerLine;
-                xOffsets[taskIndex] = mWindowRect.left +
-                    emptySpaceX / 2 + mPaddingLeftRight + (taskWidth + mPaddingTaskView) * xIndex;
-                yOffsets[taskIndex] = mWindowRect.top +
-                    emptySpaceY / 2 + mPaddingTopBottom + (taskHeight + mPaddingTaskView) * yIndex;
-            }
-        }
-
-        private int getTasksPerLine(int taskCount) {
-            switch(taskCount) {
-                case 0:
-                    return 0;
-                case 1:
-                    return 1;
-                case 2:
-                case 4:
-                    return 2;
-                case 3:
-                case 5:
-                case 6:
-                    return 3;
-                case 7:
-                case 8:
-                    return 4;
-                default:
-                    throw new IllegalArgumentException("Unsupported task count " + taskCount);
-            }
-        }
-    }
-
-    /**
-     * We can find task view sizes and positions from mTaskGridRectInfoList[k - 1] when there
-     * are k tasks.
-     */
-    private TaskGridRectInfo[] mTaskGridRectInfoList;
-
-    public TaskGridLayoutAlgorithm(Context context) {
-        reloadOnConfigurationChange(context);
-    }
-
-    public void reloadOnConfigurationChange(Context context) {
-        Resources res = context.getResources();
-        mPaddingTaskView = res.getDimensionPixelSize(R.dimen.recents_grid_padding_task_view);
-        mFocusedFrameThickness = res.getDimensionPixelSize(
-            R.dimen.recents_grid_task_view_focused_frame_thickness);
-
-        mTaskGridRect = new Rect();
-        mTitleBarHeight = res.getDimensionPixelSize(R.dimen.recents_grid_task_view_header_height);
-
-        WindowManager windowManager = (WindowManager) context
-                .getSystemService(Context.WINDOW_SERVICE);
-        windowManager.getDefaultDisplay().getRealSize(mScreenSize);
-
-        updateAppAspectRatio();
-    }
-
-    /**
-     * Returns the proper task view transform of a certain task view, according to its index and the
-     * amount of task views.
-     * @param taskIndex     The index of the task view whose transform we want. It's never greater
-     *                      than {@link MAX_LAYOUT_TASK_COUNT}.
-     * @param taskCount     The current amount of task views.
-     * @param transformOut  The result transform that this method returns.
-     * @param stackLayout   The base stack layout algorithm.
-     * @return  The expected transform of the (taskIndex)th task view.
-     */
-    public TaskViewTransform getTransform(int taskIndex, int taskCount,
-        TaskViewTransform transformOut, TaskStackLayoutAlgorithm stackLayout) {
-        if (taskCount == 0) {
-            transformOut.reset();
-            return transformOut;
-        }
-
-        TaskGridRectInfo gridInfo = mTaskGridRectInfoList[taskCount - 1];
-        mTaskGridRect.set(gridInfo.size);
-
-        int x = gridInfo.xOffsets[taskIndex];
-        int y = gridInfo.yOffsets[taskIndex];
-        float z = stackLayout.mMaxTranslationZ;
-
-        // We always set the dim alpha to 0, since we don't want grid task views to dim.
-        float dimAlpha = 0f;
-        // We always set the alpha of the view outline to 1, to make sure the shadow is visible.
-        float viewOutlineAlpha = 1f;
-
-        // We also need to invert the index in order to display the most recent tasks first.
-        int taskLayoutIndex = taskCount - taskIndex - 1;
-        boolean isTaskViewVisible = taskLayoutIndex < MAX_LAYOUT_TASK_COUNT;
-
-        // Fill out the transform
-        transformOut.scale = 1f;
-        transformOut.alpha = isTaskViewVisible ? 1f : 0f;
-        transformOut.translationZ = z;
-        transformOut.dimAlpha = dimAlpha;
-        transformOut.viewOutlineAlpha = viewOutlineAlpha;
-        transformOut.rect.set(mTaskGridRect);
-        transformOut.rect.offset(x, y);
-        Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
-        // We only show the 8 most recent tasks.
-        transformOut.visible = isTaskViewVisible;
-        return transformOut;
-    }
-
-    /**
-     * Return the proper task index to focus for arrow key navigation.
-     * @param taskCount             The amount of tasks.
-     * @param currentFocusedIndex   The index of the currently focused task.
-     * @param direction             The direction we're navigating.
-     * @return  The index of the task that should get the focus.
-     */
-    public int navigateFocus(int taskCount, int currentFocusedIndex, Direction direction) {
-        if (taskCount < 1 || taskCount > MAX_LAYOUT_TASK_COUNT) {
-            return -1;
-        }
-        if (currentFocusedIndex == -1) {
-            return 0;
-        }
-        int newIndex = currentFocusedIndex;
-        final TaskGridRectInfo gridInfo = mTaskGridRectInfoList[taskCount - 1];
-        final int currentLine = (taskCount - 1 - currentFocusedIndex) / gridInfo.tasksPerLine;
-        switch (direction) {
-            case UP:
-                newIndex += gridInfo.tasksPerLine;
-                newIndex = newIndex >= taskCount ? currentFocusedIndex : newIndex;
-                break;
-            case DOWN:
-                newIndex -= gridInfo.tasksPerLine;
-                newIndex = newIndex < 0 ? currentFocusedIndex : newIndex;
-                break;
-            case LEFT:
-                newIndex++;
-                final int leftMostIndex = (taskCount - 1) - currentLine * gridInfo.tasksPerLine;
-                newIndex = newIndex > leftMostIndex ? currentFocusedIndex : newIndex;
-                break;
-            case RIGHT:
-                newIndex--;
-                int rightMostIndex =
-                    (taskCount - 1) - (currentLine + 1) * gridInfo.tasksPerLine + 1;
-                rightMostIndex = rightMostIndex < 0 ? 0 : rightMostIndex;
-                newIndex = newIndex < rightMostIndex ? currentFocusedIndex : newIndex;
-                break;
-        }
-        return newIndex;
-    }
-
-    public void initialize(Rect windowRect) {
-        mWindowRect = windowRect;
-        // Define paddings in terms of percentage of the total area.
-        mPaddingLeftRight = (int) (0.025f * Math.min(mWindowRect.width(), mWindowRect.height()));
-        mPaddingTopBottom = (int) (0.1 * mWindowRect.height());
-
-        // Pre-calculate the positions and offsets of task views so that we can reuse them directly
-        // in the future.
-        mTaskGridRectInfoList = new TaskGridRectInfo[MAX_LAYOUT_TASK_COUNT];
-        for (int i = 0; i < MAX_LAYOUT_TASK_COUNT; i++) {
-            mTaskGridRectInfoList[i] = new TaskGridRectInfo(i + 1);
-        }
-    }
-
-    public void setSystemInsets(Rect systemInsets) {
-        mSystemInsets = systemInsets;
-        updateAppAspectRatio();
-    }
-
-    private void updateAppAspectRatio() {
-        int usableWidth = mScreenSize.x - mSystemInsets.left - mSystemInsets.right;
-        int usableHeight = mScreenSize.y - mSystemInsets.top - mSystemInsets.bottom;
-        mAppAspectRatio = (float) usableWidth / (float) usableHeight;
-    }
-
-    public Rect getStackActionButtonRect() {
-        Rect buttonRect = new Rect(mWindowRect);
-        buttonRect.right -= mPaddingLeftRight;
-        buttonRect.left += mPaddingLeftRight;
-        buttonRect.bottom = buttonRect.top + mPaddingTopBottom;
-        return buttonRect;
-    }
-
-    public void updateTaskGridRect(int taskCount) {
-        if (taskCount > 0) {
-            TaskGridRectInfo gridInfo = mTaskGridRectInfoList[taskCount - 1];
-            mTaskGridRect.set(gridInfo.size);
-        }
-    }
-
-    public Rect getTaskGridRect() {
-        return mTaskGridRect;
-    }
-
-    public int getFocusFrameThickness() {
-        return mFocusedFrameThickness;
-    }
-
-    public VisibilityReport computeStackVisibilityReport(ArrayList<Task> tasks) {
-        int visibleCount = Math.min(TaskGridLayoutAlgorithm.MAX_LAYOUT_TASK_COUNT, tasks.size());
-        return new VisibilityReport(visibleCount, visibleCount);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/grid/TaskViewFocusFrame.java b/packages/SystemUI/src/com/android/systemui/recents/views/grid/TaskViewFocusFrame.java
deleted file mode 100644
index fe6bafb..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/grid/TaskViewFocusFrame.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.views.grid;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-
-import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
-import com.android.systemui.R;
-import com.android.systemui.shared.recents.model.TaskStack;
-import com.android.systemui.recents.views.TaskStackView;
-
-public class TaskViewFocusFrame extends View implements OnGlobalFocusChangeListener {
-
-    private TaskStackView mSv;
-    private TaskGridLayoutAlgorithm mTaskGridLayoutAlgorithm;
-    public TaskViewFocusFrame(Context context) {
-        this(context, null);
-    }
-
-    public TaskViewFocusFrame(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public TaskViewFocusFrame(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public TaskViewFocusFrame(Context context, AttributeSet attrs, int defStyleAttr,
-        int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        setBackground(mContext.getDrawable(
-            R.drawable.recents_grid_task_view_focus_frame_background));
-        setFocusable(false);
-        hide();
-    }
-
-    public TaskViewFocusFrame(Context context, TaskStackView stackView,
-        TaskGridLayoutAlgorithm taskGridLayoutAlgorithm) {
-        this(context);
-        mSv = stackView;
-        mTaskGridLayoutAlgorithm = taskGridLayoutAlgorithm;
-    }
-
-    /**
-     * Measure the width and height of the focus frame according to the current grid task view size.
-     */
-    public void measure() {
-        int thickness = mTaskGridLayoutAlgorithm.getFocusFrameThickness();
-        Rect rect = mTaskGridLayoutAlgorithm.getTaskGridRect();
-        measure(
-            MeasureSpec.makeMeasureSpec(rect.width() + thickness * 2, MeasureSpec.EXACTLY),
-            MeasureSpec.makeMeasureSpec(rect.height() + thickness * 2, MeasureSpec.EXACTLY));
-    }
-
-    /**
-     * Layout the focus frame with its size.
-     */
-    public void layout() {
-        layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
-    }
-
-    /**
-     * Update the current size of grid task view and the focus frame.
-     */
-    public void resize() {
-        if (mSv.useGridLayout()) {
-            mTaskGridLayoutAlgorithm.updateTaskGridRect(mSv.getStack().getTaskCount());
-            measure();
-            requestLayout();
-        }
-    }
-
-    /**
-     * Move the task view focus frame to surround the newly focused view. If it's {@code null} or
-     * it's not an instance of GridTaskView, we hide the focus frame.
-     * @param newFocus The newly focused view.
-     */
-    public void moveGridTaskViewFocus(View newFocus) {
-        if (mSv.useGridLayout()) {
-            // The frame only shows up in the grid layout. It shouldn't show up in the stack
-            // layout including when we're in the split screen.
-            if (newFocus instanceof GridTaskView) {
-                // If the focus goes to a GridTaskView, we show the frame and layout it.
-                int[] location = new int[2];
-                newFocus.getLocationInWindow(location);
-                int thickness = mTaskGridLayoutAlgorithm.getFocusFrameThickness();
-                setTranslationX(location[0] - thickness);
-                setTranslationY(location[1] - thickness);
-                show();
-            } else {
-                // If focus goes to other views, we hide the frame.
-                hide();
-            }
-        }
-    }
-
-    @Override
-    public void onGlobalFocusChanged(View oldFocus, View newFocus) {
-        if (!mSv.useGridLayout()) {
-            return;
-        }
-        if (newFocus == null) {
-            // We're going to touch mode, unset the focus.
-            moveGridTaskViewFocus(null);
-            return;
-        }
-        if (oldFocus == null) {
-            // We're returning from touch mode, set the focus to the previously focused task.
-            final TaskStack stack = mSv.getStack();
-            final int taskCount = stack.getTaskCount();
-            final int k = stack.indexOfTask(mSv.getFocusedTask());
-            final int taskIndexToFocus = k == -1 ? (taskCount - 1) : (k % taskCount);
-            mSv.setFocusedTask(taskIndexToFocus, false, true);
-        }
-    }
-
-    private void show() {
-        setAlpha(1f);
-    }
-
-    private void hide() {
-        setAlpha(0f);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
deleted file mode 100644
index 49cac26..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2017 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.systemui.recents.views.lowram;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.view.ViewConfiguration;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivityLaunchState;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
-import com.android.systemui.recents.views.TaskViewTransform;
-
-import java.util.ArrayList;
-
-import static com.android.systemui.recents.views.TaskStackLayoutAlgorithm.VisibilityReport;
-
-public class TaskStackLowRamLayoutAlgorithm {
-
-    private static final String TAG = "TaskStackLowRamLayoutAlgorithm";
-    private static final float MAX_OVERSCROLL = 0.2f / 0.3f;
-
-    public static final int MAX_LAYOUT_TASK_COUNT = 9;
-    public static final int NUM_TASK_VISIBLE_LAUNCHED_FROM_HOME = 2;
-    public static final int NUM_TASK_VISIBLE_LAUNCHED_FROM_APP =
-            NUM_TASK_VISIBLE_LAUNCHED_FROM_HOME + 1;
-    private Rect mWindowRect;
-
-    private int mFlingThreshold;
-    private int mPadding;
-    private int mPaddingLeftRight;
-    private int mTopOffset;
-    private int mPaddingEndTopBottom;
-    private Rect mTaskRect = new Rect();
-    private Rect mSystemInsets = new Rect();
-
-    public TaskStackLowRamLayoutAlgorithm(Context context) {
-        reloadOnConfigurationChange(context);
-    }
-
-    public void reloadOnConfigurationChange(Context context) {
-        mPadding = context.getResources()
-                .getDimensionPixelSize(R.dimen.recents_layout_side_margin_phone);
-        mFlingThreshold = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
-    }
-
-    public void initialize(Rect windowRect) {
-        mWindowRect = windowRect;
-        if (mWindowRect.height() > 0) {
-            int windowHeight = mWindowRect.height() - mSystemInsets.bottom;
-            int windowWidth = mWindowRect.width() - mSystemInsets.right - mSystemInsets.left;
-            int width = Math.min(windowWidth, windowHeight) - mPadding * 2;
-            boolean isLandscape = windowWidth > windowHeight;
-            mTaskRect.set(0, 0, width, isLandscape ? width * 2 / 3 : width);
-            mPaddingLeftRight = (windowWidth - mTaskRect.width()) / 2;
-            mPaddingEndTopBottom = (windowHeight - mTaskRect.height()) / 2;
-
-            // Compute the top offset to center tasks in the middle of the screen
-            mTopOffset = (getTotalHeightOfTasks(MAX_LAYOUT_TASK_COUNT) - windowHeight) / 2;
-        }
-    }
-
-    public void setSystemInsets(Rect systemInsets) {
-        mSystemInsets = systemInsets;
-    }
-
-    public VisibilityReport computeStackVisibilityReport(ArrayList<Task> tasks) {
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-        int maxVisible = launchState.launchedFromHome || launchState.launchedFromPipApp
-                    || launchState.launchedWithNextPipApp
-                ? NUM_TASK_VISIBLE_LAUNCHED_FROM_HOME
-                : NUM_TASK_VISIBLE_LAUNCHED_FROM_APP;
-        int visibleCount = Math.min(maxVisible, tasks.size());
-        return new VisibilityReport(visibleCount, visibleCount);
-    }
-
-    public void getFrontOfStackTransform(TaskViewTransform transformOut,
-            TaskStackLayoutAlgorithm stackLayout) {
-        if (mWindowRect == null) {
-            transformOut.reset();
-            return;
-        }
-
-        // Calculate the static task y position 2 tasks after/below the middle/current task
-        int windowHeight = mWindowRect.height() - mSystemInsets.bottom;
-        int bottomOfCurrentTask = (windowHeight + mTaskRect.height()) / 2;
-        int y = bottomOfCurrentTask + mTaskRect.height() + mPadding * 2;
-        fillStackTransform(transformOut, y, stackLayout.mMaxTranslationZ, true);
-    }
-
-    public void getBackOfStackTransform(TaskViewTransform transformOut,
-            TaskStackLayoutAlgorithm stackLayout) {
-        if (mWindowRect == null) {
-            transformOut.reset();
-            return;
-        }
-
-        // Calculate the static task y position 2 tasks before/above the middle/current task
-        int windowHeight = mWindowRect.height() - mSystemInsets.bottom;
-        int topOfCurrentTask = (windowHeight - mTaskRect.height()) / 2;
-        int y = topOfCurrentTask - (mTaskRect.height() + mPadding) * 2;
-        fillStackTransform(transformOut, y, stackLayout.mMaxTranslationZ, true);
-    }
-
-    public TaskViewTransform getTransform(int taskIndex, float stackScroll,
-            TaskViewTransform transformOut, int taskCount, TaskStackLayoutAlgorithm stackLayout) {
-        if (taskCount == 0) {
-            transformOut.reset();
-            return transformOut;
-        }
-        boolean visible = true;
-        int y;
-        if (taskCount > 1) {
-            y = getTaskTopFromIndex(taskIndex) - percentageToScroll(stackScroll);
-
-            // Check visibility from the bottom of the task
-            visible = y + mPadding + getTaskRect().height() > 0;
-        } else {
-            int windowHeight = mWindowRect.height() - mSystemInsets.bottom;
-            y = (windowHeight - mTaskRect.height()) / 2 - percentageToScroll(stackScroll);
-        }
-        fillStackTransform(transformOut, y, stackLayout.mMaxTranslationZ, visible);
-        return transformOut;
-    }
-
-    /**
-     * Finds the closest task to the scroll percentage in the y axis and returns the percentage of
-     * the task to scroll to.
-     * @param scrollP percentage to find nearest to
-     * @param numTasks number of tasks in recents stack
-     * @param velocity speed of fling
-     */
-    public float getClosestTaskP(float scrollP, int numTasks, int velocity) {
-        int y = percentageToScroll(scrollP);
-
-        int lastY = getTaskTopFromIndex(0) - mPaddingEndTopBottom;
-        for (int i = 1; i < numTasks; i++) {
-            int taskY = getTaskTopFromIndex(i) - mPaddingEndTopBottom;
-            int diff = taskY - y;
-            if (diff > 0) {
-                int diffPrev = Math.abs(y - lastY);
-                boolean useNext = diff > diffPrev;
-                if (Math.abs(velocity) > mFlingThreshold) {
-                    useNext = velocity > 0;
-                }
-                return useNext
-                        ? scrollToPercentage(lastY) : scrollToPercentage(taskY);
-            }
-            lastY = taskY;
-        }
-        return scrollToPercentage(lastY);
-    }
-
-    /**
-     * Convert a scroll value to a percentage
-     * @param scroll a scroll value
-     * @return a percentage that represents the scroll from the total height of tasks
-     */
-    public float scrollToPercentage(int scroll) {
-        return (float) scroll / (mTaskRect.height() + mPadding);
-    }
-
-    /**
-     * Converts a percentage to the scroll value from the total height of tasks
-     * @param p a percentage that represents the scroll value
-     * @return a scroll value in pixels
-     */
-    public int percentageToScroll(float p) {
-        return (int) (p * (mTaskRect.height() + mPadding));
-    }
-
-    /**
-     * Get the min scroll progress for low ram layout. This computes the top position of the
-     * first task and reduce by the end padding to center the first task
-     * @return position of max scroll
-     */
-    public float getMinScrollP() {
-        return getScrollPForTask(0);
-    }
-
-    /**
-     * Get the max scroll progress for low ram layout. This computes the top position of the last
-     * task and reduce by the end padding to center the last task
-     * @param taskCount the amount of tasks in the recents stack
-     * @return position of max scroll
-     */
-    public float getMaxScrollP(int taskCount) {
-        return getScrollPForTask(taskCount - 1);
-    }
-
-    /**
-     * Get the initial scroll value whether launched from home or from an app.
-     * @param taskCount the amount of tasks currently in recents
-     * @param fromHome if launching recents from home or not
-     * @return from home it will return max value and from app it will return 2nd last task
-     */
-    public float getInitialScrollP(int taskCount, boolean fromHome) {
-        if (fromHome) {
-            return getMaxScrollP(taskCount);
-        }
-        if (taskCount < 2) {
-            return 0;
-        }
-        return getScrollPForTask(taskCount - 2);
-    }
-
-    /**
-     * Get the scroll progress for any task
-     * @param taskIndex task index to get the scroll progress of
-     * @return scroll progress of task
-     */
-    public float getScrollPForTask(int taskIndex) {
-        return scrollToPercentage(getTaskTopFromIndex(taskIndex) - mPaddingEndTopBottom);
-    }
-
-    public Rect getTaskRect() {
-        return mTaskRect;
-    }
-
-    public float getMaxOverscroll() {
-        return MAX_OVERSCROLL;
-    }
-
-    private int getTaskTopFromIndex(int index) {
-        return getTotalHeightOfTasks(index) - mTopOffset;
-    }
-
-    private int getTotalHeightOfTasks(int taskCount) {
-        return taskCount * mTaskRect.height() + (taskCount + 1) * mPadding;
-    }
-
-    private void fillStackTransform(TaskViewTransform transformOut, int y, int translationZ,
-            boolean visible) {
-        transformOut.scale = 1f;
-        transformOut.alpha = 1f;
-        transformOut.translationZ = translationZ;
-        transformOut.dimAlpha = 0f;
-        transformOut.viewOutlineAlpha = 1f;
-        transformOut.rect.set(getTaskRect());
-        transformOut.rect.offset(mPaddingLeftRight + mSystemInsets.left, y);
-        Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
-        transformOut.visible = visible;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 178c5c5..38011d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -44,11 +44,10 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
-import com.android.systemui.OverviewProxyService;
+import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 59c15f1..329a33d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -19,7 +19,7 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 
-import static com.android.systemui.OverviewProxyService.OverviewProxyListener;
+import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
@@ -74,7 +74,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.LatencyTracker;
 import com.android.systemui.Dependency;
-import com.android.systemui.OverviewProxyService;
+import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.assist.AssistManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 52134d9..22b6ba6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -34,7 +34,7 @@
 import android.widget.Space;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.OverviewProxyService;
+import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 2ab5958..6728f08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -57,7 +57,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.DockedStackExistsListener;
 import com.android.systemui.Interpolators;
-import com.android.systemui.OverviewProxyService;
+import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.PluginListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index fd5403f..3980126 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -20,8 +20,8 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
 import static com.android.systemui.Interpolators.ALPHA_IN;
 import static com.android.systemui.Interpolators.ALPHA_OUT;
-import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
-import static com.android.systemui.OverviewProxyService.TAG_OPS;
+import static com.android.systemui.recents.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
+import static com.android.systemui.recents.OverviewProxyService.TAG_OPS;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
 
@@ -56,7 +56,7 @@
 import android.view.WindowManagerGlobal;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
-import com.android.systemui.OverviewProxyService;
+import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
index 855592f..c6e98e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
@@ -44,8 +44,8 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
-import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 import com.android.systemui.statusbar.policy.RotationLockController;
 
@@ -400,7 +400,7 @@
         }
     }
 
-    private class TaskStackListenerImpl extends SysUiTaskStackChangeListener {
+    private class TaskStackListenerImpl extends TaskStackChangeListener {
         // Invalidate any rotation suggestion on task change or activity orientation change
         // Note: all callbacks happen on main thread
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 37eccb5..b2a04ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -135,7 +135,6 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
-import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
@@ -4121,7 +4120,7 @@
 
     protected Display mDisplay;
 
-    protected RecentsComponent mRecents;
+    protected Recents mRecents;
 
     protected NotificationShelf mNotificationShelf;
     protected EmptyShadeView mEmptyShadeView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 298a93e..6fa73ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -34,7 +34,6 @@
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.TypedValue;
-import android.view.Display;
 import android.view.HapticFeedbackConstants;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
@@ -49,7 +48,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
-import com.android.systemui.OverviewProxyService;
+import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
 import com.android.systemui.shared.system.NavigationBarCompat;