diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 510ad4c433..104e5e0e33 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -197,8 +197,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public static final long APP_LAUNCH_DURATION = 500; - private static final long APP_LAUNCH_ALPHA_DURATION = 50; - private static final long APP_LAUNCH_ALPHA_START_DELAY = 25; + public static final long APP_LAUNCH_ALPHA_DURATION = 50; + public static final long APP_LAUNCH_ALPHA_START_DELAY = 25; public static final int ANIMATION_NAV_FADE_IN_DURATION = 266; public static final int ANIMATION_NAV_FADE_OUT_DURATION = 133; @@ -222,8 +222,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // is solved. private static final int TASKBAR_TO_HOME_DURATION_FAST = 300; private static final int TASKBAR_TO_HOME_DURATION_SLOW = 1000; - protected static final int CONTENT_SCALE_DURATION = 350; - protected static final int CONTENT_SCRIM_DURATION = 350; + public static final int CONTENT_SCALE_DURATION = 350; + public static final int CONTENT_SCRIM_DURATION = 350; private static final int MAX_NUM_TASKS = 5; @@ -319,6 +319,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onDeviceProfileChanged(DeviceProfile dp) { mDeviceProfile = dp; + var item = new RemoteAnimationTarget[0]; } /** @@ -1303,7 +1304,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener return unlockAnimator; } - private static int getRotationChange(RemoteAnimationTarget[] appTargets) { + public static int getRotationChange(RemoteAnimationTarget[] appTargets) { int rotationChange = 0; for (RemoteAnimationTarget target : appTargets) { // LC: https://github.com/LawnchairLauncher/lawnchair/pull/3776 @@ -2033,16 +2034,16 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener target, currentRect, toLauncher, resultRect); } - private static class RemoteAnimationCoordinateTransfer { + public static class RemoteAnimationCoordinateTransfer { private final QuickstepLauncher mLauncher; private final Rect mDisplayRect = new Rect(); private final Rect mTmpResult = new Rect(); - RemoteAnimationCoordinateTransfer(QuickstepLauncher launcher) { + public RemoteAnimationCoordinateTransfer(QuickstepLauncher launcher) { mLauncher = launcher; } - void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect, + public void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect, boolean toLauncher, RectF resultRect) { final int taskRotation = target.windowConfiguration.getRotation(); final DeviceProfile profile = mLauncher.getDeviceProfile(); @@ -2070,7 +2071,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * RectFSpringAnim update listener to be used for app to home animation. */ - private class SpringAnimRunner implements RectFSpringAnim.OnUpdateListener { + public class SpringAnimRunner implements RectFSpringAnim.OnUpdateListener { private final RemoteAnimationTarget[] mAppTargets; private final Matrix mMatrix = new Matrix(); private final Point mTmpPos = new Point(); @@ -2095,7 +2096,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * @param closingWindowOriginalRect Original unscaled window rect * @param startWindowCornerRadius corner radius of window at the start position */ - SpringAnimRunner(RemoteAnimationTarget[] appTargets, RectF targetRect, + public SpringAnimRunner(RemoteAnimationTarget[] appTargets, RectF targetRect, Rect closingWindowStartRect, Rect closingWindowOriginalRect, float startWindowCornerRadius) { mAppTargets = appTargets; @@ -2196,8 +2197,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } - private static class LaunchDepthController extends DepthController { - LaunchDepthController(QuickstepLauncher launcher) { + public static class LaunchDepthController extends DepthController { + public LaunchDepthController(QuickstepLauncher launcher) { super(launcher); try { setCrossWindowBlursEnabled( diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index b46bfc7418..aa0cc1f0f0 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -95,7 +95,7 @@ public class QuickstepInteractionHandler implements RemoteViews.InteractionHandl } try { activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR); + activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON); activityOptions.options.setPendingIntentBackgroundActivityStartMode( ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); } catch (Throwable t) { diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 786fd49b59..fe3c35251b 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -233,6 +233,8 @@ public abstract class AbsSwipeUpHandler rawTasks = mSysUiProxy.getRecentTasks(numTasks, currentUserId); - // The raw tasks are given in most-recent to least-recent order, we need to - // reverse it - Collections.reverse(rawTasks); + List recentTasks; + try { + ParceledListSlice parceledList = + ActivityManager.getService().getRecentTasks( + numTasks, ActivityManager.RECENT_IGNORE_UNAVAILABLE, currentUserId + ); + recentTasks = (parceledList != null) ? parceledList.getList() : new ArrayList<>(); + } catch (RemoteException e) { + return new TaskLoadResult(requestId, loadKeysOnly, 0); + } + + Collections.reverse(recentTasks); SparseBooleanArray tmpLockedUsers = new SparseBooleanArray() { @Override public boolean get(int key) { @@ -347,57 +356,26 @@ public class RecentTasksList { } }; - TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size()); - + TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, recentTasks.size()); int numVisibleTasks = 0; - for (GroupedRecentTaskInfo rawTask : rawTasks) { - if (rawTask.getType() == TYPE_FREEFORM) { - // TYPE_FREEFORM tasks is only created when enableDesktopWindowingMode() is - // true, - // leftover TYPE_FREEFORM tasks created when flag was on should be ignored. - if (enableDesktopWindowingMode()) { - GroupTask desktopTask = createDesktopTask(rawTask); - allTasks.add(desktopTask); - } - continue; - } - ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1(); - ActivityManager.RecentTaskInfo taskInfo2 = rawTask.getTaskInfo2(); - Task.TaskKey task1Key = new Task.TaskKey(taskInfo1); - Task task1 = loadKeysOnly - ? new Task(task1Key) - : Task.from(task1Key, taskInfo1, - tmpLockedUsers.get(task1Key.userId) /* isLocked */); - task1.setLastSnapshotData(taskInfo1); - Task task2 = null; - if (taskInfo2 != null) { - // Is split task - Task.TaskKey task2Key = new Task.TaskKey(taskInfo2); - task2 = loadKeysOnly - ? new Task(task2Key) - : Task.from(task2Key, taskInfo2, - tmpLockedUsers.get(task2Key.userId) /* isLocked */); - task2.setLastSnapshotData(taskInfo2); - } else if (Utilities.ATLEAST_S) { - // Is fullscreen task - if (numVisibleTasks > 0) { - boolean isExcluded = (taskInfo1.baseIntent.getFlags() - & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0; - if (isExcluded) { - // If there are already visible tasks, then ignore the excluded tasks and - // don't add them to the returned list - continue; - } - } - } + + for (ActivityManager.RecentTaskInfo taskInfo : recentTasks) { + Task.TaskKey taskKey = new Task.TaskKey(taskInfo); + Task task = loadKeysOnly + ? new Task(taskKey) + : Task.from(taskKey, taskInfo, tmpLockedUsers.get(taskKey.userId)); + task.setLastSnapshotData(taskInfo); + if (Utilities.ATLEAST_S) { - if (taskInfo1.isVisible) { + if (taskInfo.isVisible) { numVisibleTasks++; } + if (numVisibleTasks > 0 && (taskInfo.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0) { + continue; + } } - final SplitConfigurationOptions.SplitBounds launcherSplitBounds = convertShellSplitBoundsToLauncher( - rawTask.getSplitBounds()); - allTasks.add(new GroupTask(task1, task2, launcherSplitBounds)); + + allTasks.add(new GroupTask(task, null, null)); } return allTasks; diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 6c91ed4fe6..d7aa644973 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -105,8 +105,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn */ public void preloadRecentsAnimation(Intent intent) { // Pass null animation handler to indicate this start is for preloading - UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() - .startRecentsActivity(intent, 0, null, null, null)); + UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance().preloadRecentsActivity(intent)); } boolean shouldIgnoreMotionEvents() { diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java index 5a41b8d8a7..f04ef97f16 100644 --- a/quickstep/src/com/android/quickstep/TopTaskTracker.java +++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java @@ -28,7 +28,6 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO import android.annotation.UserIdInt; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; -import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -48,7 +47,6 @@ import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.splitscreen.ISplitScreenListener; -import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -60,19 +58,14 @@ import java.util.stream.Collectors; import app.lawnchair.compat.LawnchairQuickstepCompat; /** - * This class tracked the top-most task and some 'approximate' task history to - * allow faster + * 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, SafeCloseable { - private static final String TAG = "TopTaskTracker"; - - private static final boolean DEBUG = true; - - public static MainThreadInitializedObject INSTANCE = new MainThreadInitializedObject<>( - TopTaskTracker::new); + public static MainThreadInitializedObject INSTANCE = + new MainThreadInitializedObject<>(TopTaskTracker::new); private static final int HISTORY_SIZE = 5; @@ -101,59 +94,34 @@ public class TopTaskTracker extends ISplitScreenListener.Stub @Override public void onTaskRemoved(int taskId) { - if (!LawnchairQuickstepCompat.ATLEAST_T) - return; mOrderedTaskList.removeIf(rto -> rto.taskId == taskId); - if (DEBUG) { - Log.i(TAG, "onTaskRemoved: taskId=" + taskId); - } } @Override public void onTaskMovedToFront(RunningTaskInfo taskInfo) { - if (!LawnchairQuickstepCompat.ATLEAST_T) - return; - - if (!mOrderedTaskList.isEmpty() - && mOrderedTaskList.getFirst().taskId != taskInfo.taskId - && DEBUG) { - Log.i(TAG, "onTaskMovedToFront: (moved taskInfo to front) taskId=" + taskInfo.taskId - + ", baseIntent=" + taskInfo.baseIntent); - } mOrderedTaskList.removeIf(rto -> rto.taskId == taskInfo.taskId); mOrderedTaskList.addFirst(taskInfo); // Keep the home display's top running task in the first while adding a non-home - // display's task to the list, to avoid showing non-home display's task upon - // going to + // display's task to the list, to avoid showing non-home display's task upon going to // Recents animation. if (taskInfo.displayId != DEFAULT_DISPLAY) { final RunningTaskInfo topTaskOnHomeDisplay = mOrderedTaskList.stream() .filter(rto -> rto.displayId == DEFAULT_DISPLAY).findFirst().orElse(null); if (topTaskOnHomeDisplay != null) { - if (DEBUG) { - Log.i(TAG, "onTaskMovedToFront: (removing top task on home display) taskId=" - + topTaskOnHomeDisplay.taskId - + ", baseIntent=" + topTaskOnHomeDisplay.baseIntent); - } mOrderedTaskList.removeIf(rto -> rto.taskId == topTaskOnHomeDisplay.taskId); mOrderedTaskList.addFirst(topTaskOnHomeDisplay); } } if (mOrderedTaskList.size() >= HISTORY_SIZE) { - // If we grow in size, remove the last taskInfo which is not part of the split - // task. + // 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) { - if (DEBUG) { - Log.i(TAG, "onTaskMovedToFront: (removing task list overflow) taskId=" - + taskInfo.taskId + ", baseIntent=" + taskInfo.baseIntent); - } itr.remove(); return; } @@ -163,9 +131,6 @@ public class TopTaskTracker extends ISplitScreenListener.Stub @Override public void onStagePositionChanged(@StageType int stage, @StagePosition int position) { - if (DEBUG) { - Log.i(TAG, "onStagePositionChanged: stage=" + stage + ", position=" + position); - } if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) { mMainStagePosition.stagePosition = position; } else { @@ -175,12 +140,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub @Override public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) { - if (DEBUG) { - Log.i(TAG, "onTaskStageChanged: taskId=" + taskId - + ", stage=" + stage + ", visible=" + visible); - } - // If a task is not visible anymore or has been moved to undefined, stop - // tracking it. + // If a task is not visible anymore or has been moved to undefined, stop tracking it. if (!visible || stage == SplitConfigurationOptions.STAGE_TYPE_UNDEFINED) { if (mMainStagePosition.taskId == taskId) { mMainStagePosition.taskId = INVALID_TASK_ID; @@ -199,30 +159,22 @@ public class TopTaskTracker extends ISplitScreenListener.Stub @Override public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { - if (DEBUG) { - Log.i(TAG, "onActivityPinned: packageName=" + packageName - + ", userId=" + userId + ", stackId=" + stackId); - } mPinnedTaskId = taskId; } @Override public void onActivityUnpinned() { - if (DEBUG) { - Log.i(TAG, "onActivityUnpinned"); - } mPinnedTaskId = INVALID_TASK_ID; } /** - * @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 + * @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 == INVALID_TASK_ID || mSideStagePosition.taskId == INVALID_TASK_ID) { - return new int[] {}; + return new int[]{}; } int[] out = new int[2]; if (mMainStagePosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) { @@ -235,33 +187,24 @@ public class TopTaskTracker extends ISplitScreenListener.Stub return out; } + /** * Returns the CachedTaskInfo for the top most task */ @NonNull @UiThread public CachedTaskInfo getCachedTopTask(boolean filterOnlyVisibleRecents) { - if (!LawnchairQuickstepCompat.ATLEAST_U) { - RunningTaskInfo task = TraceHelper.allowIpcs("getCachedTopTask.false", - () -> ActivityManagerWrapper.getInstance().getRunningTask( - false /* filterOnlyVisibleRecents */)); - ArrayList taskList = new ArrayList<>(); - Collections.addAll(taskList, task); - return new CachedTaskInfo(taskList); - } 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)); + // 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( + RunningTaskInfo[] tasks = TraceHelper.allowIpcs("getCachedTopTask.false", () -> + ActivityManagerWrapper.getInstance().getRunningTasks( false /* filterOnlyVisibleRecents */)); Collections.addAll(mOrderedTaskList, tasks); } @@ -272,24 +215,8 @@ public class TopTaskTracker extends ISplitScreenListener.Stub return new CachedTaskInfo(tasks); } - public void dump(String prefix, PrintWriter writer) { - writer.println(prefix + "TopTaskTracker:"); - - writer.println(prefix + "\tmOrderedTaskList=["); - for (RunningTaskInfo taskInfo : mOrderedTaskList) { - writer.println(prefix + "\t\t(taskId=" + taskInfo.taskId - + "; baseIntent=" + taskInfo.baseIntent - + "; isRunning=" + taskInfo.isRunning + ")"); - } - writer.println(prefix + "\t]"); - writer.println(prefix + "\tmMainStagePosition=" + mMainStagePosition); - writer.println(prefix + "\tmSideStagePosition=" + mSideStagePosition); - writer.println(prefix + "\tmPinnedTaskId=" + mPinnedTaskId); - } - /** - * Class to provide information about a task which can be safely cached and do - * not change + * 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 { @@ -316,8 +243,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub /** * If the given task holds an activity that is excluded from recents, and there - * is another running task that is not excluded from recents, returns that - * underlying task. + * is another running task that is not excluded from recents, returns that underlying task. */ public @Nullable CachedTaskInfo getVisibleNonExcludedTask() { if (mTopTask == null @@ -326,8 +252,10 @@ public class TopTaskTracker extends ISplitScreenListener.Stub return null; } List visibleNonExcludedTasks = mAllCachedTasks.stream() - .filter(t -> (LawnchairQuickstepCompat.ATLEAST_S && t.isVisible) - && (t.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) + .filter(t -> LawnchairQuickstepCompat.ATLEAST_S && t.isVisible + && (t.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0 + && t.getActivityType() != ACTIVITY_TYPE_HOME + && t.getActivityType() != ACTIVITY_TYPE_RECENTS) .collect(Collectors.toList()); return visibleNonExcludedTasks.isEmpty() ? null : new CachedTaskInfo(visibleNonExcludedTasks); @@ -351,23 +279,21 @@ public class TopTaskTracker extends ISplitScreenListener.Stub * android.app.WindowConfiguration#WINDOWING_MODE_FREEFORM} */ public boolean isFreeformTask() { - return mTopTask != null - && mTopTask.configuration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM; + return mTopTask != null && mTopTask.configuration.windowConfiguration.getWindowingMode() + == WINDOWING_MODE_FREEFORM; } /** - * Returns {@link Task} array which can be used as a placeholder until the true - * object + * Returns {@link Task} array which can be used as a placeholder until the true object * is loaded by the model */ public Task[] getPlaceholderTasks() { return mTopTask == null ? new Task[0] - : new Task[] { Task.from(new TaskKey(mTopTask), mTopTask, false) }; + : 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 + * 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) { @@ -401,4 +327,4 @@ public class TopTaskTracker extends ISplitScreenListener.Stub return mTopTask.baseActivity.getPackageName(); } } -} +} \ No newline at end of file diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index f8b1c8812e..1485172f4c 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -96,6 +96,7 @@ import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarActivityContext; import com.android.launcher3.taskbar.TaskbarManager; import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks; +import com.android.launcher3.taskbar.bubbles.BubbleControllers; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.ResourceUtils; import com.android.launcher3.testing.shared.TestProtocol; @@ -1013,6 +1014,7 @@ public class TouchInteractionService extends Service { private InputConsumer newConsumer( GestureState previousGestureState, GestureState newGestureState, MotionEvent event) { + TaskbarActivityContext tac = mTaskbarManager.getCurrentActivityContext(); AnimatedFloat progressProxy = mSwipeUpProxyProvider.apply(mGestureState); if (progressProxy != null) { InputConsumer consumer = new ProgressDelegateInputConsumer( @@ -1077,7 +1079,6 @@ public class TouchInteractionService extends Service { } // If Taskbar is present, we listen for swipe or cursor hover events to unstash it. - TaskbarActivityContext tac = mTaskbarManager.getCurrentActivityContext(); if (tac != null && !(base instanceof AssistantInputConsumer)) { // Present always on large screen or on small screen w/ flag boolean useTaskbarConsumer = tac.getDeviceProfile().isTaskbarPresent @@ -1108,7 +1109,8 @@ public class TouchInteractionService extends Service { NavHandle navHandle = tac != null ? tac.getNavHandle() : SystemUiProxy.INSTANCE.get(this); if (canStartSystemGesture && !previousGestureState.isRecentsAnimationRunning() - && navHandle.canNavHandleBeLongPressed()) { + && navHandle.canNavHandleBeLongPressed() + && !ignoreThreeFingerTrackpadForNavHandleLongPress(mGestureState)) { reasonString.append(NEWLINE_PREFIX) .append(reasonPrefix) .append(SUBSTRING_PREFIX) @@ -1140,7 +1142,7 @@ public class TouchInteractionService extends Service { getBaseContext(), mDeviceState, mInputMonitorCompat); } - if (ENABLE_TRACKPAD_GESTURE.get() && mGestureState.isTrackpadGesture() + if (mGestureState.isTrackpadGesture() && canStartSystemGesture && !previousGestureState.isRecentsAnimationRunning()) { reasonString = newCompoundString(reasonPrefix) .append(SUBSTRING_PREFIX) @@ -1204,6 +1206,10 @@ public class TouchInteractionService extends Service { return new CompoundString(NEWLINE_PREFIX).append(substring); } + private boolean ignoreThreeFingerTrackpadForNavHandleLongPress(GestureState gestureState) { + return gestureState.isThreeFingerTrackpadGesture(); + } + private void logInputConsumerSelectionReason( InputConsumer consumer, CompoundString reasonString) { ActiveGestureLog.INSTANCE.addLog(new CompoundString("setInputConsumer: ") @@ -1538,7 +1544,6 @@ public class TouchInteractionService extends Service { pw.println("\tmConsumer=" + mConsumer.getName()); ActiveGestureLog.INSTANCE.dump("", pw); RecentsModel.INSTANCE.get(this).dump("", pw); - TopTaskTracker.INSTANCE.get(this).dump("", pw); if (mTaskAnimationManager != null) { mTaskAnimationManager.dump("", pw); } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 51a91fd740..0cad4ecbfc 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2565,12 +2565,9 @@ public class Launcher extends StatefulActivity } /** - * Finds the first view matching the ordered operators across the given - * viewgroups in order. - * + * Finds the first view matching the ordered operators across the given viewgroups in order. * @param containers List of ViewGroups to scan, in order of preference. - * @param operators List of operators, in order starting from best matching - * operator. + * @param operators List of operators, in order starting from best matching operator. */ @Nullable private static View getFirstMatch(Iterable containers, @@ -2598,8 +2595,7 @@ public class Launcher extends StatefulActivity } /** - * Returns the first view matching the operator in the given ViewGroups, or null - * if none. + * Returns the first view matching the operator in the given ViewGroups, or null if none. * Forward iteration matters. */ @Nullable @@ -2607,6 +2603,9 @@ public class Launcher extends StatefulActivity final int itemCount = container.getChildCount(); for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) { View item = container.getChildAt(itemIdx); + if (item.getVisibility() != View.VISIBLE) { + continue; + } if (item instanceof ViewGroup viewGroup) { View view = mapOverViewGroup(viewGroup, op); if (view != null) { diff --git a/systemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/systemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index 8e4daf6172..7d63faf5b7 100644 --- a/systemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/systemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -46,7 +46,6 @@ import android.provider.Settings; import android.util.Log; import android.view.Display; import android.view.IRecentsAnimationController; -import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationTarget; import android.window.TaskSnapshot; @@ -54,10 +53,14 @@ import com.android.internal.app.IVoiceInteractionManagerService; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; +import java.lang.reflect.Method; +import java.util.HashMap; import java.util.List; import java.util.function.Consumer; import app.lawnchair.compat.LawnchairQuickstepCompat; +import app.lawnchair.compatlib.RecentsAnimationRunnerCompat; +import app.lawnchair.compatlib.eleven.ActivityManagerCompatVR; public class ActivityManagerWrapper { @@ -222,18 +225,17 @@ public class ActivityManagerWrapper { public boolean startRecentsActivity( Intent intent, long eventTime, RecentsAnimationListener animationHandler) { try { - IRecentsAnimationRunner runner = null; + RecentsAnimationRunnerCompat runner = null; if (animationHandler != null) { - runner = new IRecentsAnimationRunner.Stub() { + runner = new RecentsAnimationRunnerCompat() { @Override public void onAnimationStart(IRecentsAnimationController controller, - RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - Rect homeContentInsets, Rect minimizedHomeBounds, - Bundle extras) { + RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, + Rect homeContentInsets, Rect minimizedHomeBounds) { final RecentsAnimationControllerCompat controllerCompat = new RecentsAnimationControllerCompat(controller); animationHandler.onAnimationStart(controllerCompat, apps, - wallpapers, homeContentInsets, minimizedHomeBounds, extras); + wallpapers, homeContentInsets, minimizedHomeBounds, new Bundle()); } @Override @@ -242,13 +244,41 @@ public class ActivityManagerWrapper { ThumbnailData.wrap(taskIds, taskSnapshots)); } + + /** + * compat for android 12/11/10 + */ + public void onAnimationCanceled(Object taskSnapshot) { + if (LawnchairQuickstepCompat.ATLEAST_S) { + animationHandler.onAnimationCanceled( + ThumbnailData.wrap(new int[]{0}, new TaskSnapshot[]{(TaskSnapshot) taskSnapshot})); + } else if (LawnchairQuickstepCompat.ATLEAST_R) { + ActivityManagerCompatVR compat = (ActivityManagerCompatVR) LawnchairQuickstepCompat.getActivityManagerCompat(); + ActivityManagerCompatVR.ThumbnailData data = compat.convertTaskSnapshotToThumbnailData(taskSnapshot); + HashMap thumbnailDatas = new HashMap<>(); + if (data != null) { + thumbnailDatas.put(0, new ThumbnailData()); + } + animationHandler.onAnimationCanceled(thumbnailDatas); + } else { + animationHandler.onAnimationCanceled(new HashMap<>()); + } + } + + /** + * compat for android 12/11 + */ + public void onTaskAppeared(RemoteAnimationTarget app) { + animationHandler.onTasksAppeared(new RemoteAnimationTarget[]{app}); + } + @Override public void onTasksAppeared(RemoteAnimationTarget[] apps) { animationHandler.onTasksAppeared(apps); } }; } - getService().startRecentsActivity(intent, eventTime, runner); + LawnchairQuickstepCompat.getActivityManagerCompat().startRecentsActivity(intent, eventTime, runner); return true; } catch (Exception e) { return false; @@ -273,6 +303,24 @@ public class ActivityManagerWrapper { return startActivityFromRecents(taskKey.id, options); } + /** + * Preloads the recents activity. The caller should manage the thread on which this is called. + */ + public void preloadRecentsActivity(Intent intent) { + try { + Class activityTaskManagerClass = Class.forName("android.app.ActivityTaskManager"); + Method getServiceMethod = activityTaskManagerClass.getMethod("getService"); + Object activityTaskManagerService = getServiceMethod.invoke(null); + Method preloadRecentsActivityMethod = activityTaskManagerService.getClass() + .getMethod("preloadRecentsActivity", Intent.class); + + preloadRecentsActivityMethod.invoke(activityTaskManagerService, intent); + } catch (Throwable e) { + Log.w(TAG, "Failed to preload recents activity", e); + startRecentsActivity(intent, 0, null, null, null); + } + } + /** * Starts a task from Recents synchronously. */