diff options
Diffstat (limited to 'quickstep/src/com/android/quickstep/TouchInteractionService.java')
-rw-r--r-- | quickstep/src/com/android/quickstep/TouchInteractionService.java | 190 |
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( |