Loading quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +7 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ import com.android.quickstep.util.StaggeredWorkspaceAnim; import com.android.quickstep.util.SurfaceTransaction; import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.TaskRestartedDuringLaunchListener; import com.android.quickstep.util.WorkspaceRevealAnim; import com.android.quickstep.views.FloatingWidgetView; import com.android.quickstep.views.RecentsView; Loading Loading @@ -299,6 +300,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener boolean fromRecents = isLaunchingFromRecents(v, null /* targets */); RunnableList onEndCallback = new RunnableList(); // Handle the case where an already visible task is launched which results in no transition TaskRestartedDuringLaunchListener restartedListener = new TaskRestartedDuringLaunchListener(); restartedListener.register(onEndCallback::executeAllAndDestroy); onEndCallback.add(restartedListener::unregister); mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback); ItemInfo tag = (ItemInfo) v.getTag(); if (tag != null && tag.shouldUseBackgroundAnimation()) { Loading quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +5 −3 Original line number Diff line number Diff line Loading @@ -345,11 +345,13 @@ public class QuickstepLauncher extends Launcher { @Override public RunnableList startActivitySafely(View v, Intent intent, ItemInfo item) { // Only pause is taskbar controller is not present // Only pause is taskbar controller is not present until the transition (if it exists) ends mHotseatPredictionController.setPauseUIUpdate(getTaskbarUIController() == null); RunnableList result = super.startActivitySafely(v, intent, item); if (getTaskbarUIController() == null && result == null) { if (result == null) { if (getTaskbarUIController() == null) { mHotseatPredictionController.setPauseUIUpdate(false); } } else { result.add(() -> mHotseatPredictionController.setPauseUIUpdate(false)); } Loading quickstep/src/com/android/quickstep/util/TaskRestartedDuringLaunchListener.java 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.util; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import android.app.Activity; import android.app.ActivityManager; import android.util.Log; import androidx.annotation.NonNull; import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter; import com.android.quickstep.RecentsModel; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; /** * This class tracks the failure of a task launch through the Launcher.startActivitySafely() call, * in an edge case in which a task may already be visible on screen (ie. in PIP) and no transition * will be run in WM, which results in expected callbacks to not be processed. * * We transiently register a task stack listener during a task launch and if the restart signal is * received, then the registered callback will be notified. */ public class TaskRestartedDuringLaunchListener implements TaskStackChangeListener { private static final String TAG = "TaskRestartedDuringLaunchListener"; private @NonNull Runnable mTaskRestartedCallback = null; /** * Registers a failure listener callback if it detects a scenario in which an app launch * resulted in an already existing task to be "restarted". */ public void register(@NonNull Runnable taskRestartedCallback) { TaskStackChangeListeners.getInstance().registerTaskStackListener(this); mTaskRestartedCallback = taskRestartedCallback; } /** * Unregisters the failure listener. */ public void unregister() { TaskStackChangeListeners.getInstance().unregisterTaskStackListener(this); mTaskRestartedCallback = null; } @Override public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { if (wasVisible) { Log.d(TAG, "Detected activity restart during launch for task=" + task.taskId); mTaskRestartedCallback.run(); unregister(); } } } Loading
quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +7 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ import com.android.quickstep.util.StaggeredWorkspaceAnim; import com.android.quickstep.util.SurfaceTransaction; import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.TaskRestartedDuringLaunchListener; import com.android.quickstep.util.WorkspaceRevealAnim; import com.android.quickstep.views.FloatingWidgetView; import com.android.quickstep.views.RecentsView; Loading Loading @@ -299,6 +300,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener boolean fromRecents = isLaunchingFromRecents(v, null /* targets */); RunnableList onEndCallback = new RunnableList(); // Handle the case where an already visible task is launched which results in no transition TaskRestartedDuringLaunchListener restartedListener = new TaskRestartedDuringLaunchListener(); restartedListener.register(onEndCallback::executeAllAndDestroy); onEndCallback.add(restartedListener::unregister); mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback); ItemInfo tag = (ItemInfo) v.getTag(); if (tag != null && tag.shouldUseBackgroundAnimation()) { Loading
quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +5 −3 Original line number Diff line number Diff line Loading @@ -345,11 +345,13 @@ public class QuickstepLauncher extends Launcher { @Override public RunnableList startActivitySafely(View v, Intent intent, ItemInfo item) { // Only pause is taskbar controller is not present // Only pause is taskbar controller is not present until the transition (if it exists) ends mHotseatPredictionController.setPauseUIUpdate(getTaskbarUIController() == null); RunnableList result = super.startActivitySafely(v, intent, item); if (getTaskbarUIController() == null && result == null) { if (result == null) { if (getTaskbarUIController() == null) { mHotseatPredictionController.setPauseUIUpdate(false); } } else { result.add(() -> mHotseatPredictionController.setPauseUIUpdate(false)); } Loading
quickstep/src/com/android/quickstep/util/TaskRestartedDuringLaunchListener.java 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.util; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import android.app.Activity; import android.app.ActivityManager; import android.util.Log; import androidx.annotation.NonNull; import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter; import com.android.quickstep.RecentsModel; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; /** * This class tracks the failure of a task launch through the Launcher.startActivitySafely() call, * in an edge case in which a task may already be visible on screen (ie. in PIP) and no transition * will be run in WM, which results in expected callbacks to not be processed. * * We transiently register a task stack listener during a task launch and if the restart signal is * received, then the registered callback will be notified. */ public class TaskRestartedDuringLaunchListener implements TaskStackChangeListener { private static final String TAG = "TaskRestartedDuringLaunchListener"; private @NonNull Runnable mTaskRestartedCallback = null; /** * Registers a failure listener callback if it detects a scenario in which an app launch * resulted in an already existing task to be "restarted". */ public void register(@NonNull Runnable taskRestartedCallback) { TaskStackChangeListeners.getInstance().registerTaskStackListener(this); mTaskRestartedCallback = taskRestartedCallback; } /** * Unregisters the failure listener. */ public void unregister() { TaskStackChangeListeners.getInstance().unregisterTaskStackListener(this); mTaskRestartedCallback = null; } @Override public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { if (wasVisible) { Log.d(TAG, "Detected activity restart during launch for task=" + task.taskId); mTaskRestartedCallback.run(); unregister(); } } }