1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.quickstep.util; 18 19 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 20 21 import android.app.Activity; 22 import android.app.ActivityManager; 23 import android.util.Log; 24 25 import androidx.annotation.NonNull; 26 27 import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter; 28 import com.android.quickstep.RecentsModel; 29 import com.android.systemui.shared.system.TaskStackChangeListener; 30 import com.android.systemui.shared.system.TaskStackChangeListeners; 31 32 /** 33 * This class tracks the failure of a task launch through the Launcher.startActivitySafely() call, 34 * in an edge case in which a task may already be visible on screen (ie. in PIP) and no transition 35 * will be run in WM, which results in expected callbacks to not be processed. 36 * 37 * We transiently register a task stack listener during a task launch and if the restart signal is 38 * received, then the registered callback will be notified. 39 */ 40 public class TaskRestartedDuringLaunchListener implements TaskStackChangeListener { 41 42 private static final String TAG = "TaskRestartedDuringLaunchListener"; 43 44 private @NonNull Runnable mTaskRestartedCallback = null; 45 46 /** 47 * Registers a failure listener callback if it detects a scenario in which an app launch 48 * resulted in an already existing task to be "restarted". 49 */ register(@onNull Runnable taskRestartedCallback)50 public void register(@NonNull Runnable taskRestartedCallback) { 51 TaskStackChangeListeners.getInstance().registerTaskStackListener(this); 52 mTaskRestartedCallback = taskRestartedCallback; 53 } 54 55 /** 56 * Unregisters the failure listener. 57 */ unregister()58 public void unregister() { 59 TaskStackChangeListeners.getInstance().unregisterTaskStackListener(this); 60 mTaskRestartedCallback = null; 61 } 62 63 @Override onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask, boolean wasVisible)64 public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, 65 boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) { 66 if (wasVisible) { 67 Log.d(TAG, "Detected activity restart during launch for task=" + task.taskId); 68 mTaskRestartedCallback.run(); 69 unregister(); 70 } 71 } 72 } 73