diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
new file mode 100644
index 0000000..0d7ca07
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -0,0 +1,1515 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
+
+import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.RECENT_TASKS_MISSING;
+import static com.android.quickstep.util.LogUtils.splitFailureMessage;
+
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.PendingIntent;
+import android.app.PictureInPictureParams;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ShortcutInfo;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.IRecentsAnimationController;
+import android.view.IRecentsAnimationRunner;
+import android.view.IRemoteAnimationRunner;
+import android.view.MotionEvent;
+import android.view.RemoteAnimationAdapter;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
+import android.window.IOnBackInvokedCallback;
+import android.window.RemoteTransition;
+import android.window.TaskSnapshot;
+import android.window.TransitionFilter;
+
+import androidx.annotation.MainThread;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
+
+import com.android.internal.logging.InstanceId;
+import com.android.internal.util.ScreenshotRequest;
+import com.android.internal.view.AppearanceRegion;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.Preconditions;
+import com.android.quickstep.util.ActiveGestureLog;
+import com.android.quickstep.util.AssistUtils;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import com.android.systemui.shared.system.RecentsAnimationListener;
+import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController;
+import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController;
+import com.android.systemui.shared.system.smartspace.SmartspaceState;
+import com.android.systemui.unfold.progress.IUnfoldAnimation;
+import com.android.systemui.unfold.progress.IUnfoldTransitionListener;
+import com.android.wm.shell.back.IBackAnimation;
+import com.android.wm.shell.bubbles.IBubbles;
+import com.android.wm.shell.bubbles.IBubblesListener;
+import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
+import com.android.wm.shell.desktopmode.IDesktopMode;
+import com.android.wm.shell.desktopmode.IDesktopTaskListener;
+import com.android.wm.shell.draganddrop.IDragAndDrop;
+import com.android.wm.shell.onehanded.IOneHanded;
+import com.android.wm.shell.pip.IPip;
+import com.android.wm.shell.pip.IPipAnimationListener;
+import com.android.wm.shell.recents.IRecentTasks;
+import com.android.wm.shell.recents.IRecentTasksListener;
+import com.android.wm.shell.splitscreen.ISplitScreen;
+import com.android.wm.shell.splitscreen.ISplitScreenListener;
+import com.android.wm.shell.splitscreen.ISplitSelectListener;
+import com.android.wm.shell.startingsurface.IStartingWindow;
+import com.android.wm.shell.startingsurface.IStartingWindowListener;
+import com.android.wm.shell.transition.IHomeTransitionListener;
+import com.android.wm.shell.transition.IShellTransitions;
+import com.android.wm.shell.util.GroupedRecentTaskInfo;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+
+/**
+ * Holds the reference to SystemUI.
+ */
+public class SystemUiProxy implements ISystemUiProxy {
+    private static final String TAG = SystemUiProxy.class.getSimpleName();
+
+    public static final MainThreadInitializedObject<SystemUiProxy> INSTANCE =
+            new MainThreadInitializedObject<>(SystemUiProxy::new);
+
+    private static final int MSG_SET_SHELF_HEIGHT = 1;
+    private static final int MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT = 2;
+
+    private ISystemUiProxy mSystemUiProxy;
+    private IPip mPip;
+    private IBubbles mBubbles;
+    private ISysuiUnlockAnimationController mSysuiUnlockAnimationController;
+    private ISplitScreen mSplitScreen;
+    private IOneHanded mOneHanded;
+    private IShellTransitions mShellTransitions;
+    private IStartingWindow mStartingWindow;
+    private IRecentTasks mRecentTasks;
+    private IBackAnimation mBackAnimation;
+    private IDesktopMode mDesktopMode;
+    private IUnfoldAnimation mUnfoldAnimation;
+    private final DeathRecipient mSystemUiProxyDeathRecipient = () -> {
+        MAIN_EXECUTOR.execute(() -> clearProxy());
+    };
+
+    // Save the listeners passed into the proxy since OverviewProxyService may not have been bound
+    // yet, and we'll need to set/register these listeners with SysUI when they do.  Note that it is
+    // up to the caller to clear the listeners to prevent leaks as these can be held indefinitely
+    // in case SysUI needs to rebind.
+    private IPipAnimationListener mPipAnimationListener;
+    private IBubblesListener mBubblesListener;
+    private ISplitScreenListener mSplitScreenListener;
+    private ISplitSelectListener mSplitSelectListener;
+    private IStartingWindowListener mStartingWindowListener;
+    private ILauncherUnlockAnimationController mLauncherUnlockAnimationController;
+    private String mLauncherActivityClass;
+    private IRecentTasksListener mRecentTasksListener;
+    private IUnfoldTransitionListener mUnfoldAnimationListener;
+    private IDesktopTaskListener mDesktopTaskListener;
+    private final LinkedHashMap<RemoteTransition, TransitionFilter> mRemoteTransitions =
+            new LinkedHashMap<>();
+    private IBinder mOriginalTransactionToken = null;
+    private IOnBackInvokedCallback mBackToLauncherCallback;
+    private IRemoteAnimationRunner mBackToLauncherRunner;
+    private IDragAndDrop mDragAndDrop;
+    private IHomeTransitionListener mHomeTransitionListener;
+
+    // Used to dedupe calls to SystemUI
+    private int mLastShelfHeight;
+    private boolean mLastShelfVisible;
+
+    // Used to dedupe calls to SystemUI
+    private int mLastLauncherKeepClearAreaHeight;
+    private boolean mLastLauncherKeepClearAreaHeightVisible;
+
+    private final Context mContext;
+    private final Handler mAsyncHandler;
+
+    // TODO(141886704): Find a way to remove this
+    private int mLastSystemUiStateFlags;
+
+    /**
+     * This is a singleton pending intent that is used to start recents via Shell (which is a
+     * different process). It is bare-bones, so it's expected that the component and options will
+     * be provided via fill-in intent.
+     */
+    private final PendingIntent mRecentsPendingIntent;
+
+    public SystemUiProxy(Context context) {
+        mContext = context;
+        mAsyncHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleMessageAsync);
+        final Intent baseIntent = new Intent().setPackage(mContext.getPackageName());
+        final ActivityOptions options = ActivityOptions.makeBasic()
+                .setPendingIntentCreatorBackgroundActivityStartMode(
+                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+        mRecentsPendingIntent = PendingIntent.getActivity(mContext, 0, baseIntent,
+                PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT
+                        | Intent.FILL_IN_COMPONENT, options.toBundle());
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onBackPressed();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onBackPressed", e);
+            }
+        }
+    }
+
+    @Override
+    public void onImeSwitcherPressed() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onImeSwitcherPressed();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onImeSwitcherPressed", e);
+            }
+        }
+    }
+
+    @Override
+    public void setHomeRotationEnabled(boolean enabled) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.setHomeRotationEnabled(enabled);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onBackPressed", e);
+            }
+        }
+    }
+
+    @Override
+    public IBinder asBinder() {
+        // Do nothing
+        return null;
+    }
+
+    /**
+     * Sets proxy state, including death linkage, various listeners, and other configuration objects
+     */
+    @MainThread
+    public void setProxy(ISystemUiProxy proxy, IPip pip, IBubbles bubbles, ISplitScreen splitScreen,
+            IOneHanded oneHanded, IShellTransitions shellTransitions,
+            IStartingWindow startingWindow, IRecentTasks recentTasks,
+            ISysuiUnlockAnimationController sysuiUnlockAnimationController,
+            IBackAnimation backAnimation, IDesktopMode desktopMode,
+            IUnfoldAnimation unfoldAnimation, IDragAndDrop dragAndDrop) {
+        Preconditions.assertUIThread();
+        unlinkToDeath();
+        mSystemUiProxy = proxy;
+        mPip = pip;
+        mBubbles = bubbles;
+        mSplitScreen = splitScreen;
+        mOneHanded = oneHanded;
+        mShellTransitions = shellTransitions;
+        mStartingWindow = startingWindow;
+        mSysuiUnlockAnimationController = sysuiUnlockAnimationController;
+        mRecentTasks = recentTasks;
+        mBackAnimation = backAnimation;
+        mDesktopMode = desktopMode;
+        mUnfoldAnimation = unfoldAnimation;
+        mDragAndDrop = dragAndDrop;
+        linkToDeath();
+        // re-attach the listeners once missing due to setProxy has not been initialized yet.
+        setPipAnimationListener(mPipAnimationListener);
+        setBubblesListener(mBubblesListener);
+        registerSplitScreenListener(mSplitScreenListener);
+        registerSplitSelectListener(mSplitSelectListener);
+        setHomeTransitionListener(mHomeTransitionListener);
+        setStartingWindowListener(mStartingWindowListener);
+        setLauncherUnlockAnimationController(
+                mLauncherActivityClass, mLauncherUnlockAnimationController);
+        new LinkedHashMap<>(mRemoteTransitions).forEach(this::registerRemoteTransition);
+        setupTransactionQueue();
+        registerRecentTasksListener(mRecentTasksListener);
+        setBackToLauncherCallback(mBackToLauncherCallback, mBackToLauncherRunner);
+        setUnfoldAnimationListener(mUnfoldAnimationListener);
+        setDesktopTaskListener(mDesktopTaskListener);
+        setAssistantOverridesRequested(
+                AssistUtils.newInstance(mContext).getSysUiAssistOverrideInvocationTypes());
+    }
+
+    /**
+     * Clear the proxy to release held resources and turn the majority of its operations into no-ops
+     */
+    @MainThread
+    public void clearProxy() {
+        setProxy(null, null, null, null, null, null, null, null, null, null, null, null, null);
+    }
+
+    // TODO(141886704): Find a way to remove this
+    public void setLastSystemUiStateFlags(int stateFlags) {
+        mLastSystemUiStateFlags = stateFlags;
+    }
+
+    // TODO(141886704): Find a way to remove this
+    public int getLastSystemUiStateFlags() {
+        return mLastSystemUiStateFlags;
+    }
+
+    public boolean isActive() {
+        return mSystemUiProxy != null;
+    }
+
+    private void linkToDeath() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.asBinder().linkToDeath(mSystemUiProxyDeathRecipient, 0 /* flags */);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to link sysui proxy death recipient");
+            }
+        }
+    }
+
+    private void unlinkToDeath() {
+        if (mSystemUiProxy != null) {
+            mSystemUiProxy.asBinder().unlinkToDeath(mSystemUiProxyDeathRecipient, 0 /* flags */);
+        }
+    }
+
+    @Override
+    public void startScreenPinning(int taskId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.startScreenPinning(taskId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call startScreenPinning", e);
+            }
+        }
+    }
+
+    @Override
+    public void onOverviewShown(boolean fromHome) {
+        onOverviewShown(fromHome, TAG);
+    }
+
+    public void onOverviewShown(boolean fromHome, String tag) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onOverviewShown(fromHome);
+            } catch (RemoteException e) {
+                Log.w(tag, "Failed call onOverviewShown from: " + (fromHome ? "home" : "app"), e);
+            }
+        }
+    }
+
+    @MainThread
+    @Override
+    public void onStatusBarTouchEvent(MotionEvent event) {
+        Preconditions.assertUIThread();
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onStatusBarTouchEvent(event);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onStatusBarTouchEvent with arg: " + event, e);
+            }
+        }
+    }
+
+    @Override
+    public void onStatusBarTrackpadEvent(MotionEvent event) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onStatusBarTrackpadEvent(event);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onStatusBarTrackpadEvent with arg: " + event, e);
+            }
+        }
+    }
+
+    @Override
+    public void onAssistantProgress(float progress) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onAssistantProgress(progress);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onAssistantProgress with progress: " + progress, e);
+            }
+        }
+    }
+
+    @Override
+    public void onAssistantGestureCompletion(float velocity) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onAssistantGestureCompletion(velocity);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onAssistantGestureCompletion", e);
+            }
+        }
+    }
+
+    @Override
+    public void startAssistant(Bundle args) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.startAssistant(args);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call startAssistant", e);
+            }
+        }
+    }
+
+    @Override
+    public void setAssistantOverridesRequested(int[] invocationTypes) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.setAssistantOverridesRequested(invocationTypes);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setAssistantOverridesRequested", e);
+            }
+        }
+    }
+
+    @Override
+    public void animateNavBarLongPress(boolean isTouchDown, long durationMs) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.animateNavBarLongPress(isTouchDown, durationMs);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call animateNavBarLongPress", e);
+            }
+        }
+    }
+
+    @Override
+    public void notifyAccessibilityButtonClicked(int displayId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.notifyAccessibilityButtonClicked(displayId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call notifyAccessibilityButtonClicked", e);
+            }
+        }
+    }
+
+    @Override
+    public void notifyAccessibilityButtonLongClicked() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.notifyAccessibilityButtonLongClicked();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call notifyAccessibilityButtonLongClicked", e);
+            }
+        }
+    }
+
+    @Override
+    public void stopScreenPinning() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.stopScreenPinning();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call stopScreenPinning", e);
+            }
+        }
+    }
+
+    @Override
+    public void notifyPrioritizedRotation(int rotation) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.notifyPrioritizedRotation(rotation);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call notifyPrioritizedRotation with arg: " + rotation, e);
+            }
+        }
+    }
+
+    @Override
+    public void notifyTaskbarStatus(boolean visible, boolean stashed) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.notifyTaskbarStatus(visible, stashed);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call notifyTaskbarStatus with arg: " +
+                        visible + ", " + stashed, e);
+            }
+        }
+    }
+
+    /**
+     * NOTE: If called to suspend, caller MUST call this method to also un-suspend
+     * @param suspend should be true to stop auto-hide, false to resume normal behavior
+     */
+    @Override
+    public void notifyTaskbarAutohideSuspend(boolean suspend) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.notifyTaskbarAutohideSuspend(suspend);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call notifyTaskbarAutohideSuspend with arg: " +
+                        suspend, e);
+            }
+        }
+    }
+
+    @Override
+    public void takeScreenshot(ScreenshotRequest request) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.takeScreenshot(request);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call takeScreenshot");
+            }
+        }
+    }
+
+    @Override
+    public void expandNotificationPanel() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.expandNotificationPanel();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call expandNotificationPanel", e);
+            }
+        }
+    }
+
+    @Override
+    public void toggleNotificationPanel() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.toggleNotificationPanel();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call toggleNotificationPanel", e);
+            }
+        }
+    }
+
+    //
+    // Pip
+    //
+
+    /**
+     * Sets the shelf height.
+     */
+    public void setShelfHeight(boolean visible, int shelfHeight) {
+        Message.obtain(mAsyncHandler, MSG_SET_SHELF_HEIGHT,
+                visible ? 1 : 0 , shelfHeight).sendToTarget();
+    }
+
+    @WorkerThread
+    private void setShelfHeightAsync(int visibleInt, int shelfHeight) {
+        boolean visible = visibleInt != 0;
+        boolean changed = visible != mLastShelfVisible || shelfHeight != mLastShelfHeight;
+        IPip pip = mPip;
+        if (pip != null && changed) {
+            mLastShelfVisible = visible;
+            mLastShelfHeight = shelfHeight;
+            try {
+                pip.setShelfHeight(visible, shelfHeight);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setShelfHeight visible: " + visible
+                        + " height: " + shelfHeight, e);
+            }
+        }
+    }
+
+    /**
+     * Sets the height of the keep clear area that is going to be reported by
+     * the Launcher for the Hotseat.
+     */
+    public void setLauncherKeepClearAreaHeight(boolean visible, int height) {
+        Message.obtain(mAsyncHandler, MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT,
+                visible ? 1 : 0 , height).sendToTarget();
+    }
+
+    @WorkerThread
+    private void setLauncherKeepClearAreaHeight(int visibleInt, int height) {
+        boolean visible = visibleInt != 0;
+        boolean changed = visible != mLastLauncherKeepClearAreaHeightVisible
+                || height != mLastLauncherKeepClearAreaHeight;
+        IPip pip = mPip;
+        if (pip != null && changed) {
+            mLastLauncherKeepClearAreaHeightVisible = visible;
+            mLastLauncherKeepClearAreaHeight = height;
+            try {
+                pip.setLauncherKeepClearAreaHeight(visible, height);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setLauncherKeepClearAreaHeight visible: " + visible
+                        + " height: " + height, e);
+            }
+        }
+    }
+
+    /**
+     * Sets listener to get pip animation callbacks.
+     */
+    public void setPipAnimationListener(IPipAnimationListener listener) {
+        if (mPip != null) {
+            try {
+                mPip.setPipAnimationListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setPinnedStackAnimationListener", e);
+            }
+        }
+        mPipAnimationListener = listener;
+    }
+
+    /**
+     * @return Destination bounds of auto-pip animation, {@code null} if the animation is not ready.
+     */
+    @Nullable
+    public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
+            PictureInPictureParams pictureInPictureParams, int launcherRotation,
+            Rect hotseatKeepClearArea) {
+        if (mPip != null) {
+            try {
+                return mPip.startSwipePipToHome(componentName, activityInfo,
+                        pictureInPictureParams, launcherRotation, hotseatKeepClearArea);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call startSwipePipToHome", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Notifies WM Shell that launcher has finished the preparation of the animation for swipe to
+     * home. WM Shell can choose to fade out the overlay when entering PIP is finished, and WM Shell
+     * should be responsible for cleaning up the overlay.
+     */
+    public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
+            SurfaceControl overlay) {
+        if (mPip != null) {
+            try {
+                mPip.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call stopSwipePipToHome");
+            }
+        }
+    }
+
+    /**
+     * Notifies WM Shell that launcher has aborted all the animation for swipe to home. WM Shell
+     * can use this callback to clean up its internal states.
+     */
+    public void abortSwipePipToHome(int taskId, ComponentName componentName) {
+        if (mPip != null) {
+            try {
+                mPip.abortSwipePipToHome(taskId, componentName);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call abortSwipePipToHome");
+            }
+        }
+    }
+
+    /**
+     * Sets the next pip animation type to be the alpha animation.
+     */
+    public void setPipAnimationTypeToAlpha() {
+        if (mPip != null) {
+            try {
+                mPip.setPipAnimationTypeToAlpha();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setPipAnimationTypeToAlpha", e);
+            }
+        }
+    }
+
+    /**
+     * Sets the app icon size in pixel used by Launcher all apps.
+     */
+    public void setLauncherAppIconSize(int iconSizePx) {
+        if (mPip != null) {
+            try {
+                mPip.setLauncherAppIconSize(iconSizePx);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setLauncherAppIconSize", e);
+            }
+        }
+    }
+
+    //
+    // Bubbles
+    //
+
+    /**
+     * Sets the listener to be notified of bubble state changes.
+     */
+    public void setBubblesListener(IBubblesListener listener) {
+        if (mBubbles != null) {
+            try {
+                if (mBubblesListener != null) {
+                    // Clear out any previous listener
+                    mBubbles.unregisterBubbleListener(mBubblesListener);
+                }
+                if (listener != null) {
+                    mBubbles.registerBubbleListener(listener);
+                }
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerBubblesListener");
+            }
+        }
+        mBubblesListener = listener;
+    }
+
+    /**
+     * Tells SysUI to show the bubble with the provided key.
+     * @param key the key of the bubble to show.
+     * @param bubbleBarOffsetX the offset of the bubble bar from the edge of the screen on the X
+     *                         axis.
+     * @param bubbleBarOffsetY the offset of the bubble bar from the edge of the screen on the Y
+     *                         axis.
+     */
+    public void showBubble(String key, int bubbleBarOffsetX, int bubbleBarOffsetY) {
+        if (mBubbles != null) {
+            try {
+                mBubbles.showBubble(key, bubbleBarOffsetX, bubbleBarOffsetY);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call showBubble");
+            }
+        }
+    }
+
+    /**
+     * Tells SysUI to remove the bubble with the provided key.
+     * @param key the key of the bubble to show.
+     */
+    public void removeBubble(String key) {
+        if (mBubbles == null) return;
+        try {
+            mBubbles.removeBubble(key);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed call removeBubble");
+        }
+    }
+
+    /**
+     * Tells SysUI to remove all bubbles.
+     */
+    public void removeAllBubbles() {
+        if (mBubbles == null) return;
+        try {
+            mBubbles.removeAllBubbles();
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed call removeAllBubbles");
+        }
+    }
+
+    /**
+     * Tells SysUI to collapse the bubbles.
+     */
+    public void collapseBubbles() {
+        if (mBubbles != null) {
+            try {
+                mBubbles.collapseBubbles();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call collapseBubbles");
+            }
+        }
+    }
+
+    /**
+     * Tells SysUI when the bubble is being dragged.
+     * Should be called only when the bubble bar is expanded.
+     * @param bubbleKey the key of the bubble to collapse/expand
+     * @param isBeingDragged whether the bubble is being dragged
+     */
+    public void onBubbleDrag(@Nullable String bubbleKey, boolean isBeingDragged) {
+        if (mBubbles == null) return;
+        try {
+            mBubbles.onBubbleDrag(bubbleKey, isBeingDragged);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed call onBubbleDrag");
+        }
+    }
+
+    /**
+     * Tells SysUI to show user education relative to the reference point provided.
+     * @param position the bubble bar top center position in Screen coordinates.
+     */
+    public void showUserEducation(Point position) {
+        try {
+            mBubbles.showUserEducation(position.x, position.y);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed call showUserEducation");
+        }
+    }
+
+    //
+    // Splitscreen
+    //
+
+    public void registerSplitScreenListener(ISplitScreenListener listener) {
+        if (mSplitScreen != null) {
+            try {
+                mSplitScreen.registerSplitScreenListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerSplitScreenListener");
+            }
+        }
+        mSplitScreenListener = listener;
+    }
+
+    public void unregisterSplitScreenListener(ISplitScreenListener listener) {
+        if (mSplitScreen != null) {
+            try {
+                mSplitScreen.unregisterSplitScreenListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call unregisterSplitScreenListener");
+            }
+        }
+        mSplitScreenListener = null;
+    }
+
+    public void registerSplitSelectListener(ISplitSelectListener listener) {
+        if (mSplitScreen != null) {
+            try {
+                mSplitScreen.registerSplitSelectListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerSplitSelectListener");
+            }
+        }
+        mSplitSelectListener = listener;
+    }
+
+    public void unregisterSplitSelectListener(ISplitSelectListener listener) {
+        if (mSplitScreen != null) {
+            try {
+                mSplitScreen.unregisterSplitSelectListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call unregisterSplitSelectListener");
+            }
+        }
+        mSplitSelectListener = null;
+    }
+
+    /** Start multiple tasks in split-screen simultaneously. */
+    public void startTasks(int taskId1, Bundle options1, int taskId2, Bundle options2,
+            @StagePosition int splitPosition, @PersistentSnapPosition int snapPosition,
+            RemoteTransition remoteTransition, InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startTasks(taskId1, options1, taskId2, options2, splitPosition,
+                        snapPosition, remoteTransition, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage("startTasks", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void startIntentAndTask(PendingIntent pendingIntent, int userId1, Bundle options1,
+            int taskId, Bundle options2, @StagePosition int splitPosition,
+            @PersistentSnapPosition int snapPosition, RemoteTransition remoteTransition,
+            InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startIntentAndTask(pendingIntent, userId1, options1, taskId, options2,
+                        splitPosition, snapPosition, remoteTransition, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage("startIntentAndTask", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void startIntents(PendingIntent pendingIntent1, int userId1,
+            @Nullable ShortcutInfo shortcutInfo1, Bundle options1, PendingIntent pendingIntent2,
+            int userId2, @Nullable ShortcutInfo shortcutInfo2, Bundle options2,
+            @StagePosition int splitPosition, @PersistentSnapPosition int snapPosition,
+            RemoteTransition remoteTransition, InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startIntents(pendingIntent1, userId1, shortcutInfo1, options1,
+                        pendingIntent2, userId2, shortcutInfo2, options2, splitPosition,
+                        snapPosition, remoteTransition, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage("startIntents", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void startShortcutAndTask(ShortcutInfo shortcutInfo, Bundle options1, int taskId,
+            Bundle options2, @StagePosition int splitPosition,
+            @PersistentSnapPosition int snapPosition, RemoteTransition remoteTransition,
+            InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startShortcutAndTask(shortcutInfo, options1, taskId, options2,
+                        splitPosition, snapPosition, remoteTransition, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage("startShortcutAndTask", "RemoteException"), e);
+            }
+        }
+    }
+
+    /**
+     * Start multiple tasks in split-screen simultaneously.
+     */
+    public void startTasksWithLegacyTransition(int taskId1, Bundle options1, int taskId2,
+            Bundle options2, @StagePosition int splitPosition,
+            @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startTasksWithLegacyTransition(taskId1, options1, taskId2, options2,
+                        splitPosition, snapPosition, adapter, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage(
+                        "startTasksWithLegacyTransition", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
+            Bundle options1, int taskId, Bundle options2, @StagePosition int splitPosition,
+            @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, userId1,
+                        options1, taskId, options2, splitPosition, snapPosition, adapter,
+                        instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage(
+                        "startIntentAndTaskWithLegacyTransition", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, Bundle options1,
+            int taskId, Bundle options2, @StagePosition int splitPosition,
+            @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startShortcutAndTaskWithLegacyTransition(shortcutInfo, options1,
+                        taskId, options2, splitPosition, snapPosition, adapter, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage(
+                        "startShortcutAndTaskWithLegacyTransition", "RemoteException"), e);
+            }
+        }
+    }
+
+    /**
+     * Starts a pair of intents or shortcuts in split-screen using legacy transition. Passing a
+     * non-null shortcut info means to start the app as a shortcut.
+     */
+    public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
+            @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
+            PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
+            @Nullable Bundle options2, @StagePosition int sidePosition,
+            @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startIntentsWithLegacyTransition(pendingIntent1, userId1,
+                        shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2, options2,
+                        sidePosition, snapPosition, adapter, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage(
+                        "startIntentsWithLegacyTransition", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void startShortcut(String packageName, String shortcutId, int position,
+            Bundle options, UserHandle user, InstanceId instanceId) {
+        if (mSplitScreen != null) {
+            try {
+                mSplitScreen.startShortcut(packageName, shortcutId, position, options,
+                        user, instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage("startShortcut", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void startIntent(PendingIntent intent, int userId, Intent fillInIntent, int position,
+            Bundle options, InstanceId instanceId) {
+        if (mSplitScreen != null) {
+            try {
+                mSplitScreen.startIntent(intent, userId, fillInIntent, position, options,
+                        instanceId);
+            } catch (RemoteException e) {
+                Log.w(TAG, splitFailureMessage("startIntent", "RemoteException"), e);
+            }
+        }
+    }
+
+    public void removeFromSideStage(int taskId) {
+        if (mSplitScreen != null) {
+            try {
+                mSplitScreen.removeFromSideStage(taskId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call removeFromSideStage");
+            }
+        }
+    }
+
+    /**
+     * Call this when going to recents so that shell can set-up and provide appropriate leashes
+     * for animation (eg. DividerBar).
+     *
+     * @return RemoteAnimationTargets of windows that need to animate but only exist in shell.
+     */
+    @Nullable
+    public RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
+        if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS && mSplitScreen != null) {
+            try {
+                return mSplitScreen.onGoingToRecentsLegacy(apps);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onGoingToRecentsLegacy");
+            }
+        }
+        return null;
+    }
+
+    @Nullable
+    public RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
+        if (mSplitScreen != null) {
+            try {
+                return mSplitScreen.onStartingSplitLegacy(apps);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onStartingSplitLegacy");
+            }
+        }
+        return null;
+    }
+
+    //
+    // One handed
+    //
+
+    public void startOneHandedMode() {
+        if (mOneHanded != null) {
+            try {
+                mOneHanded.startOneHanded();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call startOneHandedMode", e);
+            }
+        }
+    }
+
+    public void stopOneHandedMode() {
+        if (mOneHanded != null) {
+            try {
+                mOneHanded.stopOneHanded();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call stopOneHandedMode", e);
+            }
+        }
+    }
+
+    //
+    // Remote transitions
+    //
+
+    public void registerRemoteTransition(
+            RemoteTransition remoteTransition, TransitionFilter filter) {
+        if (mShellTransitions != null) {
+            try {
+                mShellTransitions.registerRemote(filter, remoteTransition);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerRemoteTransition");
+            }
+        }
+        if (!mRemoteTransitions.containsKey(remoteTransition)) {
+            mRemoteTransitions.put(remoteTransition, filter);
+        }
+    }
+
+    public void unregisterRemoteTransition(RemoteTransition remoteTransition) {
+        if (mShellTransitions != null) {
+            try {
+                mShellTransitions.unregisterRemote(remoteTransition);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerRemoteTransition");
+            }
+        }
+        mRemoteTransitions.remove(remoteTransition);
+    }
+
+    public void setHomeTransitionListener(IHomeTransitionListener listener) {
+        if (!FeatureFlags.enableHomeTransitionListener()) {
+            return;
+        }
+
+        mHomeTransitionListener = listener;
+
+        if (mShellTransitions != null) {
+            try {
+                mShellTransitions.setHomeTransitionListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setHomeTransitionListener", e);
+            }
+        } else  {
+            Log.w(TAG, "Unable to call setHomeTransitionListener because ShellTransitions is null");
+        }
+    }
+
+    /**
+     * Use SystemUI's transaction-queue instead of Launcher's independent one. This is necessary
+     * if Launcher and SystemUI need to coordinate transactions (eg. for shell transitions).
+     */
+    public void shareTransactionQueue() {
+        if (mOriginalTransactionToken == null) {
+            mOriginalTransactionToken = SurfaceControl.Transaction.getDefaultApplyToken();
+        }
+        setupTransactionQueue();
+    }
+
+    /**
+     * Switch back to using Launcher's independent transaction queue.
+     */
+    public void unshareTransactionQueue() {
+        if (mOriginalTransactionToken == null) {
+            return;
+        }
+        SurfaceControl.Transaction.setDefaultApplyToken(mOriginalTransactionToken);
+        mOriginalTransactionToken = null;
+    }
+
+    private void setupTransactionQueue() {
+        if (mOriginalTransactionToken == null) {
+            return;
+        }
+        if (mShellTransitions == null) {
+            SurfaceControl.Transaction.setDefaultApplyToken(mOriginalTransactionToken);
+            return;
+        }
+        final IBinder shellApplyToken;
+        try {
+            shellApplyToken = mShellTransitions.getShellApplyToken();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error getting Shell's apply token", e);
+            return;
+        }
+        if (shellApplyToken == null) {
+            Log.e(TAG, "Didn't receive apply token from Shell");
+            return;
+        }
+        SurfaceControl.Transaction.setDefaultApplyToken(shellApplyToken);
+    }
+
+    //
+    // Starting window
+    //
+
+    /**
+     * Sets listener to get callbacks when launching a task.
+     */
+    public void setStartingWindowListener(IStartingWindowListener listener) {
+        if (mStartingWindow != null) {
+            try {
+                mStartingWindow.setStartingWindowListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setStartingWindowListener", e);
+            }
+        }
+        mStartingWindowListener = listener;
+    }
+
+    //
+    // SmartSpace transitions
+    //
+
+    /**
+     * Sets the instance of {@link ILauncherUnlockAnimationController} that System UI should use to
+     * control the launcher side of the unlock animation. This will also cause us to dispatch the
+     * current state of the smartspace to System UI (this will subsequently happen if the state
+     * changes).
+     */
+    public void setLauncherUnlockAnimationController(
+            String activityClass, ILauncherUnlockAnimationController controller) {
+        if (mSysuiUnlockAnimationController != null) {
+            try {
+                mSysuiUnlockAnimationController.setLauncherUnlockController(
+                        activityClass, controller);
+                if (controller != null) {
+                    controller.dispatchSmartspaceStateToSysui();
+                }
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setLauncherUnlockAnimationController", e);
+            }
+        }
+        mLauncherActivityClass = activityClass;
+        mLauncherUnlockAnimationController = controller;
+    }
+
+    /**
+     * Tells System UI that the Launcher's smartspace state has been updated, so that it can prepare
+     * the unlock animation accordingly.
+     */
+    public void notifySysuiSmartspaceStateUpdated(SmartspaceState state) {
+        if (mSysuiUnlockAnimationController != null) {
+            try {
+                mSysuiUnlockAnimationController.onLauncherSmartspaceStateUpdated(state);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call notifySysuiSmartspaceStateUpdated", e);
+                e.printStackTrace();
+            }
+        }
+    }
+
+    //
+    // Recents
+    //
+
+    public void registerRecentTasksListener(IRecentTasksListener listener) {
+        if (mRecentTasks != null) {
+            try {
+                mRecentTasks.registerRecentTasksListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call registerRecentTasksListener", e);
+            }
+        }
+        mRecentTasksListener = listener;
+    }
+
+    public void unregisterRecentTasksListener(IRecentTasksListener listener) {
+        if (mRecentTasks != null) {
+            try {
+                mRecentTasks.unregisterRecentTasksListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call unregisterRecentTasksListener");
+            }
+        }
+        mRecentTasksListener = null;
+    }
+
+    //
+    // Back navigation transitions
+    //
+
+    /** Sets the launcher {@link android.window.IOnBackInvokedCallback} to shell */
+    public void setBackToLauncherCallback(IOnBackInvokedCallback callback,
+            IRemoteAnimationRunner runner) {
+        mBackToLauncherCallback = callback;
+        mBackToLauncherRunner = runner;
+        if (mBackAnimation == null || mBackToLauncherCallback == null) {
+            return;
+        }
+        try {
+            mBackAnimation.setBackToLauncherCallback(callback, runner);
+        } catch (RemoteException | SecurityException e) {
+            Log.e(TAG, "Failed call setBackToLauncherCallback", e);
+        }
+    }
+
+    /** Clears the previously registered {@link IOnBackInvokedCallback}.
+     *
+     * @param callback The previously registered callback instance.
+     */
+    public void clearBackToLauncherCallback(IOnBackInvokedCallback callback) {
+        if (mBackToLauncherCallback != callback) {
+            return;
+        }
+        mBackToLauncherCallback = null;
+        mBackToLauncherRunner = null;
+        if (mBackAnimation == null) {
+            return;
+        }
+        try {
+            mBackAnimation.clearBackToLauncherCallback();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed call clearBackToLauncherCallback", e);
+        }
+    }
+
+    /**
+     * Called when the status bar color needs to be customized when back navigation.
+     */
+    public void customizeStatusBarAppearance(AppearanceRegion appearance) {
+        if (mBackAnimation == null) {
+            return;
+        }
+        try {
+            mBackAnimation.customizeStatusBarAppearance(appearance);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed call useLauncherSysBarFlags", e);
+        }
+    }
+
+    public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {
+        if (mRecentTasks == null) {
+            Log.w(TAG, "getRecentTasks() failed due to null mRecentTasks");
+            return new ArrayList<>();
+        }
+        try {
+            final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
+                    RECENT_IGNORE_UNAVAILABLE, userId);
+            if (rawTasks == null) {
+                return new ArrayList<>();
+            }
+            return new ArrayList<>(Arrays.asList(rawTasks));
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed call getRecentTasks", e);
+            return new ArrayList<>();
+        }
+    }
+
+    /**
+     * Gets the set of running tasks.
+     */
+    public ArrayList<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) {
+        if (mRecentTasks != null
+                && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PC)) {
+            try {
+                return new ArrayList<>(Arrays.asList(mRecentTasks.getRunningTasks(numTasks)));
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call getRunningTasks", e);
+            }
+        }
+        return new ArrayList<>();
+    }
+
+    private boolean handleMessageAsync(Message msg) {
+        switch (msg.what) {
+            case MSG_SET_SHELF_HEIGHT:
+                setShelfHeightAsync(msg.arg1, msg.arg2);
+                return true;
+            case MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT:
+                setLauncherKeepClearAreaHeight(msg.arg1, msg.arg2);
+                return true;
+        }
+
+        return false;
+    }
+
+    //
+    // Desktop Mode
+    //
+
+    /** Call shell to show all apps active on the desktop */
+    public void showDesktopApps(int displayId, @Nullable RemoteTransition transition) {
+        if (mDesktopMode != null) {
+            try {
+                mDesktopMode.showDesktopApps(displayId, transition);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call showDesktopApps", e);
+            }
+        }
+    }
+
+    /** Call shell to stash desktop apps */
+    public void stashDesktopApps(int displayId) {
+        if (mDesktopMode != null) {
+            try {
+                mDesktopMode.stashDesktopApps(displayId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call stashDesktopApps", e);
+            }
+        }
+    }
+
+    /** Call shell to hide desktop apps that may be stashed */
+    public void hideStashedDesktopApps(int displayId) {
+        if (mDesktopMode != null) {
+            try {
+                mDesktopMode.hideStashedDesktopApps(displayId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call hideStashedDesktopApps", e);
+            }
+        }
+    }
+
+    /**
+     * If task with the given id is on the desktop, bring it to front
+     */
+    public void showDesktopApp(int taskId) {
+        if (mDesktopMode != null) {
+            try {
+                mDesktopMode.showDesktopApp(taskId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call showDesktopApp", e);
+            }
+        }
+    }
+
+    /** Call shell to get number of visible freeform tasks */
+    public int getVisibleDesktopTaskCount(int displayId) {
+        if (mDesktopMode != null) {
+            try {
+                return mDesktopMode.getVisibleTaskCount(displayId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call getVisibleDesktopTaskCount", e);
+            }
+        }
+        return 0;
+    }
+
+    /** Set a listener on shell to get updates about desktop task state */
+    public void setDesktopTaskListener(@Nullable IDesktopTaskListener listener) {
+        mDesktopTaskListener = listener;
+        if (mDesktopMode != null) {
+            try {
+                mDesktopMode.setTaskListener(listener);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setDesktopTaskListener", e);
+            }
+        }
+    }
+
+    /** Perform cleanup transactions after animation to split select is complete */
+    public void onDesktopSplitSelectAnimComplete(ActivityManager.RunningTaskInfo taskInfo) {
+        if (mDesktopMode != null) {
+            try {
+                mDesktopMode.onDesktopSplitSelectAnimComplete(taskInfo);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onDesktopSplitSelectAnimComplete", e);
+            }
+        }
+    }
+
+    //
+    // Unfold transition
+    //
+
+    /** Sets the unfold animation lister to sysui. */
+    public void setUnfoldAnimationListener(IUnfoldTransitionListener callback) {
+        mUnfoldAnimationListener = callback;
+        if (mUnfoldAnimation == null) {
+            return;
+        }
+        try {
+            Log.d(TAG, "Registering unfold animation receiver");
+            mUnfoldAnimation.setListener(callback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed call setUnfoldAnimationListener", e);
+        }
+    }
+
+    //
+    // Recents
+    //
+
+    /**
+     * Starts the recents activity. The caller should manage the thread on which this is called.
+     */
+    public boolean startRecentsActivity(Intent intent, ActivityOptions options,
+            RecentsAnimationListener listener) {
+        if (mRecentTasks == null) {
+            ActiveGestureLog.INSTANCE.addLog("Null mRecentTasks", RECENT_TASKS_MISSING);
+            return false;
+        }
+        final IRecentsAnimationRunner runner = new IRecentsAnimationRunner.Stub() {
+            @Override
+            public void onAnimationStart(IRecentsAnimationController controller,
+                    RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
+                    Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras) {
+                // Aidl bundles need to explicitly set class loader
+                // https://developer.android.com/guide/components/aidl#Bundles
+                if (extras != null) {
+                    extras.setClassLoader(getClass().getClassLoader());
+                }
+                listener.onAnimationStart(new RecentsAnimationControllerCompat(controller), apps,
+                        wallpapers, homeContentInsets, minimizedHomeBounds, extras);
+            }
+
+            @Override
+            public void onAnimationCanceled(int[] taskIds, TaskSnapshot[] taskSnapshots) {
+                listener.onAnimationCanceled(
+                        ThumbnailData.wrap(taskIds, taskSnapshots));
+            }
+
+            @Override
+            public void onTasksAppeared(RemoteAnimationTarget[] apps) {
+                listener.onTasksAppeared(apps);
+            }
+        };
+        final Bundle optsBundle = options.toBundle();
+        try {
+            mRecentTasks.startRecentsTransition(mRecentsPendingIntent, intent, optsBundle,
+                    mContext.getIApplicationThread(), runner);
+            return true;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error starting recents via shell", e);
+            return false;
+        }
+    }
+
+    //
+    // Drag and drop
+    //
+
+    /**
+     * For testing purposes.  Returns `true` only if the shell drop target has shown and
+     * drawn and is ready to handle drag events and the subsequent drop.
+     */
+    public boolean isDragAndDropReady() {
+        if (mDragAndDrop == null) {
+            return false;
+        }
+        try {
+            return mDragAndDrop.isReadyToHandleDrag();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error querying drag state", e);
+            return false;
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println(TAG + ":");
+
+        pw.println("\tmSystemUiProxy=" + mSystemUiProxy);
+        pw.println("\tmPip=" + mPip);
+        pw.println("\tmPipAnimationListener=" + mPipAnimationListener);
+        pw.println("\tmBubbles=" + mBubbles);
+        pw.println("\tmBubblesListener=" + mBubblesListener);
+        pw.println("\tmSplitScreen=" + mSplitScreen);
+        pw.println("\tmSplitScreenListener=" + mSplitScreenListener);
+        pw.println("\tmSplitSelectListener=" + mSplitSelectListener);
+        pw.println("\tmOneHanded=" + mOneHanded);
+        pw.println("\tmShellTransitions=" + mShellTransitions);
+        pw.println("\tmHomeTransitionListener=" + mHomeTransitionListener);
+        pw.println("\tmStartingWindow=" + mStartingWindow);
+        pw.println("\tmStartingWindowListener=" + mStartingWindowListener);
+        pw.println("\tmSysuiUnlockAnimationController=" + mSysuiUnlockAnimationController);
+        pw.println("\tmLauncherActivityClass=" + mLauncherActivityClass);
+        pw.println("\tmLauncherUnlockAnimationController=" + mLauncherUnlockAnimationController);
+        pw.println("\tmRecentTasks=" + mRecentTasks);
+        pw.println("\tmRecentTasksListener=" + mRecentTasksListener);
+        pw.println("\tmBackAnimation=" + mBackAnimation);
+        pw.println("\tmBackToLauncherCallback=" + mBackToLauncherCallback);
+        pw.println("\tmBackToLauncherRunner=" + mBackToLauncherRunner);
+        pw.println("\tmDesktopMode=" + mDesktopMode);
+        pw.println("\tmDesktopTaskListener=" + mDesktopTaskListener);
+        pw.println("\tmUnfoldAnimation=" + mUnfoldAnimation);
+        pw.println("\tmUnfoldAnimationListener=" + mUnfoldAnimationListener);
+        pw.println("\tmDragAndDrop=" + mDragAndDrop);
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.kt b/quickstep/src/com/android/quickstep/SystemUiProxy.kt
deleted file mode 100644
index 6184785..0000000
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.kt
+++ /dev/null
@@ -1,1232 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep
-
-import android.app.ActivityManager
-import android.app.ActivityManager.RunningTaskInfo
-import android.app.ActivityOptions
-import android.app.PendingIntent
-import android.app.PictureInPictureParams
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.content.pm.ActivityInfo
-import android.content.pm.PackageManager
-import android.content.pm.ShortcutInfo
-import android.graphics.Point
-import android.graphics.Rect
-import android.os.Bundle
-import android.os.Handler
-import android.os.IBinder
-import android.os.Message
-import android.os.RemoteException
-import android.os.UserHandle
-import android.util.Log
-import android.view.IRecentsAnimationController
-import android.view.IRecentsAnimationRunner
-import android.view.IRemoteAnimationRunner
-import android.view.MotionEvent
-import android.view.RemoteAnimationAdapter
-import android.view.RemoteAnimationTarget
-import android.view.SurfaceControl
-import android.window.IOnBackInvokedCallback
-import android.window.RemoteTransition
-import android.window.TaskSnapshot
-import android.window.TransitionFilter
-import androidx.annotation.MainThread
-import androidx.annotation.WorkerThread
-import com.android.internal.logging.InstanceId
-import com.android.internal.util.ScreenshotRequest
-import com.android.internal.view.AppearanceRegion
-import com.android.launcher3.config.FeatureFlags
-import com.android.launcher3.util.Executors
-import com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR
-import com.android.launcher3.util.MainThreadInitializedObject
-import com.android.launcher3.util.Preconditions
-import com.android.launcher3.util.SplitConfigurationOptions.StagePosition
-import com.android.quickstep.util.ActiveGestureErrorDetector
-import com.android.quickstep.util.ActiveGestureLog
-import com.android.quickstep.util.AssistUtils
-import com.android.quickstep.util.LogUtils.splitFailureMessage
-import com.android.systemui.shared.recents.ISystemUiProxy
-import com.android.systemui.shared.recents.model.ThumbnailData
-import com.android.systemui.shared.system.RecentsAnimationControllerCompat
-import com.android.systemui.shared.system.RecentsAnimationListener
-import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController
-import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController
-import com.android.systemui.shared.system.smartspace.SmartspaceState
-import com.android.systemui.unfold.progress.IUnfoldAnimation
-import com.android.systemui.unfold.progress.IUnfoldTransitionListener
-import com.android.wm.shell.back.IBackAnimation
-import com.android.wm.shell.bubbles.IBubbles
-import com.android.wm.shell.bubbles.IBubblesListener
-import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition
-import com.android.wm.shell.desktopmode.IDesktopMode
-import com.android.wm.shell.desktopmode.IDesktopTaskListener
-import com.android.wm.shell.draganddrop.IDragAndDrop
-import com.android.wm.shell.onehanded.IOneHanded
-import com.android.wm.shell.pip.IPip
-import com.android.wm.shell.pip.IPipAnimationListener
-import com.android.wm.shell.recents.IRecentTasks
-import com.android.wm.shell.recents.IRecentTasksListener
-import com.android.wm.shell.splitscreen.ISplitScreen
-import com.android.wm.shell.splitscreen.ISplitScreenListener
-import com.android.wm.shell.splitscreen.ISplitSelectListener
-import com.android.wm.shell.startingsurface.IStartingWindow
-import com.android.wm.shell.startingsurface.IStartingWindowListener
-import com.android.wm.shell.transition.IHomeTransitionListener
-import com.android.wm.shell.transition.IShellTransitions
-import com.android.wm.shell.util.GroupedRecentTaskInfo
-import java.io.PrintWriter
-
-/** Holds the reference to SystemUI. */
-class SystemUiProxy(private val context: Context) {
-
-    private val asyncHandler = Handler(UI_HELPER_EXECUTOR.looper, this::handleMessageAsync)
-
-    /**
-     * This is a singleton pending intent that is used to start recents via Shell (which is a
-     * different process). It is bare-bones, so it's expected that the component and options will be
-     * provided via fill-in intent.
-     */
-    private val recentsPendingIntent =
-        PendingIntent.getActivity(
-            context,
-            0,
-            Intent().setPackage(context.packageName),
-            PendingIntent.FLAG_MUTABLE or
-                PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT or
-                Intent.FILL_IN_COMPONENT,
-            ActivityOptions.makeBasic()
-                .setPendingIntentCreatorBackgroundActivityStartMode(
-                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
-                )
-                .toBundle()
-        )
-
-    private val systemUiProxyDeathRecipient =
-        IBinder.DeathRecipient { Executors.MAIN_EXECUTOR.execute { clearProxy() } }
-
-    private var systemUiProxy: ISystemUiProxy? = null
-
-    private var pip: IPip? = null
-    private var bubbles: IBubbles? = null
-    private var sysuiUnlockAnimationController: ISysuiUnlockAnimationController? = null
-    private var splitScreen: ISplitScreen? = null
-    private var oneHanded: IOneHanded? = null
-    private var shellTransitions: IShellTransitions? = null
-    private var startingWindow: IStartingWindow? = null
-    private var recentTasks: IRecentTasks? = null
-    private var backAnimation: IBackAnimation? = null
-    private var desktopMode: IDesktopMode? = null
-    private var unfoldAnimation: IUnfoldAnimation? = null
-
-    // Save the listeners passed into the proxy since OverviewProxyService may not have been bound
-    // yet, and we'll need to set/register these listeners with SysUI when they do.  Note that it is
-    // up to the caller to clear the listeners to prevent leaks as these can be held indefinitely
-    // in case SysUI needs to rebind.
-    private var pipAnimationListener: IPipAnimationListener? = null
-    private var bubblesListener: IBubblesListener? = null
-    private var splitScreenListener: ISplitScreenListener? = null
-    private var splitSelectListener: ISplitSelectListener? = null
-    private var startingWindowListener: IStartingWindowListener? = null
-    private var launcherUnlockAnimationController: ILauncherUnlockAnimationController? = null
-    private var launcherActivityClass: String? = null
-    private var recentTasksListener: IRecentTasksListener? = null
-    private var unfoldAnimationListener: IUnfoldTransitionListener? = null
-    private var desktopTaskListener: IDesktopTaskListener? = null
-    private val remoteTransitions = LinkedHashMap<RemoteTransition, TransitionFilter>()
-    private var originalTransactionToken: IBinder? = null
-    private var backToLauncherCallback: IOnBackInvokedCallback? = null
-    private var backToLauncherRunner: IRemoteAnimationRunner? = null
-    private var dragAndDrop: IDragAndDrop? = null
-    private var homeTransitionListener: IHomeTransitionListener? = null
-
-    // Used to dedupe calls to SystemUI
-    private var lastShelfHeight = 0
-    private var lastShelfVisible = false
-
-    // Used to dedupe calls to SystemUI
-    private var lastLauncherKeepClearAreaHeight = 0
-    private var lastLauncherKeepClearAreaHeightVisible = false
-
-    // TODO(141886704): Find a way to remove this
-    var lastSystemUiStateFlags = 0
-
-    /**
-     * Sets proxy state, including death linkage, various listeners, and other configuration objects
-     */
-    @MainThread
-    fun setProxy(
-        proxy: ISystemUiProxy?,
-        pip: IPip?,
-        bubbles: IBubbles?,
-        splitScreen: ISplitScreen?,
-        oneHanded: IOneHanded?,
-        shellTransitions: IShellTransitions?,
-        startingWindow: IStartingWindow?,
-        recentTasks: IRecentTasks?,
-        sysuiUnlockAnimationController: ISysuiUnlockAnimationController?,
-        backAnimation: IBackAnimation?,
-        desktopMode: IDesktopMode?,
-        unfoldAnimation: IUnfoldAnimation?,
-        dragAndDrop: IDragAndDrop?
-    ) {
-        Preconditions.assertUIThread()
-        unlinkToDeath()
-        systemUiProxy = proxy
-        this.pip = pip
-        this.bubbles = bubbles
-        this.splitScreen = splitScreen
-        this.oneHanded = oneHanded
-        this.shellTransitions = shellTransitions
-        this.startingWindow = startingWindow
-        this.sysuiUnlockAnimationController = sysuiUnlockAnimationController
-        this.recentTasks = recentTasks
-        this.backAnimation = backAnimation
-        this.desktopMode = desktopMode
-        this.unfoldAnimation = unfoldAnimation
-        this.dragAndDrop = dragAndDrop
-        linkToDeath()
-        // re-attach the listeners once missing due to setProxy has not been initialized yet.
-        setPipAnimationListener(pipAnimationListener)
-        setBubblesListener(bubblesListener)
-        registerSplitScreenListener(splitScreenListener)
-        registerSplitSelectListener(splitSelectListener)
-        setHomeTransitionListener(homeTransitionListener)
-        setStartingWindowListener(startingWindowListener)
-        setLauncherUnlockAnimationController(
-            launcherActivityClass,
-            launcherUnlockAnimationController
-        )
-        LinkedHashMap(remoteTransitions).forEach(this::registerRemoteTransition)
-        setupTransactionQueue()
-        registerRecentTasksListener(recentTasksListener)
-        setBackToLauncherCallback(backToLauncherCallback, backToLauncherRunner)
-        setUnfoldAnimationListener(unfoldAnimationListener)
-        setDesktopTaskListener(desktopTaskListener)
-        setAssistantOverridesRequested(
-            AssistUtils.newInstance(context).sysUiAssistOverrideInvocationTypes
-        )
-    }
-
-    /**
-     * Clear the proxy to release held resources and turn the majority of its operations into no-ops
-     */
-    @MainThread
-    fun clearProxy() {
-        setProxy(null, null, null, null, null, null, null, null, null, null, null, null, null)
-    }
-
-    val isActive: Boolean
-        get() = systemUiProxy != null
-
-    private fun linkToDeath() {
-        tryOrLog("Failed to link sysui proxy death recipient") {
-            systemUiProxy?.asBinder()?.linkToDeath(systemUiProxyDeathRecipient, 0 /* flags */)
-        }
-    }
-
-    private fun unlinkToDeath() {
-        systemUiProxy?.asBinder()?.unlinkToDeath(systemUiProxyDeathRecipient, 0 /* flags */)
-    }
-
-    fun onBackPressed() {
-        tryOrLog("Failed call onBackPressed") { systemUiProxy?.onBackPressed() }
-    }
-
-    fun onImeSwitcherPressed() {
-        tryOrLog("Failed call onImeSwitcherPressed") { systemUiProxy?.onImeSwitcherPressed() }
-    }
-
-    fun setHomeRotationEnabled(enabled: Boolean) {
-        tryOrLog("Failed call setHomeRotationEnabled") {
-            systemUiProxy?.setHomeRotationEnabled(enabled)
-        }
-    }
-
-    fun startScreenPinning(taskId: Int) {
-        tryOrLog("Failed call startScreenPinning") { systemUiProxy?.startScreenPinning(taskId) }
-    }
-
-    fun onOverviewShown(fromHome: Boolean, tag: String?) {
-        try {
-            systemUiProxy?.onOverviewShown(fromHome)
-        } catch (e: RemoteException) {
-            Log.w(tag, "Failed call onOverviewShown from: ${if (fromHome) "home" else "app"}", e)
-        }
-    }
-
-    @MainThread
-    fun onStatusBarTouchEvent(event: MotionEvent) {
-        Preconditions.assertUIThread()
-        tryOrLog("Failed call onStatusBarTouchEvent with arg: $event") {
-            systemUiProxy?.onStatusBarTouchEvent(event)
-        }
-    }
-
-    fun onStatusBarTrackpadEvent(event: MotionEvent) {
-        tryOrLog("Failed call onStatusBarTrackpadEvent with arg: $event") {
-            systemUiProxy?.onStatusBarTrackpadEvent(event)
-        }
-    }
-
-    fun onAssistantProgress(progress: Float) {
-        tryOrLog("Failed call onAssistantProgress with progress: $progress") {
-            systemUiProxy?.onAssistantProgress(progress)
-        }
-    }
-
-    fun onAssistantGestureCompletion(velocity: Float) {
-        tryOrLog("Failed call onAssistantGestureCompletion") {
-            systemUiProxy?.onAssistantGestureCompletion(velocity)
-        }
-    }
-
-    fun startAssistant(args: Bundle?) {
-        tryOrLog("Failed call startAssistant") { systemUiProxy?.startAssistant(args) }
-    }
-
-    fun setAssistantOverridesRequested(invocationTypes: IntArray?) {
-        tryOrLog("Failed call setAssistantOverridesRequested") {
-            systemUiProxy?.setAssistantOverridesRequested(invocationTypes)
-        }
-    }
-
-    fun animateNavBarLongPress(isTouchDown: Boolean, durationMs: Long) {
-        tryOrLog("Failed call animateNavBarLongPress") {
-            systemUiProxy?.animateNavBarLongPress(isTouchDown, durationMs)
-        }
-    }
-
-    fun notifyAccessibilityButtonClicked(displayId: Int) {
-        tryOrLog("Failed call notifyAccessibilityButtonClicked") {
-            systemUiProxy?.notifyAccessibilityButtonClicked(displayId)
-        }
-    }
-
-    fun notifyAccessibilityButtonLongClicked() {
-        tryOrLog("Failed call notifyAccessibilityButtonLongClicked") {
-            systemUiProxy?.notifyAccessibilityButtonLongClicked()
-        }
-    }
-
-    fun stopScreenPinning() {
-        tryOrLog("Failed call stopScreenPinning") { systemUiProxy?.stopScreenPinning() }
-    }
-
-    fun notifyPrioritizedRotation(rotation: Int) {
-        tryOrLog("Failed call notifyPrioritizedRotation with arg: $rotation") {
-            systemUiProxy?.notifyPrioritizedRotation(rotation)
-        }
-    }
-
-    fun notifyTaskbarStatus(visible: Boolean, stashed: Boolean) {
-        tryOrLog("Failed call notifyTaskbarStatus with arg: $visible, $stashed") {
-            systemUiProxy?.notifyTaskbarStatus(visible, stashed)
-        }
-    }
-
-    /**
-     * NOTE: If called to suspend, caller MUST call this method to also un-suspend
-     *
-     * @param suspend should be true to stop auto-hide, false to resume normal behavior
-     */
-    fun notifyTaskbarAutohideSuspend(suspend: Boolean) {
-        tryOrLog("Failed call notifyTaskbarAutohideSuspend with arg: $suspend") {
-            systemUiProxy?.notifyTaskbarAutohideSuspend(suspend)
-        }
-    }
-
-    fun takeScreenshot(request: ScreenshotRequest?) {
-        tryOrLog("Failed call takeScreenshot") { systemUiProxy?.takeScreenshot(request) }
-    }
-
-    fun expandNotificationPanel() {
-        tryOrLog("Failed call expandNotificationPanel") { systemUiProxy?.expandNotificationPanel() }
-    }
-
-    fun toggleNotificationPanel() {
-        tryOrLog("Failed call toggleNotificationPanel") { systemUiProxy?.toggleNotificationPanel() }
-    }
-
-    //
-    // Pip
-    //
-    /** Sets the shelf height. */
-    fun setShelfHeight(visible: Boolean, shelfHeight: Int) {
-        Message.obtain(asyncHandler, MSG_SET_SHELF_HEIGHT, if (visible) 1 else 0, shelfHeight)
-            .sendToTarget()
-    }
-
-    @WorkerThread
-    private fun setShelfHeightAsync(visibleInt: Int, shelfHeight: Int) {
-        val visible = visibleInt != 0
-        if (visible == lastShelfVisible && shelfHeight == lastShelfHeight) return
-
-        pip?.let {
-            tryOrLog("Failed call setShelfHeight visible: $visible height: $shelfHeight") {
-                it.setShelfHeight(visible, shelfHeight)
-                lastShelfVisible = visible
-                lastShelfHeight = shelfHeight
-            }
-        }
-    }
-
-    /**
-     * Sets the height of the keep clear area that is going to be reported by the Launcher for the
-     * Hotseat.
-     */
-    fun setLauncherKeepClearAreaHeight(visible: Boolean, height: Int) {
-        Message.obtain(
-                asyncHandler,
-                MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT,
-                if (visible) 1 else 0,
-                height
-            )
-            .sendToTarget()
-    }
-
-    @WorkerThread
-    private fun setLauncherKeepClearAreaHeight(visibleInt: Int, height: Int) {
-        val visible = visibleInt != 0
-        if (
-            visible == lastLauncherKeepClearAreaHeightVisible &&
-                height == lastLauncherKeepClearAreaHeight
-        )
-            return
-
-        pip?.let {
-            tryOrLog("Failed call setLauncherKeepClearAreaHeight vis: $visible height: $height") {
-                it.setLauncherKeepClearAreaHeight(visible, height)
-                lastLauncherKeepClearAreaHeightVisible = visible
-                lastLauncherKeepClearAreaHeight = height
-            }
-        }
-    }
-
-    /** Sets listener to get pip animation callbacks. */
-    fun setPipAnimationListener(listener: IPipAnimationListener?) {
-        tryOrLog("Failed call setPinnedStackAnimationListener") {
-            pip?.setPipAnimationListener(listener)
-        }
-        pipAnimationListener = listener
-    }
-
-    /** @return Destination bounds of auto-pip animation, `null` if the animation is not ready. */
-    fun startSwipePipToHome(
-        componentName: ComponentName?,
-        activityInfo: ActivityInfo?,
-        pictureInPictureParams: PictureInPictureParams?,
-        launcherRotation: Int,
-        hotseatKeepClearArea: Rect?
-    ): Rect? {
-        return tryOrElse("Failed call startSwipePipToHome", null) {
-            return pip?.startSwipePipToHome(
-                componentName,
-                activityInfo,
-                pictureInPictureParams,
-                launcherRotation,
-                hotseatKeepClearArea
-            )
-        }
-    }
-
-    /**
-     * Notifies WM Shell that launcher has finished the preparation of the animation for swipe to
-     * home. WM Shell can choose to fade out the overlay when entering PIP is finished, and WM Shell
-     * should be responsible for cleaning up the overlay.
-     */
-    fun stopSwipePipToHome(
-        taskId: Int,
-        componentName: ComponentName?,
-        destinationBounds: Rect?,
-        overlay: SurfaceControl?
-    ) {
-        tryOrLog("Failed call stopSwipePipToHome") {
-            pip?.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay)
-        }
-    }
-
-    /**
-     * Notifies WM Shell that launcher has aborted all the animation for swipe to home. WM Shell can
-     * use this callback to clean up its internal states.
-     */
-    fun abortSwipePipToHome(taskId: Int, componentName: ComponentName?) {
-        tryOrLog("Failed call abortSwipePipToHome") {
-            pip?.abortSwipePipToHome(taskId, componentName)
-        }
-    }
-
-    /** Sets the next pip animation type to be the alpha animation. */
-    fun setPipAnimationTypeToAlpha() {
-        tryOrLog("Failed call setPipAnimationTypeToAlpha") { pip?.setPipAnimationTypeToAlpha() }
-    }
-
-    /** Sets the app icon size in pixel used by Launcher all apps. */
-    fun setLauncherAppIconSize(iconSizePx: Int) {
-        tryOrLog("Failed call setLauncherAppIconSize") { pip?.setLauncherAppIconSize(iconSizePx) }
-    }
-
-    //
-    // Bubbles
-    //
-    /** Sets the listener to be notified of bubble state changes. */
-    fun setBubblesListener(listener: IBubblesListener?) {
-        bubbles?.let {
-            tryOrLog("Failed call setLauncherAppIconSize") {
-                bubblesListener?.let(it::unregisterBubbleListener)
-                listener?.let(it::registerBubbleListener)
-            }
-        }
-        bubblesListener = listener
-    }
-
-    /**
-     * Tells SysUI to show the bubble with the provided key.
-     *
-     * @param key the key of the bubble to show.
-     * @param bubbleBarOffsetX the offset of the bubble bar from the edge of the screen on the X
-     *   axis.
-     * @param bubbleBarOffsetY the offset of the bubble bar from the edge of the screen on the Y
-     *   axis.
-     */
-    fun showBubble(key: String?, bubbleBarOffsetX: Int, bubbleBarOffsetY: Int) {
-        tryOrLog("Failed call showBubble") {
-            bubbles?.showBubble(key, bubbleBarOffsetX, bubbleBarOffsetY)
-        }
-    }
-
-    /**
-     * Tells SysUI to remove the bubble with the provided key.
-     *
-     * @param key the key of the bubble to show.
-     */
-    fun removeBubble(key: String?) {
-        tryOrLog("Failed call removeBubble") { bubbles?.removeBubble(key) }
-    }
-
-    /** Tells SysUI to remove all bubbles. */
-    fun removeAllBubbles() {
-        tryOrLog("Failed call removeAllBubbles") { bubbles?.removeAllBubbles() }
-    }
-
-    /** Tells SysUI to collapse the bubbles. */
-    fun collapseBubbles() {
-        tryOrLog("Failed call collapseBubbles") { bubbles?.collapseBubbles() }
-    }
-
-    /**
-     * Tells SysUI when the bubble is being dragged. Should be called only when the bubble bar is
-     * expanded.
-     *
-     * @param bubbleKey the key of the bubble to collapse/expand
-     * @param isBeingDragged whether the bubble is being dragged
-     */
-    fun onBubbleDrag(bubbleKey: String?, isBeingDragged: Boolean) {
-        tryOrLog("Failed call onBubbleDrag") { bubbles?.onBubbleDrag(bubbleKey, isBeingDragged) }
-    }
-
-    /**
-     * Tells SysUI to show user education relative to the reference point provided.
-     *
-     * @param position the bubble bar top center position in Screen coordinates.
-     */
-    fun showUserEducation(position: Point) {
-        tryOrLog("Failed call showUserEducation") {
-            bubbles?.showUserEducation(position.x, position.y)
-        }
-    }
-
-    //
-    // Splitscreen
-    //
-    fun registerSplitScreenListener(listener: ISplitScreenListener?) {
-        tryOrLog("Failed call registerSplitScreenListener") {
-            splitScreen?.registerSplitScreenListener(listener)
-        }
-        splitScreenListener = listener
-    }
-
-    fun registerSplitSelectListener(listener: ISplitSelectListener?) {
-        tryOrLog("Failed call registerSplitScreenListener") {
-            splitScreen?.registerSplitSelectListener(listener)
-        }
-        splitSelectListener = listener
-    }
-
-    /** Start multiple tasks in split-screen simultaneously. */
-    fun startTasks(
-        taskId1: Int,
-        options1: Bundle?,
-        taskId2: Int,
-        options2: Bundle?,
-        @StagePosition splitPosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        remoteTransition: RemoteTransition?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startTasks", "RemoteException")) {
-            splitScreen?.startTasks(
-                taskId1,
-                options1,
-                taskId2,
-                options2,
-                splitPosition,
-                snapPosition,
-                remoteTransition,
-                instanceId
-            )
-        }
-    }
-
-    fun startIntentAndTask(
-        pendingIntent: PendingIntent?,
-        userId1: Int,
-        options1: Bundle?,
-        taskId: Int,
-        options2: Bundle?,
-        @StagePosition splitPosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        remoteTransition: RemoteTransition?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startIntentAndTask", "RemoteException")) {
-            splitScreen?.startIntentAndTask(
-                pendingIntent,
-                userId1,
-                options1,
-                taskId,
-                options2,
-                splitPosition,
-                snapPosition,
-                remoteTransition,
-                instanceId
-            )
-        }
-    }
-
-    fun startIntents(
-        pendingIntent1: PendingIntent?,
-        userId1: Int,
-        shortcutInfo1: ShortcutInfo?,
-        options1: Bundle?,
-        pendingIntent2: PendingIntent?,
-        userId2: Int,
-        shortcutInfo2: ShortcutInfo?,
-        options2: Bundle?,
-        @StagePosition splitPosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        remoteTransition: RemoteTransition?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startIntents", "RemoteException")) {
-            splitScreen?.startIntents(
-                pendingIntent1,
-                userId1,
-                shortcutInfo1,
-                options1,
-                pendingIntent2,
-                userId2,
-                shortcutInfo2,
-                options2,
-                splitPosition,
-                snapPosition,
-                remoteTransition,
-                instanceId
-            )
-        }
-    }
-
-    fun startShortcutAndTask(
-        shortcutInfo: ShortcutInfo?,
-        options1: Bundle?,
-        taskId: Int,
-        options2: Bundle?,
-        @StagePosition splitPosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        remoteTransition: RemoteTransition?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startShortcutAndTask", "RemoteException")) {
-            splitScreen?.startShortcutAndTask(
-                shortcutInfo,
-                options1,
-                taskId,
-                options2,
-                splitPosition,
-                snapPosition,
-                remoteTransition,
-                instanceId
-            )
-        }
-    }
-
-    /** Start multiple tasks in split-screen simultaneously. */
-    fun startTasksWithLegacyTransition(
-        taskId1: Int,
-        options1: Bundle?,
-        taskId2: Int,
-        options2: Bundle?,
-        @StagePosition splitPosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        adapter: RemoteAnimationAdapter?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startTasksWithLegacyTransition", "RemoteException")) {
-            splitScreen?.startTasksWithLegacyTransition(
-                taskId1,
-                options1,
-                taskId2,
-                options2,
-                splitPosition,
-                snapPosition,
-                adapter,
-                instanceId
-            )
-        }
-    }
-
-    fun startIntentAndTaskWithLegacyTransition(
-        pendingIntent: PendingIntent?,
-        userId1: Int,
-        options1: Bundle?,
-        taskId: Int,
-        options2: Bundle?,
-        @StagePosition splitPosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        adapter: RemoteAnimationAdapter?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startIntentAndTaskWithLegacyTransition", "RemoteException")) {
-            splitScreen?.startIntentAndTaskWithLegacyTransition(
-                pendingIntent,
-                userId1,
-                options1,
-                taskId,
-                options2,
-                splitPosition,
-                snapPosition,
-                adapter,
-                instanceId
-            )
-        }
-    }
-
-    fun startShortcutAndTaskWithLegacyTransition(
-        shortcutInfo: ShortcutInfo?,
-        options1: Bundle?,
-        taskId: Int,
-        options2: Bundle?,
-        @StagePosition splitPosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        adapter: RemoteAnimationAdapter?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(
-            splitFailureMessage("startShortcutAndTaskWithLegacyTransition", "RemoteException")
-        ) {
-            splitScreen?.startShortcutAndTaskWithLegacyTransition(
-                shortcutInfo,
-                options1,
-                taskId,
-                options2,
-                splitPosition,
-                snapPosition,
-                adapter,
-                instanceId
-            )
-        }
-    }
-
-    /**
-     * Starts a pair of intents or shortcuts in split-screen using legacy transition. Passing a
-     * non-null shortcut info means to start the app as a shortcut.
-     */
-    fun startIntentsWithLegacyTransition(
-        pendingIntent1: PendingIntent?,
-        userId1: Int,
-        shortcutInfo1: ShortcutInfo?,
-        options1: Bundle?,
-        pendingIntent2: PendingIntent?,
-        userId2: Int,
-        shortcutInfo2: ShortcutInfo?,
-        options2: Bundle?,
-        @StagePosition sidePosition: Int,
-        @PersistentSnapPosition snapPosition: Int,
-        adapter: RemoteAnimationAdapter?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startIntentsWithLegacyTransition", "RemoteException")) {
-            splitScreen?.startIntentsWithLegacyTransition(
-                pendingIntent1,
-                userId1,
-                shortcutInfo1,
-                options1,
-                pendingIntent2,
-                userId2,
-                shortcutInfo2,
-                options2,
-                sidePosition,
-                snapPosition,
-                adapter,
-                instanceId
-            )
-        }
-    }
-
-    fun startShortcut(
-        packageName: String?,
-        shortcutId: String?,
-        position: Int,
-        options: Bundle?,
-        user: UserHandle?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startShortcut", "RemoteException")) {
-            splitScreen?.startShortcut(packageName, shortcutId, position, options, user, instanceId)
-        }
-    }
-
-    fun startIntent(
-        intent: PendingIntent?,
-        userId: Int,
-        fillInIntent: Intent?,
-        position: Int,
-        options: Bundle?,
-        instanceId: InstanceId?
-    ) {
-        tryOrLog(splitFailureMessage("startIntent", "RemoteException")) {
-            splitScreen?.startIntent(intent, userId, fillInIntent, position, options, instanceId)
-        }
-    }
-
-    /**
-     * Call this when going to recents so that shell can set-up and provide appropriate leashes for
-     * animation (eg. DividerBar).
-     *
-     * @return RemoteAnimationTargets of windows that need to animate but only exist in shell.
-     */
-    fun onGoingToRecentsLegacy(
-        apps: Array<RemoteAnimationTarget?>?
-    ): Array<RemoteAnimationTarget>? {
-        if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) return null
-        return tryOrElse("Failed call onGoingToRecentsLegacy", null) {
-            return splitScreen?.onGoingToRecentsLegacy(apps)
-        }
-    }
-
-    fun onStartingSplitLegacy(apps: Array<RemoteAnimationTarget?>?): Array<RemoteAnimationTarget>? {
-        return tryOrElse("Failed call onStartingSplitLegacy", null) {
-            return splitScreen?.onStartingSplitLegacy(apps)
-        }
-    }
-
-    //
-    // One handed
-    //
-    fun startOneHandedMode() {
-        tryOrLog("Failed call startOneHandedMode") { oneHanded?.startOneHanded() }
-    }
-
-    fun stopOneHandedMode() {
-        tryOrLog("Failed call startOneHandedstopOneHandedModeMode") { oneHanded?.stopOneHanded() }
-    }
-
-    //
-    // Remote transitions
-    //
-    fun registerRemoteTransition(remoteTransition: RemoteTransition, filter: TransitionFilter) {
-        tryOrLog("Failed call registerRemoteTransition") {
-            shellTransitions?.registerRemote(filter, remoteTransition)
-        }
-        if (!remoteTransitions.containsKey(remoteTransition)) {
-            remoteTransitions[remoteTransition] = filter
-        }
-    }
-
-    fun unregisterRemoteTransition(remoteTransition: RemoteTransition) {
-        tryOrLog("Failed call unregisterRemoteTransition") {
-            shellTransitions?.unregisterRemote(remoteTransition)
-        }
-        remoteTransitions.remove(remoteTransition)
-    }
-
-    fun setHomeTransitionListener(listener: IHomeTransitionListener?) {
-        if (!FeatureFlags.enableHomeTransitionListener()) return
-
-        homeTransitionListener = listener
-
-        tryOrLog("Failed call unregisterRemoteTransition") {
-            shellTransitions?.setHomeTransitionListener(listener)
-                ?: Log.w(
-                    TAG,
-                    "Unable to call setHomeTransitionListener because ShellTransitions is null"
-                )
-        }
-    }
-
-    /**
-     * Use SystemUI's transaction-queue instead of Launcher's independent one. This is necessary if
-     * Launcher and SystemUI need to coordinate transactions (eg. for shell transitions).
-     */
-    fun shareTransactionQueue() {
-        if (originalTransactionToken == null) {
-            originalTransactionToken = SurfaceControl.Transaction.getDefaultApplyToken()
-        }
-        setupTransactionQueue()
-    }
-
-    /** Switch back to using Launcher's independent transaction queue. */
-    fun unshareTransactionQueue() {
-        originalTransactionToken?.let { SurfaceControl.Transaction.setDefaultApplyToken(it) }
-        originalTransactionToken = null
-    }
-
-    private fun setupTransactionQueue() {
-        originalTransactionToken ?: return
-
-        shellTransitions?.apply {
-            tryOrLog("Error getting Shell's apply token") {
-                this.shellApplyToken?.apply {
-                    SurfaceControl.Transaction.setDefaultApplyToken(this)
-                }
-                    ?: Log.e(TAG, "Didn't receive apply token from Shell")
-            }
-        }
-            ?: SurfaceControl.Transaction.setDefaultApplyToken(originalTransactionToken)
-    }
-
-    //
-    // Starting window
-    //
-    /** Sets listener to get callbacks when launching a task. */
-    fun setStartingWindowListener(listener: IStartingWindowListener?) {
-        tryOrLog("Failed call setStartingWindowListener") {
-            startingWindow?.setStartingWindowListener(listener)
-        }
-        startingWindowListener = listener
-    }
-
-    //
-    // SmartSpace transitions
-    //
-    /**
-     * Sets the instance of [ILauncherUnlockAnimationController] that System UI should use to
-     * control the launcher side of the unlock animation. This will also cause us to dispatch the
-     * current state of the smartspace to System UI (this will subsequently happen if the state
-     * changes).
-     */
-    fun setLauncherUnlockAnimationController(
-        activityClass: String?,
-        controller: ILauncherUnlockAnimationController?
-    ) {
-        tryOrLog("Failed call setLauncherUnlockAnimationController") {
-            sysuiUnlockAnimationController?.let {
-                it.setLauncherUnlockController(activityClass, controller)
-                controller?.dispatchSmartspaceStateToSysui()
-            }
-        }
-
-        launcherActivityClass = activityClass
-        launcherUnlockAnimationController = controller
-    }
-
-    /**
-     * Tells System UI that the Launcher's smartspace state has been updated, so that it can prepare
-     * the unlock animation accordingly.
-     */
-    fun notifySysuiSmartspaceStateUpdated(state: SmartspaceState?) {
-        tryOrLog("Failed call notifySysuiSmartspaceStateUpdated") {
-            sysuiUnlockAnimationController?.onLauncherSmartspaceStateUpdated(state)
-        }
-    }
-
-    //
-    // Recents
-    //
-    fun registerRecentTasksListener(listener: IRecentTasksListener?) {
-        tryOrLog("Failed call registerRecentTasksListener") {
-            recentTasks?.registerRecentTasksListener(listener)
-        }
-        recentTasksListener = listener
-    }
-
-    //
-    // Back navigation transitions
-    //
-    /** Sets the launcher [android.window.IOnBackInvokedCallback] to shell */
-    fun setBackToLauncherCallback(
-        callback: IOnBackInvokedCallback?,
-        runner: IRemoteAnimationRunner?
-    ) {
-        backToLauncherCallback = callback
-        backToLauncherRunner = runner
-
-        callback ?: return
-        tryOrLog("Failed call setBackToLauncherCallback") {
-            backAnimation?.setBackToLauncherCallback(callback, runner)
-        }
-    }
-
-    /**
-     * Clears the previously registered [IOnBackInvokedCallback].
-     *
-     * @param callback The previously registered callback instance.
-     */
-    fun clearBackToLauncherCallback(callback: IOnBackInvokedCallback) {
-        if (backToLauncherCallback !== callback) {
-            return
-        }
-        backToLauncherCallback = null
-        backToLauncherRunner = null
-        tryOrLog("Failed call clearBackToLauncherCallback") {
-            backAnimation?.clearBackToLauncherCallback()
-        }
-    }
-
-    /** Called when the status bar color needs to be customized when back navigation. */
-    fun customizeStatusBarAppearance(appearance: AppearanceRegion?) {
-        tryOrLog("Failed call customizeStatusBarAppearance") {
-            backAnimation?.customizeStatusBarAppearance(appearance)
-        }
-    }
-
-    fun getRecentTasks(numTasks: Int, userId: Int): ArrayList<GroupedRecentTaskInfo> {
-        return tryOrElse("Failed call getRecentTasks", ArrayList()) {
-            return recentTasks
-                ?.getRecentTasks(numTasks, ActivityManager.RECENT_IGNORE_UNAVAILABLE, userId)
-                ?.let { ArrayList(it.asList()) }
-                ?: ArrayList()
-        }
-    }
-
-    /** Gets the set of running tasks. */
-    fun getRunningTasks(numTasks: Int): ArrayList<RunningTaskInfo> {
-        if (!context.packageManager.hasSystemFeature(PackageManager.FEATURE_PC)) {
-            return ArrayList()
-        }
-
-        return tryOrElse("Failed call getRunningTasks", ArrayList()) {
-            recentTasks?.getRunningTasks(numTasks)?.let { ArrayList(it.asList()) } ?: ArrayList()
-        }
-    }
-
-    private fun handleMessageAsync(msg: Message): Boolean {
-        when (msg.what) {
-            MSG_SET_SHELF_HEIGHT -> {
-                setShelfHeightAsync(msg.arg1, msg.arg2)
-                return true
-            }
-            MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT -> {
-                setLauncherKeepClearAreaHeight(msg.arg1, msg.arg2)
-                return true
-            }
-        }
-        return false
-    }
-
-    //
-    // Desktop Mode
-    //
-    /** Call shell to show all apps active on the desktop */
-    fun showDesktopApps(displayId: Int, transition: RemoteTransition?) {
-        tryOrLog("Failed call showDesktopApps") {
-            desktopMode?.showDesktopApps(displayId, transition)
-        }
-    }
-
-    /** Call shell to stash desktop apps */
-    fun stashDesktopApps(displayId: Int) {
-        tryOrLog("Failed call stashDesktopApps") { desktopMode?.stashDesktopApps(displayId) }
-    }
-
-    /** Call shell to hide desktop apps that may be stashed */
-    fun hideStashedDesktopApps(displayId: Int) {
-        tryOrLog("Failed call hideStashedDesktopApps") {
-            desktopMode?.hideStashedDesktopApps(displayId)
-        }
-    }
-
-    /** If task with the given id is on the desktop, bring it to front */
-    fun showDesktopApp(taskId: Int) {
-        tryOrLog("Failed call showDesktopApp") { desktopMode?.showDesktopApp(taskId) }
-    }
-
-    /** Call shell to get number of visible freeform tasks */
-    fun getVisibleDesktopTaskCount(displayId: Int): Int {
-        return tryOrElse("Failed call getVisibleDesktopTaskCount", 0) {
-            return desktopMode?.getVisibleTaskCount(displayId) ?: 0
-        }
-    }
-
-    /** Set a listener on shell to get updates about desktop task state */
-    fun setDesktopTaskListener(listener: IDesktopTaskListener?) {
-        desktopTaskListener = listener
-        tryOrLog("Failed call setDesktopTaskListener") { desktopMode?.setTaskListener(listener) }
-    }
-
-    /** Perform cleanup transactions after animation to split select is complete */
-    fun onDesktopSplitSelectAnimComplete(taskInfo: RunningTaskInfo?) {
-        tryOrLog("Failed call onDesktopSplitSelectAnimComplete") {
-            desktopMode?.onDesktopSplitSelectAnimComplete(taskInfo)
-        }
-    }
-    //
-    // Unfold transition
-    //
-    /** Sets the unfold animation lister to sysui. */
-    fun setUnfoldAnimationListener(callback: IUnfoldTransitionListener?) {
-        unfoldAnimationListener = callback
-        tryOrLog("Failed call setUnfoldAnimationListener") {
-            unfoldAnimation?.setListener(callback)
-        }
-    }
-
-    //
-    // Recents
-    //
-    /** Starts the recents activity. The caller should manage the thread on which this is called. */
-    fun startRecentsActivity(
-        intent: Intent?,
-        options: ActivityOptions,
-        listener: RecentsAnimationListener
-    ): Boolean {
-
-        val runner: IRecentsAnimationRunner =
-            object : IRecentsAnimationRunner.Stub() {
-                override fun onAnimationStart(
-                    controller: IRecentsAnimationController,
-                    apps: Array<RemoteAnimationTarget>,
-                    wallpapers: Array<RemoteAnimationTarget>,
-                    homeContentInsets: Rect,
-                    minimizedHomeBounds: Rect,
-                    extras: Bundle?
-                ) {
-                    // Aidl bundles need to explicitly set class loader
-                    // https://developer.android.com/guide/components/aidl#Bundles
-                    extras?.classLoader = javaClass.classLoader
-                    listener.onAnimationStart(
-                        RecentsAnimationControllerCompat(controller),
-                        apps,
-                        wallpapers,
-                        homeContentInsets,
-                        minimizedHomeBounds,
-                        extras
-                    )
-                }
-
-                override fun onAnimationCanceled(
-                    taskIds: IntArray,
-                    taskSnapshots: Array<TaskSnapshot>
-                ) {
-                    listener.onAnimationCanceled(ThumbnailData.wrap(taskIds, taskSnapshots))
-                }
-
-                override fun onTasksAppeared(apps: Array<RemoteAnimationTarget>) {
-                    listener.onTasksAppeared(apps)
-                }
-            }
-
-        return tryOrElse("Error starting recents via shell", false) {
-            recentTasks?.let {
-                it.startRecentsTransition(
-                    recentsPendingIntent,
-                    intent,
-                    options.toBundle(),
-                    context.iApplicationThread,
-                    runner
-                )
-                return true
-            }
-                ?: run {
-                    ActiveGestureLog.INSTANCE.addLog(
-                        "Null recentTasks",
-                        ActiveGestureErrorDetector.GestureEvent.RECENT_TASKS_MISSING
-                    )
-                    false
-                }
-        }
-    }
-
-    //
-    // Drag and drop
-    //
-
-    /**
-     * For testing purposes. Returns `true` only if the shell drop target has shown and drawn and is
-     * ready to handle drag events and the subsequent drop.
-     */
-    val isDragAndDropReady: Boolean
-        get() =
-            tryOrElse("Error querying drag state", false) {
-                dragAndDrop?.isReadyToHandleDrag ?: false
-            }
-
-    fun dump(pw: PrintWriter) {
-        pw.println("$TAG:")
-        pw.println("\tsystemUiProxy=$systemUiProxy")
-        pw.println("\tpip=$pip")
-        pw.println("\tpipAnimationListener=$pipAnimationListener")
-        pw.println("\tbubbles=$bubbles")
-        pw.println("\tbubblesListener=$bubblesListener")
-        pw.println("\tsplitScreen=$splitScreen")
-        pw.println("\tsplitScreenListener=$splitScreenListener")
-        pw.println("\tsplitSelectListener=$splitSelectListener")
-        pw.println("\toneHanded=$oneHanded")
-        pw.println("\tshellTransitions=$shellTransitions")
-        pw.println("\thomeTransitionListener=$homeTransitionListener")
-        pw.println("\tstartingWindow=$startingWindow")
-        pw.println("\tstartingWindowListener=$startingWindowListener")
-        pw.println("\tsysuiUnlockAnimationController=$sysuiUnlockAnimationController")
-        pw.println("\tlauncherActivityClass=$launcherActivityClass")
-        pw.println("\tlauncherUnlockAnimationController=$launcherUnlockAnimationController")
-        pw.println("\trecentTasks=$recentTasks")
-        pw.println("\trecentTasksListener=$recentTasksListener")
-        pw.println("\tbackAnimation=$backAnimation")
-        pw.println("\tbackToLauncherCallback=$backToLauncherCallback")
-        pw.println("\tbackToLauncherRunner=$backToLauncherRunner")
-        pw.println("\tdesktopMode=$desktopMode")
-        pw.println("\tdesktopTaskListener=$desktopTaskListener")
-        pw.println("\tunfoldAnimation=$unfoldAnimation")
-        pw.println("\tunfoldAnimationListener=$unfoldAnimationListener")
-        pw.println("\tdragAndDrop=$dragAndDrop")
-    }
-
-    companion object {
-        private const val TAG = "SystemUiProxy"
-        private const val MSG_SET_SHELF_HEIGHT = 1
-        private const val MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT = 2
-
-        @JvmField
-        val INSTANCE = MainThreadInitializedObject { context: Context -> SystemUiProxy(context) }
-
-        private inline fun tryOrLog(msg: String, f: () -> Unit) =
-            try {
-                f()
-            } catch (e: RemoteException) {
-                Log.w(TAG, msg, e)
-            }
-
-        private inline fun <T> tryOrElse(msg: String, fallback: T, f: () -> T): T =
-            try {
-                f()
-            } catch (e: RemoteException) {
-                Log.w(TAG, msg, e)
-                fallback
-            }
-    }
-}
