summaryrefslogtreecommitdiff
path: root/quickstep/src/com/android/quickstep/TouchInteractionService.java
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep/src/com/android/quickstep/TouchInteractionService.java')
-rw-r--r--quickstep/src/com/android/quickstep/TouchInteractionService.java190
1 files changed, 130 insertions, 60 deletions
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 80682949cf..eb4591df5a 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -24,10 +24,12 @@ import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE;
+import static com.android.launcher3.LauncherPrefs.backedUpItem;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
import static com.android.quickstep.GestureState.TrackpadGestureType.getTrackpadGestureType;
@@ -60,7 +62,6 @@ import android.app.Service;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Region;
import android.graphics.drawable.Icon;
@@ -84,7 +85,9 @@ import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.ConstantItem;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.EncryptionType;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
@@ -99,9 +102,10 @@ import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.uioverrides.flags.FlagsFactory;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.Executors;
import com.android.launcher3.util.LockedUserState;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.SafeCloseable;
+import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
@@ -157,7 +161,8 @@ public class TouchInteractionService extends Service {
private static final String TAG = "TouchInteractionService";
- private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
+ private static final ConstantItem<Boolean> HAS_ENABLED_QUICKSTEP_ONCE = backedUpItem(
+ "launcher.has_enabled_quickstep_once", false, EncryptionType.ENCRYPTED);
private final TISBinder mTISBinder = new TISBinder(this);
@@ -412,18 +417,16 @@ public class TouchInteractionService extends Service {
* Sets a proxy to bypass swipe up behavior
*/
public void setSwipeUpProxy(Function<GestureState, AnimatedFloat> proxy) {
- TouchInteractionService tis = mTis.get();
- if (tis == null) return;
- tis.mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null);
+ executeForTouchInteractionService(
+ tis -> tis.mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null));
}
/**
* Sets the task id where gestures should be blocked
*/
public void setGestureBlockedTaskId(int taskId) {
- TouchInteractionService tis = mTis.get();
- if (tis == null) return;
- tis.mDeviceState.setGestureBlockingTaskId(taskId);
+ executeForTouchInteractionService(
+ tis -> tis.mDeviceState.setGestureBlockingTaskId(taskId));
}
/** Sets a listener to be run on Overview Target updates. */
@@ -437,6 +440,12 @@ public class TouchInteractionService extends Service {
mOnOverviewTargetChangeListener = null;
}
}
+
+ /** Refreshes the current overview target. */
+ public void refreshOverviewTarget() {
+ executeForTouchInteractionService(tis -> tis.onOverviewTargetChange(
+ tis.mOverviewComponentObserver.isHomeAndOverviewSame()));
+ }
}
private static boolean sConnected = false;
@@ -456,6 +465,8 @@ public class TouchInteractionService extends Service {
private final AbsSwipeUpHandler.Factory mFallbackSwipeHandlerFactory =
this::createFallbackSwipeHandler;
+ private final ScreenOnTracker.ScreenOnListener mScreenOnListener = this::onScreenOnChanged;
+
private ActivityManagerWrapper mAM;
private OverviewCommandHelper mOverviewCommandHelper;
private OverviewComponentObserver mOverviewComponentObserver;
@@ -492,6 +503,8 @@ public class TouchInteractionService extends Service {
LockedUserState.get(this).runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
sConnected = true;
+
+ ScreenOnTracker.INSTANCE.get(this).addListener(mScreenOnListener);
}
private void disposeEventHandlers(String reason) {
@@ -564,23 +577,25 @@ public class TouchInteractionService extends Service {
}
// Reset home bounce seen on quick step enabled for first time
- SharedPreferences sharedPrefs = LauncherPrefs.getPrefs(this);
- if (!sharedPrefs.getBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)) {
- sharedPrefs.edit()
- .putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)
- .putBoolean(OnboardingPrefs.HOME_BOUNCE_SEEN, false)
- .apply();
+ LauncherPrefs prefs = LauncherPrefs.get(this);
+ if (!prefs.get(HAS_ENABLED_QUICKSTEP_ONCE)) {
+ prefs.put(
+ HAS_ENABLED_QUICKSTEP_ONCE.to(true),
+ HOME_BOUNCE_SEEN.to(false));
}
}
private void onOverviewTargetChange(boolean isHomeAndOverviewSame) {
- AccessibilityManager am = getSystemService(AccessibilityManager.class);
+ Executors.UI_HELPER_EXECUTOR.execute(() -> {
+ AccessibilityManager am = getSystemService(AccessibilityManager.class);
- if (isHomeAndOverviewSame) {
- am.registerSystemAction(createAllAppsAction(), GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
- } else {
- am.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
- }
+ if (isHomeAndOverviewSame) {
+ am.registerSystemAction(
+ createAllAppsAction(), GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
+ } else {
+ am.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
+ }
+ });
StatefulActivity newOverviewActivity = mOverviewComponentObserver.getActivityInterface()
.getCreatedActivity();
@@ -664,6 +679,8 @@ public class TouchInteractionService extends Service {
mTaskbarManager.destroy();
sConnected = false;
+
+ ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
super.onDestroy();
}
@@ -673,9 +690,22 @@ public class TouchInteractionService extends Service {
return mTISBinder;
}
+ protected void onScreenOnChanged(boolean isOn) {
+ if (isOn) {
+ return;
+ }
+ long currentTime = SystemClock.uptimeMillis();
+ MotionEvent cancelEvent = MotionEvent.obtain(
+ currentTime, currentTime, ACTION_CANCEL, 0f, 0f, 0);
+ onInputEvent(cancelEvent);
+ cancelEvent.recycle();
+ }
+
private void onInputEvent(InputEvent ev) {
if (!(ev instanceof MotionEvent)) {
- Log.e(TAG, "Unknown event " + ev);
+ ActiveGestureLog.INSTANCE.addLog(new CompoundString("TIS.onInputEvent: ")
+ .append("Cannot process input event, received unknown event ")
+ .append(ev.toString()));
return;
}
MotionEvent event = (MotionEvent) ev;
@@ -683,8 +713,14 @@ public class TouchInteractionService extends Service {
TestLogging.recordMotionEvent(
TestProtocol.SEQUENCE_TIS, "TouchInteractionService.onInputEvent", event);
- if (!LockedUserState.get(this).isUserUnlocked() || (mDeviceState.isButtonNavMode()
+ boolean isUserUnlocked = LockedUserState.get(this).isUserUnlocked();
+ if (!isUserUnlocked || (mDeviceState.isButtonNavMode()
&& !isTrackpadMotionEvent(event))) {
+ ActiveGestureLog.INSTANCE.addLog(new CompoundString("TIS.onInputEvent: ")
+ .append("Cannot process input event, ")
+ .append(!isUserUnlocked
+ ? "user is locked"
+ : "using 3-button nav and event is not a trackpad event"));
return;
}
@@ -695,12 +731,19 @@ public class TouchInteractionService extends Service {
// an ACTION_HOVER_ENTER will fire as well.
boolean isHoverActionWithoutConsumer =
event.isHoverEvent() && (mUncheckedConsumer.getType() & TYPE_CURSOR_HOVER) == 0;
+ CompoundString reasonString = action == ACTION_DOWN
+ ? new CompoundString("onMotionEvent: ") : CompoundString.NO_OP;
if (action == ACTION_DOWN || isHoverActionWithoutConsumer) {
mRotationTouchHelper.setOrientationTransformIfNeeded(event);
- if ((!mDeviceState.isOneHandedModeActive()
- && mRotationTouchHelper.isInSwipeUpTouchRegion(event))
+ boolean isOneHandedModeActive = mDeviceState.isOneHandedModeActive();
+ boolean isInSwipeUpTouchRegion = mRotationTouchHelper.isInSwipeUpTouchRegion(event);
+ if ((!isOneHandedModeActive && isInSwipeUpTouchRegion)
|| isHoverActionWithoutConsumer) {
+ reasonString.append(!isOneHandedModeActive && isInSwipeUpTouchRegion
+ ? "one handed mode is not active and event is in swipe up region"
+ : "isHoverActionWithoutConsumer == true")
+ .append(", creating new input consumer");
// Clone the previous gesture state since onConsumerAboutToBeSwitched might trigger
// onConsumerInactive and wipe the previous gesture state
GestureState prevGestureState = new GestureState(mGestureState);
@@ -711,9 +754,13 @@ public class TouchInteractionService extends Service {
mGestureState = newGestureState;
mConsumer = newConsumer(prevGestureState, mGestureState, event);
mUncheckedConsumer = mConsumer;
- } else if (LockedUserState.get(this).isUserUnlocked()
- && (mDeviceState.isFullyGesturalNavMode() || isTrackpadMultiFingerSwipe(event))
+ } else if ((mDeviceState.isFullyGesturalNavMode() || isTrackpadMultiFingerSwipe(event))
&& mDeviceState.canTriggerAssistantAction(event)) {
+ reasonString.append(mDeviceState.isFullyGesturalNavMode()
+ ? "using fully gestural nav"
+ : "event is a trackpad multi-finger swipe")
+ .append(" and event can trigger assistant action")
+ .append(", consuming gesture for assistant action");
mGestureState = createGestureState(mGestureState,
getTrackpadGestureType(event));
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
@@ -721,6 +768,8 @@ public class TouchInteractionService extends Service {
// happen if the next gesture is also quick switch.
mUncheckedConsumer = tryCreateAssistantInputConsumer(mGestureState, event);
} else if (mDeviceState.canTriggerOneHandedAction(event)) {
+ reasonString.append("event can trigger one-handed action")
+ .append(", consuming gesture for one-handed action");
// Consume gesture event for triggering one handed feature.
mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
InputConsumer.NO_OP, mInputMonitorCompat);
@@ -736,29 +785,43 @@ public class TouchInteractionService extends Service {
}
if (mUncheckedConsumer != InputConsumer.NO_OP) {
- switch (event.getActionMasked()) {
+ switch (action) {
case ACTION_DOWN:
+ ActiveGestureLog.INSTANCE.addLog(reasonString);
// fall through
case ACTION_UP:
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "onMotionEvent(" + (int) event.getRawX() + ", "
- + (int) event.getRawY() + "): "
- + MotionEvent.actionToString(event.getActionMasked()) + ", "
- + MotionEvent.classificationToString(event.getClassification()),
- /* gestureEvent= */ event.getActionMasked() == ACTION_DOWN
+ new CompoundString("onMotionEvent(")
+ .append((int) event.getRawX())
+ .append(", ")
+ .append((int) event.getRawY())
+ .append("): ")
+ .append(MotionEvent.actionToString(action))
+ .append(", ")
+ .append(MotionEvent.classificationToString(
+ event.getClassification())),
+ /* gestureEvent= */ action == ACTION_DOWN
? MOTION_DOWN
: MOTION_UP);
break;
case ACTION_MOVE:
- ActiveGestureLog.INSTANCE.addLog("onMotionEvent: "
- + MotionEvent.actionToString(event.getActionMasked()) + ","
- + MotionEvent.classificationToString(event.getClassification())
- + ", pointerCount: " + event.getPointerCount(), MOTION_MOVE);
+ ActiveGestureLog.INSTANCE.addLog(
+ new CompoundString("onMotionEvent: ")
+ .append(MotionEvent.actionToString(action))
+ .append(",")
+ .append(MotionEvent.classificationToString(
+ event.getClassification()))
+ .append(", pointerCount: ")
+ .append(event.getPointerCount()),
+ MOTION_MOVE);
break;
default: {
- ActiveGestureLog.INSTANCE.addLog("onMotionEvent: "
- + MotionEvent.actionToString(event.getActionMasked()) + ","
- + MotionEvent.classificationToString(event.getClassification()));
+ ActiveGestureLog.INSTANCE.addLog(
+ new CompoundString("onMotionEvent: ")
+ .append(MotionEvent.actionToString(action))
+ .append(",")
+ .append(MotionEvent.classificationToString(
+ event.getClassification())));
}
}
}
@@ -821,7 +884,11 @@ public class TouchInteractionService extends Service {
if (mTaskAnimationManager.isRecentsAnimationRunning()) {
gestureState = new GestureState(mOverviewComponentObserver,
ActiveGestureLog.INSTANCE.getLogId());
- taskInfo = previousGestureState.getRunningTask();
+ TopTaskTracker.CachedTaskInfo previousTaskInfo = previousGestureState.getRunningTask();
+ // previousTaskInfo can be null iff previousGestureState == GestureState.DEFAULT_STATE
+ taskInfo = previousTaskInfo != null
+ ? previousTaskInfo
+ : TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false);
gestureState.updateRunningTask(taskInfo);
gestureState.updateLastStartedTaskIds(previousGestureState.getLastStartedTaskIds());
gestureState.updatePreviouslyAppearedTaskIds(
@@ -836,7 +903,7 @@ public class TouchInteractionService extends Service {
// Log initial state for the gesture.
ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current running task package name=")
- .append(taskInfo == null ? "no running task" : taskInfo.getPackageName()));
+ .append(taskInfo.getPackageName()));
ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current SystemUi state flags=")
.append(mDeviceState.getSystemUiStateString()));
return gestureState;
@@ -896,8 +963,8 @@ public class TouchInteractionService extends Service {
handleOrientationSetup(base);
}
if (mDeviceState.isFullyGesturalNavMode() || newGestureState.isTrackpadGesture()) {
- String reasonPrefix = "device is in gesture navigation mode or 3-button mode with a"
- + " trackpad gesture";
+ String reasonPrefix =
+ "device is in gesture navigation mode or 3-button mode with a trackpad gesture";
if (mDeviceState.canTriggerAssistantAction(event)) {
reasonString.append(NEWLINE_PREFIX)
.append(reasonPrefix)
@@ -918,19 +985,19 @@ public class TouchInteractionService extends Service {
reasonString.append(NEWLINE_PREFIX)
.append(reasonPrefix)
.append(SUBSTRING_PREFIX)
- .append("TaskbarActivityContext != null, "
- + "using TaskbarUnstashInputConsumer");
+ .append("TaskbarActivityContext != null, ")
+ .append("using TaskbarUnstashInputConsumer");
base = new TaskbarUnstashInputConsumer(this, base, mInputMonitorCompat, tac,
mOverviewCommandHelper);
}
- } else if (canStartSystemGesture && FeatureFlags.ENABLE_LONG_PRESS_NAV_HANDLE.get()
- && !previousGestureState.isRecentsAnimationRunning()) {
+ } else if (canStartSystemGesture && !previousGestureState.isRecentsAnimationRunning()) {
reasonString.append(NEWLINE_PREFIX)
.append(reasonPrefix)
.append(SUBSTRING_PREFIX)
- .append("Long press nav handle enabled, "
- + "using NavHandleLongPressInputConsumer");
- base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat);
+ .append("Not running recents animation, ")
+ .append("using NavHandleLongPressInputConsumer");
+ base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat,
+ mDeviceState);
}
if (mDeviceState.isBubblesExpanded()) {
@@ -1044,21 +1111,22 @@ public class TouchInteractionService extends Service {
reasonString.append(SUBSTRING_PREFIX).append("keyguard is not showing occluded");
+ TopTaskTracker.CachedTaskInfo runningTask = gestureState.getRunningTask();
// Use overview input consumer for sharesheets on top of home.
boolean forceOverviewInputConsumer = gestureState.getActivityInterface().isStarted()
- && gestureState.getRunningTask() != null
- && gestureState.getRunningTask().isRootChooseActivity();
+ && runningTask != null
+ && runningTask.isRootChooseActivity();
// In the case where we are in an excluded, translucent overlay, ignore it and treat the
// running activity as the task behind the overlay.
- TopTaskTracker.CachedTaskInfo otherVisibleTask = gestureState.getRunningTask() == null
+ TopTaskTracker.CachedTaskInfo otherVisibleTask = runningTask == null
? null
- : gestureState.getRunningTask().otherVisibleTaskThisIsExcludedOver();
+ : runningTask.otherVisibleTaskThisIsExcludedOver();
if (otherVisibleTask != null) {
ActiveGestureLog.INSTANCE.addLog(new CompoundString("Changing active task to ")
.append(otherVisibleTask.getPackageName())
.append(" because the previous task running on top of this one (")
- .append(gestureState.getRunningTask().getPackageName())
+ .append(runningTask.getPackageName())
.append(") was excluded from recents"));
gestureState.updateRunningTask(otherVisibleTask);
}
@@ -1078,7 +1146,7 @@ public class TouchInteractionService extends Service {
forceOverviewInputConsumer,
reasonString.append(SUBSTRING_PREFIX)
.append("is in live tile mode, trying to use overview input consumer"));
- } else if (gestureState.getRunningTask() == null) {
+ } else if (runningTask == null) {
return getDefaultInputConsumer(reasonString.append(SUBSTRING_PREFIX)
.append("running task == null"));
} else if (previousGestureAnimatedToLauncher
@@ -1096,7 +1164,7 @@ public class TouchInteractionService extends Service {
? "launcher resumed through a shell transition"
: "forceOverviewInputConsumer == true"))
.append(", trying to use overview input consumer"));
- } else if (mDeviceState.isGestureBlockedTask(gestureState.getRunningTask())) {
+ } else if (mDeviceState.isGestureBlockedTask(runningTask)) {
return getDefaultInputConsumer(reasonString.append(SUBSTRING_PREFIX)
.append("is gesture-blocked task, trying to use default input consumer"));
} else {
@@ -1128,8 +1196,8 @@ public class TouchInteractionService extends Service {
if ((mDeviceState.isFullyGesturalNavMode() || gestureState.isTrackpadGesture())
&& gestureState.getRunningTask() != null) {
reasonString.append(SUBSTRING_PREFIX)
- .append("device is in gesture nav mode or 3-button mode with a trackpad gesture"
- + "and running task != null")
+ .append("device is in gesture nav mode or 3-button mode with a trackpad")
+ .append(" gesture and running task != null")
.append(", using DeviceLockedInputConsumer");
return new DeviceLockedInputConsumer(
this, mDeviceState, mTaskAnimationManager, gestureState, mInputMonitorCompat);
@@ -1265,6 +1333,7 @@ public class TouchInteractionService extends Service {
Log.i(TAG, "preloadOverview: forSUWAllSet=" + forSUWAllSet
+ ", isHomeAndOverviewSame=" + mOverviewComponentObserver.isHomeAndOverviewSame());
+ ActiveGestureLog.INSTANCE.addLog("preloadRecentsAnimation");
mTaskAnimationManager.preloadRecentsAnimation(overviewIntent);
}
@@ -1339,6 +1408,7 @@ public class TouchInteractionService extends Service {
mTaskbarManager.dumpLogs("", pw);
pw.println("AssistStateManager:");
AssistStateManager.INSTANCE.get(this).dump(" ", pw);
+ SystemUiProxy.INSTANCE.get(this).dump(pw);
}
private AbsSwipeUpHandler createLauncherSwipeHandler(