2/ Move device state logic to its own class
- Feed the class down to the input consumers and related gesture classes
instead of specific sysui state flags
Bug: 141886704
Change-Id: I2ade7f48555c9d0ba0d3fac5c1f2dae694624224
diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 19dd82f..6b936cb 100644
--- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -34,6 +34,8 @@
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.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -44,15 +46,6 @@
public class TouchInteractionService extends Service {
private static final String TAG = "GoTouchInteractionService";
- private boolean mIsUserUnlocked;
- private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
- initWhenUserUnlocked();
- }
- }
- };
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
@@ -68,21 +61,21 @@
@Override
public void onOverviewToggle() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewCommandHelper.onOverviewToggle();
}
}
@Override
public void onOverviewShown(boolean triggeredFromAltTab) {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewCommandHelper.onOverviewShown(triggeredFromAltTab);
}
}
@Override
public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- if (mIsUserUnlocked && triggeredFromAltTab && !triggeredFromHomeKey) {
+ if (mDeviceState.isUserUnlocked() && triggeredFromAltTab && !triggeredFromHomeKey) {
// onOverviewShownFromAltTab hides the overview and ends at the target app
mOverviewCommandHelper.onOverviewHidden();
}
@@ -90,7 +83,7 @@
@Override
public void onTip(int actionType, int viewType) {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewCommandHelper.onTip(actionType, viewType);
}
}
@@ -140,35 +133,30 @@
private RecentsModel mRecentsModel;
private OverviewComponentObserver mOverviewComponentObserver;
private OverviewCommandHelper mOverviewCommandHelper;
+ private RecentsAnimationDeviceState mDeviceState;
@Override
public void onCreate() {
super.onCreate();
- if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) {
- initWhenUserUnlocked();
- } else {
- mIsUserUnlocked = false;
- registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
- }
+ mDeviceState = new RecentsAnimationDeviceState(this);
+ mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
sConnected = true;
}
- private void initWhenUserUnlocked() {
+ public void onUserUnlocked() {
mRecentsModel = RecentsModel.INSTANCE.get(this);
- mOverviewComponentObserver = new OverviewComponentObserver(this);
+ mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
mOverviewCommandHelper = new OverviewCommandHelper(this,
mOverviewComponentObserver);
- mIsUserUnlocked = true;
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
}
@Override
public void onDestroy() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewComponentObserver.onDestroy();
}
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
+ mDeviceState.destroy();
sConnected = false;
super.onDestroy();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index bb73521..c749761 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -38,7 +38,6 @@
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.Region;
import android.os.UserHandle;
import android.view.MotionEvent;
import android.view.View;
@@ -441,8 +440,8 @@
}
@Override
- public boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
- return activeNavBarRegion.contains((int) ev.getX(), (int) ev.getY());
+ public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
+ return deviceState.isInDeferredGestureRegion(ev);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
index c4f375a..6ac7546 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -5,10 +5,12 @@
import android.content.Context;
import android.os.Bundle;
+import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.testing.TestInformationHandler;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
+import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -78,7 +80,8 @@
}
private RecentsView getRecentsView() {
- OverviewComponentObserver observer = new OverviewComponentObserver(mContext);
+ OverviewComponentObserver observer = new OverviewComponentObserver(mContext,
+ new RecentsAnimationDeviceState(mContext));
try {
return observer.getActivityControlHelper().getCreatedActivity().getOverviewPanel();
} finally {
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 3b48fa7..4ca8055 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -27,15 +27,6 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;
import android.annotation.TargetApi;
@@ -43,44 +34,31 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.app.TaskInfo;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Process;
import android.os.RemoteException;
-import android.text.TextUtils;
import android.util.Log;
import android.view.Choreographer;
import android.view.InputEvent;
import android.view.MotionEvent;
-import android.view.Surface;
-import androidx.annotation.BinderThread;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.R;
-import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.logging.EventLogArray;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.DejankBinderTracker;
-import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
@@ -99,10 +77,7 @@
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
-import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.RecentsAnimationListener;
-import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
import com.android.systemui.shared.system.TaskInfoCompat;
import java.io.FileDescriptor;
@@ -133,7 +108,7 @@
*/
@TargetApi(Build.VERSION_CODES.Q)
public class TouchInteractionService extends Service implements
- NavigationModeChangeListener, DefaultDisplay.DisplayInfoChangeListener {
+ NavigationModeChangeListener {
/**
* NOTE: This value should be kept same as
@@ -154,10 +129,6 @@
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
- public void onActiveNavBarRegionChanges(Region region) {
- mActiveNavBarRegion = region;
- }
-
public void onInitialize(Bundle bundle) {
mISystemUiProxy = ISystemUiProxy.Stub
.asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
@@ -192,14 +163,14 @@
@Override
public void onAssistantAvailable(boolean available) {
- mAssistantAvailable = available;
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setAssistantAvailable(available));
+ MAIN_EXECUTOR.execute(TouchInteractionService.this::onAssistantVisibilityChanged);
}
@Override
public void onAssistantVisibilityChanged(float visibility) {
- mLastAssistantVisibility = visibility;
- MAIN_EXECUTOR.execute(
- TouchInteractionService.this::onAssistantVisibilityChanged);
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setAssistantVisibility(visibility));
+ MAIN_EXECUTOR.execute(TouchInteractionService.this::onAssistantVisibilityChanged);
}
public void onBackAction(boolean completed, int downX, int downY, boolean isButton,
@@ -219,10 +190,14 @@
}
public void onSystemUiStateChanged(int stateFlags) {
- mSystemUiStateFlags = stateFlags;
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setSystemUiFlags(stateFlags));
MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged);
}
+ public void onActiveNavBarRegionChanges(Region region) {
+ MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
+ }
+
/** Deprecated methods **/
public void onQuickStep(MotionEvent motionEvent) { }
@@ -272,71 +247,28 @@
private OverviewCommandHelper mOverviewCommandHelper;
private OverviewComponentObserver mOverviewComponentObserver;
private OverviewInteractionState mOverviewInteractionState;
- private TaskOverlayFactory mTaskOverlayFactory;
private InputConsumerController mInputConsumer;
- private boolean mAssistantAvailable;
- private float mLastAssistantVisibility = 0;
- private @SystemUiStateFlags int mSystemUiStateFlags;
-
- private boolean mIsUserUnlocked;
- private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
- initWhenUserUnlocked();
- }
- }
- };
+ private RecentsAnimationDeviceState mDeviceState;
private InputConsumer mUncheckedConsumer = InputConsumer.NO_OP;
private InputConsumer mConsumer = InputConsumer.NO_OP;
private Choreographer mMainChoreographer;
- private Region mActiveNavBarRegion = new Region();
-
private InputMonitorCompat mInputMonitorCompat;
private InputEventReceiver mInputEventReceiver;
private Mode mMode = Mode.THREE_BUTTONS;
- private int mDefaultDisplayId;
- private final RectF mSwipeTouchRegion = new RectF();
- private final RectF mAssistantLeftRegion = new RectF();
- private final RectF mAssistantRightRegion = new RectF();
-
- private ComponentName mGestureBlockingActivity;
-
- private Region mExclusionRegion;
- private SystemGestureExclusionListenerCompat mExclusionListener;
@Override
public void onCreate() {
super.onCreate();
+ mDeviceState = new RecentsAnimationDeviceState(this);
+ mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
// Initialize anything here that is needed in direct boot mode.
- // Everything else should be initialized in initWhenUserUnlocked() below.
+ // Everything else should be initialized in onUserUnlocked() below.
mMainChoreographer = Choreographer.getInstance();
mAM = ActivityManagerWrapper.getInstance();
- if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) {
- initWhenUserUnlocked();
- } else {
- mIsUserUnlocked = false;
- registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
- }
-
- mDefaultDisplayId = DefaultDisplay.INSTANCE.get(this).getInfo().id;
- String blockingActivity = getString(R.string.gesture_blocking_activity);
- mGestureBlockingActivity = TextUtils.isEmpty(blockingActivity) ? null :
- ComponentName.unflattenFromString(blockingActivity);
-
- mExclusionListener = new SystemGestureExclusionListenerCompat(mDefaultDisplayId) {
- @Override
- @BinderThread
- public void onExclusionChanged(Region region) {
- // Assignments are atomic, it should be safe on binder thread
- mExclusionRegion = region;
- }
- };
-
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this));
sConnected = true;
}
@@ -359,17 +291,18 @@
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 1");
}
+ disposeEventHandlers();
if (!mMode.hasGestures || mISystemUiProxy == null) {
return;
}
- disposeEventHandlers();
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 2");
}
try {
mInputMonitorCompat = InputMonitorCompat.fromBundle(mISystemUiProxy
- .monitorGestureInput("swipe-up", mDefaultDisplayId), KEY_EXTRA_INPUT_MONITOR);
+ .monitorGestureInput("swipe-up", mDeviceState.getDisplayId()),
+ KEY_EXTRA_INPUT_MONITOR);
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
mMainChoreographer, this::onInputEvent);
if (TestProtocol.sDebugTracing) {
@@ -378,55 +311,8 @@
} catch (RemoteException e) {
Log.e(TAG, "Unable to create input monitor", e);
}
- initTouchBounds();
- }
- private int getNavbarSize(String resName) {
- return ResourceUtils.getNavbarSize(resName, getResources());
- }
-
- private void initTouchBounds() {
- if (!mMode.hasGestures) {
- return;
- }
-
- DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(this).getInfo();
- Point realSize = new Point(displayInfo.realSize);
- mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y);
- if (mMode == Mode.NO_BUTTON) {
- int touchHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
- mSwipeTouchRegion.top = mSwipeTouchRegion.bottom - touchHeight;
-
- final int assistantWidth = getResources()
- .getDimensionPixelSize(R.dimen.gestures_assistant_width);
- final float assistantHeight = Math.max(touchHeight,
- QuickStepContract.getWindowCornerRadius(getResources()));
- mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = mSwipeTouchRegion.bottom;
- mAssistantLeftRegion.top = mAssistantRightRegion.top =
- mSwipeTouchRegion.bottom - assistantHeight;
-
- mAssistantLeftRegion.left = 0;
- mAssistantLeftRegion.right = assistantWidth;
-
- mAssistantRightRegion.right = mSwipeTouchRegion.right;
- mAssistantRightRegion.left = mSwipeTouchRegion.right - assistantWidth;
- } else {
- mAssistantLeftRegion.setEmpty();
- mAssistantRightRegion.setEmpty();
- switch (displayInfo.rotation) {
- case Surface.ROTATION_90:
- mSwipeTouchRegion.left = mSwipeTouchRegion.right
- - getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
- break;
- case Surface.ROTATION_270:
- mSwipeTouchRegion.right = mSwipeTouchRegion.left
- + getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
- break;
- default:
- mSwipeTouchRegion.top = mSwipeTouchRegion.bottom
- - getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
- }
- }
+ mDeviceState.updateGestureTouchRegions();
}
@Override
@@ -434,43 +320,17 @@
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onNavigationModeChanged " + newMode);
}
- if (mMode.hasGestures != newMode.hasGestures) {
- if (newMode.hasGestures) {
- DefaultDisplay.INSTANCE.get(this).addChangeListener(this);
- } else {
- DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
- }
- }
mMode = newMode;
-
- disposeEventHandlers();
initInputMonitor();
-
- if (mMode == Mode.NO_BUTTON) {
- mExclusionListener.register();
- } else {
- mExclusionListener.unregister();
- }
}
- @Override
- public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
- if (info.id != mDefaultDisplayId) {
- return;
- }
-
- initTouchBounds();
- }
-
- private void initWhenUserUnlocked() {
+ public void onUserUnlocked() {
mRecentsModel = RecentsModel.INSTANCE.get(this);
- mOverviewComponentObserver = new OverviewComponentObserver(this);
+ mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
- mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
- mIsUserUnlocked = true;
sSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver);
mInputConsumer.registerInputConsumer();
@@ -482,13 +342,11 @@
// new ModelPreload().start(this);
mBackGestureNotificationCounter = Math.max(0, Utilities.getDevicePrefs(this)
.getInt(KEY_BACK_NOTIFICATION_COUNT, MAX_BACK_NOTIFICATION_COUNT));
-
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
}
@UiThread
private void onSystemUiProxySet() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
}
@@ -496,37 +354,32 @@
@UiThread
private void onSystemUiFlagsChanged() {
- if (mIsUserUnlocked) {
- mOverviewInteractionState.setSystemUiStateFlags(mSystemUiStateFlags);
- mOverviewComponentObserver.onSystemUiStateChanged(mSystemUiStateFlags);
+ if (mDeviceState.isUserUnlocked()) {
+ mOverviewInteractionState.setSystemUiStateFlags(mDeviceState.getSystemUiStateFlags());
+ mOverviewComponentObserver.onSystemUiStateChanged();
}
}
@UiThread
private void onAssistantVisibilityChanged() {
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewComponentObserver.getActivityControlHelper().onAssistantVisibilityChanged(
- mLastAssistantVisibility);
+ mDeviceState.getAssistantVisibility());
}
}
@Override
public void onDestroy() {
sIsInitialized = false;
- if (mIsUserUnlocked) {
+ if (mDeviceState.isUserUnlocked()) {
mInputConsumer.unregisterInputConsumer();
mOverviewComponentObserver.onDestroy();
}
disposeEventHandlers();
- if (mMode.hasGestures) {
- DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
- }
+ SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
+ mDeviceState.destroy();
sConnected = false;
- Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
- SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
- mExclusionListener.unregister();
-
super.onDestroy();
}
@@ -551,14 +404,14 @@
mLogId = TOUCH_INTERACTION_LOG.generateAndSetLogId();
sSwipeSharedState.setLogTraceId(mLogId);
- if (mSwipeTouchRegion.contains(event.getX(), event.getY())) {
+ if (mDeviceState.isInSwipeUpTouchRegion(event)) {
boolean useSharedState = mConsumer.useSharedSwipeState();
mConsumer.onConsumerAboutToBeSwitched();
mConsumer = newConsumer(useSharedState, event);
TOUCH_INTERACTION_LOG.addLog("setInputConsumer", mConsumer.getType());
mUncheckedConsumer = mConsumer;
- } else if (mIsUserUnlocked && mMode == Mode.NO_BUTTON
- && canTriggerAssistantAction(event)) {
+ } else if (mDeviceState.isUserUnlocked() && mMode == Mode.NO_BUTTON
+ && mDeviceState.canTriggerAssistantAction(event)) {
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we should
// not interrupt it. QuickSwitch assumes that interruption can only happen if the
// next gesture is also quick switch.
@@ -576,27 +429,11 @@
DejankBinderTracker.disallowBinderTrackingInTests();
}
- private boolean validSystemUiFlags() {
- return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
- && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
- && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
- && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
- || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
- }
-
- private boolean canTriggerAssistantAction(MotionEvent ev) {
- return mAssistantAvailable
- && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
- && (mAssistantLeftRegion.contains(ev.getX(), ev.getY()) ||
- mAssistantRightRegion.contains(ev.getX(), ev.getY()))
- && !ActivityManagerWrapper.getInstance().isLockToAppActive();
- }
-
private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) {
- boolean isInValidSystemUiState = validSystemUiFlags();
+ boolean canStartSystemGesture = mDeviceState.canStartSystemGesture();
- if (!mIsUserUnlocked) {
- if (isInValidSystemUiState) {
+ if (!mDeviceState.isUserUnlocked()) {
+ if (canStartSystemGesture) {
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps
// launched while device is locked even after exiting direct boot mode (e.g. camera).
return createDeviceLockedInputConsumer(mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
@@ -607,29 +444,28 @@
// When using sharedState, bypass systemState check as this is a followup gesture and the
// first gesture started in a valid system state.
- InputConsumer base = isInValidSystemUiState || useSharedState
+ InputConsumer base = canStartSystemGesture || useSharedState
? newBaseConsumer(useSharedState, event) : mResetGestureInputConsumer;
if (mMode == Mode.NO_BUTTON) {
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
- if (canTriggerAssistantAction(event)) {
+ if (mDeviceState.canTriggerAssistantAction(event)) {
base = new AssistantInputConsumer(this, mISystemUiProxy, activityControl, base,
mInputMonitorCompat);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
+ 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);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) {
- base = new AccessibilityInputConsumer(this, mISystemUiProxy,
- (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0, base,
- mInputMonitorCompat, mSwipeTouchRegion);
+ if (mDeviceState.isAccessibilityMenuAvailable()) {
+ base = new AccessibilityInputConsumer(this, mDeviceState, mISystemUiProxy, base,
+ mInputMonitorCompat);
}
} else {
- if ((mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0) {
+ if (mDeviceState.isScreenPinningActive()) {
base = mResetGestureInputConsumer;
}
}
@@ -642,7 +478,7 @@
if (!useSharedState) {
sSwipeSharedState.clearAllState(false /* finishAnimation */);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0) {
+ if (mDeviceState.isKeyguardShowingOccluded()) {
// This handles apps showing over the lockscreen (e.g. camera)
return createDeviceLockedInputConsumer(runningTaskInfo);
}
@@ -678,8 +514,7 @@
return createOverviewInputConsumer(event);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
return createOverviewInputConsumer(event);
- } else if (mGestureBlockingActivity != null && runningTaskInfo != null
- && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
+ } else if (mDeviceState.isGestureBlockedActivity(runningTaskInfo)) {
return mResetGestureInputConsumer;
} else {
return createOtherActivityInputConsumer(event, runningTaskInfo);
@@ -692,13 +527,6 @@
&& (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
}
- private boolean disableHorizontalSwipe(MotionEvent event) {
- // mExclusionRegion can change on binder thread, use a local instance here.
- Region exclusionRegion = mExclusionRegion;
- return mMode == Mode.NO_BUTTON && exclusionRegion != null
- && exclusionRegion.contains((int) event.getX(), (int) event.getY());
- }
-
private InputConsumer createOtherActivityInputConsumer(MotionEvent event,
RunningTaskInfo runningTaskInfo) {
@@ -711,19 +539,20 @@
shouldDefer = !sSwipeSharedState.recentsAnimationFinishInterrupted;
factory = mFallbackNoButtonFactory;
} else {
- shouldDefer = activityControlHelper.deferStartingActivity(mActiveNavBarRegion, event);
+ shouldDefer = activityControlHelper.deferStartingActivity(mDeviceState, event);
factory = mWindowTreansformFactory;
}
- return new OtherActivityInputConsumer(this, runningTaskInfo, shouldDefer,
- this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
- disableHorizontalSwipe(event), activityControlHelper, factory, mLogId);
+ final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
+ return new OtherActivityInputConsumer(this, mDeviceState, runningTaskInfo, shouldDefer,
+ this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat,
+ disableHorizontalSwipe, activityControlHelper, factory, mLogId);
}
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
if (mMode == Mode.NO_BUTTON && taskInfo != null) {
- return new DeviceLockedInputConsumer(this, sSwipeSharedState, mInputMonitorCompat,
- mSwipeTouchRegion, taskInfo.taskId, mLogId);
+ return new DeviceLockedInputConsumer(this, mDeviceState, sSwipeSharedState,
+ mInputMonitorCompat, taskInfo.taskId, mLogId);
} else {
return mResetGestureInputConsumer;
}
@@ -741,8 +570,9 @@
return new OverviewInputConsumer(activity, mInputMonitorCompat,
false /* startingInActivityBounds */, activityControl);
} else {
+ final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
return new OverviewWithoutFocusInputConsumer(activity, mInputMonitorCompat,
- activityControl, disableHorizontalSwipe(event));
+ activityControl, disableHorizontalSwipe);
}
}
@@ -757,7 +587,7 @@
}
private void preloadOverview(boolean fromInit) {
- if (!mIsUserUnlocked) {
+ if (!mDeviceState.isUserUnlocked()) {
return;
}
if (!mMode.hasGestures && !mOverviewComponentObserver.isHomeAndOverviewSame()) {
@@ -793,7 +623,7 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
- if (!mIsUserUnlocked) {
+ if (!mDeviceState.isUserUnlocked()) {
return;
}
final ActivityControlHelper activityControl =
@@ -826,15 +656,9 @@
}
} else {
// Dump everything
+ mDeviceState.dump(pw);
pw.println("TouchState:");
pw.println(" navMode=" + mMode);
- pw.println(" validSystemUiFlags=" + validSystemUiFlags());
- pw.println(" systemUiFlags=" + mSystemUiStateFlags);
- pw.println(" systemUiFlagsDesc="
- + QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
- pw.println(" assistantAvailable=" + mAssistantAvailable);
- pw.println(" assistantDisabled="
- + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
boolean resumed = mOverviewComponentObserver != null
&& mOverviewComponentObserver.getActivityControlHelper().isResumed();
pw.println(" resumed=" + resumed);
@@ -870,7 +694,7 @@
private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask,
long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) {
- return new WindowTransformSwipeHandler(runningTask, this, touchTimeMs,
+ return new WindowTransformSwipeHandler(mDeviceState, runningTask, this, touchTimeMs,
mOverviewComponentObserver, continuingLastGesture, mInputConsumer, mRecentsModel);
}
@@ -882,7 +706,7 @@
protected boolean shouldNotifyBackGesture() {
return mBackGestureNotificationCounter > 0 &&
- mGestureBlockingActivity != null;
+ mDeviceState.getGestureBlockedActivityPackage() != null;
}
@WorkerThread
@@ -892,7 +716,7 @@
Utilities.getDevicePrefs(this).edit()
.putInt(KEY_BACK_NOTIFICATION_COUNT, mBackGestureNotificationCounter).apply();
sendBroadcast(new Intent(NOTIFY_ACTION_BACK).setPackage(
- mGestureBlockingActivity.getPackageName()));
+ mDeviceState.getGestureBlockedActivityPackage()));
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index fd1ed62..5cf987a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -35,7 +35,6 @@
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.NEW_TASK;
import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.RECENTS;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -198,6 +197,8 @@
*/
private static final int LOG_NO_OP_PAGE_INDEX = -1;
+ private RecentsAnimationDeviceState mDeviceState;
+
private GestureEndTarget mGestureEndTarget;
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
private RunningWindowAnim mRunningWindowAnim;
@@ -229,11 +230,12 @@
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
- public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context,
- long touchTimeMs, OverviewComponentObserver overviewComponentObserver,
- boolean continuingLastGesture,
+ public WindowTransformSwipeHandler(RecentsAnimationDeviceState deviceState,
+ RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs,
+ OverviewComponentObserver overviewComponentObserver, boolean continuingLastGesture,
InputConsumerController inputConsumer, RecentsModel recentsModel) {
super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id);
+ mDeviceState = deviceState;
mTouchTimeMs = touchTimeMs;
mContinuingLastGesture = continuingLastGesture;
initStateCallbacks();
@@ -755,9 +757,7 @@
}
}
- int stateFlags = OverviewInteractionState.INSTANCE.get(mActivity).getSystemUiStateFlags();
- if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0
- && (endTarget == RECENTS || endTarget == LAST_TASK)) {
+ if (mDeviceState.isOverviewDisabled() && (endTarget == RECENTS || endTarget == LAST_TASK)) {
return LAST_TASK;
}
return endTarget;
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 1f73a28..92bcfb5 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,7 +23,6 @@
import static android.view.MotionEvent.ACTION_UP;
import android.content.Context;
-import android.graphics.RectF;
import android.os.RemoteException;
import android.util.Log;
import android.view.Display;
@@ -32,12 +31,13 @@
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.systemui.shared.system.InputMonitorCompat;
/**
- * Touch consumer for two finger swipe actions for accessibility actions
+ * Input consumer for two finger swipe actions for accessibility actions
*/
public class AccessibilityInputConsumer extends DelegateInputConsumer {
@@ -46,8 +46,7 @@
private final ISystemUiProxy mSystemUiProxy;
private final VelocityTracker mVelocityTracker;
private final MotionPauseDetector mMotionPauseDetector;
- private final boolean mAllowLongClick;
- private final RectF mSwipeTouchRegion;
+ private final RecentsAnimationDeviceState mDeviceState;
private final float mMinGestureDistance;
private final float mMinFlingVelocity;
@@ -56,19 +55,17 @@
private float mDownY;
private float mTotalY;
- public AccessibilityInputConsumer(Context context, ISystemUiProxy systemUiProxy,
- boolean allowLongClick, InputConsumer delegate, InputMonitorCompat inputMonitor,
- RectF swipeTouchRegion) {
+ public AccessibilityInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
+ ISystemUiProxy systemUiProxy, InputConsumer delegate, InputMonitorCompat inputMonitor) {
super(delegate, inputMonitor);
mSystemUiProxy = systemUiProxy;
mVelocityTracker = VelocityTracker.obtain();
mMinGestureDistance = context.getResources()
.getDimension(R.dimen.accessibility_gesture_min_swipe_distance);
mMinFlingVelocity = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
- mSwipeTouchRegion = swipeTouchRegion;
+ mDeviceState = deviceState;
mMotionPauseDetector = new MotionPauseDetector(context);
- mAllowLongClick = allowLongClick;
}
@Override
@@ -103,7 +100,7 @@
case ACTION_POINTER_DOWN: {
if (mState == STATE_INACTIVE) {
int pointerIndex = ev.getActionIndex();
- if (mSwipeTouchRegion.contains(ev.getX(pointerIndex), ev.getY(pointerIndex))
+ if (mDeviceState.isInSwipeUpTouchRegion(ev, pointerIndex)
&& mDelegate.allowInterceptByParent()) {
setActive(ev);
@@ -116,7 +113,7 @@
break;
}
case ACTION_MOVE: {
- if (mState == STATE_ACTIVE && mAllowLongClick) {
+ if (mState == STATE_ACTIVE && mDeviceState.isAccessibilityMenuShortcutAvailable()) {
int pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) {
break;
@@ -130,7 +127,8 @@
case ACTION_UP:
if (mState == STATE_ACTIVE) {
try {
- if (mAllowLongClick && mMotionPauseDetector.isPaused()) {
+ if (mDeviceState.isAccessibilityMenuShortcutAvailable()
+ && mMotionPauseDetector.isPaused()) {
mSystemUiProxy.notifyAccessibilityButtonLongClicked();
} else {
mTotalY += (ev.getY() - mDownY);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 536470b..ba2d6d1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -32,7 +32,6 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
@@ -42,6 +41,7 @@
import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.LockScreenRecentsActivity;
import com.android.quickstep.MultiStateCallback;
+import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.util.RecentsAnimationCallbacks;
@@ -73,6 +73,7 @@
getFlagForIndex(1, "STATE_HANDLER_INVALIDATED");
private final Context mContext;
+ private final RecentsAnimationDeviceState mDeviceState;
private final float mTouchSlopSquared;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat;
@@ -83,7 +84,6 @@
private final AppWindowAnimationHelper.TransformParams mTransformParams;
private final Point mDisplaySize;
private final MultiStateCallback mStateCallback;
- private final RectF mSwipeTouchRegion;
public final int mRunningTaskId;
private VelocityTracker mVelocityTracker;
@@ -93,17 +93,17 @@
private RecentsAnimationTargets mTargetSet;
- public DeviceLockedInputConsumer(Context context, SwipeSharedState swipeSharedState,
- InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, int runningTaskId,
- int logId) {
+ public DeviceLockedInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
+ SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
+ int runningTaskId, int logId) {
mContext = context;
+ mDeviceState = deviceState;
mTouchSlopSquared = squaredTouchSlop(context);
mSwipeSharedState = swipeSharedState;
mAppWindowAnimationHelper = new AppWindowAnimationHelper(context);
mLogId = logId;
mTransformParams = new AppWindowAnimationHelper.TransformParams();
mInputMonitorCompat = inputMonitorCompat;
- mSwipeTouchRegion = swipeTouchRegion;
mRunningTaskId = runningTaskId;
// Do not use DeviceProfile as the user data might be locked
@@ -139,7 +139,7 @@
if (!mThresholdCrossed) {
// Cancel interaction in case of multi-touch interaction
int ptrIdx = ev.getActionIndex();
- if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
+ if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
int action = ev.getAction();
ev.setAction(ACTION_CANCEL);
finishTouchTracking(ev);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index e4d898b..6776e84 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -38,7 +38,6 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.PointF;
-import android.graphics.RectF;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -55,6 +54,7 @@
import com.android.quickstep.ActivityControlHelper;
import com.android.quickstep.BaseSwipeUpHandler;
import com.android.quickstep.BaseSwipeUpHandler.Factory;
+import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
@@ -79,12 +79,12 @@
// TODO: Move to quickstep contract
public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3;
+ private final RecentsAnimationDeviceState mDeviceState;
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
private final RunningTaskInfo mRunningTask;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat;
private final SysUINavigationMode.Mode mMode;
- private final RectF mSwipeTouchRegion;
private final ActivityControlHelper mActivityControlHelper;
private final BaseSwipeUpHandler.Factory mHandlerFactory;
@@ -124,19 +124,19 @@
};
private int mLogId;
- public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo,
- boolean isDeferredDownTarget, Consumer<OtherActivityInputConsumer> onCompleteCallback,
+ public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState,
+ RunningTaskInfo runningTaskInfo, boolean isDeferredDownTarget,
+ Consumer<OtherActivityInputConsumer> onCompleteCallback,
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
- RectF swipeTouchRegion, boolean disableHorizontalSwipe,
- ActivityControlHelper activityControlHelper,
+ boolean disableHorizontalSwipe, ActivityControlHelper activityControlHelper,
Factory handlerFactory, int logId) {
super(base);
mLogId = logId;
+ mDeviceState = deviceState;
mMainThreadHandler = new Handler(Looper.getMainLooper());
mRunningTask = runningTaskInfo;
mMode = SysUINavigationMode.getMode(base);
- mSwipeTouchRegion = swipeTouchRegion;
mHandlerFactory = handlerFactory;
mActivityControlHelper = activityControlHelper;
@@ -217,7 +217,7 @@
if (!mPassedPilferInputSlop) {
// Cancel interaction in case of multi-touch interaction
int ptrIdx = ev.getActionIndex();
- if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) {
+ if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
forceCancelGesture(ev);
}
}
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 5fb5fd7..132d6ab 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.Region;
import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
@@ -81,7 +80,7 @@
boolean shouldMinimizeSplitScreen();
- default boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
+ default boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
return true;
}
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 88a4eb6..331183a 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -57,6 +56,7 @@
}
};
private final Context mContext;
+ private final RecentsAnimationDeviceState mDeviceState;
private final Intent mCurrentHomeIntent;
private final Intent mMyHomeIntent;
private final Intent mFallbackIntent;
@@ -64,12 +64,13 @@
private String mUpdateRegisteredPackage;
private ActivityControlHelper mActivityControlHelper;
private Intent mOverviewIntent;
- private int mSystemUiStateFlags;
private boolean mIsHomeAndOverviewSame;
private boolean mIsDefaultHome;
+ private boolean mIsHomeDisabled;
- public OverviewComponentObserver(Context context) {
+ public OverviewComponentObserver(Context context, RecentsAnimationDeviceState deviceState) {
mContext = context;
+ mDeviceState = deviceState;
mCurrentHomeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)
@@ -98,11 +99,8 @@
updateOverviewTargets();
}
- public void onSystemUiStateChanged(int stateFlags) {
- boolean homeDisabledChanged = (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED)
- != (stateFlags & SYSUI_STATE_HOME_DISABLED);
- mSystemUiStateFlags = stateFlags;
- if (homeDisabledChanged) {
+ public void onSystemUiStateChanged() {
+ if (mDeviceState.isHomeDisabled() != mIsHomeDisabled) {
updateOverviewTargets();
}
}
@@ -115,6 +113,7 @@
ComponentName defaultHome = PackageManagerWrapper.getInstance()
.getHomeActivities(new ArrayList<>());
+ mIsHomeDisabled = mDeviceState.isHomeDisabled();
mIsDefaultHome = Objects.equals(mMyHomeIntent.getComponent(), defaultHome);
// Set assistant visibility to 0 from launcher's perspective, ensures any elements that
@@ -124,8 +123,7 @@
mActivityControlHelper.onAssistantVisibilityChanged(0.f);
}
- if ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
- && (defaultHome == null || mIsDefaultHome)) {
+ if (!mDeviceState.isHomeDisabled() && (defaultHome == null || mIsDefaultHome)) {
// User default home is same as out home app. Use Overview integrated in Launcher.
mActivityControlHelper = new LauncherActivityControllerHelper();
mIsHomeAndOverviewSame = true;
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 858c3b6..17462ab 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -86,6 +86,7 @@
mBgHandler.obtainMessage(MSG_SET_PROXY, proxy).sendToTarget();
}
+ // TODO(141886704): See if we can remove this
public void setSystemUiStateFlags(int stateFlags) {
mSystemUiStateFlags = stateFlags;
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
new file mode 100644
index 0000000..9b094f6
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static android.content.Intent.ACTION_USER_UNLOCKED;
+import static com.android.launcher3.ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE;
+import static com.android.launcher3.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.os.Process;
+import android.text.TextUtils;
+import android.view.MotionEvent;
+import android.view.Surface;
+import androidx.annotation.BinderThread;
+import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.DefaultDisplay;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Manages the state of the system during a swipe up gesture.
+ */
+public class RecentsAnimationDeviceState implements
+ SysUINavigationMode.NavigationModeChangeListener,
+ DefaultDisplay.DisplayInfoChangeListener {
+
+ private Context mContext;
+ private UserManagerCompat mUserManager;
+ private SysUINavigationMode mSysUiNavMode;
+ private DefaultDisplay mDefaultDisplay;
+ private int mDisplayId;
+
+ private @SystemUiStateFlags int mSystemUiStateFlags;
+ private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
+
+ private final RectF mSwipeUpTouchRegion = new RectF();
+ private final Region mDeferredGestureRegion = new Region();
+ private final RectF mAssistantLeftRegion = new RectF();
+ private final RectF mAssistantRightRegion = new RectF();
+ private boolean mAssistantAvailable;
+ private float mAssistantVisibility;
+
+ private boolean mIsUserUnlocked;
+ private final ArrayList<Runnable> mUserUnlockedActions = new ArrayList<>();
+ private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+ mIsUserUnlocked = true;
+ notifyUserUnlocked();
+ }
+ }
+ };
+
+ private Region mExclusionRegion;
+ private SystemGestureExclusionListenerCompat mExclusionListener;
+
+ private ComponentName mGestureBlockedActivity;
+
+ public RecentsAnimationDeviceState(Context context) {
+ mContext = context;
+ mUserManager = UserManagerCompat.getInstance(context);
+ mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
+ mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
+ mDisplayId = mDefaultDisplay.getInfo().id;
+
+ // Register for user unlocked if necessary
+ mIsUserUnlocked = mUserManager.isUserUnlocked(Process.myUserHandle());
+ if (!mIsUserUnlocked) {
+ mContext.registerReceiver(mUserUnlockedReceiver,
+ new IntentFilter(ACTION_USER_UNLOCKED));
+ }
+
+ // Register for exclusion updates
+ mExclusionListener = new SystemGestureExclusionListenerCompat(mDisplayId) {
+ @Override
+ @BinderThread
+ public void onExclusionChanged(Region region) {
+ // Assignments are atomic, it should be safe on binder thread
+ mExclusionRegion = region;
+ }
+ };
+ onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
+
+ // Add any blocked activities
+ String blockingActivity = context.getString(R.string.gesture_blocking_activity);
+ if (!TextUtils.isEmpty(blockingActivity)) {
+ mGestureBlockedActivity = ComponentName.unflattenFromString(blockingActivity);
+ }
+ }
+
+ /**
+ * Cleans up all the registered listeners and receivers.
+ */
+ public void destroy() {
+ Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver);
+ mSysUiNavMode.removeModeChangeListener(this);
+ mDefaultDisplay.removeChangeListener(this);
+ mExclusionListener.unregister();
+ }
+
+ @Override
+ public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
+ mDefaultDisplay.removeChangeListener(this);
+ if (newMode.hasGestures) {
+ mDefaultDisplay.addChangeListener(this);
+ }
+
+ if (mMode == NO_BUTTON) {
+ mExclusionListener.register();
+ } else {
+ mExclusionListener.unregister();
+ }
+ mMode = newMode;
+ }
+
+ @Override
+ public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
+ if (info.id != getDisplayId()) {
+ return;
+ }
+
+ updateGestureTouchRegions();
+ }
+
+ /**
+ * @return the display id for the display that Launcher is running on.
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ /**
+ * Adds a callback for when a user is unlocked. If the user is already unlocked, this listener
+ * will be called back immediately.
+ */
+ public void runOnUserUnlocked(Runnable action) {
+ if (mIsUserUnlocked) {
+ action.run();
+ } else {
+ mUserUnlockedActions.add(action);
+ }
+ }
+
+ /**
+ * @return whether the user is unlocked.
+ */
+ public boolean isUserUnlocked() {
+ return mIsUserUnlocked;
+ }
+
+ private void notifyUserUnlocked() {
+ for (Runnable action : mUserUnlockedActions) {
+ action.run();
+ }
+ mUserUnlockedActions.clear();
+ Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver);
+ }
+
+ /**
+ * @return whether the given running task info matches the gesture-blocked activity.
+ */
+ public boolean isGestureBlockedActivity(ActivityManager.RunningTaskInfo runningTaskInfo) {
+ return runningTaskInfo != null
+ && mGestureBlockedActivity.equals(runningTaskInfo.topActivity);
+ }
+
+ /**
+ * @return the package of the gesture-blocked activity or {@code null} if there is none.
+ */
+ public String getGestureBlockedActivityPackage() {
+ return (mGestureBlockedActivity != null)
+ ? mGestureBlockedActivity.getPackageName()
+ : null;
+ }
+
+ /**
+ * Updates the system ui state flags from SystemUI.
+ */
+ public void setSystemUiFlags(int stateFlags) {
+ mSystemUiStateFlags = stateFlags;
+ }
+
+ /**
+ * @return the system ui state flags.
+ */
+ // TODO(141886704): See if we can remove this
+ public @SystemUiStateFlags int getSystemUiStateFlags() {
+ return mSystemUiStateFlags;
+ }
+
+ /**
+ * @return whether SystemUI is in a state where we can start a system gesture.
+ */
+ public boolean canStartSystemGesture() {
+ return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
+ && ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
+ || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
+ }
+
+ /**
+ * @return whether the keyguard is showing and is occluded by an app showing above the keyguard
+ * (like camera or maps)
+ */
+ public boolean isKeyguardShowingOccluded() {
+ return (mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
+ }
+
+ /**
+ * @return whether screen pinning is enabled and active
+ */
+ public boolean isScreenPinningActive() {
+ return (mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
+ }
+
+ /**
+ * @return whether lock-task mode is active
+ */
+ public boolean isLockToAppActive() {
+ return ActivityManagerWrapper.getInstance().isLockToAppActive();
+ }
+
+ /**
+ * @return whether the accessibility menu is available.
+ */
+ public boolean isAccessibilityMenuAvailable() {
+ return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+ }
+
+ /**
+ * @return whether the accessibility menu shortcut is available.
+ */
+ public boolean isAccessibilityMenuShortcutAvailable() {
+ return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+ }
+
+ /**
+ * @return whether home is disabled (either by SUW/SysUI/device policy)
+ */
+ public boolean isHomeDisabled() {
+ return (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
+ }
+
+ /**
+ * @return whether overview is disabled (either by SUW/SysUI/device policy)
+ */
+ public boolean isOverviewDisabled() {
+ return (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+ }
+
+ /**
+ * Updates the regions for detecting the swipe up/quickswitch and assistant gestures.
+ */
+ public void updateGestureTouchRegions() {
+ if (!mMode.hasGestures) {
+ return;
+ }
+
+ Resources res = mContext.getResources();
+ DefaultDisplay.Info displayInfo = mDefaultDisplay.getInfo();
+ Point realSize = new Point(displayInfo.realSize);
+ mSwipeUpTouchRegion.set(0, 0, realSize.x, realSize.y);
+ if (mMode == NO_BUTTON) {
+ int touchHeight = ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE, res);
+ mSwipeUpTouchRegion.top = mSwipeUpTouchRegion.bottom - touchHeight;
+
+ final int assistantWidth = res.getDimensionPixelSize(R.dimen.gestures_assistant_width);
+ final float assistantHeight = Math.max(touchHeight,
+ QuickStepContract.getWindowCornerRadius(res));
+ mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = mSwipeUpTouchRegion.bottom;
+ mAssistantLeftRegion.top = mAssistantRightRegion.top =
+ mSwipeUpTouchRegion.bottom - assistantHeight;
+
+ mAssistantLeftRegion.left = 0;
+ mAssistantLeftRegion.right = assistantWidth;
+
+ mAssistantRightRegion.right = mSwipeUpTouchRegion.right;
+ mAssistantRightRegion.left = mSwipeUpTouchRegion.right - assistantWidth;
+ } else {
+ mAssistantLeftRegion.setEmpty();
+ mAssistantRightRegion.setEmpty();
+ switch (displayInfo.rotation) {
+ case Surface.ROTATION_90:
+ mSwipeUpTouchRegion.left = mSwipeUpTouchRegion.right
+ - ResourceUtils.getNavbarSize(NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE, res);
+ break;
+ case Surface.ROTATION_270:
+ mSwipeUpTouchRegion.right = mSwipeUpTouchRegion.left
+ + ResourceUtils.getNavbarSize(NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE, res);
+ break;
+ default:
+ mSwipeUpTouchRegion.top = mSwipeUpTouchRegion.bottom
+ - ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE, res);
+ }
+ }
+ }
+
+ /**
+ * @return whether the coordinates of the {@param event} is in the swipe up gesture region.
+ */
+ public boolean isInSwipeUpTouchRegion(MotionEvent event) {
+ return mSwipeUpTouchRegion.contains(event.getX(), event.getY());
+ }
+
+ /**
+ * @return whether the coordinates of the {@param event} with the given {@param pointerIndex}
+ * is in the swipe up gesture region.
+ */
+ public boolean isInSwipeUpTouchRegion(MotionEvent event, int pointerIndex) {
+ return mSwipeUpTouchRegion.contains(event.getX(pointerIndex), event.getY(pointerIndex));
+ }
+
+ /**
+ * Sets the region in screen space where the gestures should be deferred (ie. due to specific
+ * nav bar ui).
+ */
+ public void setDeferredGestureRegion(Region deferredGestureRegion) {
+ mDeferredGestureRegion.set(deferredGestureRegion);
+ }
+
+ /**
+ * @return whether the given {@param event} is in the deferred gesture region indicating that
+ * the Launcher should not immediately start the recents animation until the gesture
+ * passes a certain threshold.
+ */
+ public boolean isInDeferredGestureRegion(MotionEvent event) {
+ return mDeferredGestureRegion.contains((int) event.getX(), (int) event.getY());
+ }
+
+ /**
+ * @return whether the given {@param event} is in the app-requested gesture-exclusion region.
+ * This is only used for quickswitch, and not swipe up.
+ */
+ public boolean isInExclusionRegion(MotionEvent event) {
+ // mExclusionRegion can change on binder thread, use a local instance here.
+ Region exclusionRegion = mExclusionRegion;
+ return mMode == NO_BUTTON && exclusionRegion != null
+ && exclusionRegion.contains((int) event.getX(), (int) event.getY());
+ }
+
+ /**
+ * Sets whether the assistant is available.
+ */
+ public void setAssistantAvailable(boolean assistantAvailable) {
+ mAssistantAvailable = assistantAvailable;
+ }
+
+ /**
+ * Sets the visibility fraction of the assistant.
+ */
+ public void setAssistantVisibility(float visibility) {
+ mAssistantVisibility = visibility;
+ }
+
+ /**
+ * @return the visibility fraction of the assistant.
+ */
+ public float getAssistantVisibility() {
+ return mAssistantVisibility;
+ }
+
+ /**
+ * @param ev An ACTION_DOWN motion event
+ * @return whether the given motion event can trigger the assistant.
+ */
+ public boolean canTriggerAssistantAction(MotionEvent ev) {
+ return mAssistantAvailable
+ && !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
+ && (mAssistantLeftRegion.contains(ev.getX(), ev.getY())
+ || mAssistantRightRegion.contains(ev.getX(), ev.getY()))
+ && !isLockToAppActive();
+ }
+
+ public void dump(PrintWriter pw) {
+ pw.println("DeviceState:");
+ pw.println(" canStartSystemGesture=" + canStartSystemGesture());
+ pw.println(" systemUiFlags=" + mSystemUiStateFlags);
+ pw.println(" systemUiFlagsDesc="
+ + QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
+ pw.println(" assistantAvailable=" + mAssistantAvailable);
+ pw.println(" assistantDisabled="
+ + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
+ }
+}