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

Bug: 141886704
Change-Id: I415b9ef7b57b525407e3a341b946e3ca66125102
This commit is contained in:
Winson Chung 2019-10-01 14:10:37 -07:00
parent 629c87283f
commit 8ff53f7e65
13 changed files with 371 additions and 229 deletions

View File

@ -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);
}
};

View File

@ -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.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(false);
}

View File

@ -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<T extends SystemShortcut> 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<T extends SystemShortcut> 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<T extends SystemShortcut> extends SystemShortcut
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);
}

View File

@ -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,25 +283,21 @@ 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);
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");
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to create input monitor", e);
}
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 {

View File

@ -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,23 +124,19 @@ public class AccessibilityInputConsumer extends DelegateInputConsumer {
}
case ACTION_UP:
if (mState == STATE_ACTIVE) {
try {
if (mDeviceState.isAccessibilityMenuShortcutAvailable()
&& mMotionPauseDetector.isPaused()) {
mSystemUiProxy.notifyAccessibilityButtonLongClicked();
SystemUiProxy.INSTANCE.get(mContext).notifyAccessibilityButtonLongClicked();
} else {
mTotalY += (ev.getY() - mDownY);
mVelocityTracker.computeCurrentVelocity(1000);
if ((-mTotalY) > mMinGestureDistance
|| (-mVelocityTracker.getYVelocity()) > mMinFlingVelocity) {
mSystemUiProxy.notifyAccessibilityButtonClicked(
SystemUiProxy.INSTANCE.get(mContext).notifyAccessibilityButtonClicked(
Display.DEFAULT_DISPLAY);
}
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to notify accessibility event", e);
}
}
// Follow through
case ACTION_CANCEL: {

View File

@ -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);
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);
SystemUiProxy.INSTANCE.get(mContext).startAssistant(args);
mLaunchedAssistant = true;
} else {
mSysUiProxy.onAssistantProgress(mLastProgress);
}
} catch (RemoteException e) {
Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + mLastProgress,
e);
SystemUiProxy.INSTANCE.get(mContext).onAssistantProgress(mLastProgress);
}
}
}
@ -278,20 +262,14 @@ public class AssistantInputConsumer extends DelegateInputConsumer {
&& !mLaunchedAssistant
&& mState != STATE_DELEGATE_ACTIVE) {
mLastProgress = 1;
try {
mSysUiProxy.onAssistantGestureCompletion(
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);
SystemUiProxy.INSTANCE.get(mContext).startAssistant(args);
mLaunchedAssistant = true;
} catch (RemoteException e) {
Log.w(TAG,
"Failed to send SysUI start/send assistant progress: " + mLastProgress,
e);
}
}
return true;
}

View File

@ -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,15 +37,13 @@ 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();
SystemUiProxy.INSTANCE.get(context).stopScreenPinning();
BaseDraggingActivity launcherActivity = activityControl.getCreatedActivity();
if (launcherActivity != null) {
launcherActivity.getRootView().performHapticFeedback(
@ -55,9 +51,6 @@ public class ScreenPinnedInputConsumer implements InputConsumer {
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
mMotionPauseDetector.clear();
} catch (RemoteException e) {
Log.e(TAG, "Unable to stop screen pinning ", e);
}
}
});
}

View File

@ -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());
SystemUiProxy proxy = SystemUiProxy.INSTANCE.get(activity);
if (proxy.isActive()) {
mSourceStackBounds.set(proxy.getNonMinimizedSplitScreenSecondaryBounds());
return;
} catch (RemoteException e) {
// Use half screen size
}
}
// Assume that the task size is half screen size (minus the insets and the divider size)

View File

@ -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<PointF> 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) {
if (mSystemUiProxy.isActive()) {
mLastAction = ev.getActionMasked();
mSysUiProxy.onStatusBarMotionEvent(ev);
}
} catch (RemoteException e) {
Log.e(TAG, "Remote exception on sysUiProxy.", e);
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();
}
}

View File

@ -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<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 @@ 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) {

View File

@ -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<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 @@ 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() {

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}