4/ Move SystemUiProxy to its own singleton instead of routing through the model

Bug: 141886704
Change-Id: I415b9ef7b57b525407e3a341b946e3ca66125102
diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 6b936cb..0012ad4 100644
--- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -36,6 +36,7 @@
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.util.DefaultDisplay;
 import com.android.quickstep.RecentsAnimationDeviceState;
+import com.android.quickstep.SystemUiProxy;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 
@@ -56,7 +57,7 @@
         public void onInitialize(Bundle bundle) throws RemoteException {
             ISystemUiProxy iSystemUiProxy = ISystemUiProxy.Stub
                     .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
-            mRecentsModel.setSystemUiProxy(iSystemUiProxy);
+            SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(iSystemUiProxy);
         }
 
         @Override
@@ -120,7 +121,7 @@
         public void onMotionEvent(MotionEvent ev) { }
 
         public void onBind(ISystemUiProxy iSystemUiProxy) {
-            mRecentsModel.setSystemUiProxy(iSystemUiProxy);
+            SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(iSystemUiProxy);
         }
     };
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index 2f8af44..b8e9137 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -23,8 +23,6 @@
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.os.RemoteException;
-import android.util.Log;
 import android.view.Gravity;
 
 import com.android.launcher3.DeviceProfile;
@@ -45,13 +43,11 @@
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
-import com.android.quickstep.RecentsModel;
 import com.android.quickstep.SysUINavigationMode;
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.TouchInteractionService;
-import com.android.quickstep.util.SharedApiCompat;
+import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.views.RecentsView;
-import com.android.systemui.shared.recents.ISystemUiProxy;
 
 import java.util.ArrayList;
 
@@ -60,21 +56,16 @@
  */
 public abstract class RecentsUiFactory {
 
-    public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
-
     private static final String TAG = RecentsUiFactory.class.getSimpleName();
 
-    private static AsyncCommand newSetShelfHeightCmd(Context context) {
-        return (visible, height) -> {
-            ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(context).getSystemUiProxy();
-            if (sysUiProxy == null) return;
-            try {
-                SharedApiCompat.setShelfHeight(sysUiProxy, visible != 0, height);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error setShelfHeight", e);
-            }
-        };
-    }
+    public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
+
+    /**
+     * Reusable command for applying the shelf height on the background thread.
+     */
+    public static final AsyncCommand SET_SHELF_HEIGHT = (context, visible, height) -> {
+        SystemUiProxy.INSTANCE.get(context).setShelfHeight(visible, (int) height);
+    };
 
     public static RotationMode ROTATION_LANDSCAPE = new RotationMode(-90) {
         @Override
@@ -218,9 +209,8 @@
         DeviceProfile profile = launcher.getDeviceProfile();
         boolean visible = (state == NORMAL || state == OVERVIEW) && launcher.isUserActive()
                 && !profile.isVerticalBarLayout();
-        UiThreadHelper.runAsyncCommand(launcher, newSetShelfHeightCmd(launcher),
-                visible ? 1 : 0, profile.hotseatBarSizePx);
-
+        UiThreadHelper.runAsyncCommand(launcher, SET_SHELF_HEIGHT, visible,
+                profile.hotseatBarSizePx);
         if (state == NORMAL) {
             launcher.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(false);
         }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
index 1af0db0..5a2e3ff 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
@@ -28,9 +28,7 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.RemoteException;
 import android.os.UserHandle;
-import android.util.Log;
 import android.view.View;
 
 import com.android.launcher3.BaseDraggingActivity;
@@ -44,7 +42,6 @@
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskThumbnailView;
 import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
 import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
@@ -240,13 +237,7 @@
 
         @Override
         protected boolean onActivityStarted(BaseDraggingActivity activity) {
-            ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
-            try {
-                sysUiProxy.onSplitScreenInvoked();
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
-                return false;
-            }
+            SystemUiProxy.INSTANCE.get(activity).onSplitScreenInvoked();
             activity.getUserEventDispatcher().logActionOnControl(TAP,
                     LauncherLogProto.ControlType.SPLIT_SCREEN_TARGET);
             return true;
@@ -293,8 +284,7 @@
         @Override
         public View.OnClickListener getOnClickListener(
                 BaseDraggingActivity activity, TaskView taskView) {
-            ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
-            if (sysUiProxy == null) {
+            if (!SystemUiProxy.INSTANCE.get(activity).isActive()) {
                 return null;
             }
             if (!ActivityManagerWrapper.getInstance().isScreenPinningEnabled()) {
@@ -307,11 +297,8 @@
             return view -> {
                 Consumer<Boolean> resultCallback = success -> {
                     if (success) {
-                        try {
-                            sysUiProxy.startScreenPinning(taskView.getTask().key.id);
-                        } catch (RemoteException e) {
-                            Log.w(TAG, "Failed to start screen pinning: ", e);
-                        }
+                        SystemUiProxy.INSTANCE.get(activity).startScreenPinning(
+                                taskView.getTask().key.id);
                     } else {
                         taskView.notifyTaskLaunchFailed(TAG);
                     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 708408a..d1c6381 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -42,7 +42,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.RemoteException;
 import android.util.Log;
 import android.view.Choreographer;
 import android.view.InputEvent;
@@ -122,10 +121,11 @@
     private final IBinder mMyBinder = new IOverviewProxy.Stub() {
 
         public void onInitialize(Bundle bundle) {
-            mISystemUiProxy = ISystemUiProxy.Stub
-                    .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
+            ISystemUiProxy proxy = ISystemUiProxy.Stub.asInterface(
+                    bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
+            MAIN_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(TouchInteractionService.this)
+                    .setProxy(proxy));
             MAIN_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor);
-            MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet);
             MAIN_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */));
             sIsInitialized = true;
         }
@@ -235,7 +235,6 @@
 
     private ActivityManagerWrapper mAM;
     private RecentsModel mRecentsModel;
-    private ISystemUiProxy mISystemUiProxy;
     private OverviewCommandHelper mOverviewCommandHelper;
     private OverviewComponentObserver mOverviewComponentObserver;
     private OverviewInteractionState mOverviewInteractionState;
@@ -284,24 +283,20 @@
             Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 1");
         }
         disposeEventHandlers();
-        if (!mMode.hasGestures || mISystemUiProxy == null) {
+        if (!mMode.hasGestures || !SystemUiProxy.INSTANCE.get(this).isActive()) {
             return;
         }
         if (TestProtocol.sDebugTracing) {
             Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 2");
         }
 
-        try {
-            mInputMonitorCompat = InputMonitorCompat.fromBundle(mISystemUiProxy
-                    .monitorGestureInput("swipe-up", mDeviceState.getDisplayId()),
-                    KEY_EXTRA_INPUT_MONITOR);
-            mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
-                    mMainChoreographer, this::onInputEvent);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 3");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Unable to create input monitor", e);
+        Bundle bundle = SystemUiProxy.INSTANCE.get(this).monitorGestureInput("swipe-up",
+                mDeviceState.getDisplayId());
+        mInputMonitorCompat = InputMonitorCompat.fromBundle(bundle, KEY_EXTRA_INPUT_MONITOR);
+        mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
+                mMainChoreographer, this::onInputEvent);
+        if (TestProtocol.sDebugTracing) {
+            Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 3");
         }
 
         mDeviceState.updateGestureTouchRegions();
@@ -326,7 +321,6 @@
 
         sSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver);
         mInputConsumer.registerInputConsumer();
-        onSystemUiProxySet();
         onSystemUiFlagsChanged();
         onAssistantVisibilityChanged();
 
@@ -337,14 +331,6 @@
     }
 
     @UiThread
-    private void onSystemUiProxySet() {
-        if (mDeviceState.isUserUnlocked()) {
-            mRecentsModel.setSystemUiProxy(mISystemUiProxy);
-            mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
-        }
-    }
-
-    @UiThread
     private void onSystemUiFlagsChanged() {
         if (mDeviceState.isUserUnlocked()) {
             mOverviewInteractionState.setSystemUiStateFlags(mDeviceState.getSystemUiStateFlags());
@@ -368,8 +354,9 @@
             mOverviewComponentObserver.onDestroy();
         }
         disposeEventHandlers();
-        SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
         mDeviceState.destroy();
+        SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
+        SystemUiProxy.INSTANCE.get(this).setProxy(null);
 
         sConnected = false;
         super.onDestroy();
@@ -408,7 +395,7 @@
                 // not interrupt it. QuickSwitch assumes that interruption can only happen if the
                 // next gesture is also quick switch.
                 mUncheckedConsumer =
-                        new AssistantInputConsumer(this, mISystemUiProxy,
+                        new AssistantInputConsumer(this,
                                 mOverviewComponentObserver.getActivityControlHelper(),
                                 InputConsumer.NO_OP, mInputMonitorCompat);
             } else {
@@ -442,8 +429,7 @@
             final ActivityControlHelper activityControl =
                     mOverviewComponentObserver.getActivityControlHelper();
             if (mDeviceState.canTriggerAssistantAction(event)) {
-                base = new AssistantInputConsumer(this, mISystemUiProxy, activityControl, base,
-                        mInputMonitorCompat);
+                base = new AssistantInputConsumer(this, activityControl, base, mInputMonitorCompat);
             }
 
             if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) {
@@ -456,11 +442,11 @@
             if (mDeviceState.isScreenPinningActive()) {
                 // Note: we only allow accessibility to wrap this, and it replaces the previous
                 // base input consumer (which should be NO_OP anyway since topTaskLocked == true).
-                base = new ScreenPinnedInputConsumer(this, mISystemUiProxy, activityControl);
+                base = new ScreenPinnedInputConsumer(this, activityControl);
             }
 
             if (mDeviceState.isAccessibilityMenuAvailable()) {
-                base = new AccessibilityInputConsumer(this, mDeviceState, mISystemUiProxy, base,
+                base = new AccessibilityInputConsumer(this, mDeviceState, base,
                         mInputMonitorCompat);
             }
         } else {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
index 92bcfb5..f9bbd37 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
@@ -23,8 +23,6 @@
 import static android.view.MotionEvent.ACTION_UP;
 
 import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
 import android.view.Display;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -33,7 +31,7 @@
 import com.android.launcher3.R;
 import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.util.MotionPauseDetector;
-import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.quickstep.SystemUiProxy;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
 /**
@@ -43,7 +41,7 @@
 
     private static final String TAG = "A11yInputConsumer";
 
-    private final ISystemUiProxy mSystemUiProxy;
+    private final Context mContext;
     private final VelocityTracker mVelocityTracker;
     private final MotionPauseDetector mMotionPauseDetector;
     private final RecentsAnimationDeviceState mDeviceState;
@@ -56,9 +54,9 @@
     private float mTotalY;
 
     public AccessibilityInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
-            ISystemUiProxy systemUiProxy, InputConsumer delegate, InputMonitorCompat inputMonitor) {
+            InputConsumer delegate, InputMonitorCompat inputMonitor) {
         super(delegate, inputMonitor);
-        mSystemUiProxy = systemUiProxy;
+        mContext = context;
         mVelocityTracker = VelocityTracker.obtain();
         mMinGestureDistance = context.getResources()
                 .getDimension(R.dimen.accessibility_gesture_min_swipe_distance);
@@ -126,22 +124,18 @@
             }
             case ACTION_UP:
                 if (mState == STATE_ACTIVE) {
-                    try {
-                        if (mDeviceState.isAccessibilityMenuShortcutAvailable()
-                                && mMotionPauseDetector.isPaused()) {
-                            mSystemUiProxy.notifyAccessibilityButtonLongClicked();
-                        } else {
-                            mTotalY += (ev.getY() - mDownY);
-                            mVelocityTracker.computeCurrentVelocity(1000);
+                    if (mDeviceState.isAccessibilityMenuShortcutAvailable()
+                            && mMotionPauseDetector.isPaused()) {
+                        SystemUiProxy.INSTANCE.get(mContext).notifyAccessibilityButtonLongClicked();
+                    } else {
+                        mTotalY += (ev.getY() - mDownY);
+                        mVelocityTracker.computeCurrentVelocity(1000);
 
-                            if ((-mTotalY) > mMinGestureDistance
-                                    || (-mVelocityTracker.getYVelocity()) > mMinFlingVelocity) {
-                                mSystemUiProxy.notifyAccessibilityButtonClicked(
-                                        Display.DEFAULT_DISPLAY);
-                            }
+                        if ((-mTotalY) > mMinGestureDistance
+                                || (-mVelocityTracker.getYVelocity()) > mMinFlingVelocity) {
+                            SystemUiProxy.INSTANCE.get(mContext).notifyAccessibilityButtonClicked(
+                                    Display.DEFAULT_DISPLAY);
                         }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Unable to notify accessibility event", e);
                     }
                 }
                 // Follow through
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index 7cec924..7cc29e4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -37,9 +37,7 @@
 import android.content.res.Resources;
 import android.graphics.PointF;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.SystemClock;
-import android.util.Log;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.HapticFeedbackConstants;
@@ -51,7 +49,7 @@
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.quickstep.ActivityControlHelper;
-import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.quickstep.SystemUiProxy;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
 /**
@@ -88,17 +86,14 @@
     private final long mTimeThreshold;
     private final int mAngleThreshold;
     private final float mSquaredSlop;
-    private final ISystemUiProxy mSysUiProxy;
     private final Context mContext;
     private final GestureDetector mGestureDetector;
 
-    public AssistantInputConsumer(Context context, ISystemUiProxy systemUiProxy,
-            ActivityControlHelper activityControlHelper, InputConsumer delegate,
-            InputMonitorCompat inputMonitor) {
+    public AssistantInputConsumer(Context context, ActivityControlHelper activityControlHelper,
+            InputConsumer delegate, InputMonitorCompat inputMonitor) {
         super(delegate, inputMonitor);
         final Resources res = context.getResources();
         mContext = context;
-        mSysUiProxy = systemUiProxy;
         mDragDistThreshold = res.getDimension(R.dimen.gestures_assistant_drag_threshold);
         mFlingDistThreshold = res.getDimension(R.dimen.gestures_assistant_fling_threshold);
         mTimeThreshold = res.getInteger(R.integer.assistant_gesture_min_time_threshold);
@@ -198,13 +193,7 @@
                         SWIPE_NOOP, mDirection, NAVBAR);
                     animator.addUpdateListener(valueAnimator -> {
                         float progress = (float) valueAnimator.getAnimatedValue();
-                        try {
-
-                            mSysUiProxy.onAssistantProgress(progress);
-                        } catch (RemoteException e) {
-                            Log.w(TAG, "Failed to send SysUI start/send assistant progress: "
-                                + progress, e);
-                        }
+                        SystemUiProxy.INSTANCE.get(mContext).onAssistantProgress(progress);
                     });
                     animator.setInterpolator(Interpolators.DEACCEL_2);
                     animator.start();
@@ -224,22 +213,17 @@
     private void updateAssistantProgress() {
         if (!mLaunchedAssistant) {
             mLastProgress = Math.min(mDistance * 1f / mDragDistThreshold, 1) * mTimeFraction;
-            try {
-                if (mDistance >= mDragDistThreshold && mTimeFraction >= 1) {
-                    mSysUiProxy.onAssistantGestureCompletion(0);
-                    startAssistantInternal(SWIPE);
+            if (mDistance >= mDragDistThreshold && mTimeFraction >= 1) {
+                SystemUiProxy.INSTANCE.get(mContext).onAssistantGestureCompletion(0);
+                startAssistantInternal(SWIPE);
 
-                    Bundle args = new Bundle();
-                    args.putInt(OPA_BUNDLE_TRIGGER, OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE);
-                    args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
-                    mSysUiProxy.startAssistant(args);
-                    mLaunchedAssistant = true;
-                } else {
-                    mSysUiProxy.onAssistantProgress(mLastProgress);
-                }
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + mLastProgress,
-                    e);
+                Bundle args = new Bundle();
+                args.putInt(OPA_BUNDLE_TRIGGER, OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE);
+                args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
+                SystemUiProxy.INSTANCE.get(mContext).startAssistant(args);
+                mLaunchedAssistant = true;
+            } else {
+                SystemUiProxy.INSTANCE.get(mContext).onAssistantProgress(mLastProgress);
             }
         }
     }
@@ -274,24 +258,18 @@
         @Override
         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
             if (isValidAssistantGestureAngle(velocityX, -velocityY)
-                && mDistance >= mFlingDistThreshold
-                && !mLaunchedAssistant
-                && mState != STATE_DELEGATE_ACTIVE) {
+                    && mDistance >= mFlingDistThreshold
+                    && !mLaunchedAssistant
+                    && mState != STATE_DELEGATE_ACTIVE) {
                 mLastProgress = 1;
-                try {
-                    mSysUiProxy.onAssistantGestureCompletion(
-                        (float) Math.sqrt(velocityX * velocityX + velocityY * velocityY));
-                    startAssistantInternal(FLING);
+                SystemUiProxy.INSTANCE.get(mContext).onAssistantGestureCompletion(
+                    (float) Math.sqrt(velocityX * velocityX + velocityY * velocityY));
+                startAssistantInternal(FLING);
 
-                    Bundle args = new Bundle();
-                    args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
-                    mSysUiProxy.startAssistant(args);
-                    mLaunchedAssistant = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG,
-                        "Failed to send SysUI start/send assistant progress: " + mLastProgress,
-                        e);
-                }
+                Bundle args = new Bundle();
+                args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
+                SystemUiProxy.INSTANCE.get(mContext).startAssistant(args);
+                mLaunchedAssistant = true;
             }
             return true;
         }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
index a0e20f2..cfd9d91 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
@@ -16,8 +16,6 @@
 package com.android.quickstep.inputconsumers;
 
 import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 
@@ -25,7 +23,7 @@
 import com.android.launcher3.R;
 import com.android.quickstep.ActivityControlHelper;
 import com.android.quickstep.util.MotionPauseDetector;
-import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.quickstep.SystemUiProxy;
 
 /**
  * An input consumer that detects swipe up and hold to exit screen pinning mode.
@@ -39,25 +37,20 @@
 
     private float mTouchDownY;
 
-    public ScreenPinnedInputConsumer(Context context, ISystemUiProxy sysuiProxy,
-            ActivityControlHelper activityControl) {
+    public ScreenPinnedInputConsumer(Context context, ActivityControlHelper activityControl) {
         mMotionPauseMinDisplacement = context.getResources().getDimension(
                 R.dimen.motion_pause_detector_min_displacement_from_app);
         mMotionPauseDetector = new MotionPauseDetector(context, true /* makePauseHarderToTrigger*/);
         mMotionPauseDetector.setOnMotionPauseListener(isPaused -> {
             if (isPaused) {
-                try {
-                    sysuiProxy.stopScreenPinning();
-                    BaseDraggingActivity launcherActivity = activityControl.getCreatedActivity();
-                    if (launcherActivity != null) {
-                        launcherActivity.getRootView().performHapticFeedback(
-                                HapticFeedbackConstants.LONG_PRESS,
-                                HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
-                    }
-                    mMotionPauseDetector.clear();
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to stop screen pinning ", e);
+                SystemUiProxy.INSTANCE.get(context).stopScreenPinning();
+                BaseDraggingActivity launcherActivity = activityControl.getCreatedActivity();
+                if (launcherActivity != null) {
+                    launcherActivity.getRootView().performHapticFeedback(
+                            HapticFeedbackConstants.LONG_PRESS,
+                            HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
                 }
+                mMotionPauseDetector.clear();
             }
         });
     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index dddfc8d..c035809 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -28,7 +28,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Build;
-import android.os.RemoteException;
 
 import androidx.annotation.Nullable;
 
@@ -36,13 +35,12 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
+import com.android.quickstep.SystemUiProxy;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.RecentsModel;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskThumbnailView;
 import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.utilities.RectFEvaluator;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
@@ -337,14 +335,10 @@
     }
 
     private void updateStackBoundsToMultiWindowTaskSize(BaseDraggingActivity activity) {
-        ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
-        if (sysUiProxy != null) {
-            try {
-                mSourceStackBounds.set(sysUiProxy.getNonMinimizedSplitScreenSecondaryBounds());
-                return;
-            } catch (RemoteException e) {
-                // Use half screen size
-            }
+        SystemUiProxy proxy = SystemUiProxy.INSTANCE.get(activity);
+        if (proxy.isActive()) {
+            mSourceStackBounds.set(proxy.getNonMinimizedSplitScreenSecondaryBounds());
+            return;
         }
 
         // Assume that the task size is half screen size (minus the insets and the divider size)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
index 11a8043..16bd9ed 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
@@ -21,8 +21,6 @@
 import static android.view.MotionEvent.ACTION_CANCEL;
 
 import android.graphics.PointF;
-import android.os.RemoteException;
-import android.util.Log;
 import android.util.SparseArray;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
@@ -37,9 +35,8 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.TouchController;
-import com.android.quickstep.RecentsModel;
-import com.android.systemui.shared.recents.ISystemUiProxy;
 
+import com.android.quickstep.SystemUiProxy;
 import java.io.PrintWriter;
 
 /**
@@ -62,9 +59,9 @@
      */
     private static final int FLAG_SLIPPERY = 0x20000000;
 
-    protected final Launcher mLauncher;
+    private final Launcher mLauncher;
+    private final SystemUiProxy mSystemUiProxy;
     private final float mTouchSlop;
-    private ISystemUiProxy mSysUiProxy;
     private int mLastAction;
     private final SparseArray<PointF> mDownEvents;
 
@@ -73,6 +70,7 @@
 
     public StatusBarTouchController(Launcher l) {
         mLauncher = l;
+        mSystemUiProxy = SystemUiProxy.INSTANCE.get(mLauncher);
         // Guard against TAPs by increasing the touch slop.
         mTouchSlop = 2 * ViewConfiguration.get(l).getScaledTouchSlop();
         mDownEvents = new SparseArray<>();
@@ -82,17 +80,14 @@
     public void dump(String prefix, PrintWriter writer) {
         writer.println(prefix + "mCanIntercept:" + mCanIntercept);
         writer.println(prefix + "mLastAction:" + MotionEvent.actionToString(mLastAction));
-        writer.println(prefix + "mSysUiProxy available:" + (mSysUiProxy != null));
+        writer.println(prefix + "mSysUiProxy available:"
+                + SystemUiProxy.INSTANCE.get(mLauncher).isActive());
     }
 
     private void dispatchTouchEvent(MotionEvent ev) {
-        try {
-            if (mSysUiProxy != null) {
-                mLastAction = ev.getActionMasked();
-                mSysUiProxy.onStatusBarMotionEvent(ev);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Remote exception on sysUiProxy.", e);
+        if (mSystemUiProxy.isActive()) {
+            mLastAction = ev.getActionMasked();
+            mSystemUiProxy.onStatusBarMotionEvent(ev);
         }
     }
 
@@ -170,7 +165,6 @@
                 return false;
             }
         }
-        mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy();
-        return mSysUiProxy != null;
+        return SystemUiProxy.INSTANCE.get(mLauncher).isActive();
     }
 }
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 17462ab..6b68b19 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -20,15 +20,12 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
 
 import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.Utilities;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.systemui.shared.recents.ISystemUiProxy;
 
 /**
  * Sets alpha for the back button
@@ -43,7 +40,6 @@
     public static final MainThreadInitializedObject<OverviewInteractionState> INSTANCE =
             new MainThreadInitializedObject<>(OverviewInteractionState::new);
 
-    private static final int MSG_SET_PROXY = 200;
     private static final int MSG_SET_BACK_BUTTON_ALPHA = 201;
 
     private final Context mContext;
@@ -51,7 +47,6 @@
     private final Handler mBgHandler;
 
     // These are updated on the background thread
-    private ISystemUiProxy mISystemUiProxy;
     private float mBackButtonAlpha = 1;
 
     private int mSystemUiStateFlags;
@@ -82,10 +77,6 @@
                 .sendToTarget();
     }
 
-    public void setSystemUiProxy(ISystemUiProxy proxy) {
-        mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
-    }
-
     // TODO(141886704): See if we can remove this
     public void setSystemUiStateFlags(int stateFlags) {
         mSystemUiStateFlags = stateFlags;
@@ -105,9 +96,6 @@
 
     private boolean handleBgMessage(Message msg) {
         switch (msg.what) {
-            case MSG_SET_PROXY:
-                mISystemUiProxy = (ISystemUiProxy) msg.obj;
-                break;
             case MSG_SET_BACK_BUTTON_ALPHA:
                 applyBackButtonAlpha((float) msg.obj, msg.arg1 == 1);
                 return true;
@@ -117,14 +105,7 @@
 
     @WorkerThread
     private void applyBackButtonAlpha(float alpha, boolean animate) {
-        if (mISystemUiProxy == null) {
-            return;
-        }
-        try {
-            mISystemUiProxy.setBackButtonAlpha(alpha, animate);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Unable to update overview back button alpha", e);
-        }
+        SystemUiProxy.INSTANCE.get(mContext).setBackButtonAlpha(alpha, animate);
     }
 
     private void onNavigationModeChanged(SysUINavigationMode.Mode mode) {
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index e86a1c1..465d464 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -29,12 +29,9 @@
 import android.os.Build;
 import android.os.Looper;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.UserHandle;
-import android.util.Log;
 
 import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -60,8 +57,6 @@
     private final List<TaskThumbnailChangeListener> mThumbnailChangeListeners = new ArrayList<>();
     private final Context mContext;
 
-    private ISystemUiProxy mSystemUiProxy;
-
     private final RecentTasksList mTaskList;
     private final TaskIconCache mIconCache;
     private final TaskThumbnailCache mThumbnailCache;
@@ -177,14 +172,6 @@
         mIconCache.onTaskRemoved(dummyKey);
     }
 
-    public void setSystemUiProxy(ISystemUiProxy systemUiProxy) {
-        mSystemUiProxy = systemUiProxy;
-    }
-
-    public ISystemUiProxy getSystemUiProxy() {
-        return mSystemUiProxy;
-    }
-
     public void onTrimMemory(int level) {
         if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
             mThumbnailCache.getHighResLoadingState().setVisible(false);
@@ -197,16 +184,7 @@
     }
 
     public void onOverviewShown(boolean fromHome, String tag) {
-        if (mSystemUiProxy == null) {
-            return;
-        }
-        try {
-            mSystemUiProxy.onOverviewShown(fromHome);
-        } catch (RemoteException e) {
-            Log.w(tag,
-                    "Failed to notify SysUI of overview shown from " + (fromHome ? "home" : "app")
-                            + ": ", e);
-        }
+        SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(fromHome, tag);
     }
 
     private void setupPackageListener() {
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
new file mode 100644
index 0000000..f37e679
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -0,0 +1,262 @@
+/*
+ * 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 com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.MotionEvent;
+import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.quickstep.util.SharedApiCompat;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+
+/**
+ * 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 ISystemUiProxy mSystemUiProxy;
+    private final DeathRecipient mSystemUiProxyDeathRecipient = () -> {
+        MAIN_EXECUTOR.execute(() -> setProxy(null));
+    };
+
+    // Used to dedupe calls to SystemUI
+    private int mLastShelfHeight;
+    private boolean mLastShelfVisible;
+
+    public SystemUiProxy(Context context) {
+        // Do nothing
+    }
+
+    @Override
+    public IBinder asBinder() {
+        // Do nothing
+        return null;
+    }
+
+    public void setProxy(ISystemUiProxy proxy) {
+        unlinkToDeath();
+        mSystemUiProxy = proxy;
+        linkToDeath();
+    }
+
+    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 onSplitScreenInvoked() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onSplitScreenInvoked();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onSplitScreenInvoked", 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);
+            }
+        }
+    }
+
+    @Override
+    public Rect getNonMinimizedSplitScreenSecondaryBounds() {
+        if (mSystemUiProxy != null) {
+            try {
+                return mSystemUiProxy.getNonMinimizedSplitScreenSecondaryBounds();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call getNonMinimizedSplitScreenSecondaryBounds", e);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void setBackButtonAlpha(float alpha, boolean animate) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.setBackButtonAlpha(alpha, animate);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setBackButtonAlpha", e);
+            }
+        }
+    }
+
+    @Override
+    public void setNavBarButtonAlpha(float alpha, boolean animate) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.setNavBarButtonAlpha(alpha, animate);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setNavBarButtonAlpha", e);
+            }
+        }
+    }
+
+    @Override
+    public void onStatusBarMotionEvent(MotionEvent event) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onStatusBarMotionEvent(event);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onStatusBarMotionEvent", 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 Bundle monitorGestureInput(String name, int displayId) {
+        if (mSystemUiProxy != null) {
+            try {
+                return mSystemUiProxy.monitorGestureInput(name, displayId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call monitorGestureInput: " + name, e);
+            }
+        }
+        return null;
+    }
+
+    @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);
+            }
+        }
+    }
+
+    /**
+     * See SharedApiCompat#setShelfHeight()
+     */
+    public void setShelfHeight(boolean visible, int shelfHeight) {
+        boolean changed = visible != mLastShelfVisible || shelfHeight != mLastShelfHeight;
+        if (mSystemUiProxy != null && changed) {
+            mLastShelfVisible = visible;
+            mLastShelfHeight = shelfHeight;
+            try {
+                SharedApiCompat.setShelfHeight(mSystemUiProxy, visible, shelfHeight);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setShelfHeight visible: " + visible
+                        + " height: " + shelfHeight, e);
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java
index f8d1632..fb1dc0d 100644
--- a/src/com/android/launcher3/util/UiThreadHelper.java
+++ b/src/com/android/launcher3/util/UiThreadHelper.java
@@ -52,15 +52,19 @@
                 .sendToTarget();
     }
 
-    public static void runAsyncCommand(Context context, AsyncCommand command, int arg1, int arg2) {
-        Message.obtain(getHandler(context), MSG_RUN_COMMAND, arg1, arg2, command).sendToTarget();
+    public static void runAsyncCommand(Context context, AsyncCommand command, boolean arg1,
+            float arg2) {
+        Message.obtain(getHandler(context), MSG_RUN_COMMAND, arg1 ? 1 : 0,
+                Float.floatToIntBits(arg2), command).sendToTarget();
     }
 
     private static class UiCallbacks implements Handler.Callback {
 
+        private final Context mContext;
         private final InputMethodManager mIMM;
 
         UiCallbacks(Context context) {
+            mContext = context;
             mIMM = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
         }
 
@@ -74,7 +78,8 @@
                     ((Activity) message.obj).setRequestedOrientation(message.arg1);
                     return true;
                 case MSG_RUN_COMMAND:
-                    ((AsyncCommand) message.obj).execute(message.arg1, message.arg2);
+                    ((AsyncCommand) message.obj).execute(mContext, message.arg1 == 1,
+                            Float.intBitsToFloat(message.arg2));
                     return true;
             }
             return false;
@@ -82,7 +87,6 @@
     }
 
     public interface AsyncCommand {
-
-        void execute(int arg1, int arg2);
+        void execute(Context proxy, boolean state, float value);
     }
 }