From 8ff53f7e65fb776da729500cc7b82ec37ea8f843 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 1 Oct 2019 14:10:37 -0700 Subject: [PATCH] 4/ Move SystemUiProxy to its own singleton instead of routing through the model Bug: 141886704 Change-Id: I415b9ef7b57b525407e3a341b946e3ca66125102 --- .../quickstep/TouchInteractionService.java | 5 +- .../uioverrides/RecentsUiFactory.java | 32 +-- .../android/quickstep/TaskSystemShortcut.java | 21 +- .../quickstep/TouchInteractionService.java | 50 ++-- .../AccessibilityInputConsumer.java | 34 +-- .../AssistantInputConsumer.java | 70 ++--- .../ScreenPinnedInputConsumer.java | 25 +- .../util/AppWindowAnimationHelper.java | 16 +- .../StatusBarTouchController.java | 26 +- .../quickstep/OverviewInteractionState.java | 21 +- .../com/android/quickstep/RecentsModel.java | 24 +- .../com/android/quickstep/SystemUiProxy.java | 262 ++++++++++++++++++ .../launcher3/util/UiThreadHelper.java | 14 +- 13 files changed, 371 insertions(+), 229 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/SystemUiProxy.java diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index 6b936cbfc0..0012ad4e98 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.Utilities; 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 class TouchInteractionService extends Service { 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 class TouchInteractionService extends Service { 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 2f8af44663..b8e9137fbc 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 static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; 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.uioverrides.touchcontrollers.TransposedQuickSwitchT 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 @@ import java.util.ArrayList; */ 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 @@ public abstract class RecentsUiFactory { 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.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 1af0db07d8..5a2e3ff821 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.Color; 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.launcher3.util.InstantAppResolver; 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 @@ public class TaskSystemShortcut extends SystemShortcut @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 @@ public class TaskSystemShortcut extends SystemShortcut @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 @@ public class TaskSystemShortcut extends SystemShortcut return view -> { Consumer 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 708408a863..d1c63819ac 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.Build; 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 @@ public class TouchInteractionService extends Service implements 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 @@ public class TouchInteractionService extends Service implements private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; - private ISystemUiProxy mISystemUiProxy; private OverviewCommandHelper mOverviewCommandHelper; private OverviewComponentObserver mOverviewComponentObserver; private OverviewInteractionState mOverviewInteractionState; @@ -284,24 +283,20 @@ public class TouchInteractionService extends Service implements 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 @@ public class TouchInteractionService extends Service implements sSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver); mInputConsumer.registerInputConsumer(); - onSystemUiProxySet(); onSystemUiFlagsChanged(); onAssistantVisibilityChanged(); @@ -336,14 +330,6 @@ public class TouchInteractionService extends Service implements .getInt(KEY_BACK_NOTIFICATION_COUNT, MAX_BACK_NOTIFICATION_COUNT)); } - @UiThread - private void onSystemUiProxySet() { - if (mDeviceState.isUserUnlocked()) { - mRecentsModel.setSystemUiProxy(mISystemUiProxy); - mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); - } - } - @UiThread private void onSystemUiFlagsChanged() { if (mDeviceState.isUserUnlocked()) { @@ -368,8 +354,9 @@ public class TouchInteractionService extends Service implements 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 @@ public class TouchInteractionService extends Service implements // 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 @@ public class TouchInteractionService extends Service implements 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 @@ public class TouchInteractionService extends Service implements 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 92bcfb5fda..f9bbd37abb 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_POINTER_UP; 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 android.view.ViewConfiguration; import com.android.launcher3.R; import com.android.quickstep.RecentsAnimationDeviceState; import com.android.quickstep.util.MotionPauseDetector; -import com.android.systemui.shared.recents.ISystemUiProxy; +import com.android.quickstep.SystemUiProxy; import com.android.systemui.shared.system.InputMonitorCompat; /** @@ -43,7 +41,7 @@ public class AccessibilityInputConsumer extends DelegateInputConsumer { 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 @@ public class AccessibilityInputConsumer extends DelegateInputConsumer { 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 @@ public class AccessibilityInputConsumer extends DelegateInputConsumer { } 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 7cec924d52..7cc29e4cc3 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.Context; 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.R; 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 @@ public class AssistantInputConsumer extends DelegateInputConsumer { 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 @@ public class AssistantInputConsumer extends DelegateInputConsumer { 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 @@ public class AssistantInputConsumer extends DelegateInputConsumer { 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 @@ public class AssistantInputConsumer extends DelegateInputConsumer { @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 a0e20f2cd8..cfd9d91428 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.BaseDraggingActivity; 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 @@ public class ScreenPinnedInputConsumer implements InputConsumer { 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 dddfc8da34..c03580917c 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.Matrix.ScaleToFit; 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.BaseDraggingActivity; 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 @@ public class AppWindowAnimationHelper { } 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 11a804356d..16bd9ed384 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_UP; 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.Direction; 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 @@ public class StatusBarTouchController implements TouchController { */ 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 mDownEvents; @@ -73,6 +70,7 @@ public class StatusBarTouchController implements TouchController { 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 class StatusBarTouchController implements TouchController { 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 @@ public class StatusBarTouchController implements TouchController { 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 17462ab6b3..6b68b1952a 100644 --- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java +++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java @@ -20,15 +20,12 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; 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 class OverviewInteractionState { public static final MainThreadInitializedObject 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 @@ public class OverviewInteractionState { 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 @@ public class OverviewInteractionState { .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 @@ public class OverviewInteractionState { 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 @@ public class OverviewInteractionState { @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 e86a1c100e..465d4648e6 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -29,12 +29,9 @@ import android.content.pm.LauncherApps; 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 @@ public class RecentsModel extends TaskStackChangeListener { private final List 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 @@ public class RecentsModel extends TaskStackChangeListener { 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 class RecentsModel extends TaskStackChangeListener { } 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 0000000000..f37e679ef7 --- /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 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 f8d163230d..fb1dc0d840 100644 --- a/src/com/android/launcher3/util/UiThreadHelper.java +++ b/src/com/android/launcher3/util/UiThreadHelper.java @@ -52,15 +52,19 @@ public class UiThreadHelper { .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 @@ public class UiThreadHelper { ((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 class UiThreadHelper { } public interface AsyncCommand { - - void execute(int arg1, int arg2); + void execute(Context proxy, boolean state, float value); } }