From f9042d32aedf9dd214d00a5633e844e9d011cd4a Mon Sep 17 00:00:00 2001 From: Sam Dubey Date: Mon, 18 Apr 2022 16:47:24 +0000 Subject: [PATCH] Revert "Removing AM.getTasks call on UI thread during touch down" This reverts commit 013a8a75abb9e940163dfafceb0c1fefc218652f. Reason for revert: Broke builds Bug: 229619753 Change-Id: Idb1aecf1d43db50aa4f11dbb88079c37e401d694 --- .../NavBarToHomeTouchController.java | 5 +- .../android/quickstep/AbsSwipeUpHandler.java | 29 +- .../quickstep/FallbackSwipeHandler.java | 25 +- .../com/android/quickstep/GestureState.java | 30 ++- .../RecentsAnimationDeviceState.java | 39 ++- .../android/quickstep/RemoteTargetGluer.java | 12 +- .../quickstep/SwipeUpAnimationLogic.java | 4 +- .../quickstep/TaskAnimationManager.java | 6 +- .../com/android/quickstep/TopTaskTracker.java | 248 ------------------ .../quickstep/TouchInteractionService.java | 39 ++- .../fallback/FallbackRecentsView.java | 42 +-- .../quickstep/interaction/AllSetActivity.java | 4 +- .../interaction/GestureSandboxActivity.java | 41 +-- .../quickstep/util/AssistantUtilities.java | 46 ++++ .../util/LauncherSplitScreenListener.java | 119 +++++++++ .../android/quickstep/views/RecentsView.java | 45 ++-- 16 files changed, 335 insertions(+), 399 deletions(-) delete mode 100644 quickstep/src/com/android/quickstep/TopTaskTracker.java create mode 100644 quickstep/src/com/android/quickstep/util/AssistantUtilities.java create mode 100644 quickstep/src/com/android/quickstep/util/LauncherSplitScreenListener.java diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 7bfb76a978..4d3b05721c 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -48,8 +48,8 @@ import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.SingleAxisSwipeDetector; import com.android.launcher3.util.TouchController; import com.android.quickstep.TaskUtils; -import com.android.quickstep.TopTaskTracker; import com.android.quickstep.util.AnimatorControllerWithResistance; +import com.android.quickstep.util.AssistantUtilities; import com.android.quickstep.util.OverviewToHomeAnim; import com.android.quickstep.views.RecentsView; @@ -112,8 +112,7 @@ public class NavBarToHomeTouchController implements TouchController, return true; } if (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get() - && TopTaskTracker.INSTANCE.get(mLauncher).getCachedTopTask(false) - .isExcludedAssistant()) { + && AssistantUtilities.isExcludedAssistantRunning()) { return true; } return false; diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 2ae0646ed0..6e804021f1 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -102,6 +102,7 @@ import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.InputConsumerProxy; import com.android.quickstep.util.InputProxyHandlerFactory; +import com.android.quickstep.util.LauncherSplitScreenListener; import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.ProtoTracer; import com.android.quickstep.util.RecentsOrientedState; @@ -113,7 +114,6 @@ import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.VibratorWrapper; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; -import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; @@ -564,12 +564,24 @@ public abstract class AbsSwipeUpHandler, } protected void notifyGestureAnimationStartToRecents() { - Task[] runningTasks; + ActivityManager.RunningTaskInfo[] runningTasks; if (mIsSwipeForStagedSplit) { - int[] splitTaskIds = TopTaskTracker.INSTANCE.get(mContext).getRunningSplitTaskIds(); - runningTasks = mGestureState.getRunningTask().getPlaceholderTasks(splitTaskIds); + int[] splitTaskIds = + LauncherSplitScreenListener.INSTANCE.getNoCreate().getRunningSplitTaskIds(); + runningTasks = new ActivityManager.RunningTaskInfo[splitTaskIds.length]; + for (int i = 0; i < splitTaskIds.length; i++) { + int taskId = splitTaskIds[i]; + // Order matters here, we want first indexed RunningTaskInfo to be leftTop task + for (ActivityManager.RunningTaskInfo rti : mGestureState.getRunningTasks()) { + if (taskId == rti.taskId) { + runningTasks[i] = rti; + break; + } + + } + } } else { - runningTasks = mGestureState.getRunningTask().getPlaceholderTasks(); + runningTasks = new ActivityManager.RunningTaskInfo[]{mGestureState.getRunningTask()}; } mRecentsView.onGestureAnimationStart(runningTasks, mDeviceState.getRotationTouchHelper()); } @@ -789,7 +801,7 @@ public abstract class AbsSwipeUpHandler, RecentsAnimationTargets targets) { super.onRecentsAnimationStart(controller, targets); ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targets.apps.length); - mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(mContext, targets); + mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(targets); mRecentsAnimationController = controller; mRecentsAnimationTargets = targets; @@ -1368,7 +1380,7 @@ public abstract class AbsSwipeUpHandler, private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory, RemoteAnimationTargetCompat runningTaskTarget, float startProgress) { // Directly animate the app to PiP (picture-in-picture) mode - final ActivityManager.RunningTaskInfo taskInfo = runningTaskTarget.taskInfo; + final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask(); final RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator() .getOrientationState(); final int windowRotation = calculateWindowRotation(runningTaskTarget, orientationState); @@ -1770,7 +1782,8 @@ public abstract class AbsSwipeUpHandler, new PictureInPictureSurfaceTransaction.Builder() .setAlpha(0f) .build(); - int[] taskIds = TopTaskTracker.INSTANCE.get(mContext).getRunningSplitTaskIds(); + int[] taskIds = + LauncherSplitScreenListener.INSTANCE.getNoCreate().getRunningSplitTaskIds(); for (int taskId : taskIds) { mRecentsAnimationController.setFinishTaskTransaction(taskId, tx, null /* overlay */); diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java index ee5bb44040..9828467c79 100644 --- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java @@ -30,7 +30,7 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACT import android.animation.ObjectAnimator; import android.annotation.TargetApi; -import android.app.ActivityManager.RunningTaskInfo; +import android.app.ActivityManager; import android.app.ActivityOptions; import android.content.ActivityNotFoundException; import android.content.Context; @@ -69,6 +69,7 @@ import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.TransformParams; import com.android.quickstep.util.TransformParams.BuilderProxy; import com.android.systemui.shared.recents.model.Task.TaskKey; +import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; @@ -108,7 +109,7 @@ public class FallbackSwipeHandler extends super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs, continuingLastGesture, inputConsumer); - mRunningOverHome = mGestureState.getRunningTask().isHomeTask(); + mRunningOverHome = ActivityManagerWrapper.isHomeTask(mGestureState.getRunningTask()); if (mRunningOverHome) { runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams().setHomeBuilderProxy( @@ -149,17 +150,16 @@ public class FallbackSwipeHandler extends return new FallbackPipToHomeAnimationFactory(); } mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration); - startHomeIntent(mActiveAnimationFactory, runningTaskTarget); + startHomeIntent(mActiveAnimationFactory); return mActiveAnimationFactory; } private void startHomeIntent( - @Nullable FallbackHomeAnimationFactory gestureContractAnimationFactory, - @Nullable RemoteAnimationTargetCompat runningTaskTarget) { + @Nullable FallbackHomeAnimationFactory gestureContractAnimationFactory) { ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); Intent intent = new Intent(mGestureState.getHomeIntent()); - if (gestureContractAnimationFactory != null && runningTaskTarget != null) { - gestureContractAnimationFactory.addGestureContract(intent, runningTaskTarget.taskInfo); + if (gestureContractAnimationFactory != null) { + gestureContractAnimationFactory.addGestureContract(intent); } try { mContext.startActivity(intent, options.toBundle()); @@ -187,8 +187,7 @@ public class FallbackSwipeHandler extends // the PiP task appearing. recentsCallback = () -> { callback.run(); - startHomeIntent( - null /* gestureContractAnimationFactory */, null /* runningTaskTarget */); + startHomeIntent(null /* gestureContractAnimationFactory */); }; } else { recentsCallback = callback; @@ -213,7 +212,7 @@ public class FallbackSwipeHandler extends if (mRunningOverHome) { if (DisplayController.getNavigationMode(mContext).hasGestures) { mRecentsView.onGestureAnimationStartOnHome( - mGestureState.getRunningTask().getPlaceholderTasks(), + new ActivityManager.RunningTaskInfo[]{mGestureState.getRunningTask()}, mDeviceState.getRotationTouchHelper()); } } else { @@ -397,12 +396,12 @@ public class FallbackSwipeHandler extends } } - private void addGestureContract(Intent intent, RunningTaskInfo runningTaskInfo) { - if (mRunningOverHome || runningTaskInfo == null) { + private void addGestureContract(Intent intent) { + if (mRunningOverHome || mGestureState.getRunningTask() == null) { return; } - TaskKey key = new TaskKey(runningTaskInfo); + TaskKey key = new TaskKey(mGestureState.getRunningTask()); if (key.getComponent() != null) { if (sMessageReceiver == null) { sMessageReceiver = new StaticMessageReceiver(); diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 3b52e9178e..ed0623da24 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -22,6 +22,7 @@ import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import android.annotation.Nullable; import android.annotation.TargetApi; +import android.app.ActivityManager; import android.content.Intent; import android.os.Build; @@ -29,7 +30,6 @@ import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.tracing.GestureStateProto; import com.android.launcher3.tracing.SwipeHandlerProto; -import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.util.ActiveGestureLog; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -135,7 +135,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL private final MultiStateCallback mStateCallback; private final int mGestureId; - private CachedTaskInfo mRunningTask; + private ActivityManager.RunningTaskInfo mRunningTask; + private ActivityManager.RunningTaskInfo[] mRunningTasks; private GestureEndTarget mEndTarget; private RemoteAnimationTargetCompat mLastAppearedTaskTarget; private Set mPreviouslyAppearedTaskIds = new HashSet<>(); @@ -231,24 +232,41 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL /** * @return the running task for this gesture. */ - public CachedTaskInfo getRunningTask() { + public ActivityManager.RunningTaskInfo getRunningTask() { return mRunningTask; } + /** + * This will array will contain the task returned by {@link #getRunningTask()} + * @return the running tasks for this gesture. + */ + public ActivityManager.RunningTaskInfo[] getRunningTasks() { + return mRunningTasks; + } + /** * @return the running task id for this gesture. */ public int getRunningTaskId() { - return mRunningTask != null ? mRunningTask.getTaskId() : -1; + return mRunningTask != null ? mRunningTask.taskId : -1; } /** * Updates the running task for the gesture to be the given {@param runningTask}. */ - public void updateRunningTask(CachedTaskInfo runningTask) { + public void updateRunningTask(ActivityManager.RunningTaskInfo runningTask) { mRunningTask = runningTask; } + /** + * TODO(b/210903248) refactor to consolidate w/ method above + * Updates the running task for the gesture to be the given {@param runningTask}. + */ + public void updateRunningTasks(ActivityManager.RunningTaskInfo[] runningTasks) { + mRunningTasks = runningTasks; + updateRunningTask(runningTasks[0]); + } + /** * Updates the last task that appeared during this gesture. */ @@ -321,7 +339,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL * user controlled gesture. */ public void setHandlingAtomicEvent(boolean handlingAtomicEvent) { - mHandlingAtomicEvent = handlingAtomicEvent; + mHandlingAtomicEvent = true; } /** diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index 920ed71b80..7ad60bb0bc 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -45,11 +45,14 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_Q 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.app.ActivityTaskManager; 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.Region; import android.inputmethodservice.InputMethodService; import android.net.Uri; @@ -58,17 +61,18 @@ import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserManager; import android.provider.Settings; +import android.text.TextUtils; import android.view.MotionEvent; import androidx.annotation.BinderThread; +import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.DisplayController.NavigationMode; import com.android.launcher3.util.SettingsCache; -import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.util.NavBarPosition; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; @@ -79,6 +83,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; /** * Manages the state of the system during a swipe up gesture. @@ -92,6 +97,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { private final int mDisplayId; private final RotationTouchHelper mRotationTouchHelper; private final TaskStackChangeListener mPipListener; + private final List mGestureBlockedActivities; // Cache for better performance since it doesn't change at runtime. private final boolean mCanImeRenderGesturalNavButtons = InputMethodService.canImeRenderGesturalNavButtons(); @@ -123,7 +129,6 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { } }; - private int mGestureBlockingTaskId = -1; private Region mExclusionRegion; private SystemGestureExclusionListenerCompat mExclusionListener; @@ -173,6 +178,22 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { onDisplayInfoChanged(context, mDisplayController.getInfo(), CHANGE_ALL); runOnDestroy(() -> mDisplayController.removeChangeListener(this)); + // Add any blocked activities + String[] blockingActivities; + try { + blockingActivities = + context.getResources().getStringArray(R.array.gesture_blocking_activities); + } catch (Resources.NotFoundException e) { + blockingActivities = new String[0]; + } + mGestureBlockedActivities = new ArrayList<>(blockingActivities.length); + for (String blockingActivity : blockingActivities) { + if (!TextUtils.isEmpty(blockingActivity)) { + mGestureBlockedActivities.add( + ComponentName.unflattenFromString(blockingActivity)); + } + } + SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext); if (mIsOneHandedModeSupported) { Uri oneHandedUri = Settings.Secure.getUriFor(ONE_HANDED_ENABLED); @@ -346,17 +367,11 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { } /** - * Sets the task id where gestures should be blocked + * @return whether the given running task info matches the gesture-blocked activity. */ - public void setGestureBlockingTaskId(int taskId) { - mGestureBlockingTaskId = taskId; - } - - /** - * @return whether the given running task info matches the gesture-blocked task. - */ - public boolean isGestureBlockedTask(CachedTaskInfo taskInfo) { - return taskInfo != null && taskInfo.getTaskId() == mGestureBlockingTaskId; + public boolean isGestureBlockedActivity(ActivityManager.RunningTaskInfo runningTaskInfo) { + return runningTaskInfo != null + && mGestureBlockedActivities.contains(runningTaskInfo.topActivity); } /** diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java index c3ea25683d..afb4d4dfe4 100644 --- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java +++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java @@ -22,6 +22,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds; import com.android.quickstep.util.AnimatorControllerWithResistance; +import com.android.quickstep.util.LauncherSplitScreenListener; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -49,7 +50,8 @@ public class RemoteTargetGluer { * running tasks */ public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) { - int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds(); + int[] splitIds = LauncherSplitScreenListener.INSTANCE.getNoCreate() + .getRunningSplitTaskIds(); mRemoteTargetHandles = createHandles(context, sizingStrategy, splitIds.length == 2 ? 2 : 1); } @@ -71,7 +73,7 @@ public class RemoteTargetGluer { * Length of targets.apps should match that of {@link #mRemoteTargetHandles}. * * If split screen may be active when this is called, you might want to use - * {@link #assignTargetsForSplitScreen(Context, RemoteAnimationTargets)} + * {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)} */ public RemoteTargetHandle[] assignTargets(RemoteAnimationTargets targets) { for (int i = 0; i < mRemoteTargetHandles.length; i++) { @@ -88,9 +90,9 @@ public class RemoteTargetGluer { * apps in targets.apps to that of the _active_ split screened tasks. * See {@link #assignTargetsForSplitScreen(RemoteAnimationTargets, int[])} */ - public RemoteTargetHandle[] assignTargetsForSplitScreen( - Context context, RemoteAnimationTargets targets) { - int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds(); + public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) { + int[] splitIds = LauncherSplitScreenListener.INSTANCE.getNoCreate() + .getRunningSplitTaskIds(); return assignTargetsForSplitScreen(targets, splitIds); } diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java index 088e1cfc00..8862073725 100644 --- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java @@ -37,6 +37,7 @@ import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle; import com.android.quickstep.util.AnimatorControllerWithResistance; +import com.android.quickstep.util.LauncherSplitScreenListener; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; @@ -81,7 +82,8 @@ public abstract class SwipeUpAnimationLogic implements mGestureState = gestureState; mIsSwipeForStagedSplit = ENABLE_SPLIT_SELECT.get() && - TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds().length > 1; + LauncherSplitScreenListener.INSTANCE.getNoCreate() + .getRunningSplitTaskIds().length > 1; mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getActivityInterface()); mRemoteTargetHandles = mTargetGluer.getRemoteTargetHandles(); diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index b8334a9ae8..4bb2400df1 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -35,7 +35,6 @@ import androidx.annotation.UiThread; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; -import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -235,8 +234,9 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn // Allowing to pause Home if Home is top activity and Recents is not Home. So when user // start home when recents animation is playing, the home activity can be resumed again // to let the transition controller collect Home activity. - CachedTaskInfo cti = gestureState.getRunningTask(); - boolean homeIsOnTop = cti != null && cti.isHomeTask(); + ActivityManager.RunningTaskInfo rti = gestureState.getRunningTask(); + boolean homeIsOnTop = rti != null && rti.topActivity != null + && rti.topActivity.equals(gestureState.getHomeIntent().getComponent()); if (!homeIsOnTop) { options.setTransientLaunch(); } diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java deleted file mode 100644 index 80bc329620..0000000000 --- a/quickstep/src/com/android/quickstep/TopTaskTracker.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2022 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.app.WindowConfiguration.ACTIVITY_TYPE_HOME; -import static android.content.Intent.ACTION_CHOOSER; -import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; - -import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT; - -import android.app.ActivityManager.RunningTaskInfo; -import android.content.Context; - -import androidx.annotation.UiThread; - -import com.android.launcher3.util.MainThreadInitializedObject; -import com.android.launcher3.util.SplitConfigurationOptions; -import com.android.launcher3.util.SplitConfigurationOptions.StagePosition; -import com.android.launcher3.util.SplitConfigurationOptions.StageType; -import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitTaskPosition; -import com.android.launcher3.util.TraceHelper; -import com.android.systemui.shared.recents.model.Task; -import com.android.systemui.shared.recents.model.Task.TaskKey; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.TaskStackChangeListener; -import com.android.systemui.shared.system.TaskStackChangeListeners; -import com.android.wm.shell.splitscreen.ISplitScreenListener; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * This class tracked the top-most task and some 'approximate' task history to allow faster - * system state estimation during touch interaction - */ -public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskStackChangeListener { - - public static MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>(TopTaskTracker::new); - - private static final int HISTORY_SIZE = 5; - - // Ordered list with first item being the most recent task. - private final LinkedList mOrderedTaskList = new LinkedList<>(); - - private final StagedSplitTaskPosition mMainStagePosition = new StagedSplitTaskPosition(); - private final StagedSplitTaskPosition mSideStagePosition = new StagedSplitTaskPosition(); - - private TopTaskTracker(Context context) { - mMainStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_MAIN; - mSideStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_SIDE; - - TaskStackChangeListeners.getInstance().registerTaskStackListener(this); - SystemUiProxy.INSTANCE.get(context).registerSplitScreenListener(this); - } - - @Override - public void onTaskRemoved(int taskId) { - mOrderedTaskList.removeIf(rto -> rto.taskId == taskId); - } - - @Override - public void onTaskMovedToFront(RunningTaskInfo taskInfo) { - mOrderedTaskList.removeIf(rto -> rto.taskId == taskInfo.taskId); - mOrderedTaskList.addFirst(taskInfo); - if (mOrderedTaskList.size() >= HISTORY_SIZE) { - // If we grow in size, remove the last taskInfo which is not part of the split task. - Iterator itr = mOrderedTaskList.descendingIterator(); - while (itr.hasNext()) { - RunningTaskInfo info = itr.next(); - if (info.taskId != taskInfo.taskId - && info.taskId != mMainStagePosition.taskId - && info.taskId != mSideStagePosition.taskId) { - itr.remove(); - return; - } - } - } - } - - @Override - public void onStagePositionChanged(@StageType int stage, @StagePosition int position) { - if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) { - mMainStagePosition.stagePosition = position; - } else { - mSideStagePosition.stagePosition = position; - } - } - - @Override - public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) { - // If task is not visible but we are tracking it, stop tracking it - if (!visible) { - if (mMainStagePosition.taskId == taskId) { - resetTaskId(mMainStagePosition); - } else if (mSideStagePosition.taskId == taskId) { - resetTaskId(mSideStagePosition); - } // else it's an un-tracked child - return; - } - - // If stage has moved to undefined, stop tracking the task - if (stage == SplitConfigurationOptions.STAGE_TYPE_UNDEFINED) { - resetTaskId(taskId == mMainStagePosition.taskId - ? mMainStagePosition : mSideStagePosition); - return; - } - - if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) { - mMainStagePosition.taskId = taskId; - } else { - mSideStagePosition.taskId = taskId; - } - } - - private void resetTaskId(StagedSplitTaskPosition taskPosition) { - taskPosition.taskId = -1; - } - - /** - * @return index 0 will be task in left/top position, index 1 in right/bottom position. - * Will return empty array if device is not in staged split - */ - public int[] getRunningSplitTaskIds() { - if (mMainStagePosition.taskId == -1 || mSideStagePosition.taskId == -1) { - return new int[]{}; - } - int[] out = new int[2]; - if (mMainStagePosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) { - out[0] = mMainStagePosition.taskId; - out[1] = mSideStagePosition.taskId; - } else { - out[1] = mMainStagePosition.taskId; - out[0] = mSideStagePosition.taskId; - } - return out; - } - - - /** - * Returns the CachedTaskInfo for the top most task - */ - @UiThread - public CachedTaskInfo getCachedTopTask(boolean filterOnlyVisibleRecents) { - if (filterOnlyVisibleRecents) { - // Since we only know about the top most task, any filtering may not be applied on the - // cache. The second to top task may change while the top task is still the same. - RunningTaskInfo[] tasks = TraceHelper.allowIpcs("getCachedTopTask.true", () -> - ActivityManagerWrapper.getInstance().getRunningTasks(true)); - return new CachedTaskInfo(Arrays.asList(tasks)); - } - - if (mOrderedTaskList.isEmpty()) { - RunningTaskInfo[] tasks = TraceHelper.allowIpcs("getCachedTopTask.false", () -> - ActivityManagerWrapper.getInstance().getRunningTasks( - false /* filterOnlyVisibleRecents */)); - Collections.addAll(mOrderedTaskList, tasks); - } - return new CachedTaskInfo(new ArrayList<>(mOrderedTaskList)); - } - - /** - * Class to provide information about a task which can be safely cached and do not change - * during the lifecycle of the task. - */ - public static class CachedTaskInfo { - - private final RunningTaskInfo mTopTask; - private final List mAllCachedTasks; - - CachedTaskInfo(List allCachedTasks) { - mAllCachedTasks = allCachedTasks; - mTopTask = allCachedTasks.get(0); - } - - public int getTaskId() { - return mTopTask.taskId; - } - - /** - * Returns true if the root of the task chooser activity - */ - public boolean isRootChooseActivity() { - return ACTION_CHOOSER.equals(mTopTask.baseIntent.getAction()); - } - - /** - * Returns true if the given task holds an Assistant activity that is excluded from recents - */ - public boolean isExcludedAssistant() { - return mTopTask.configuration.windowConfiguration - .getActivityType() == ACTIVITY_TYPE_ASSISTANT - && (mTopTask.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0; - } - - /** - * Returns true if this represents the HOME task - */ - public boolean isHomeTask() { - return mTopTask.configuration.windowConfiguration - .getActivityType() == ACTIVITY_TYPE_HOME; - } - - /** - * Returns {@link Task} array which can be used as a placeholder until the true object - * is loaded by the model - */ - public Task[] getPlaceholderTasks() { - return new Task[] {Task.from(new TaskKey(mTopTask), mTopTask, false)}; - } - - /** - * Returns {@link Task} array corresponding to the provided task ids which can be used as a - * placeholder until the true object is loaded by the model - */ - public Task[] getPlaceholderTasks(int[] taskIds) { - Task[] result = new Task[taskIds.length]; - for (int i = 0; i < taskIds.length; i++) { - final int index = i; - int taskId = taskIds[i]; - mAllCachedTasks.forEach(rti -> { - if (rti.taskId == taskId) { - result[index] = Task.from(new TaskKey(rti), rti, false); - } - }); - } - return result; - } - } -} diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 0078d55398..320682521c 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static android.content.Intent.ACTION_CHOOSER; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; @@ -40,6 +41,7 @@ import android.annotation.TargetApi; import android.app.PendingIntent; import android.app.RemoteAction; import android.app.Service; +import android.content.ComponentName; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -93,6 +95,8 @@ import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.quickstep.inputconsumers.SysUiOverlayInputConsumer; import com.android.quickstep.inputconsumers.TaskbarStashInputConsumer; import com.android.quickstep.util.ActiveGestureLog; +import com.android.quickstep.util.AssistantUtilities; +import com.android.quickstep.util.LauncherSplitScreenListener; import com.android.quickstep.util.ProtoTracer; import com.android.quickstep.util.ProxyScreenStatusProvider; import com.android.quickstep.util.SplitScreenBounds; @@ -310,13 +314,6 @@ public class TouchInteractionService extends Service public void setSwipeUpProxy(Function proxy) { mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null); } - - /** - * Sets the task id where gestures should be blocked - */ - public void setGestureBlockedTaskId(int taskId) { - mDeviceState.setGestureBlockingTaskId(taskId); - } } private static boolean sConnected = false; @@ -372,6 +369,7 @@ public class TouchInteractionService extends Service mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged); ProtoTracer.INSTANCE.get(this).add(this); + LauncherSplitScreenListener.INSTANCE.get(this).init(); sConnected = true; } @@ -421,9 +419,6 @@ public class TouchInteractionService extends Service onSystemUiFlagsChanged(mDeviceState.getSystemUiStateFlags()); onAssistantVisibilityChanged(); - // Initialize the task tracker - TopTaskTracker.INSTANCE.get(this); - // Temporarily disable model preload // new ModelPreload().start(this); mBackGestureNotificationCounter = Math.max(0, Utilities.getDevicePrefs(this) @@ -536,6 +531,7 @@ public class TouchInteractionService extends Service getSystemService(AccessibilityManager.class) .unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS); + LauncherSplitScreenListener.INSTANCE.get(this).destroy(); mTaskbarManager.destroy(); sConnected = false; super.onDestroy(); @@ -637,7 +633,7 @@ public class TouchInteractionService extends Service private InputConsumer tryCreateAssistantInputConsumer(InputConsumer base, GestureState gestureState, MotionEvent motionEvent) { - return mDeviceState.isGestureBlockedTask(gestureState.getRunningTask()) + return mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask()) ? base : new AssistantInputConsumer(this, gestureState, base, mInputMonitorCompat, mDeviceState, motionEvent); @@ -652,8 +648,8 @@ public class TouchInteractionService extends Service gestureState.updatePreviouslyAppearedTaskIds( previousGestureState.getPreviouslyAppearedTaskIds()); } else { - gestureState.updateRunningTask( - TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false)); + gestureState.updateRunningTasks(TraceHelper.allowIpcs("getRunningTask.0", + () -> mAM.getRunningTasks(false /* filterOnlyVisibleRecents */))); } return gestureState; } @@ -747,14 +743,17 @@ public class TouchInteractionService extends Service // Use overview input consumer for sharesheets on top of home. boolean forceOverviewInputConsumer = gestureState.getActivityInterface().isStarted() && gestureState.getRunningTask() != null - && gestureState.getRunningTask().isRootChooseActivity(); - if (gestureState.getRunningTask() != null - && gestureState.getRunningTask().isExcludedAssistant()) { + && ACTION_CHOOSER.equals(gestureState.getRunningTask().baseIntent.getAction()); + if (AssistantUtilities.isExcludedAssistant(gestureState.getRunningTask())) { // In the case where we are in the excluded assistant state, ignore it and treat the // running activity as the task behind the assistant - gestureState.updateRunningTask(TopTaskTracker.INSTANCE.get(this) - .getCachedTopTask(true /* filterOnlyVisibleRecents */)); - forceOverviewInputConsumer = gestureState.getRunningTask().isHomeTask(); + gestureState.updateRunningTask(TraceHelper.allowIpcs("getRunningTask.assistant", + () -> mAM.getRunningTask(true /* filterOnlyVisibleRecents */))); + ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent(); + ComponentName runningComponent = + gestureState.getRunningTask().baseIntent.getComponent(); + forceOverviewInputConsumer = + runningComponent != null && runningComponent.equals(homeComponent); } if (ENABLE_QUICKSTEP_LIVE_TILE.get() @@ -771,7 +770,7 @@ public class TouchInteractionService extends Service || forceOverviewInputConsumer) { return createOverviewInputConsumer( previousGestureState, gestureState, event, forceOverviewInputConsumer); - } else if (mDeviceState.isGestureBlockedTask(gestureState.getRunningTask())) { + } else if (mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())) { return getDefaultInputConsumer(); } else { return createOtherActivityInputConsumer(gestureState, event); diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index c9ee2db1f1..48af802ff8 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -24,6 +24,7 @@ import static com.android.quickstep.fallback.RecentsState.OVERVIEW_SPLIT_SELECT; import android.animation.AnimatorSet; import android.annotation.TargetApi; +import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.os.Build; import android.util.AttributeSet; @@ -49,6 +50,7 @@ import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; +import com.android.systemui.shared.recents.model.Task.TaskKey; import java.util.ArrayList; @@ -56,7 +58,7 @@ import java.util.ArrayList; public class FallbackRecentsView extends RecentsView implements StateListener { - private Task mHomeTask; + private RunningTaskInfo mHomeTaskInfo; public FallbackRecentsView(Context context, AttributeSet attrs) { this(context, attrs, 0); @@ -85,12 +87,12 @@ public class FallbackRecentsView extends RecentsView 1) { + protected boolean shouldAddStubTaskView(RunningTaskInfo[] runningTaskInfos) { + if (runningTaskInfos.length > 1) { // can't be in split screen w/ home task - return super.shouldAddStubTaskView(runningTasks); + return super.shouldAddStubTaskView(runningTaskInfos); } - Task runningTask = runningTasks[0]; - if (mHomeTask != null && runningTask != null - && mHomeTask.key.id == runningTask.key.id + RunningTaskInfo runningTaskInfo = runningTaskInfos[0]; + if (mHomeTaskInfo != null && runningTaskInfo != null && + mHomeTaskInfo.taskId == runningTaskInfo.taskId && getTaskViewCount() == 0 && mLoadPlanEverApplied) { // Do not add a stub task if we are running over home with empty recents, so that we // show the empty recents message instead of showing a stub task and later removing it. // Ignore empty task signal if applyLoadPlan has never run. return false; } - return super.shouldAddStubTaskView(runningTasks); + return super.shouldAddStubTaskView(runningTaskInfos); } @Override @@ -167,7 +169,7 @@ public class FallbackRecentsView extends RecentsView newList = new ArrayList<>(taskGroups.size() + 1); newList.addAll(taskGroups); - newList.add(new GroupTask(mHomeTask, null, null)); + newList.add(new GroupTask( + Task.from(new TaskKey(mHomeTaskInfo), mHomeTaskInfo, false), + null, null)); taskGroups = newList; } } @@ -189,7 +193,7 @@ public class FallbackRecentsView extends RecentsView