• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.server.wm;
18 
19 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
20 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
23 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
24 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
25 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
26 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
27 import static android.app.WindowConfiguration.activityTypeToString;
28 import static android.app.WindowConfiguration.windowingModeToString;
29 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
30 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
31 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
32 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
33 import static android.view.Display.DEFAULT_DISPLAY;
34 import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
35 import static android.view.Display.INVALID_DISPLAY;
36 import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
37 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
38 import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
39 import static android.view.WindowManager.TRANSIT_NONE;
40 import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
41 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
42 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
43 import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
44 import static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
45 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
46 
47 import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
48 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
49 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
50 import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
51 import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
52 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
53 import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
54 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
55 import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
56 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
57 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
58 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
59 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP;
60 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
61 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
62 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
63 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
64 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
65 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
66 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
67 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
68 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_APP;
69 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CLEANUP;
70 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
71 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
72 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
73 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
74 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
75 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
76 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
77 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TRANSITION;
78 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
79 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
80 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
81 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
82 import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG;
83 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
84 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
85 import static com.android.server.wm.TaskProto.ACTIVITY_TYPE;
86 import static com.android.server.wm.TaskProto.ANIMATING_BOUNDS;
87 import static com.android.server.wm.TaskProto.BOUNDS;
88 import static com.android.server.wm.TaskProto.CREATED_BY_ORGANIZER;
89 import static com.android.server.wm.TaskProto.DISPLAY_ID;
90 import static com.android.server.wm.TaskProto.FILLS_PARENT;
91 import static com.android.server.wm.TaskProto.LAST_NON_FULLSCREEN_BOUNDS;
92 import static com.android.server.wm.TaskProto.MIN_HEIGHT;
93 import static com.android.server.wm.TaskProto.MIN_WIDTH;
94 import static com.android.server.wm.TaskProto.ORIG_ACTIVITY;
95 import static com.android.server.wm.TaskProto.REAL_ACTIVITY;
96 import static com.android.server.wm.TaskProto.RESIZE_MODE;
97 import static com.android.server.wm.TaskProto.RESUMED_ACTIVITY;
98 import static com.android.server.wm.TaskProto.ROOT_TASK_ID;
99 import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
100 import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
101 import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
102 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
103 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
104 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
105 
106 import static java.lang.Integer.MAX_VALUE;
107 
108 import android.annotation.IntDef;
109 import android.annotation.Nullable;
110 import android.app.Activity;
111 import android.app.ActivityManager;
112 import android.app.ActivityManagerInternal;
113 import android.app.ActivityOptions;
114 import android.app.AppGlobals;
115 import android.app.IActivityController;
116 import android.app.RemoteAction;
117 import android.app.ResultInfo;
118 import android.app.servertransaction.ActivityResultItem;
119 import android.app.servertransaction.ClientTransaction;
120 import android.app.servertransaction.NewIntentItem;
121 import android.app.servertransaction.PauseActivityItem;
122 import android.app.servertransaction.ResumeActivityItem;
123 import android.content.ComponentName;
124 import android.content.Intent;
125 import android.content.pm.ActivityInfo;
126 import android.content.res.Configuration;
127 import android.graphics.Point;
128 import android.graphics.Rect;
129 import android.os.Binder;
130 import android.os.Debug;
131 import android.os.Handler;
132 import android.os.IBinder;
133 import android.os.Looper;
134 import android.os.Message;
135 import android.os.RemoteException;
136 import android.os.SystemClock;
137 import android.os.Trace;
138 import android.os.UserHandle;
139 import android.service.voice.IVoiceInteractionSession;
140 import android.util.Log;
141 import android.util.Slog;
142 import android.util.proto.ProtoOutputStream;
143 import android.view.Display;
144 import android.view.DisplayInfo;
145 
146 import com.android.internal.annotations.GuardedBy;
147 import com.android.internal.annotations.VisibleForTesting;
148 import com.android.internal.app.IVoiceInteractor;
149 import com.android.internal.util.function.pooled.PooledConsumer;
150 import com.android.internal.util.function.pooled.PooledFunction;
151 import com.android.internal.util.function.pooled.PooledLambda;
152 import com.android.server.Watchdog;
153 import com.android.server.am.ActivityManagerService;
154 import com.android.server.am.ActivityManagerService.ItemMatcher;
155 import com.android.server.am.AppTimeTracker;
156 import com.android.server.uri.NeededUriGrants;
157 
158 import java.io.FileDescriptor;
159 import java.io.PrintWriter;
160 import java.util.ArrayList;
161 import java.util.List;
162 import java.util.Objects;
163 import java.util.concurrent.atomic.AtomicBoolean;
164 import java.util.function.Consumer;
165 
166 /**
167  * State and management of a single stack of activities.
168  */
169 class ActivityStack extends Task {
170     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_ATM;
171     static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
172     private static final String TAG_APP = TAG + POSTFIX_APP;
173     static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
174     private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
175     private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
176     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
177     private static final String TAG_STACK = TAG + POSTFIX_STACK;
178     private static final String TAG_STATES = TAG + POSTFIX_STATES;
179     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
180     static final String TAG_TASKS = TAG + POSTFIX_TASKS;
181     private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
182     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
183     static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
184 
185     // Set to false to disable the preview that is shown while a new activity
186     // is being started.
187     private static final boolean SHOW_APP_STARTING_PREVIEW = true;
188 
189     // How long to wait for all background Activities to redraw following a call to
190     // convertToTranslucent().
191     private static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
192 
193     @IntDef(prefix = {"STACK_VISIBILITY"}, value = {
194             STACK_VISIBILITY_VISIBLE,
195             STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
196             STACK_VISIBILITY_INVISIBLE,
197     })
198     @interface StackVisibility {}
199 
200     /** Stack is visible. No other stacks on top that fully or partially occlude it. */
201     static final int STACK_VISIBILITY_VISIBLE = 0;
202 
203     /** Stack is partially occluded by other translucent stack(s) on top of it. */
204     static final int STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1;
205 
206     /** Stack is completely invisible. */
207     static final int STACK_VISIBILITY_INVISIBLE = 2;
208 
209     enum ActivityState {
210         INITIALIZING,
211         STARTED,
212         RESUMED,
213         PAUSING,
214         PAUSED,
215         STOPPING,
216         STOPPED,
217         FINISHING,
218         DESTROYING,
219         DESTROYED,
220         RESTARTING_PROCESS
221     }
222 
223     // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
224     // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
225     // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
226     // Activity in mTranslucentActivityWaiting is notified via
227     // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
228     // background activity being drawn then the same call will be made with a true value.
229     ActivityRecord mTranslucentActivityWaiting = null;
230     ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>();
231 
232     /**
233      * Set when we know we are going to be calling updateConfiguration()
234      * soon, so want to skip intermediate config checks.
235      */
236     boolean mConfigWillChange;
237 
238     /**
239      * Used to keep resumeTopActivityUncheckedLocked() from being entered recursively
240      */
241     boolean mInResumeTopActivity = false;
242 
243     int mCurrentUser;
244 
245     /** For comparison with DisplayContent bounds. */
246     private Rect mTmpRect = new Rect();
247     private Rect mTmpRect2 = new Rect();
248 
249     // If this is true, we are in the bounds animating mode. The task will be down or upscaled to
250     // perfectly fit the region it would have been cropped to. We may also avoid certain logic we
251     // would otherwise apply while resizing, while resizing in the bounds animating mode.
252     private boolean mBoundsAnimating = false;
253     // Set when an animation has been requested but has not yet started from the UI thread. This is
254     // cleared when the animation actually starts.
255     private boolean mBoundsAnimatingRequested = false;
256     private Rect mBoundsAnimationTarget = new Rect();
257     private Rect mBoundsAnimationSourceHintBounds = new Rect();
258 
259     Rect mPreAnimationBounds = new Rect();
260 
261     private final AnimatingActivityRegistry mAnimatingActivityRegistry =
262             new AnimatingActivityRegistry();
263 
264     private boolean mTopActivityOccludesKeyguard;
265     private ActivityRecord mTopDismissingKeyguardActivity;
266 
267     private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1;
268 
269     private final Handler mHandler;
270 
271     private class ActivityStackHandler extends Handler {
272 
ActivityStackHandler(Looper looper)273         ActivityStackHandler(Looper looper) {
274             super(looper);
275         }
276 
277         @Override
handleMessage(Message msg)278         public void handleMessage(Message msg) {
279             switch (msg.what) {
280                 case TRANSLUCENT_TIMEOUT_MSG: {
281                     synchronized (mAtmService.mGlobalLock) {
282                         notifyActivityDrawnLocked(null);
283                     }
284                 } break;
285             }
286         }
287     }
288 
289     private static final ResetTargetTaskHelper sResetTargetTaskHelper = new ResetTargetTaskHelper();
290     private final EnsureActivitiesVisibleHelper mEnsureActivitiesVisibleHelper =
291             new EnsureActivitiesVisibleHelper(this);
292     private final EnsureVisibleActivitiesConfigHelper mEnsureVisibleActivitiesConfigHelper =
293             new EnsureVisibleActivitiesConfigHelper();
294     private class EnsureVisibleActivitiesConfigHelper {
295         private boolean mUpdateConfig;
296         private boolean mPreserveWindow;
297         private boolean mBehindFullscreen;
298 
reset(boolean preserveWindow)299         void reset(boolean preserveWindow) {
300             mPreserveWindow = preserveWindow;
301             mUpdateConfig = false;
302             mBehindFullscreen = false;
303         }
304 
process(ActivityRecord start, boolean preserveWindow)305         void process(ActivityRecord start, boolean preserveWindow) {
306             if (start == null || !start.mVisibleRequested) {
307                 return;
308             }
309             reset(preserveWindow);
310 
311             final PooledFunction f = PooledLambda.obtainFunction(
312                     EnsureVisibleActivitiesConfigHelper::processActivity, this,
313                     PooledLambda.__(ActivityRecord.class));
314             forAllActivities(f, start, true /*includeBoundary*/, true /*traverseTopToBottom*/);
315             f.recycle();
316 
317             if (mUpdateConfig) {
318                 // Ensure the resumed state of the focus activity if we updated the configuration of
319                 // any activity.
320                 mRootWindowContainer.resumeFocusedStacksTopActivities();
321             }
322         }
323 
processActivity(ActivityRecord r)324         boolean processActivity(ActivityRecord r) {
325             mUpdateConfig |= r.ensureActivityConfiguration(0 /*globalChanges*/, mPreserveWindow);
326             mBehindFullscreen |= r.occludesParent();
327             return mBehindFullscreen;
328         }
329     }
330 
331     private final CheckBehindFullscreenActivityHelper mCheckBehindFullscreenActivityHelper =
332             new CheckBehindFullscreenActivityHelper();
333     private class CheckBehindFullscreenActivityHelper {
334         private boolean mAboveTop;
335         private boolean mBehindFullscreenActivity;
336         private ActivityRecord mToCheck;
337         private Consumer<ActivityRecord> mHandleBehindFullscreenActivity;
338         private boolean mHandlingOccluded;
339 
reset(ActivityRecord toCheck, Consumer<ActivityRecord> handleBehindFullscreenActivity)340         private void reset(ActivityRecord toCheck,
341                 Consumer<ActivityRecord> handleBehindFullscreenActivity) {
342             mToCheck = toCheck;
343             mHandleBehindFullscreenActivity = handleBehindFullscreenActivity;
344             mAboveTop = true;
345             mBehindFullscreenActivity = false;
346 
347             if (!shouldBeVisible(null)) {
348                 // The stack is not visible, so no activity in it should be displaying a starting
349                 // window. Mark all activities below top and behind fullscreen.
350                 mAboveTop = false;
351                 mBehindFullscreenActivity = true;
352             }
353 
354             mHandlingOccluded = mToCheck == null && mHandleBehindFullscreenActivity != null;
355         }
356 
process(ActivityRecord toCheck, Consumer<ActivityRecord> handleBehindFullscreenActivity)357         boolean process(ActivityRecord toCheck,
358                 Consumer<ActivityRecord> handleBehindFullscreenActivity) {
359             reset(toCheck, handleBehindFullscreenActivity);
360 
361             if (!mHandlingOccluded && mBehindFullscreenActivity) {
362                 return true;
363             }
364 
365             final ActivityRecord topActivity = topRunningActivity();
366             final PooledFunction f = PooledLambda.obtainFunction(
367                     CheckBehindFullscreenActivityHelper::processActivity, this,
368                     PooledLambda.__(ActivityRecord.class), topActivity);
369             forAllActivities(f);
370             f.recycle();
371 
372             return mBehindFullscreenActivity;
373         }
374 
375         /** Returns {@code true} to stop the outer loop and indicate the result is computed. */
processActivity(ActivityRecord r, ActivityRecord topActivity)376         private boolean processActivity(ActivityRecord r, ActivityRecord topActivity) {
377             if (mAboveTop) {
378                 if (r == topActivity) {
379                     if (r == mToCheck) {
380                         // It is the top activity in a visible stack.
381                         mBehindFullscreenActivity = false;
382                         return true;
383                     }
384                     mAboveTop = false;
385                 }
386                 mBehindFullscreenActivity |= r.occludesParent();
387                 return false;
388             }
389 
390             if (mHandlingOccluded) {
391                 // Iterating through all occluded activities.
392                 if (mBehindFullscreenActivity) {
393                     mHandleBehindFullscreenActivity.accept(r);
394                 }
395             } else if (r == mToCheck) {
396                 return true;
397             } else if (mBehindFullscreenActivity) {
398                 // It is occluded before {@param toCheck} is found.
399                 return true;
400             }
401             mBehindFullscreenActivity |= r.occludesParent();
402             return false;
403         }
404     }
405 
406     // TODO: Can we just loop through WindowProcessController#mActivities instead of doing this?
407     private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp =
408             new RemoveHistoryRecordsForApp();
409     private class RemoveHistoryRecordsForApp {
410         private boolean mHasVisibleActivities;
411         private boolean mIsProcessRemoved;
412         private WindowProcessController mApp;
413         private ArrayList<ActivityRecord> mToRemove = new ArrayList<>();
414 
process(WindowProcessController app)415         boolean process(WindowProcessController app) {
416             mToRemove.clear();
417             mHasVisibleActivities = false;
418             mApp = app;
419             mIsProcessRemoved = app.isRemoved();
420             if (mIsProcessRemoved) {
421                 // The package of the died process should be force-stopped, so make its activities
422                 // as finishing to prevent the process from being started again if the next top
423                 // (or being visible) activity also resides in the same process.
424                 app.makeFinishingForProcessRemoved();
425             }
426 
427             final PooledConsumer c = PooledLambda.obtainConsumer(
428                     RemoveHistoryRecordsForApp::addActivityToRemove, this,
429                     PooledLambda.__(ActivityRecord.class));
430             forAllActivities(c);
431             c.recycle();
432 
433             while (!mToRemove.isEmpty()) {
434                 processActivity(mToRemove.remove(0));
435             }
436 
437             mApp = null;
438             return mHasVisibleActivities;
439         }
440 
addActivityToRemove(ActivityRecord r)441         private void addActivityToRemove(ActivityRecord r) {
442             if (r.app == mApp) {
443                 mToRemove.add(r);
444             }
445         }
446 
processActivity(ActivityRecord r)447         private void processActivity(ActivityRecord r) {
448             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record " + r + ": app=" + r.app);
449 
450             if (r.app != mApp) {
451                 return;
452             }
453             if (r.isVisible() || r.mVisibleRequested) {
454                 // While an activity launches a new activity, it's possible that the old
455                 // activity is already requested to be hidden (mVisibleRequested=false), but
456                 // this visibility is not yet committed, so isVisible()=true.
457                 mHasVisibleActivities = true;
458             }
459             final boolean remove;
460             if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE
461                     || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE)
462                     && r.launchCount < 3 && !r.finishing) {
463                 // If the process crashed during a resize, always try to relaunch it, unless
464                 // it has failed more than twice. Skip activities that's already finishing
465                 // cleanly by itself.
466                 remove = false;
467             } else if ((!r.hasSavedState() && !r.stateNotNeeded
468                     && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) {
469                 // Don't currently have state for the activity, or
470                 // it is finishing -- always remove it.
471                 remove = true;
472             } else if (!r.mVisibleRequested && r.launchCount > 2
473                     && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) {
474                 // We have launched this activity too many times since it was
475                 // able to run, so give up and remove it.
476                 // (Note if the activity is visible, we don't remove the record.
477                 // We leave the dead window on the screen but the process will
478                 // not be restarted unless user explicitly tap on it.)
479                 remove = true;
480             } else {
481                 // The process may be gone, but the activity lives on!
482                 remove = false;
483             }
484             if (remove) {
485                 if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
486                         "Removing activity " + r + " from stack "
487                                 + ": hasSavedState=" + r.hasSavedState()
488                                 + " stateNotNeeded=" + r.stateNotNeeded
489                                 + " finishing=" + r.finishing
490                                 + " state=" + r.getState() + " callers=" + Debug.getCallers(5));
491                 if (!r.finishing || mIsProcessRemoved) {
492                     Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
493                     EventLogTags.writeWmFinishActivity(r.mUserId,
494                         System.identityHashCode(r), r.getTask().mTaskId,
495                             r.shortComponentName, "proc died without state saved");
496                 }
497             } else {
498                 // We have the current state for this activity, so
499                 // it can be restarted later when needed.
500                 if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null");
501                 if (DEBUG_APP) Slog.v(TAG_APP,
502                         "Clearing app during removeHistory for activity " + r);
503                 r.app = null;
504                 // Set nowVisible to previous visible state. If the app was visible while
505                 // it died, we leave the dead window on screen so it's basically visible.
506                 // This is needed when user later tap on the dead window, we need to stop
507                 // other apps when user transfers focus to the restarted activity.
508                 r.nowVisible = r.mVisibleRequested;
509             }
510             r.cleanUp(true /* cleanServices */, true /* setState */);
511             if (remove) {
512                 r.removeFromHistory("appDied");
513             }
514         }
515     }
516 
ActivityStack(ActivityTaskManagerService atmService, int id, int activityType, ActivityInfo info, Intent intent, boolean createdByOrganizer)517     ActivityStack(ActivityTaskManagerService atmService, int id, int activityType,
518             ActivityInfo info, Intent intent, boolean createdByOrganizer) {
519         this(atmService, id, info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
520                 null /*taskDescription*/, null /*stack*/);
521         mCreatedByOrganizer = createdByOrganizer;
522         setActivityType(activityType);
523     }
524 
ActivityStack(ActivityTaskManagerService atmService, int id, ActivityInfo info, Intent _intent, IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, ActivityManager.TaskDescription _taskDescription, ActivityStack stack)525     ActivityStack(ActivityTaskManagerService atmService, int id, ActivityInfo info, Intent _intent,
526             IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
527             ActivityManager.TaskDescription _taskDescription, ActivityStack stack) {
528         this(atmService, id, _intent,  null /*_affinityIntent*/, null /*_affinity*/,
529                 null /*_rootAffinity*/, null /*_realActivity*/, null /*_origActivity*/,
530                 false /*_rootWasReset*/, false /*_autoRemoveRecents*/, false /*_askedCompatMode*/,
531                 UserHandle.getUserId(info.applicationInfo.uid), 0 /*_effectiveUid*/,
532                 null /*_lastDescription*/, System.currentTimeMillis(),
533                 true /*neverRelinquishIdentity*/,
534                 _taskDescription != null ? _taskDescription : new ActivityManager.TaskDescription(),
535                 id, INVALID_TASK_ID, INVALID_TASK_ID, 0 /*taskAffiliationColor*/,
536                 info.applicationInfo.uid, info.packageName, null, info.resizeMode,
537                 info.supportsPictureInPicture(), false /*_realActivitySuspended*/,
538                 false /*userSetupComplete*/, INVALID_MIN_SIZE, INVALID_MIN_SIZE, info,
539                 _voiceSession, _voiceInteractor, stack);
540     }
541 
ActivityStack(ActivityTaskManagerService atmService, int id, Intent _intent, Intent _affinityIntent, String _affinity, String _rootAffinity, ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset, boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId, int _effectiveUid, String _lastDescription, long lastTimeMoved, boolean neverRelinquishIdentity, ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage, @Nullable String callingFeatureId, int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended, boolean userSetupComplete, int minWidth, int minHeight, ActivityInfo info, IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, ActivityStack stack)542     ActivityStack(ActivityTaskManagerService atmService, int id, Intent _intent,
543             Intent _affinityIntent, String _affinity, String _rootAffinity,
544             ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
545             boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId, int _effectiveUid,
546             String _lastDescription, long lastTimeMoved, boolean neverRelinquishIdentity,
547             ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
548             int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid,
549             String callingPackage, @Nullable String callingFeatureId, int resizeMode,
550             boolean supportsPictureInPicture, boolean _realActivitySuspended,
551             boolean userSetupComplete, int minWidth, int minHeight,
552             ActivityInfo info, IVoiceInteractionSession _voiceSession,
553             IVoiceInteractor _voiceInteractor, ActivityStack stack) {
554         super(atmService, id, _intent, _affinityIntent, _affinity, _rootAffinity,
555                 _realActivity, _origActivity, _rootWasReset, _autoRemoveRecents, _askedCompatMode,
556                 _userId, _effectiveUid, _lastDescription, lastTimeMoved, neverRelinquishIdentity,
557                 _lastTaskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
558                 callingUid, callingPackage, callingFeatureId, resizeMode, supportsPictureInPicture,
559                 _realActivitySuspended, userSetupComplete, minWidth, minHeight, info, _voiceSession,
560                 _voiceInteractor, stack);
561 
562         EventLogTags.writeWmStackCreated(id);
563         mHandler = new ActivityStackHandler(mStackSupervisor.mLooper);
564         mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();
565     }
566 
567     @Override
onConfigurationChanged(Configuration newParentConfig)568     public void onConfigurationChanged(Configuration newParentConfig) {
569         // Calling Task#onConfigurationChanged() for leaf task since the ops in this method are
570         // particularly for ActivityStack, like preventing bounds changes when inheriting certain
571         // windowing mode.
572         if (!isRootTask()) {
573             super.onConfigurationChanged(newParentConfig);
574             return;
575         }
576 
577         final int prevWindowingMode = getWindowingMode();
578         final boolean prevIsAlwaysOnTop = isAlwaysOnTop();
579         final int prevRotation = getWindowConfiguration().getRotation();
580         final Rect newBounds = mTmpRect;
581         // Initialize the new bounds by previous bounds as the input and output for calculating
582         // override bounds in pinned (pip) or split-screen mode.
583         getBounds(newBounds);
584 
585         super.onConfigurationChanged(newParentConfig);
586 
587         final TaskDisplayArea taskDisplayArea = getDisplayArea();
588         if (taskDisplayArea == null) {
589             return;
590         }
591 
592         if (prevWindowingMode != getWindowingMode()) {
593             taskDisplayArea.onStackWindowingModeChanged(this);
594         }
595 
596         final DisplayContent display = getDisplay();
597         if (display == null ) {
598             return;
599         }
600 
601         final boolean windowingModeChanged = prevWindowingMode != getWindowingMode();
602         final int overrideWindowingMode = getRequestedOverrideWindowingMode();
603         // Update bounds if applicable
604         boolean hasNewOverrideBounds = false;
605         // Use override windowing mode to prevent extra bounds changes if inheriting the mode.
606         if ((overrideWindowingMode != WINDOWING_MODE_PINNED) && !matchParentBounds()) {
607             // If the parent (display) has rotated, rotate our bounds to best-fit where their
608             // bounds were on the pre-rotated display.
609             final int newRotation = getWindowConfiguration().getRotation();
610             final boolean rotationChanged = prevRotation != newRotation;
611             if (rotationChanged) {
612                 display.mDisplayContent.rotateBounds(
613                         newParentConfig.windowConfiguration.getBounds(), prevRotation, newRotation,
614                         newBounds);
615                 hasNewOverrideBounds = true;
616             }
617         }
618 
619         if (windowingModeChanged) {
620             taskDisplayArea.onStackWindowingModeChanged(this);
621         }
622         if (hasNewOverrideBounds) {
623             if (inSplitScreenWindowingMode()) {
624                 setBounds(newBounds);
625             } else if (overrideWindowingMode != WINDOWING_MODE_PINNED) {
626                 // For pinned stack, resize is now part of the {@link WindowContainerTransaction}
627                 resize(new Rect(newBounds), PRESERVE_WINDOWS, true /* deferResume */);
628             }
629         }
630         if (prevIsAlwaysOnTop != isAlwaysOnTop()) {
631             // Since always on top is only on when the stack is freeform or pinned, the state
632             // can be toggled when the windowing mode changes. We must make sure the stack is
633             // placed properly when always on top state changes.
634             taskDisplayArea.positionStackAtTop(this, false /* includingParents */);
635         }
636     }
637 
638     @Override
setWindowingMode(int windowingMode)639     public void setWindowingMode(int windowingMode) {
640         // Reset the cached result of toString()
641         stringName = null;
642 
643         // Calling Task#setWindowingMode() for leaf task since this is the a specialization of
644         // {@link #setWindowingMode(int)} for ActivityStack.
645         if (!isRootTask()) {
646             super.setWindowingMode(windowingMode);
647             return;
648         }
649 
650         setWindowingMode(windowingMode, false /* creating */);
651     }
652 
653     /**
654      * Specialization of {@link #setWindowingMode(int)} for this subclass.
655      *
656      * @param preferredWindowingMode the preferred windowing mode. This may not be honored depending
657      *         on the state of things. For example, WINDOWING_MODE_UNDEFINED will resolve to the
658      *         previous non-transient mode if this stack is currently in a transient mode.
659      * @param creating {@code true} if this is being run during ActivityStack construction.
660      */
setWindowingMode(int preferredWindowingMode, boolean creating)661     void setWindowingMode(int preferredWindowingMode, boolean creating) {
662         mWmService.inSurfaceTransaction(() -> setWindowingModeInSurfaceTransaction(
663                 preferredWindowingMode, creating));
664     }
665 
setWindowingModeInSurfaceTransaction(int preferredWindowingMode, boolean creating)666     private void setWindowingModeInSurfaceTransaction(int preferredWindowingMode,
667             boolean creating) {
668         final TaskDisplayArea taskDisplayArea = getDisplayArea();
669         if (taskDisplayArea == null) {
670             Slog.d(TAG, "taskDisplayArea is null, bail early");
671             return;
672         }
673         final int currentMode = getWindowingMode();
674         final int currentOverrideMode = getRequestedOverrideWindowingMode();
675         final Task topTask = getTopMostTask();
676         int windowingMode = preferredWindowingMode;
677 
678         // Need to make sure windowing mode is supported. If we in the process of creating the stack
679         // no need to resolve the windowing mode again as it is already resolved to the right mode.
680         if (!creating) {
681             if (!taskDisplayArea.isValidWindowingMode(windowingMode, null /* ActivityRecord */,
682                     topTask, getActivityType())) {
683                 windowingMode = WINDOWING_MODE_UNDEFINED;
684             }
685         }
686 
687         final boolean alreadyInSplitScreenMode = taskDisplayArea.isSplitScreenModeActivated();
688 
689         if (creating && alreadyInSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN
690                 && isActivityTypeStandardOrUndefined()) {
691             // If the stack is being created explicitly in fullscreen mode, dismiss split-screen
692             // and display a warning toast about it.
693             mAtmService.getTaskChangeNotificationController()
694                     .notifyActivityDismissingDockedStack();
695             taskDisplayArea.onSplitScreenModeDismissed(this);
696         }
697 
698         if (currentMode == windowingMode) {
699             // You are already in the window mode, so we can skip most of the work below. However,
700             // it's possible that we have inherited the current windowing mode from a parent. So,
701             // fulfill this method's contract by setting the override mode directly.
702             getRequestedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode);
703             return;
704         }
705 
706         final ActivityRecord topActivity = getTopNonFinishingActivity();
707 
708         // For now, assume that the Stack's windowing mode is what will actually be used
709         // by it's activities. In the future, there may be situations where this doesn't
710         // happen; so at that point, this message will need to handle that.
711         int likelyResolvedMode = windowingMode;
712         if (windowingMode == WINDOWING_MODE_UNDEFINED) {
713             final ConfigurationContainer parent = getParent();
714             likelyResolvedMode = parent != null ? parent.getWindowingMode()
715                     : WINDOWING_MODE_FULLSCREEN;
716         }
717         if (currentMode == WINDOWING_MODE_PINNED) {
718             mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned();
719         }
720         if (likelyResolvedMode == WINDOWING_MODE_PINNED
721                 && taskDisplayArea.getRootPinnedTask() != null) {
722             // Can only have 1 pip at a time, so replace an existing pip
723             taskDisplayArea.getRootPinnedTask().dismissPip();
724         }
725         if (likelyResolvedMode != WINDOWING_MODE_FULLSCREEN
726                 && topActivity != null && !topActivity.noDisplay
727                 && topActivity.isNonResizableOrForcedResizable(likelyResolvedMode)) {
728             // Inform the user that they are starting an app that may not work correctly in
729             // multi-window mode.
730             final String packageName = topActivity.info.applicationInfo.packageName;
731             mAtmService.getTaskChangeNotificationController().notifyActivityForcedResizable(
732                     topTask.mTaskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName);
733         }
734 
735         mAtmService.deferWindowLayout();
736         try {
737             if (topActivity != null) {
738                 mStackSupervisor.mNoAnimActivities.add(topActivity);
739             }
740             super.setWindowingMode(windowingMode);
741             // setWindowingMode triggers an onConfigurationChanged cascade which can result in a
742             // different resolved windowing mode (usually when preferredWindowingMode is UNDEFINED).
743             windowingMode = getWindowingMode();
744 
745             if (creating) {
746                 // Nothing else to do if we don't have a window container yet. E.g. call from ctor.
747                 return;
748             }
749 
750             if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && alreadyInSplitScreenMode) {
751                 // We already have a split-screen stack in this display, so just move the tasks over.
752                 // TODO: Figure-out how to do all the stuff in
753                 // AMS.setTaskWindowingModeSplitScreenPrimary
754                 throw new IllegalArgumentException("Setting primary split-screen windowing mode"
755                         + " while there is already one isn't currently supported");
756                 //return;
757             }
758 
759             mTmpRect2.setEmpty();
760             if (windowingMode != WINDOWING_MODE_FULLSCREEN) {
761                 if (matchParentBounds()) {
762                     mTmpRect2.setEmpty();
763                 } else {
764                     getRawBounds(mTmpRect2);
765                 }
766             }
767 
768             if (!Objects.equals(getRequestedOverrideBounds(), mTmpRect2)) {
769                 resize(mTmpRect2, false /*preserveWindows*/, true /*deferResume*/);
770             }
771         } finally {
772             mAtmService.continueWindowLayout();
773         }
774 
775         mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
776         mRootWindowContainer.resumeFocusedStacksTopActivities();
777 
778         final boolean pinnedToFullscreen = currentMode == WINDOWING_MODE_PINNED
779                 && windowingMode == WINDOWING_MODE_FULLSCREEN;
780         if (pinnedToFullscreen && topActivity != null && !isForceHidden()) {
781             mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(true);
782             try {
783                 // Report orientation as soon as possible so that the display can freeze earlier if
784                 // the display orientation will be changed. Because the surface bounds of activity
785                 // may have been set to fullscreen but the activity hasn't redrawn its content yet,
786                 // the rotation animation needs to capture snapshot earlier to avoid animating from
787                 // an intermediate state.
788                 topActivity.reportDescendantOrientationChangeIfNeeded();
789             } finally {
790                 mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(false);
791             }
792         }
793     }
794 
795     @Override
isCompatible(int windowingMode, int activityType)796     public boolean isCompatible(int windowingMode, int activityType) {
797         // TODO: Should we just move this to ConfigurationContainer?
798         if (activityType == ACTIVITY_TYPE_UNDEFINED) {
799             // Undefined activity types end up in a standard stack once the stack is created on a
800             // display, so they should be considered compatible.
801             activityType = ACTIVITY_TYPE_STANDARD;
802         }
803         return super.isCompatible(windowingMode, activityType);
804     }
805 
806     /** Resume next focusable stack after reparenting to another display. */
postReparent()807     void postReparent() {
808         adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
809                 true /* moveDisplayToTop */);
810         mRootWindowContainer.resumeFocusedStacksTopActivities();
811         // Update visibility of activities before notifying WM. This way it won't try to resize
812         // windows that are no longer visible.
813         mRootWindowContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
814                 !PRESERVE_WINDOWS);
815     }
816 
getDisplay()817     DisplayContent getDisplay() {
818         return getDisplayContent();
819     }
820 
821     /** @return true if the stack can only contain one task */
isSingleTaskInstance()822     boolean isSingleTaskInstance() {
823         final DisplayContent display = getDisplay();
824         return display != null && display.isSingleTaskInstance();
825     }
826 
isHomeOrRecentsStack()827     final boolean isHomeOrRecentsStack() {
828         return isActivityTypeHome() || isActivityTypeRecents();
829     }
830 
isOnHomeDisplay()831     final boolean isOnHomeDisplay() {
832         return getDisplayId() == DEFAULT_DISPLAY;
833     }
834 
moveToFront(String reason)835     void moveToFront(String reason) {
836         moveToFront(reason, null);
837     }
838 
839     /**
840      * @param reason The reason for moving the stack to the front.
841      * @param task If non-null, the task will be moved to the top of the stack.
842      * */
moveToFront(String reason, Task task)843     void moveToFront(String reason, Task task) {
844         if (!isAttached()) {
845             return;
846         }
847 
848         final TaskDisplayArea taskDisplayArea = getDisplayArea();
849 
850         if (inSplitScreenSecondaryWindowingMode()) {
851             // If the stack is in split-screen secondary mode, we need to make sure we move the
852             // primary split-screen stack forward in the case it is currently behind a fullscreen
853             // stack so both halves of the split-screen appear on-top and the fullscreen stack isn't
854             // cutting between them.
855             // TODO(b/70677280): This is a workaround until we can fix as part of b/70677280.
856             final ActivityStack topFullScreenStack =
857                     taskDisplayArea.getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
858             if (topFullScreenStack != null) {
859                 final ActivityStack primarySplitScreenStack =
860                         taskDisplayArea.getRootSplitScreenPrimaryTask();
861                 if (primarySplitScreenStack != null
862                         && taskDisplayArea.getIndexOf(topFullScreenStack)
863                             > taskDisplayArea.getIndexOf(primarySplitScreenStack)) {
864                     primarySplitScreenStack.moveToFront(reason + " splitScreenToTop");
865                 }
866             }
867         }
868 
869         if (!isActivityTypeHome() && returnsToHomeStack()) {
870             // Make sure the home stack is behind this stack since that is where we should return to
871             // when this stack is no longer visible.
872             taskDisplayArea.moveHomeStackToFront(reason + " returnToHome");
873         }
874 
875         if (isRootTask()) {
876             taskDisplayArea.positionStackAtTop(this, false /* includingParents */, reason);
877         }
878         if (task == null) {
879             task = this;
880         }
881         task.getParent().positionChildAt(POSITION_TOP, task, true /* includingParents */);
882     }
883 
884     /**
885      * This moves 'task' to the back of this task and also recursively moves this task to the back
886      * of its parents (if applicable).
887      *
888      * @param reason The reason for moving the stack to the back.
889      * @param task If non-null, the task will be moved to the bottom of the stack.
890      **/
moveToBack(String reason, Task task)891     void moveToBack(String reason, Task task) {
892         if (!isAttached()) {
893             return;
894         }
895         final TaskDisplayArea displayArea = getDisplayArea();
896         if (!mCreatedByOrganizer) {
897             // If this is just a normal task, so move to back of parent and then move 'task' to
898             // back of this.
899             final WindowContainer parent = getParent();
900             final Task parentTask = parent != null ? parent.asTask() : null;
901             if (parentTask != null) {
902                 ((ActivityStack) parentTask).moveToBack(reason, this);
903             } else {
904                 displayArea.positionStackAtBottom(this, reason);
905             }
906             if (task != null && task != this) {
907                 positionChildAtBottom(task);
908             }
909             return;
910         }
911         if (task == null || task == this) {
912             return;
913         }
914         // This is a created-by-organizer task. In this case, let the organizer deal with this
915         // task's ordering. However, we still need to move 'task' to back. The intention is that
916         // this ends up behind the home-task so that it is made invisible; so, if the home task
917         // is not a child of this, reparent 'task' to the back of the home task's actual parent.
918         displayArea.positionTaskBehindHome((ActivityStack) task);
919     }
920 
921     // TODO: Should each user have there own stacks?
922     @Override
switchUser(int userId)923     void switchUser(int userId) {
924         if (mCurrentUser == userId) {
925             return;
926         }
927         mCurrentUser = userId;
928 
929         super.switchUser(userId);
930         if (isLeafTask() && showToCurrentUser()) {
931             getParent().positionChildAt(POSITION_TOP, this, false /*includeParents*/);
932         }
933     }
934 
minimalResumeActivityLocked(ActivityRecord r)935     void minimalResumeActivityLocked(ActivityRecord r) {
936         if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
937                 + " callers=" + Debug.getCallers(5));
938         r.setState(RESUMED, "minimalResumeActivityLocked");
939         r.completeResumeLocked();
940     }
941 
clearLaunchTime(ActivityRecord r)942     private void clearLaunchTime(ActivityRecord r) {
943         // Make sure that there is no activity waiting for this to launch.
944         if (!mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
945             mStackSupervisor.removeIdleTimeoutForActivity(r);
946             mStackSupervisor.scheduleIdleTimeout(r);
947         }
948     }
949 
awakeFromSleepingLocked()950     void awakeFromSleepingLocked() {
951         // Ensure activities are no longer sleeping.
952         forAllActivities((Consumer<ActivityRecord>) (r) -> r.setSleeping(false));
953         if (mPausingActivity != null) {
954             Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
955             mPausingActivity.activityPaused(true);
956         }
957     }
958 
checkReadyForSleep()959     void checkReadyForSleep() {
960         if (shouldSleepActivities() && goToSleepIfPossible(false /* shuttingDown */)) {
961             mStackSupervisor.checkReadyForSleepLocked(true /* allowDelay */);
962         }
963     }
964 
965     /**
966      * Tries to put the activities in the stack to sleep.
967      *
968      * If the stack is not in a state where its activities can be put to sleep, this function will
969      * start any necessary actions to move the stack into such a state. It is expected that this
970      * function get called again when those actions complete.
971      *
972      * @param shuttingDown true when the called because the device is shutting down.
973      * @return true if the stack finished going to sleep, false if the stack only started the
974      * process of going to sleep (checkReadyForSleep will be called when that process finishes).
975      */
goToSleepIfPossible(boolean shuttingDown)976     boolean goToSleepIfPossible(boolean shuttingDown) {
977         boolean shouldSleep = true;
978 
979         if (mResumedActivity != null) {
980             // Still have something resumed; can't sleep until it is paused.
981             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
982             if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
983                     "Sleep => pause with userLeaving=false");
984 
985             startPausingLocked(false /* userLeaving */, true /* uiSleeping */, null /* resuming */);
986             shouldSleep = false ;
987         } else if (mPausingActivity != null) {
988             // Still waiting for something to pause; can't sleep yet.
989             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
990             shouldSleep = false;
991         }
992 
993         if (!shuttingDown) {
994             if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) {
995                 // Still need to tell some activities to stop; can't sleep yet.
996                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
997                         + mStackSupervisor.mStoppingActivities.size() + " activities");
998 
999                 mStackSupervisor.scheduleIdle();
1000                 shouldSleep = false;
1001             }
1002         }
1003 
1004         if (shouldSleep) {
1005             goToSleep();
1006         }
1007 
1008         return shouldSleep;
1009     }
1010 
goToSleep()1011     void goToSleep() {
1012         // Make sure all visible activities are now sleeping. This will update the activity's
1013         // visibility and onStop() will be called.
1014         forAllActivities((r) -> {
1015             if (r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED)) {
1016                 r.setSleeping(true);
1017             }
1018         });
1019 
1020         // Ensure visibility after updating sleep states without updating configuration,
1021         // as activities are about to be sent to sleep.
1022         ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
1023                 !PRESERVE_WINDOWS);
1024     }
1025 
containsActivityFromStack(List<ActivityRecord> rs)1026     private boolean containsActivityFromStack(List<ActivityRecord> rs) {
1027         for (ActivityRecord r : rs) {
1028             if (r.getRootTask() == this) {
1029                 return true;
1030             }
1031         }
1032         return false;
1033     }
1034 
1035     /**
1036      * Start pausing the currently resumed activity.  It is an error to call this if there
1037      * is already an activity being paused or there is no resumed activity.
1038      *
1039      * @param userLeaving True if this should result in an onUserLeaving to the current activity.
1040      * @param uiSleeping True if this is happening with the user interface going to sleep (the
1041      * screen turning off).
1042      * @param resuming The activity we are currently trying to resume or null if this is not being
1043      *                 called as part of resuming the top activity, so we shouldn't try to instigate
1044      *                 a resume here if not null.
1045      * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
1046      * it to tell us when it is done.
1047      */
startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming)1048     final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
1049             ActivityRecord resuming) {
1050         if (mPausingActivity != null) {
1051             Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
1052                     + " state=" + mPausingActivity.getState());
1053             if (!shouldSleepActivities()) {
1054                 // Avoid recursion among check for sleep and complete pause during sleeping.
1055                 // Because activity will be paused immediately after resume, just let pause
1056                 // be completed by the order of activity paused from clients.
1057                 completePauseLocked(false, resuming);
1058             }
1059         }
1060         ActivityRecord prev = mResumedActivity;
1061 
1062         if (prev == null) {
1063             if (resuming == null) {
1064                 Slog.wtf(TAG, "Trying to pause when nothing is resumed");
1065                 mRootWindowContainer.resumeFocusedStacksTopActivities();
1066             }
1067             return false;
1068         }
1069 
1070         if (prev == resuming) {
1071             Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
1072             return false;
1073         }
1074 
1075         if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
1076         else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
1077         mPausingActivity = prev;
1078         mLastPausedActivity = prev;
1079         mLastNoHistoryActivity = prev.isNoHistory() ? prev : null;
1080         prev.setState(PAUSING, "startPausingLocked");
1081         prev.getTask().touchActiveTime();
1082         clearLaunchTime(prev);
1083 
1084         mAtmService.updateCpuStats();
1085 
1086         boolean pauseImmediately = false;
1087         if (resuming != null && (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0) {
1088             // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous
1089             // activity to be paused, while at the same time resuming the new resume activity
1090             // only if the previous activity can't go into Pip since we want to give Pip
1091             // activities a chance to enter Pip before resuming the next activity.
1092             final boolean lastResumedCanPip = prev != null && prev.checkEnterPictureInPictureState(
1093                     "shouldResumeWhilePausing", userLeaving);
1094             if (!lastResumedCanPip) {
1095                 pauseImmediately = true;
1096             }
1097         }
1098 
1099         if (prev.attachedToProcess()) {
1100             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
1101             try {
1102                 EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
1103                         prev.shortComponentName, "userLeaving=" + userLeaving);
1104 
1105                 mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
1106                         prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
1107                                 prev.configChangeFlags, pauseImmediately));
1108             } catch (Exception e) {
1109                 // Ignore exception, if process died other code will cleanup.
1110                 Slog.w(TAG, "Exception thrown during pause", e);
1111                 mPausingActivity = null;
1112                 mLastPausedActivity = null;
1113                 mLastNoHistoryActivity = null;
1114             }
1115         } else {
1116             mPausingActivity = null;
1117             mLastPausedActivity = null;
1118             mLastNoHistoryActivity = null;
1119         }
1120 
1121         // If we are not going to sleep, we want to ensure the device is
1122         // awake until the next activity is started.
1123         if (!uiSleeping && !mAtmService.isSleepingOrShuttingDownLocked()) {
1124             mStackSupervisor.acquireLaunchWakelock();
1125         }
1126 
1127         if (mPausingActivity != null) {
1128             // Have the window manager pause its key dispatching until the new
1129             // activity has started.  If we're pausing the activity just because
1130             // the screen is being turned off and the UI is sleeping, don't interrupt
1131             // key dispatch; the same activity will pick it up again on wakeup.
1132             if (!uiSleeping) {
1133                 prev.pauseKeyDispatchingLocked();
1134             } else if (DEBUG_PAUSE) {
1135                  Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
1136             }
1137 
1138             if (pauseImmediately) {
1139                 // If the caller said they don't want to wait for the pause, then complete
1140                 // the pause now.
1141                 completePauseLocked(false, resuming);
1142                 return false;
1143 
1144             } else {
1145                 prev.schedulePauseTimeout();
1146                 return true;
1147             }
1148 
1149         } else {
1150             // This activity failed to schedule the
1151             // pause, so just treat it as being paused now.
1152             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
1153             if (resuming == null) {
1154                 mRootWindowContainer.resumeFocusedStacksTopActivities();
1155             }
1156             return false;
1157         }
1158     }
1159 
1160     @VisibleForTesting
completePauseLocked(boolean resumeNext, ActivityRecord resuming)1161     void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
1162         ActivityRecord prev = mPausingActivity;
1163         if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
1164 
1165         if (prev != null) {
1166             prev.setWillCloseOrEnterPip(false);
1167             final boolean wasStopping = prev.isState(STOPPING);
1168             prev.setState(PAUSED, "completePausedLocked");
1169             if (prev.finishing) {
1170                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
1171                 prev = prev.completeFinishing("completePausedLocked");
1172             } else if (prev.hasProcess()) {
1173                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
1174                         + " wasStopping=" + wasStopping
1175                         + " visibleRequested=" + prev.mVisibleRequested);
1176                 if (prev.deferRelaunchUntilPaused) {
1177                     // Complete the deferred relaunch that was waiting for pause to complete.
1178                     if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
1179                     prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
1180                 } else if (wasStopping) {
1181                     // We are also stopping, the stop request must have gone soon after the pause.
1182                     // We can't clobber it, because the stop confirmation will not be handled.
1183                     // We don't need to schedule another stop, we only need to let it happen.
1184                     prev.setState(STOPPING, "completePausedLocked");
1185                 } else if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) {
1186                     // Clear out any deferred client hide we might currently have.
1187                     prev.setDeferHidingClient(false);
1188                     // If we were visible then resumeTopActivities will release resources before
1189                     // stopping.
1190                     prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
1191                             "completePauseLocked");
1192                 }
1193             } else {
1194                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
1195                 prev = null;
1196             }
1197             // It is possible the activity was freezing the screen before it was paused.
1198             // In that case go ahead and remove the freeze this activity has on the screen
1199             // since it is no longer visible.
1200             if (prev != null) {
1201                 prev.stopFreezingScreenLocked(true /*force*/);
1202             }
1203             mPausingActivity = null;
1204         }
1205 
1206         if (resumeNext) {
1207             final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
1208             if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) {
1209                 mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
1210             } else {
1211                 checkReadyForSleep();
1212                 final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null;
1213                 if (top == null || (prev != null && top != prev)) {
1214                     // If there are no more activities available to run, do resume anyway to start
1215                     // something. Also if the top activity on the stack is not the just paused
1216                     // activity, we need to go ahead and resume it to ensure we complete an
1217                     // in-flight app switch.
1218                     mRootWindowContainer.resumeFocusedStacksTopActivities();
1219                 }
1220             }
1221         }
1222 
1223         if (prev != null) {
1224             prev.resumeKeyDispatchingLocked();
1225 
1226             if (prev.hasProcess() && prev.cpuTimeAtResume > 0) {
1227                 final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
1228                 if (diff > 0) {
1229                     final Runnable r = PooledLambda.obtainRunnable(
1230                             ActivityManagerInternal::updateForegroundTimeIfOnBattery,
1231                             mAtmService.mAmInternal, prev.info.packageName,
1232                             prev.info.applicationInfo.uid,
1233                             diff);
1234                     mAtmService.mH.post(r);
1235                 }
1236             }
1237             prev.cpuTimeAtResume = 0; // reset it
1238         }
1239 
1240         mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
1241 
1242         // Notify when the task stack has changed, but only if visibilities changed (not just
1243         // focus). Also if there is an active pinned stack - we always want to notify it about
1244         // task stack changes, because its positioning may depend on it.
1245         if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
1246                 || (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) {
1247             mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
1248             mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
1249         }
1250     }
1251 
isTopStackInDisplayArea()1252     boolean isTopStackInDisplayArea() {
1253         final TaskDisplayArea taskDisplayArea = getDisplayArea();
1254         return taskDisplayArea != null && taskDisplayArea.isTopStack(this);
1255     }
1256 
1257     /**
1258      * @return {@code true} if this is the focused stack on its current display, {@code false}
1259      * otherwise.
1260      */
isFocusedStackOnDisplay()1261     boolean isFocusedStackOnDisplay() {
1262         final DisplayContent display = getDisplay();
1263         return display != null && this == display.getFocusedStack();
1264     }
1265 
1266     /**
1267      * Make sure that all activities that need to be visible in the stack (that is, they
1268      * currently can be seen by the user) actually are and update their configuration.
1269      * @param starting The top most activity in the task.
1270      *                 The activity is either starting or resuming.
1271      *                 Caller should ensure starting activity is visible.
1272      * @param preserveWindows Flag indicating whether windows should be preserved when updating
1273      *                        configuration in {@link mEnsureActivitiesVisibleHelper}.
1274      * @param configChanges Parts of the configuration that changed for this activity for evaluating
1275      *                      if the screen should be frozen as part of
1276      *                      {@link mEnsureActivitiesVisibleHelper}.
1277      *
1278      */
ensureActivitiesVisible(@ullable ActivityRecord starting, int configChanges, boolean preserveWindows)1279     void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
1280             boolean preserveWindows) {
1281         ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
1282     }
1283 
1284     /**
1285      * Ensure visibility with an option to also update the configuration of visible activities.
1286      * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
1287      * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
1288      * @param starting The top most activity in the task.
1289      *                 The activity is either starting or resuming.
1290      *                 Caller should ensure starting activity is visible.
1291      * @param notifyClients Flag indicating whether the visibility updates should be sent to the
1292      *                      clients in {@link mEnsureActivitiesVisibleHelper}.
1293      * @param preserveWindows Flag indicating whether windows should be preserved when updating
1294      *                        configuration in {@link mEnsureActivitiesVisibleHelper}.
1295      * @param configChanges Parts of the configuration that changed for this activity for evaluating
1296      *                      if the screen should be frozen as part of
1297      *                      {@link mEnsureActivitiesVisibleHelper}.
1298      */
1299     // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
ensureActivitiesVisible(@ullable ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients)1300     void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
1301             boolean preserveWindows, boolean notifyClients) {
1302         mTopActivityOccludesKeyguard = false;
1303         mTopDismissingKeyguardActivity = null;
1304         mStackSupervisor.beginActivityVisibilityUpdate();
1305         try {
1306             mEnsureActivitiesVisibleHelper.process(
1307                     starting, configChanges, preserveWindows, notifyClients);
1308 
1309             if (mTranslucentActivityWaiting != null &&
1310                     mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
1311                 // Nothing is getting drawn or everything was already visible, don't wait for timeout.
1312                 notifyActivityDrawnLocked(null);
1313             }
1314         } finally {
1315             mStackSupervisor.endActivityVisibilityUpdate();
1316         }
1317     }
1318 
1319     /**
1320      * @return true if the top visible activity wants to occlude the Keyguard, false otherwise
1321      */
topActivityOccludesKeyguard()1322     boolean topActivityOccludesKeyguard() {
1323         return mTopActivityOccludesKeyguard;
1324     }
1325 
1326     /**
1327      * Returns true if this stack should be resized to match the bounds specified by
1328      * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack.
1329      */
shouldResizeStackWithLaunchBounds()1330     boolean shouldResizeStackWithLaunchBounds() {
1331         return inPinnedWindowingMode();
1332     }
1333 
1334     // TODO(NOW!)
1335     /**
1336      * Returns {@code true} if this is the top-most split-screen-primary or
1337      * split-screen-secondary stack, {@code false} otherwise.
1338      */
isTopSplitScreenStack()1339     boolean isTopSplitScreenStack() {
1340         return inSplitScreenWindowingMode()
1341                 && this == getDisplayArea().getTopStackInWindowingMode(getWindowingMode());
1342     }
1343 
1344     /**
1345      * @return the top most visible activity that wants to dismiss Keyguard
1346      */
getTopDismissingKeyguardActivity()1347     ActivityRecord getTopDismissingKeyguardActivity() {
1348         return mTopDismissingKeyguardActivity;
1349     }
1350 
1351     /**
1352      * Checks whether {@param r} should be visible depending on Keyguard state and updates
1353      * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if
1354      * necessary.
1355      *
1356      * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
1357      */
checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop)1358     boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) {
1359         int displayId = getDisplayId();
1360         if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
1361 
1362         final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController()
1363                 .isKeyguardOrAodShowing(displayId);
1364         final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked();
1365         final boolean showWhenLocked = r.canShowWhenLocked();
1366         final boolean dismissKeyguard = r.containsDismissKeyguardWindow();
1367         if (shouldBeVisible) {
1368             if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
1369                 mTopDismissingKeyguardActivity = r;
1370             }
1371 
1372             // Only the top activity may control occluded, as we can't occlude the Keyguard if the
1373             // top app doesn't want to occlude it.
1374             if (isTop) {
1375                 mTopActivityOccludesKeyguard |= showWhenLocked;
1376             }
1377 
1378             final boolean canShowWithKeyguard = canShowWithInsecureKeyguard()
1379                     && mStackSupervisor.getKeyguardController().canDismissKeyguard();
1380             if (canShowWithKeyguard) {
1381                 return true;
1382             }
1383         }
1384         if (keyguardOrAodShowing) {
1385             // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
1386             // right away and AOD isn't visible.
1387             return shouldBeVisible && mStackSupervisor.getKeyguardController()
1388                     .canShowActivityWhileKeyguardShowing(r, dismissKeyguard);
1389         } else if (keyguardLocked) {
1390             return shouldBeVisible && mStackSupervisor.getKeyguardController().canShowWhileOccluded(
1391                     dismissKeyguard, showWhenLocked);
1392         } else {
1393             return shouldBeVisible;
1394         }
1395     }
1396 
1397     /**
1398      * Check if the display to which this stack is attached has
1399      * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
1400      */
canShowWithInsecureKeyguard()1401     boolean canShowWithInsecureKeyguard() {
1402         final DisplayContent displayContent = getDisplay();
1403         if (displayContent == null) {
1404             throw new IllegalStateException("Stack is not attached to any display, stackId="
1405                     + getRootTaskId());
1406         }
1407 
1408         final int flags = displayContent.mDisplay.getFlags();
1409         return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
1410     }
1411 
checkTranslucentActivityWaiting(ActivityRecord top)1412     void checkTranslucentActivityWaiting(ActivityRecord top) {
1413         if (mTranslucentActivityWaiting != top) {
1414             mUndrawnActivitiesBelowTopTranslucent.clear();
1415             if (mTranslucentActivityWaiting != null) {
1416                 // Call the callback with a timeout indication.
1417                 notifyActivityDrawnLocked(null);
1418                 mTranslucentActivityWaiting = null;
1419             }
1420             mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1421         }
1422     }
1423 
convertActivityToTranslucent(ActivityRecord r)1424     void convertActivityToTranslucent(ActivityRecord r) {
1425         mTranslucentActivityWaiting = r;
1426         mUndrawnActivitiesBelowTopTranslucent.clear();
1427         mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
1428     }
1429 
1430     /**
1431      * Called as activities below the top translucent activity are redrawn. When the last one is
1432      * redrawn notify the top activity by calling
1433      * {@link Activity#onTranslucentConversionComplete}.
1434      *
1435      * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
1436      * occurred and the activity will be notified immediately.
1437      */
notifyActivityDrawnLocked(ActivityRecord r)1438     void notifyActivityDrawnLocked(ActivityRecord r) {
1439         if ((r == null)
1440                 || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
1441                         mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
1442             // The last undrawn activity below the top has just been drawn. If there is an
1443             // opaque activity at the top, notify it that it can become translucent safely now.
1444             final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
1445             mTranslucentActivityWaiting = null;
1446             mUndrawnActivitiesBelowTopTranslucent.clear();
1447             mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
1448 
1449             if (waitingActivity != null) {
1450                 mWmService.setWindowOpaqueLocked(waitingActivity.appToken, false);
1451                 if (waitingActivity.attachedToProcess()) {
1452                     try {
1453                         waitingActivity.app.getThread().scheduleTranslucentConversionComplete(
1454                                 waitingActivity.appToken, r != null);
1455                     } catch (RemoteException e) {
1456                     }
1457                 }
1458             }
1459         }
1460     }
1461 
1462     /** @see ActivityRecord#cancelInitializing() */
cancelInitializingActivities()1463     void cancelInitializingActivities() {
1464         // We don't want to clear starting window for activities that aren't behind fullscreen
1465         // activities as we need to display their starting window until they are done initializing.
1466         checkBehindFullscreenActivity(null /* toCheck */, ActivityRecord::cancelInitializing);
1467     }
1468 
1469     /**
1470      * If an activity {@param toCheck} is given, this method returns {@code true} if the activity
1471      * is occluded by any fullscreen activity. If there is no {@param toCheck} and the handling
1472      * function {@param handleBehindFullscreenActivity} is given, this method will pass all occluded
1473      * activities to the function.
1474      */
checkBehindFullscreenActivity(ActivityRecord toCheck, Consumer<ActivityRecord> handleBehindFullscreenActivity)1475     boolean checkBehindFullscreenActivity(ActivityRecord toCheck,
1476             Consumer<ActivityRecord> handleBehindFullscreenActivity) {
1477         return mCheckBehindFullscreenActivityHelper.process(
1478                 toCheck, handleBehindFullscreenActivity);
1479     }
1480 
1481     /**
1482      * Ensure that the top activity in the stack is resumed.
1483      *
1484      * @param prev The previously resumed activity, for when in the process
1485      * of pausing; can be null to call from elsewhere.
1486      * @param options Activity options.
1487      *
1488      * @return Returns true if something is being resumed, or false if
1489      * nothing happened.
1490      *
1491      * NOTE: It is not safe to call this method directly as it can cause an activity in a
1492      *       non-focused stack to be resumed.
1493      *       Use {@link RootWindowContainer#resumeFocusedStacksTopActivities} to resume the
1494      *       right activity for the current system state.
1495      */
1496     @GuardedBy("mService")
resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options)1497     boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
1498         if (mInResumeTopActivity) {
1499             // Don't even start recursing.
1500             return false;
1501         }
1502 
1503         boolean result = false;
1504         try {
1505             // Protect against recursion.
1506             mInResumeTopActivity = true;
1507             result = resumeTopActivityInnerLocked(prev, options);
1508 
1509             // When resuming the top activity, it may be necessary to pause the top activity (for
1510             // example, returning to the lock screen. We suppress the normal pause logic in
1511             // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
1512             // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
1513             // to ensure any necessary pause logic occurs. In the case where the Activity will be
1514             // shown regardless of the lock screen, the call to
1515             // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
1516             final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
1517             if (next == null || !next.canTurnScreenOn()) {
1518                 checkReadyForSleep();
1519             }
1520         } finally {
1521             mInResumeTopActivity = false;
1522         }
1523 
1524         return result;
1525     }
1526 
1527     @GuardedBy("mService")
resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options)1528     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
1529         if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
1530             // Not ready yet!
1531             return false;
1532         }
1533 
1534         // Find the next top-most activity to resume in this stack that is not finishing and is
1535         // focusable. If it is not focusable, we will fall into the case below to resume the
1536         // top activity in the next focusable task.
1537         ActivityRecord next = topRunningActivity(true /* focusableOnly */);
1538 
1539         final boolean hasRunningActivity = next != null;
1540 
1541         // TODO: Maybe this entire condition can get removed?
1542         if (hasRunningActivity && !isAttached()) {
1543             return false;
1544         }
1545 
1546         mRootWindowContainer.cancelInitializingActivities();
1547 
1548         // Remember how we'll process this pause/resume situation, and ensure
1549         // that the state is reset however we wind up proceeding.
1550         boolean userLeaving = mStackSupervisor.mUserLeaving;
1551         mStackSupervisor.mUserLeaving = false;
1552 
1553         if (!hasRunningActivity) {
1554             // There are no activities left in the stack, let's look somewhere else.
1555             return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
1556         }
1557 
1558         next.delayedResume = false;
1559         final TaskDisplayArea taskDisplayArea = getDisplayArea();
1560 
1561         // If the top activity is the resumed one, nothing to do.
1562         if (mResumedActivity == next && next.isState(RESUMED)
1563                 && taskDisplayArea.allResumedActivitiesComplete()) {
1564             // Make sure we have executed any pending transitions, since there
1565             // should be nothing left to do at this point.
1566             executeAppTransition(options);
1567             if (DEBUG_STATES) Slog.d(TAG_STATES,
1568                     "resumeTopActivityLocked: Top activity resumed " + next);
1569             return false;
1570         }
1571 
1572         if (!next.canResumeByCompat()) {
1573             return false;
1574         }
1575 
1576         // If we are currently pausing an activity, then don't do anything until that is done.
1577         final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
1578         if (!allPausedComplete) {
1579             if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) {
1580                 Slog.v(TAG_PAUSE, "resumeTopActivityLocked: Skip resume: some activity pausing.");
1581             }
1582             return false;
1583         }
1584 
1585         // If we are sleeping, and there is no resumed activity, and the top activity is paused,
1586         // well that is the state we want.
1587         if (shouldSleepOrShutDownActivities()
1588                 && mLastPausedActivity == next
1589                 && mRootWindowContainer.allPausedActivitiesComplete()) {
1590             // If the current top activity may be able to occlude keyguard but the occluded state
1591             // has not been set, update visibility and check again if we should continue to resume.
1592             boolean nothingToResume = true;
1593             if (!mAtmService.mShuttingDown) {
1594                 final boolean canShowWhenLocked = !mTopActivityOccludesKeyguard
1595                         && next.canShowWhenLocked();
1596                 final boolean mayDismissKeyguard = mTopDismissingKeyguardActivity != next
1597                         && next.containsDismissKeyguardWindow();
1598 
1599                 if (canShowWhenLocked || mayDismissKeyguard) {
1600                     ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
1601                             !PRESERVE_WINDOWS);
1602                     nothingToResume = shouldSleepActivities();
1603                 } else if (next.currentLaunchCanTurnScreenOn() && next.canTurnScreenOn()) {
1604                     nothingToResume = false;
1605                 }
1606             }
1607             if (nothingToResume) {
1608                 // Make sure we have executed any pending transitions, since there
1609                 // should be nothing left to do at this point.
1610                 executeAppTransition(options);
1611                 if (DEBUG_STATES) Slog.d(TAG_STATES,
1612                         "resumeTopActivityLocked: Going to sleep and all paused");
1613                 return false;
1614             }
1615         }
1616 
1617         // Make sure that the user who owns this activity is started.  If not,
1618         // we will just leave it as is because someone should be bringing
1619         // another user's activities to the top of the stack.
1620         if (!mAtmService.mAmInternal.hasStartedUserState(next.mUserId)) {
1621             Slog.w(TAG, "Skipping resume of top activity " + next
1622                     + ": user " + next.mUserId + " is stopped");
1623             return false;
1624         }
1625 
1626         // The activity may be waiting for stop, but that is no longer
1627         // appropriate for it.
1628         mStackSupervisor.mStoppingActivities.remove(next);
1629         next.setSleeping(false);
1630 
1631         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
1632 
1633         // If we are currently pausing an activity, then don't do anything until that is done.
1634         if (!mRootWindowContainer.allPausedActivitiesComplete()) {
1635             if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
1636                     "resumeTopActivityLocked: Skip resume: some activity pausing.");
1637 
1638             return false;
1639         }
1640 
1641         mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
1642 
1643         ActivityRecord lastResumed = null;
1644         final ActivityStack lastFocusedStack = taskDisplayArea.getLastFocusedStack();
1645         if (lastFocusedStack != null && lastFocusedStack != this) {
1646             // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
1647             // represent the last resumed activity. However, the last focus stack does if it isn't null.
1648             lastResumed = lastFocusedStack.mResumedActivity;
1649             if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
1650                 // The user isn't leaving if this stack is the multi-window mode and the last
1651                 // focused stack should still be visible.
1652                 if(DEBUG_USER_LEAVING) Slog.i(TAG_USER_LEAVING, "Overriding userLeaving to false"
1653                         + " next=" + next + " lastResumed=" + lastResumed);
1654                 userLeaving = false;
1655             }
1656         }
1657 
1658         boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
1659         if (mResumedActivity != null) {
1660             if (DEBUG_STATES) Slog.d(TAG_STATES,
1661                     "resumeTopActivityLocked: Pausing " + mResumedActivity);
1662             pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
1663         }
1664         if (pausing) {
1665             if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
1666                     "resumeTopActivityLocked: Skip resume: need to start pausing");
1667             // At this point we want to put the upcoming activity's process
1668             // at the top of the LRU list, since we know we will be needing it
1669             // very soon and it would be a waste to let it get killed if it
1670             // happens to be sitting towards the end.
1671             if (next.attachedToProcess()) {
1672                 next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
1673                         true /* activityChange */, false /* updateOomAdj */,
1674                         false /* addPendingTopUid */);
1675             } else if (!next.isProcessRunning()) {
1676                 // Since the start-process is asynchronous, if we already know the process of next
1677                 // activity isn't running, we can start the process earlier to save the time to wait
1678                 // for the current activity to be paused.
1679                 final boolean isTop = this == taskDisplayArea.getFocusedStack();
1680                 mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
1681                         isTop ? "pre-top-activity" : "pre-activity");
1682             }
1683             if (lastResumed != null) {
1684                 lastResumed.setWillCloseOrEnterPip(true);
1685             }
1686             return true;
1687         } else if (mResumedActivity == next && next.isState(RESUMED)
1688                 && taskDisplayArea.allResumedActivitiesComplete()) {
1689             // It is possible for the activity to be resumed when we paused back stacks above if the
1690             // next activity doesn't have to wait for pause to complete.
1691             // So, nothing else to-do except:
1692             // Make sure we have executed any pending transitions, since there
1693             // should be nothing left to do at this point.
1694             executeAppTransition(options);
1695             if (DEBUG_STATES) Slog.d(TAG_STATES,
1696                     "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
1697             return true;
1698         }
1699 
1700         // If the most recent activity was noHistory but was only stopped rather
1701         // than stopped+finished because the device went to sleep, we need to make
1702         // sure to finish it as we're making a new activity topmost.
1703         if (shouldSleepActivities() && mLastNoHistoryActivity != null
1704                 && !mLastNoHistoryActivity.finishing
1705                 && mLastNoHistoryActivity != next) {
1706             if (DEBUG_STATES) Slog.d(TAG_STATES,
1707                     "no-history finish of " + mLastNoHistoryActivity + " on new resume");
1708             mLastNoHistoryActivity.finishIfPossible("resume-no-history", false /* oomAdj */);
1709             mLastNoHistoryActivity = null;
1710         }
1711 
1712         if (prev != null && prev != next && next.nowVisible) {
1713 
1714             // The next activity is already visible, so hide the previous
1715             // activity's windows right now so we can show the new one ASAP.
1716             // We only do this if the previous is finishing, which should mean
1717             // it is on top of the one being resumed so hiding it quickly
1718             // is good.  Otherwise, we want to do the normal route of allowing
1719             // the resumed activity to be shown so we can decide if the
1720             // previous should actually be hidden depending on whether the
1721             // new one is found to be full-screen or not.
1722             if (prev.finishing) {
1723                 prev.setVisibility(false);
1724                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1725                         "Not waiting for visible to hide: " + prev
1726                         + ", nowVisible=" + next.nowVisible);
1727             } else {
1728                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
1729                         "Previous already visible but still waiting to hide: " + prev
1730                         + ", nowVisible=" + next.nowVisible);
1731             }
1732 
1733         }
1734 
1735         // Launching this app's activity, make sure the app is no longer
1736         // considered stopped.
1737         try {
1738             mAtmService.getPackageManager().setPackageStoppedState(
1739                     next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
1740         } catch (RemoteException e1) {
1741         } catch (IllegalArgumentException e) {
1742             Slog.w(TAG, "Failed trying to unstop package "
1743                     + next.packageName + ": " + e);
1744         }
1745 
1746         // We are starting up the next activity, so tell the window manager
1747         // that the previous one will be hidden soon.  This way it can know
1748         // to ignore it when computing the desired screen orientation.
1749         boolean anim = true;
1750         final DisplayContent dc = taskDisplayArea.mDisplayContent;
1751         if (prev != null) {
1752             if (prev.finishing) {
1753                 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
1754                         "Prepare close transition: prev=" + prev);
1755                 if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
1756                     anim = false;
1757                     dc.prepareAppTransition(TRANSIT_NONE, false);
1758                 } else {
1759                     dc.prepareAppTransition(
1760                             prev.getTask() == next.getTask() ? TRANSIT_ACTIVITY_CLOSE
1761                                     : TRANSIT_TASK_CLOSE, false);
1762                 }
1763                 prev.setVisibility(false);
1764             } else {
1765                 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
1766                         "Prepare open transition: prev=" + prev);
1767                 if (mStackSupervisor.mNoAnimActivities.contains(next)) {
1768                     anim = false;
1769                     dc.prepareAppTransition(TRANSIT_NONE, false);
1770                 } else {
1771                     dc.prepareAppTransition(
1772                             prev.getTask() == next.getTask() ? TRANSIT_ACTIVITY_OPEN
1773                                     : next.mLaunchTaskBehind ? TRANSIT_TASK_OPEN_BEHIND
1774                                             : TRANSIT_TASK_OPEN, false);
1775                 }
1776             }
1777         } else {
1778             if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
1779             if (mStackSupervisor.mNoAnimActivities.contains(next)) {
1780                 anim = false;
1781                 dc.prepareAppTransition(TRANSIT_NONE, false);
1782             } else {
1783                 dc.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
1784             }
1785         }
1786 
1787         if (anim) {
1788             next.applyOptionsLocked();
1789         } else {
1790             next.clearOptionsLocked();
1791         }
1792 
1793         mStackSupervisor.mNoAnimActivities.clear();
1794 
1795         if (next.attachedToProcess()) {
1796             if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
1797                     + " stopped=" + next.stopped
1798                     + " visibleRequested=" + next.mVisibleRequested);
1799 
1800             // If the previous activity is translucent, force a visibility update of
1801             // the next activity, so that it's added to WM's opening app list, and
1802             // transition animation can be set up properly.
1803             // For example, pressing Home button with a translucent activity in focus.
1804             // Launcher is already visible in this case. If we don't add it to opening
1805             // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
1806             // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
1807             final boolean lastActivityTranslucent = lastFocusedStack != null
1808                     && (lastFocusedStack.inMultiWindowMode()
1809                     || (lastFocusedStack.mLastPausedActivity != null
1810                     && !lastFocusedStack.mLastPausedActivity.occludesParent()));
1811 
1812             // This activity is now becoming visible.
1813             if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) {
1814                 next.setVisibility(true);
1815             }
1816 
1817             // schedule launch ticks to collect information about slow apps.
1818             next.startLaunchTickingLocked();
1819 
1820             ActivityRecord lastResumedActivity =
1821                     lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity;
1822             final ActivityState lastState = next.getState();
1823 
1824             mAtmService.updateCpuStats();
1825 
1826             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
1827                     + " (in existing)");
1828 
1829             next.setState(RESUMED, "resumeTopActivityInnerLocked");
1830 
1831             next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
1832                     true /* activityChange */, true /* updateOomAdj */,
1833                     true /* addPendingTopUid */);
1834 
1835             // Have the window manager re-evaluate the orientation of
1836             // the screen based on the new activity order.
1837             boolean notUpdated = true;
1838 
1839             // Activity should also be visible if set mLaunchTaskBehind to true (see
1840             // ActivityRecord#shouldBeVisibleIgnoringKeyguard()).
1841             if (shouldBeVisible(next)) {
1842                 // We have special rotation behavior when here is some active activity that
1843                 // requests specific orientation or Keyguard is locked. Make sure all activity
1844                 // visibilities are set correctly as well as the transition is updated if needed
1845                 // to get the correct rotation behavior. Otherwise the following call to update
1846                 // the orientation may cause incorrect configurations delivered to client as a
1847                 // result of invisible window resize.
1848                 // TODO: Remove this once visibilities are set correctly immediately when
1849                 // starting an activity.
1850                 notUpdated = !mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(),
1851                         true /* markFrozenIfConfigChanged */, false /* deferResume */);
1852             }
1853 
1854             if (notUpdated) {
1855                 // The configuration update wasn't able to keep the existing
1856                 // instance of the activity, and instead started a new one.
1857                 // We should be all done, but let's just make sure our activity
1858                 // is still at the top and schedule another run if something
1859                 // weird happened.
1860                 ActivityRecord nextNext = topRunningActivity();
1861                 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
1862                         "Activity config changed during resume: " + next
1863                                 + ", new next: " + nextNext);
1864                 if (nextNext != next) {
1865                     // Do over!
1866                     mStackSupervisor.scheduleResumeTopActivities();
1867                 }
1868                 if (!next.mVisibleRequested || next.stopped) {
1869                     next.setVisibility(true);
1870                 }
1871                 next.completeResumeLocked();
1872                 return true;
1873             }
1874 
1875             try {
1876                 final ClientTransaction transaction =
1877                         ClientTransaction.obtain(next.app.getThread(), next.appToken);
1878                 // Deliver all pending results.
1879                 ArrayList<ResultInfo> a = next.results;
1880                 if (a != null) {
1881                     final int N = a.size();
1882                     if (!next.finishing && N > 0) {
1883                         if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
1884                                 "Delivering results to " + next + ": " + a);
1885                         transaction.addCallback(ActivityResultItem.obtain(a));
1886                     }
1887                 }
1888 
1889                 if (next.newIntents != null) {
1890                     transaction.addCallback(
1891                             NewIntentItem.obtain(next.newIntents, true /* resume */));
1892                 }
1893 
1894                 // Well the app will no longer be stopped.
1895                 // Clear app token stopped state in window manager if needed.
1896                 next.notifyAppResumed(next.stopped);
1897 
1898                 EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
1899                         next.getTask().mTaskId, next.shortComponentName);
1900 
1901                 next.setSleeping(false);
1902                 mAtmService.getAppWarningsLocked().onResumeActivity(next);
1903                 next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState);
1904                 next.clearOptionsLocked();
1905                 transaction.setLifecycleStateRequest(
1906                         ResumeActivityItem.obtain(next.app.getReportedProcState(),
1907                                 dc.isNextTransitionForward()));
1908                 mAtmService.getLifecycleManager().scheduleTransaction(transaction);
1909 
1910                 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
1911                         + next);
1912             } catch (Exception e) {
1913                 // Whoops, need to restart this activity!
1914                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
1915                         + lastState + ": " + next);
1916                 next.setState(lastState, "resumeTopActivityInnerLocked");
1917 
1918                 // lastResumedActivity being non-null implies there is a lastStack present.
1919                 if (lastResumedActivity != null) {
1920                     lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
1921                 }
1922 
1923                 Slog.i(TAG, "Restarting because process died: " + next);
1924                 if (!next.hasBeenLaunched) {
1925                     next.hasBeenLaunched = true;
1926                 } else  if (SHOW_APP_STARTING_PREVIEW && lastFocusedStack != null
1927                         && lastFocusedStack.isTopStackInDisplayArea()) {
1928                     next.showStartingWindow(null /* prev */, false /* newTask */,
1929                             false /* taskSwitch */);
1930                 }
1931                 mStackSupervisor.startSpecificActivity(next, true, false);
1932                 return true;
1933             }
1934 
1935             // From this point on, if something goes wrong there is no way
1936             // to recover the activity.
1937             try {
1938                 next.completeResumeLocked();
1939             } catch (Exception e) {
1940                 // If any exception gets thrown, toss away this
1941                 // activity and try the next one.
1942                 Slog.w(TAG, "Exception thrown during resume of " + next, e);
1943                 next.finishIfPossible("resume-exception", true /* oomAdj */);
1944                 return true;
1945             }
1946         } else {
1947             // Whoops, need to restart this activity!
1948             if (!next.hasBeenLaunched) {
1949                 next.hasBeenLaunched = true;
1950             } else {
1951                 if (SHOW_APP_STARTING_PREVIEW) {
1952                     next.showStartingWindow(null /* prev */, false /* newTask */,
1953                             false /* taskSwich */);
1954                 }
1955                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
1956             }
1957             if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
1958             mStackSupervisor.startSpecificActivity(next, true, true);
1959         }
1960 
1961         return true;
1962     }
1963 
1964     /**
1965      * Resume the next eligible activity in a focusable stack when this one does not have any
1966      * running activities left. The focus will be adjusted to the next focusable stack and
1967      * top running activities will be resumed in all focusable stacks. However, if the current stack
1968      * is a home stack - we have to keep it focused, start and resume a home activity on the current
1969      * display instead to make sure that the display is not empty.
1970      */
resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev, ActivityOptions options)1971     private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
1972             ActivityOptions options) {
1973         final String reason = "noMoreActivities";
1974 
1975         if (!isActivityTypeHome()) {
1976             final ActivityStack nextFocusedStack = adjustFocusToNextFocusableTask(reason);
1977             if (nextFocusedStack != null) {
1978                 // Try to move focus to the next visible stack with a running activity if this
1979                 // stack is not covering the entire screen or is on a secondary display with no home
1980                 // stack.
1981                 return mRootWindowContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
1982                         prev, null /* targetOptions */);
1983             }
1984         }
1985 
1986         // If the current stack is a home stack, or if focus didn't switch to a different stack -
1987         // just start up the Launcher...
1988         ActivityOptions.abort(options);
1989         if (DEBUG_STATES) Slog.d(TAG_STATES,
1990                 "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
1991         return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea());
1992     }
1993 
startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity, boolean newTask, boolean keepCurTransition, ActivityOptions options)1994     void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity,
1995             boolean newTask, boolean keepCurTransition, ActivityOptions options) {
1996         Task rTask = r.getTask();
1997         final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
1998         final boolean isOrhasTask = rTask == this || hasChild(rTask);
1999         // mLaunchTaskBehind tasks get placed at the back of the task stack.
2000         if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {
2001             // Last activity in task had been removed or ActivityManagerService is reusing task.
2002             // Insert or replace.
2003             // Might not even be in.
2004             positionChildAtTop(rTask);
2005         }
2006         Task task = null;
2007         if (!newTask && isOrhasTask) {
2008             // Starting activity cannot be occluding activity, otherwise starting window could be
2009             // remove immediately without transferring to starting activity.
2010             final ActivityRecord occludingActivity = getOccludingActivityAbove(r);
2011             if (occludingActivity != null) {
2012                 // Here it is!  Now, if this is not yet visible (occluded by another task) to the
2013                 // user, then just add it without starting; it will get started when the user
2014                 // navigates back to it.
2015                 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " + task,
2016                         new RuntimeException("here").fillInStackTrace());
2017                 rTask.positionChildAtTop(r);
2018                 ActivityOptions.abort(options);
2019                 return;
2020             }
2021         }
2022 
2023         // Place a new activity at top of stack, so it is next to interact with the user.
2024 
2025         // If we are not placing the new activity frontmost, we do not want to deliver the
2026         // onUserLeaving callback to the actual frontmost activity
2027         final Task activityTask = r.getTask();
2028         if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) {
2029             mStackSupervisor.mUserLeaving = false;
2030             if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
2031                     "startActivity() behind front, mUserLeaving=false");
2032         }
2033 
2034         task = activityTask;
2035 
2036         // Slot the activity into the history stack and proceed
2037         if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
2038                 new RuntimeException("here").fillInStackTrace());
2039         task.positionChildAtTop(r);
2040 
2041         // The transition animation and starting window are not needed if {@code allowMoveToFront}
2042         // is false, because the activity won't be visible.
2043         if ((!isHomeOrRecentsStack() || hasActivity()) && allowMoveToFront) {
2044             final DisplayContent dc = getDisplay().mDisplayContent;
2045             if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2046                     "Prepare open transition: starting " + r);
2047             if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2048                 dc.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
2049                 mStackSupervisor.mNoAnimActivities.add(r);
2050             } else {
2051                 int transit = TRANSIT_ACTIVITY_OPEN;
2052                 if (newTask) {
2053                     if (r.mLaunchTaskBehind) {
2054                         transit = TRANSIT_TASK_OPEN_BEHIND;
2055                     } else if (getDisplay().isSingleTaskInstance()) {
2056                         // If a new task is being launched in a single task display, we don't need
2057                         // to play normal animation, but need to trigger a callback when an app
2058                         // transition is actually handled. So ignore already prepared activity, and
2059                         // override it.
2060                         transit = TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
2061                         keepCurTransition = false;
2062                     } else {
2063                         // If a new task is being launched, then mark the existing top activity as
2064                         // supporting picture-in-picture while pausing only if the starting activity
2065                         // would not be considered an overlay on top of the current activity
2066                         // (eg. not fullscreen, or the assistant)
2067                         if (canEnterPipOnTaskSwitch(focusedTopActivity,
2068                                 null /* toFrontTask */, r, options)) {
2069                             focusedTopActivity.supportsEnterPipOnTaskSwitch = true;
2070                         }
2071                         transit = TRANSIT_TASK_OPEN;
2072                     }
2073                 }
2074                 dc.prepareAppTransition(transit, keepCurTransition);
2075                 mStackSupervisor.mNoAnimActivities.remove(r);
2076             }
2077             boolean doShow = true;
2078             if (newTask) {
2079                 // Even though this activity is starting fresh, we still need
2080                 // to reset it to make sure we apply affinities to move any
2081                 // existing activities from other tasks in to it.
2082                 // If the caller has requested that the target task be
2083                 // reset, then do so.
2084                 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2085                     resetTaskIfNeeded(r, r);
2086                     doShow = topRunningNonDelayedActivityLocked(null) == r;
2087                 }
2088             } else if (options != null && options.getAnimationType()
2089                     == ActivityOptions.ANIM_SCENE_TRANSITION) {
2090                 doShow = false;
2091             }
2092             if (r.mLaunchTaskBehind) {
2093                 // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
2094                 // tell WindowManager that r is visible even though it is at the back of the stack.
2095                 r.setVisibility(true);
2096                 ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2097                 // Go ahead to execute app transition for this activity since the app transition
2098                 // will not be triggered through the resume channel.
2099                 getDisplay().mDisplayContent.executeAppTransition();
2100             } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
2101                 // Figure out if we are transitioning from another activity that is
2102                 // "has the same starting icon" as the next one.  This allows the
2103                 // window manager to keep the previous window it had previously
2104                 // created, if it still had one.
2105                 Task prevTask = r.getTask();
2106                 ActivityRecord prev = prevTask.topActivityWithStartingWindow();
2107                 if (prev != null) {
2108                     // We don't want to reuse the previous starting preview if:
2109                     // (1) The current activity is in a different task.
2110                     if (prev.getTask() != prevTask) {
2111                         prev = null;
2112                     }
2113                     // (2) The current activity is already displayed.
2114                     else if (prev.nowVisible) {
2115                         prev = null;
2116                     }
2117                 }
2118                 r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
2119             }
2120         } else {
2121             // If this is the first activity, don't do any fancy animations,
2122             // because there is nothing for it to animate on top of.
2123             ActivityOptions.abort(options);
2124         }
2125     }
2126 
2127     /**
2128      * @return Whether the switch to another task can trigger the currently running activity to
2129      * enter PiP while it is pausing (if supported). Only one of {@param toFrontTask} or
2130      * {@param toFrontActivity} should be set.
2131      */
canEnterPipOnTaskSwitch(ActivityRecord pipCandidate, Task toFrontTask, ActivityRecord toFrontActivity, ActivityOptions opts)2132     private boolean canEnterPipOnTaskSwitch(ActivityRecord pipCandidate,
2133             Task toFrontTask, ActivityRecord toFrontActivity, ActivityOptions opts) {
2134         if (opts != null && opts.disallowEnterPictureInPictureWhileLaunching()) {
2135             // Ensure the caller has requested not to trigger auto-enter PiP
2136             return false;
2137         }
2138         if (pipCandidate == null || pipCandidate.inPinnedWindowingMode()) {
2139             // Ensure that we do not trigger entering PiP an activity on the pinned stack
2140             return false;
2141         }
2142         final ActivityStack targetStack = toFrontTask != null
2143                 ? toFrontTask.getStack() : toFrontActivity.getRootTask();
2144         if (targetStack != null && targetStack.isActivityTypeAssistant()) {
2145             // Ensure the task/activity being brought forward is not the assistant
2146             return false;
2147         }
2148         return true;
2149     }
2150 
isTaskSwitch(ActivityRecord r, ActivityRecord topFocusedActivity)2151     private boolean isTaskSwitch(ActivityRecord r, ActivityRecord topFocusedActivity) {
2152         return topFocusedActivity != null && r.getTask() != topFocusedActivity.getTask();
2153     }
2154 
2155     /**
2156      * Reset the task by reparenting the activities that have same affinity to the task or
2157      * reparenting the activities that have different affinityies out of the task, while these
2158      * activities allow task reparenting.
2159      *
2160      * @param taskTop     Top activity of the task might be reset.
2161      * @param newActivity The activity that going to be started.
2162      * @return The non-finishing top activity of the task after reset or the original task top
2163      *         activity if all activities within the task are finishing.
2164      */
resetTaskIfNeeded(ActivityRecord taskTop, ActivityRecord newActivity)2165     ActivityRecord resetTaskIfNeeded(ActivityRecord taskTop, ActivityRecord newActivity) {
2166         final boolean forceReset =
2167                 (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
2168         final Task task = taskTop.getTask();
2169 
2170         // If ActivityOptions are moved out and need to be aborted or moved to taskTop.
2171         final ActivityOptions topOptions = sResetTargetTaskHelper.process(task, forceReset);
2172 
2173         if (mChildren.contains(task)) {
2174             final ActivityRecord newTop = task.getTopNonFinishingActivity();
2175             if (newTop != null) {
2176                 taskTop = newTop;
2177             }
2178         }
2179 
2180         if (topOptions != null) {
2181             // If we got some ActivityOptions from an activity on top that
2182             // was removed from the task, propagate them to the new real top.
2183             taskTop.updateOptionsLocked(topOptions);
2184         }
2185 
2186         return taskTop;
2187     }
2188 
2189     /**
2190      * Finish the topmost activity that belongs to the crashed app. We may also finish the activity
2191      * that requested launch of the crashed one to prevent launch-crash loop.
2192      * @param app The app that crashed.
2193      * @param reason Reason to perform this action.
2194      * @return The task that was finished in this stack, {@code null} if top running activity does
2195      *         not belong to the crashed app.
2196      */
finishTopCrashedActivityLocked(WindowProcessController app, String reason)2197     final Task finishTopCrashedActivityLocked(WindowProcessController app, String reason) {
2198         final ActivityRecord r = topRunningActivity();
2199         if (r == null || r.app != app) {
2200             return null;
2201         }
2202         if (r.isActivityTypeHome() && mAtmService.mHomeProcess == app) {
2203             // Home activities should not be force-finished as we have nothing else to go
2204             // back to. AppErrors will get to it after two crashes in MIN_CRASH_INTERVAL.
2205             Slog.w(TAG, "  Not force finishing home activity "
2206                     + r.intent.getComponent().flattenToShortString());
2207             return null;
2208         }
2209         Slog.w(TAG, "  Force finishing activity "
2210                 + r.intent.getComponent().flattenToShortString());
2211         Task finishedTask = r.getTask();
2212         getDisplay().mDisplayContent.prepareAppTransition(
2213                 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
2214         r.finishIfPossible(reason, false /* oomAdj */);
2215 
2216         // Also terminate any activities below it that aren't yet stopped, to avoid a situation
2217         // where one will get re-start our crashing activity once it gets resumed again.
2218         final ActivityRecord activityBelow = getActivityBelow(r);
2219         if (activityBelow != null) {
2220             if (activityBelow.isState(STARTED, RESUMED, PAUSING, PAUSED)) {
2221                 if (!activityBelow.isActivityTypeHome()
2222                         || mAtmService.mHomeProcess != activityBelow.app) {
2223                     Slog.w(TAG, "  Force finishing activity "
2224                             + activityBelow.intent.getComponent().flattenToShortString());
2225                     activityBelow.finishIfPossible(reason, false /* oomAdj */);
2226                 }
2227             }
2228         }
2229 
2230         return finishedTask;
2231     }
2232 
finishVoiceTask(IVoiceInteractionSession session)2233     void finishVoiceTask(IVoiceInteractionSession session) {
2234         final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::finishIfVoiceTask,
2235                 PooledLambda.__(Task.class), session.asBinder());
2236         forAllLeafTasks(c, true /* traverseTopToBottom */);
2237         c.recycle();
2238     }
2239 
finishIfVoiceTask(Task tr, IBinder binder)2240     private static void finishIfVoiceTask(Task tr, IBinder binder) {
2241         if (tr.voiceSession != null && tr.voiceSession.asBinder() == binder) {
2242             tr.forAllActivities((r) -> {
2243                 if (r.finishing) return;
2244                 r.finishIfPossible("finish-voice", false /* oomAdj */);
2245                 tr.mAtmService.updateOomAdj();
2246             });
2247         } else {
2248             // Check if any of the activities are using voice
2249             final PooledFunction f = PooledLambda.obtainFunction(
2250                     ActivityStack::finishIfVoiceActivity, PooledLambda.__(ActivityRecord.class),
2251                     binder);
2252             tr.forAllActivities(f);
2253             f.recycle();
2254         }
2255     }
2256 
finishIfVoiceActivity(ActivityRecord r, IBinder binder)2257     private static boolean finishIfVoiceActivity(ActivityRecord r, IBinder binder) {
2258         if (r.voiceSession == null || r.voiceSession.asBinder() != binder) return false;
2259         // Inform of cancellation
2260         r.clearVoiceSessionLocked();
2261         try {
2262             r.app.getThread().scheduleLocalVoiceInteractionStarted(r.appToken, null);
2263         } catch (RemoteException re) {
2264             // Ok Boomer...
2265         }
2266         r.mAtmService.finishRunningVoiceLocked();
2267         return true;
2268     }
2269 
2270     /** Finish all activities in the stack without waiting. */
finishAllActivitiesImmediately()2271     void finishAllActivitiesImmediately() {
2272         if (!hasChild()) {
2273             removeIfPossible();
2274             return;
2275         }
2276         forAllActivities((r) -> {
2277             Slog.d(TAG, "finishAllActivitiesImmediatelyLocked: finishing " + r);
2278             r.destroyIfPossible("finishAllActivitiesImmediately");
2279         });
2280     }
2281 
2282     /** @return true if the stack behind this one is a standard activity type. */
inFrontOfStandardStack()2283     private boolean inFrontOfStandardStack() {
2284         final TaskDisplayArea taskDisplayArea = getDisplayArea();
2285         if (taskDisplayArea == null) {
2286             return false;
2287         }
2288         final int index = taskDisplayArea.getIndexOf(this);
2289         if (index == 0) {
2290             return false;
2291         }
2292         final ActivityStack stackBehind = taskDisplayArea.getChildAt(index - 1);
2293         return stackBehind.isActivityTypeStandard();
2294     }
2295 
shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity)2296     boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) {
2297         // Basic case: for simple app-centric recents, we need to recreate
2298         // the task if the affinity has changed.
2299 
2300         final String affinity = ActivityRecord.getTaskAffinityWithUid(destAffinity, srec.getUid());
2301         if (srec == null || srec.getTask().affinity == null
2302                 || !srec.getTask().affinity.equals(affinity)) {
2303             return true;
2304         }
2305         // Document-centric case: an app may be split in to multiple documents;
2306         // they need to re-create their task if this current activity is the root
2307         // of a document, unless simply finishing it will return them to the the
2308         // correct app behind.
2309         final Task task = srec.getTask();
2310         if (srec.isRootOfTask() && task.getBaseIntent() != null
2311                 && task.getBaseIntent().isDocument()) {
2312             // Okay, this activity is at the root of its task.  What to do, what to do...
2313             if (!inFrontOfStandardStack()) {
2314                 // Finishing won't return to an application, so we need to recreate.
2315                 return true;
2316             }
2317             // We now need to get the task below it to determine what to do.
2318             final Task prevTask = getTaskBelow(task);
2319             if (prevTask == null) {
2320                 Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec);
2321                 return false;
2322             }
2323             if (!task.affinity.equals(prevTask.affinity)) {
2324                 // These are different apps, so need to recreate.
2325                 return true;
2326             }
2327         }
2328         return false;
2329     }
2330 
navigateUpTo(ActivityRecord srec, Intent destIntent, NeededUriGrants destGrants, int resultCode, Intent resultData, NeededUriGrants resultGrants)2331     boolean navigateUpTo(ActivityRecord srec, Intent destIntent, NeededUriGrants destGrants,
2332             int resultCode, Intent resultData, NeededUriGrants resultGrants) {
2333         if (!srec.attachedToProcess()) {
2334             // Nothing to do if the caller is not attached, because this method should be called
2335             // from an alive activity.
2336             return false;
2337         }
2338         final Task task = srec.getTask();
2339         if (!srec.isDescendantOf(this)) {
2340             return false;
2341         }
2342 
2343         ActivityRecord parent = task.getActivityBelow(srec);
2344         boolean foundParentInTask = false;
2345         final ComponentName dest = destIntent.getComponent();
2346         if (task.getBottomMostActivity() != srec && dest != null) {
2347             final ActivityRecord candidate = task.getActivity((ar) ->
2348                     ar.info.packageName.equals(dest.getPackageName()) &&
2349                     ar.info.name.equals(dest.getClassName()), srec, false /*includeBoundary*/,
2350                     true /*traverseTopToBottom*/);
2351             if (candidate != null) {
2352                 parent = candidate;
2353                 foundParentInTask = true;
2354             }
2355         }
2356 
2357         // TODO: There is a dup. of this block of code in ActivityTaskManagerService.finishActivity
2358         // We should consolidate.
2359         IActivityController controller = mAtmService.mController;
2360         if (controller != null) {
2361             ActivityRecord next = topRunningActivity(srec.appToken, INVALID_TASK_ID);
2362             if (next != null) {
2363                 // ask watcher if this is allowed
2364                 boolean resumeOK = true;
2365                 try {
2366                     resumeOK = controller.activityResuming(next.packageName);
2367                 } catch (RemoteException e) {
2368                     mAtmService.mController = null;
2369                     Watchdog.getInstance().setActivityController(null);
2370                 }
2371 
2372                 if (!resumeOK) {
2373                     return false;
2374                 }
2375             }
2376         }
2377         final long origId = Binder.clearCallingIdentity();
2378 
2379         final int[] resultCodeHolder = new int[1];
2380         resultCodeHolder[0] = resultCode;
2381         final Intent[] resultDataHolder = new Intent[1];
2382         resultDataHolder[0] = resultData;
2383         final NeededUriGrants[] resultGrantsHolder = new NeededUriGrants[1];
2384         resultGrantsHolder[0] = resultGrants;
2385         final ActivityRecord finalParent = parent;
2386         task.forAllActivities((ar) -> {
2387             if (ar == finalParent) return true;
2388 
2389             ar.finishIfPossible(resultCodeHolder[0], resultDataHolder[0], resultGrantsHolder[0],
2390                     "navigate-up", true /* oomAdj */);
2391             // Only return the supplied result for the first activity finished
2392             resultCodeHolder[0] = Activity.RESULT_CANCELED;
2393             resultDataHolder[0] = null;
2394             return false;
2395         }, srec, true, true);
2396         resultCode = resultCodeHolder[0];
2397         resultData = resultDataHolder[0];
2398 
2399         if (parent != null && foundParentInTask) {
2400             final int callingUid = srec.info.applicationInfo.uid;
2401             final int parentLaunchMode = parent.info.launchMode;
2402             final int destIntentFlags = destIntent.getFlags();
2403             if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
2404                     parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
2405                     parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
2406                     (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
2407                 parent.deliverNewIntentLocked(callingUid, destIntent, destGrants, srec.packageName);
2408             } else {
2409                 try {
2410                     ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
2411                             destIntent.getComponent(), ActivityManagerService.STOCK_PM_FLAGS,
2412                             srec.mUserId);
2413                     // TODO(b/64750076): Check if calling pid should really be -1.
2414                     final int res = mAtmService.getActivityStartController()
2415                             .obtainStarter(destIntent, "navigateUpTo")
2416                             .setCaller(srec.app.getThread())
2417                             .setActivityInfo(aInfo)
2418                             .setResultTo(parent.appToken)
2419                             .setCallingPid(-1)
2420                             .setCallingUid(callingUid)
2421                             .setCallingPackage(srec.packageName)
2422                             .setCallingFeatureId(parent.launchedFromFeatureId)
2423                             .setRealCallingPid(-1)
2424                             .setRealCallingUid(callingUid)
2425                             .setComponentSpecified(true)
2426                             .execute();
2427                     foundParentInTask = res == ActivityManager.START_SUCCESS;
2428                 } catch (RemoteException e) {
2429                     foundParentInTask = false;
2430                 }
2431                 parent.finishIfPossible(resultCode, resultData, resultGrants,
2432                         "navigate-top", true /* oomAdj */);
2433             }
2434         }
2435         Binder.restoreCallingIdentity(origId);
2436         return foundParentInTask;
2437     }
2438 
removeLaunchTickMessages()2439     void removeLaunchTickMessages() {
2440         forAllActivities(ActivityRecord::removeLaunchTickRunnable);
2441     }
2442 
updateTransitLocked(int transit, ActivityOptions options, boolean forceOverride)2443     private void updateTransitLocked(int transit, ActivityOptions options, boolean forceOverride) {
2444         if (options != null) {
2445             ActivityRecord r = topRunningActivity();
2446             if (r != null && !r.isState(RESUMED)) {
2447                 r.updateOptionsLocked(options);
2448             } else {
2449                 ActivityOptions.abort(options);
2450             }
2451         }
2452         getDisplay().mDisplayContent.prepareAppTransition(transit, false,
2453                 0 /* flags */, forceOverride);
2454     }
2455 
moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options, AppTimeTracker timeTracker, String reason)2456     final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options,
2457             AppTimeTracker timeTracker, String reason) {
2458         moveTaskToFront(tr, noAnimation, options, timeTracker, !DEFER_RESUME, reason);
2459     }
2460 
moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options, AppTimeTracker timeTracker, boolean deferResume, String reason)2461     final void moveTaskToFront(Task tr, boolean noAnimation, ActivityOptions options,
2462             AppTimeTracker timeTracker, boolean deferResume, String reason) {
2463         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
2464 
2465         final ActivityStack topStack = getDisplayArea().getTopStack();
2466         final ActivityRecord topActivity = topStack != null
2467                 ? topStack.getTopNonFinishingActivity() : null;
2468 
2469         if (tr != this && !tr.isDescendantOf(this)) {
2470             // nothing to do!
2471             if (noAnimation) {
2472                 ActivityOptions.abort(options);
2473             } else if (isSingleTaskInstance()) {
2474                 // When a task is moved front on the display which can only contain one task, start
2475                 // a special transition.
2476                 // {@link AppTransitionController#handleAppTransitionReady} later picks up the
2477                 // transition, and schedules
2478                 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is triggered
2479                 // after contents are drawn on the display.
2480                 updateTransitLocked(TRANSIT_SHOW_SINGLE_TASK_DISPLAY, options,
2481                         true /* forceOverride */);
2482             } else {
2483                 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options, false /* forceOverride */);
2484             }
2485             return;
2486         }
2487 
2488         if (timeTracker != null) {
2489             // The caller wants a time tracker associated with this task.
2490             final PooledConsumer c = PooledLambda.obtainConsumer(ActivityRecord::setAppTimeTracker,
2491                     PooledLambda.__(ActivityRecord.class), timeTracker);
2492             tr.forAllActivities(c);
2493             c.recycle();
2494         }
2495 
2496         try {
2497             // Defer updating the IME target since the new IME target will try to get computed
2498             // before updating all closing and opening apps, which can cause the ime target to
2499             // get calculated incorrectly.
2500             getDisplay().deferUpdateImeTarget();
2501 
2502             // Shift all activities with this task up to the top
2503             // of the stack, keeping them in the same internal order.
2504             positionChildAtTop(tr);
2505 
2506             // Don't refocus if invisible to current user
2507             final ActivityRecord top = tr.getTopNonFinishingActivity();
2508             if (top == null || !top.okToShowLocked()) {
2509                 if (top != null) {
2510                     mStackSupervisor.mRecentTasks.add(top.getTask());
2511                 }
2512                 ActivityOptions.abort(options);
2513                 return;
2514             }
2515 
2516             // Set focus to the top running activity of this stack.
2517             final ActivityRecord r = topRunningActivity();
2518             if (r != null) {
2519                 r.moveFocusableActivityToTop(reason);
2520             }
2521 
2522             if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
2523             if (noAnimation) {
2524                 getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_NONE, false);
2525                 if (r != null) {
2526                     mStackSupervisor.mNoAnimActivities.add(r);
2527                 }
2528                 ActivityOptions.abort(options);
2529             } else if (isSingleTaskInstance()) {
2530                 updateTransitLocked(TRANSIT_SHOW_SINGLE_TASK_DISPLAY, options,
2531                         true /* forceOverride */);
2532             } else {
2533                 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options, false /* forceOverride */);
2534             }
2535 
2536             // If a new task is moved to the front, then mark the existing top activity as
2537             // supporting
2538 
2539             // picture-in-picture while paused only if the task would not be considered an oerlay
2540             // on top
2541             // of the current activity (eg. not fullscreen, or the assistant)
2542             if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
2543                     options)) {
2544                 topActivity.supportsEnterPipOnTaskSwitch = true;
2545             }
2546 
2547             if (!deferResume) {
2548                 mRootWindowContainer.resumeFocusedStacksTopActivities();
2549             }
2550             EventLogTags.writeWmTaskToFront(tr.mUserId, tr.mTaskId);
2551             mAtmService.getTaskChangeNotificationController()
2552                     .notifyTaskMovedToFront(tr.getTaskInfo());
2553         } finally {
2554             getDisplay().continueUpdateImeTarget();
2555         }
2556     }
2557 
2558     /**
2559      * Worker method for rearranging history stack. Implements the function of moving all
2560      * activities for a specific task (gathering them if disjoint) into a single group at the
2561      * bottom of the stack.
2562      *
2563      * If a watcher is installed, the action is preflighted and the watcher has an opportunity
2564      * to premeptively cancel the move.
2565      *
2566      * @param tr The task to collect and move to the bottom.
2567      * @return Returns true if the move completed, false if not.
2568      */
moveTaskToBack(Task tr)2569     boolean moveTaskToBack(Task tr) {
2570         Slog.i(TAG, "moveTaskToBack: " + tr);
2571 
2572         // In LockTask mode, moving a locked task to the back of the stack may expose unlocked
2573         // ones. Therefore we need to check if this operation is allowed.
2574         if (!mAtmService.getLockTaskController().canMoveTaskToBack(tr)) {
2575             return false;
2576         }
2577 
2578         // If we have a watcher, preflight the move before committing to it.  First check
2579         // for *other* available tasks, but if none are available, then try again allowing the
2580         // current task to be selected.
2581         if (isTopStackInDisplayArea() && mAtmService.mController != null) {
2582             ActivityRecord next = topRunningActivity(null, tr.mTaskId);
2583             if (next == null) {
2584                 next = topRunningActivity(null, INVALID_TASK_ID);
2585             }
2586             if (next != null) {
2587                 // ask watcher if this is allowed
2588                 boolean moveOK = true;
2589                 try {
2590                     moveOK = mAtmService.mController.activityResuming(next.packageName);
2591                 } catch (RemoteException e) {
2592                     mAtmService.mController = null;
2593                     Watchdog.getInstance().setActivityController(null);
2594                 }
2595                 if (!moveOK) {
2596                     return false;
2597                 }
2598             }
2599         }
2600 
2601         if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task="
2602                 + tr.mTaskId);
2603 
2604         getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_TASK_TO_BACK, false);
2605         moveToBack("moveTaskToBackLocked", tr);
2606 
2607         if (inPinnedWindowingMode()) {
2608             mStackSupervisor.removeStack(this);
2609             return true;
2610         }
2611 
2612         ActivityRecord topActivity = getDisplayArea().topRunningActivity();
2613         ActivityStack topStack = topActivity.getRootTask();
2614         if (topStack != null && topStack != this && topActivity.isState(RESUMED)) {
2615             // The new top activity is already resumed, so there's a good chance that nothing will
2616             // get resumed below. So, update visibility now in case the transition is closed
2617             // prematurely.
2618             mRootWindowContainer.ensureVisibilityAndConfig(null /* starting */,
2619                     getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */,
2620                     false /* deferResume */);
2621             // Usually resuming a top activity triggers the next app transition, but nothing's got
2622             // resumed in this case, so we need to execute it explicitly.
2623             getDisplay().mDisplayContent.executeAppTransition();
2624         } else {
2625             mRootWindowContainer.resumeFocusedStacksTopActivities();
2626         }
2627         return true;
2628     }
2629 
2630     /**
2631      * Ensures all visible activities at or below the input activity have the right configuration.
2632      */
ensureVisibleActivitiesConfiguration(ActivityRecord start, boolean preserveWindow)2633     void ensureVisibleActivitiesConfiguration(ActivityRecord start, boolean preserveWindow) {
2634         mEnsureVisibleActivitiesConfigHelper.process(start, preserveWindow);
2635     }
2636 
2637     // TODO: Can only be called from special methods in ActivityStackSupervisor.
2638     // Need to consolidate those calls points into this resize method so anyone can call directly.
resize(Rect displayedBounds, boolean preserveWindows, boolean deferResume)2639     void resize(Rect displayedBounds, boolean preserveWindows, boolean deferResume) {
2640         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "stack.resize_" + getRootTaskId());
2641         mAtmService.deferWindowLayout();
2642         try {
2643             // TODO: Why not just set this on the stack directly vs. on each tasks?
2644             // Update override configurations of all tasks in the stack.
2645             final PooledConsumer c = PooledLambda.obtainConsumer(
2646                     ActivityStack::processTaskResizeBounds, PooledLambda.__(Task.class),
2647                     displayedBounds);
2648             forAllTasks(c, true /* traverseTopToBottom */);
2649             c.recycle();
2650 
2651             if (mBoundsAnimating) {
2652                 // Force to update task surface bounds and relayout windows, since configBounds
2653                 // remains unchanged during bounds animation.
2654                 updateSurfaceBounds();
2655                 getDisplay().setLayoutNeeded();
2656                 mWmService.requestTraversal();
2657             }
2658 
2659             if (!deferResume) {
2660                 ensureVisibleActivitiesConfiguration(topRunningActivity(), preserveWindows);
2661             }
2662         } finally {
2663             mAtmService.continueWindowLayout();
2664             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2665         }
2666     }
2667 
processTaskResizeBounds(Task task, Rect displayedBounds)2668     private static void processTaskResizeBounds(Task task, Rect displayedBounds) {
2669         if (!task.isResizeable()) return;
2670 
2671         task.setBounds(displayedBounds);
2672     }
2673 
2674     /**
2675      * Until we can break this "set task bounds to same as stack bounds" behavior, this
2676      * basically resizes both stack and task bounds to the same bounds.
2677      */
setTaskBounds(Rect bounds)2678    private void setTaskBounds(Rect bounds) {
2679         final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskBounds,
2680                 PooledLambda.__(Task.class), bounds);
2681         forAllLeafTasks(c, true /* traverseTopToBottom */);
2682         c.recycle();
2683     }
2684 
setTaskBounds(Task task, Rect bounds)2685     private static void setTaskBounds(Task task, Rect bounds) {
2686         task.setBounds(task.isResizeable() ? bounds : null);
2687     }
2688 
2689     /**
2690      * Returns the top-most activity that occludes the given one, or @{code null} if none.
2691      */
2692     @Nullable
getOccludingActivityAbove(ActivityRecord activity)2693     private ActivityRecord getOccludingActivityAbove(ActivityRecord activity) {
2694         ActivityRecord top = getActivity((ar) -> ar.occludesParent(),
2695                 true /* traverseTopToBottom */, activity);
2696         return top != activity ? top : null;
2697     }
2698 
willActivityBeVisible(IBinder token)2699     boolean willActivityBeVisible(IBinder token) {
2700         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
2701         if (r == null) {
2702             return false;
2703         }
2704 
2705         // See if there is an occluding activity on-top of this one.
2706         final ActivityRecord occludingActivity = getOccludingActivityAbove(r);
2707         if (occludingActivity != null) return false;
2708 
2709         if (r.finishing) Slog.e(TAG, "willActivityBeVisible: Returning false,"
2710                 + " would have returned true for r=" + r);
2711         return !r.finishing;
2712     }
2713 
unhandledBackLocked()2714     void unhandledBackLocked() {
2715         final ActivityRecord topActivity = getTopMostActivity();
2716         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
2717                 "Performing unhandledBack(): top activity: " + topActivity);
2718         if (topActivity != null) {
2719             topActivity.finishIfPossible("unhandled-back", true /* oomAdj */);
2720         }
2721     }
2722 
2723     /**
2724      * Reset local parameters because an app's activity died.
2725      * @param app The app of the activity that died.
2726      * @return {@code true} if the process has any visible activity.
2727      */
handleAppDied(WindowProcessController app)2728     boolean handleAppDied(WindowProcessController app) {
2729         boolean isPausingDied = false;
2730         if (mPausingActivity != null && mPausingActivity.app == app) {
2731             if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
2732                     "App died while pausing: " + mPausingActivity);
2733             mPausingActivity = null;
2734             isPausingDied = true;
2735         }
2736         if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
2737             mLastPausedActivity = null;
2738             mLastNoHistoryActivity = null;
2739         }
2740 
2741         mStackSupervisor.removeHistoryRecords(app);
2742         final boolean hadVisibleActivities = mRemoveHistoryRecordsForApp.process(app);
2743         return hadVisibleActivities || isPausingDied;
2744     }
2745 
dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage, final boolean needSep)2746     boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
2747             String dumpPackage, final boolean needSep) {
2748         Runnable headerPrinter = () -> {
2749             if (needSep) {
2750                 pw.println();
2751             }
2752             pw.println("  Stack #" + getRootTaskId()
2753                     + ": type=" + activityTypeToString(getActivityType())
2754                     + " mode=" + windowingModeToString(getWindowingMode()));
2755             pw.println("  isSleeping=" + shouldSleepActivities());
2756             pw.println("  mBounds=" + getRequestedOverrideBounds());
2757         };
2758 
2759         boolean printed = false;
2760 
2761         if (dumpPackage == null) {
2762             // If we are not filtering by package, we want to print absolutely everything,
2763             // so always print the header even if there are no tasks/activities inside.
2764             headerPrinter.run();
2765             headerPrinter = null;
2766             printed = true;
2767         }
2768 
2769         printed |= printThisActivity(pw, mPausingActivity, dumpPackage, false,
2770                 "    mPausingActivity: ", null);
2771         printed |= printThisActivity(pw, getResumedActivity(), dumpPackage, false,
2772                 "    mResumedActivity: ", null);
2773         if (dumpAll) {
2774             printed |= printThisActivity(pw, mLastPausedActivity, dumpPackage, false,
2775                     "    mLastPausedActivity: ", null);
2776             printed |= printThisActivity(pw, mLastNoHistoryActivity, dumpPackage,
2777                     false, "    mLastNoHistoryActivity: ", null);
2778         }
2779 
2780         printed |= dumpActivities(fd, pw, dumpAll, dumpClient, dumpPackage, false, headerPrinter);
2781 
2782         return printed;
2783     }
2784 
dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage, boolean needSep, Runnable header)2785     private boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
2786             boolean dumpClient, String dumpPackage, boolean needSep, Runnable header) {
2787         if (!hasChild()) {
2788             return false;
2789         }
2790         final AtomicBoolean printedHeader = new AtomicBoolean(false);
2791         final AtomicBoolean printed = new AtomicBoolean(false);
2792         forAllLeafTasks((task) -> {
2793             final String prefix = "    ";
2794             Runnable headerPrinter = () -> {
2795                 printed.set(true);
2796                 if (!printedHeader.get()) {
2797                     if (needSep) {
2798                         pw.println("");
2799                     }
2800                     if (header != null) {
2801                         header.run();
2802                     }
2803                     printedHeader.set(true);
2804                 }
2805                 pw.print(prefix); pw.print("* "); pw.println(task);
2806                 pw.print(prefix); pw.print("  mBounds=");
2807                 pw.println(task.getRequestedOverrideBounds());
2808                 pw.print(prefix); pw.print("  mMinWidth="); pw.print(task.mMinWidth);
2809                 pw.print(" mMinHeight="); pw.println(task.mMinHeight);
2810                 if (mLastNonFullscreenBounds != null) {
2811                     pw.print(prefix);
2812                     pw.print("  mLastNonFullscreenBounds=");
2813                     pw.println(task.mLastNonFullscreenBounds);
2814                 }
2815                 task.dump(pw, prefix + "  ");
2816             };
2817             if (dumpPackage == null) {
2818                 // If we are not filtering by package, we want to print absolutely everything,
2819                 // so always print the header even if there are no activities inside.
2820                 headerPrinter.run();
2821                 headerPrinter = null;
2822             }
2823             final ArrayList<ActivityRecord> activities = new ArrayList<>();
2824             // Add activities by traversing the hierarchy from bottom to top, since activities
2825             // are dumped in reverse order in {@link ActivityStackSupervisor#dumpHistoryList()}.
2826             task.forAllActivities((Consumer<ActivityRecord>) activities::add,
2827                     false /* traverseTopToBottom */);
2828             dumpHistoryList(fd, pw, activities, prefix, "Hist", true, !dumpAll, dumpClient,
2829                     dumpPackage, false, headerPrinter, task);
2830         }, true /* traverseTopToBottom */);
2831         return printed.get();
2832     }
2833 
getDumpActivitiesLocked(String name)2834     ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
2835         ArrayList<ActivityRecord> activities = new ArrayList<>();
2836 
2837         if ("all".equals(name)) {
2838             forAllActivities((Consumer<ActivityRecord>) activities::add);
2839         } else if ("top".equals(name)) {
2840             final ActivityRecord topActivity = getTopMostActivity();
2841             if (topActivity != null) {
2842                 activities.add(topActivity);
2843             }
2844         } else {
2845             ItemMatcher matcher = new ItemMatcher();
2846             matcher.build(name);
2847 
2848             forAllActivities((r) -> {
2849                 if (matcher.match(r, r.intent.getComponent())) {
2850                     activities.add(r);
2851                 }
2852             });
2853         }
2854 
2855         return activities;
2856     }
2857 
restartPackage(String packageName)2858     ActivityRecord restartPackage(String packageName) {
2859         ActivityRecord starting = topRunningActivity();
2860 
2861         // All activities that came from the package must be
2862         // restarted as if there was a config change.
2863         PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::restartPackage,
2864                 PooledLambda.__(ActivityRecord.class), starting, packageName);
2865         forAllActivities(c);
2866         c.recycle();
2867 
2868         return starting;
2869     }
2870 
restartPackage( ActivityRecord r, ActivityRecord starting, String packageName)2871     private static void restartPackage(
2872             ActivityRecord r, ActivityRecord starting, String packageName) {
2873         if (r.info.packageName.equals(packageName)) {
2874             r.forceNewConfig = true;
2875             if (starting != null && r == starting && r.mVisibleRequested) {
2876                 r.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
2877             }
2878         }
2879     }
2880 
reuseOrCreateTask(ActivityInfo info, Intent intent, boolean toTop)2881     Task reuseOrCreateTask(ActivityInfo info, Intent intent, boolean toTop) {
2882         return reuseOrCreateTask(info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
2883                 toTop, null /*activity*/, null /*source*/, null /*options*/);
2884     }
2885     // TODO: Can be removed once we change callpoints creating stacks to be creating tasks.
2886     /** Either returns this current task to be re-used or creates a new child task. */
reuseOrCreateTask(ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity, ActivityRecord source, ActivityOptions options)2887     Task reuseOrCreateTask(ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession,
2888             IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity,
2889             ActivityRecord source, ActivityOptions options) {
2890 
2891         Task task;
2892         if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) {
2893             // This stack will only contain one task, so just return itself since all stacks ara now
2894             // tasks and all tasks are now stacks.
2895             task = reuseAsLeafTask(voiceSession, voiceInteractor, intent, info, activity);
2896         } else {
2897             // Create child task since this stack can contain multiple tasks.
2898             final int taskId = activity != null
2899                     ? mStackSupervisor.getNextTaskIdForUser(activity.mUserId)
2900                     : mStackSupervisor.getNextTaskIdForUser();
2901             task = new ActivityStack(mAtmService, taskId, info, intent, voiceSession,
2902                     voiceInteractor, null /* taskDescription */, this);
2903 
2904             // add the task to stack first, mTaskPositioner might need the stack association
2905             addChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
2906         }
2907 
2908         int displayId = getDisplayId();
2909         if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
2910         final boolean isLockscreenShown = mAtmService.mStackSupervisor.getKeyguardController()
2911                 .isKeyguardOrAodShowing(displayId);
2912         if (!mStackSupervisor.getLaunchParamsController()
2913                 .layoutTask(task, info.windowLayout, activity, source, options)
2914                 && !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
2915             task.setBounds(getRequestedOverrideBounds());
2916         }
2917 
2918         return task;
2919     }
2920 
addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers)2921     void addChild(WindowContainer child, final boolean toTop, boolean showForAllUsers) {
2922         if (isSingleTaskInstance() && hasChild()) {
2923             throw new IllegalStateException("Can only have one child on stack=" + this);
2924         }
2925 
2926         Task task = child.asTask();
2927         try {
2928 
2929             if (task != null) {
2930                 task.setForceShowForAllUsers(showForAllUsers);
2931             }
2932             // We only want to move the parents to the parents if we are creating this task at the
2933             // top of its stack.
2934             addChild(child, toTop ? MAX_VALUE : 0, toTop /*moveParents*/);
2935         } finally {
2936             if (task != null) {
2937                 task.setForceShowForAllUsers(false);
2938             }
2939         }
2940     }
2941 
positionChildAt(Task task, int position)2942     void positionChildAt(Task task, int position) {
2943         if (task.getStack() != this) {
2944             throw new IllegalArgumentException("AS.positionChildAt: task=" + task
2945                     + " is not a child of stack=" + this + " current parent=" + task.getStack());
2946         }
2947 
2948         task.updateOverrideConfigurationForStack(this);
2949 
2950         final ActivityRecord topRunningActivity = task.topRunningActivityLocked();
2951         final boolean wasResumed = topRunningActivity == task.getStack().mResumedActivity;
2952 
2953         boolean toTop = position >= getChildCount();
2954         boolean includingParents = toTop || getDisplayArea().getNextFocusableStack(this,
2955                 true /* ignoreCurrent */) == null;
2956         if (WindowManagerDebugConfig.DEBUG_STACK) {
2957             Slog.i(TAG_WM, "positionChildAt: positioning task=" + task + " at " + position);
2958         }
2959         positionChildAt(position, task, includingParents);
2960         task.updateTaskMovement(toTop);
2961         getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
2962 
2963 
2964         // TODO: Investigate if this random code is really needed.
2965         if (task.voiceSession != null) {
2966             try {
2967                 task.voiceSession.taskStarted(task.intent, task.mTaskId);
2968             } catch (RemoteException e) {
2969             }
2970         }
2971 
2972         if (wasResumed) {
2973             if (mResumedActivity != null) {
2974                 Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from"
2975                         + " other stack to this stack mResumedActivity=" + mResumedActivity
2976                         + " other mResumedActivity=" + topRunningActivity);
2977             }
2978             topRunningActivity.setState(RESUMED, "positionChildAt");
2979         }
2980 
2981         // The task might have already been running and its visibility needs to be synchronized with
2982         // the visibility of the stack / windows.
2983         ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
2984         mRootWindowContainer.resumeFocusedStacksTopActivities();
2985     }
2986 
setAlwaysOnTop(boolean alwaysOnTop)2987     public void setAlwaysOnTop(boolean alwaysOnTop) {
2988         if (isAlwaysOnTop() == alwaysOnTop) {
2989             return;
2990         }
2991         super.setAlwaysOnTop(alwaysOnTop);
2992         final TaskDisplayArea taskDisplayArea = getDisplayArea();
2993         // positionChildAtTop() must be called even when always on top gets turned off because we
2994         // need to make sure that the stack is moved from among always on top windows to below other
2995         // always on top windows. Since the position the stack should be inserted into is calculated
2996         // properly in {@link DisplayContent#getTopInsertPosition()} in both cases, we can just
2997         // request that the stack is put at top here.
2998         taskDisplayArea.positionStackAtTop(this, false /* includingParents */);
2999     }
3000 
3001     /** NOTE: Should only be called from {@link Task#reparent}. */
moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume, boolean setPause, String reason)3002     void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume,
3003             boolean setPause, String reason) {
3004         if (!moveToFront) {
3005             return;
3006         }
3007 
3008         final ActivityState origState = r.getState();
3009         // If the activity owns the last resumed activity, transfer that together,
3010         // so that we don't resume the same activity again in the new stack.
3011         // Apps may depend on onResume()/onPause() being called in pairs.
3012         if (setResume) {
3013             r.setState(RESUMED, "moveToFrontAndResumeStateIfNeeded");
3014         }
3015         // If the activity was previously pausing, then ensure we transfer that as well
3016         if (setPause) {
3017             mPausingActivity = r;
3018             r.schedulePauseTimeout();
3019         }
3020         // Move the stack in which we are placing the activity to the front.
3021         moveToFront(reason);
3022         // If the original state is resumed, there is no state change to update focused app.
3023         // So here makes sure the activity focus is set if it is the top.
3024         if (origState == RESUMED && r == mRootWindowContainer.getTopResumedActivity()) {
3025             mAtmService.setResumedActivityUncheckLocked(r, reason);
3026         }
3027     }
3028 
dismissPip()3029     void dismissPip() {
3030         if (!isActivityTypeStandardOrUndefined()) {
3031             throw new IllegalArgumentException(
3032                     "You can't move tasks from non-standard stacks.");
3033         }
3034         if (getWindowingMode() != WINDOWING_MODE_PINNED) {
3035             throw new IllegalArgumentException(
3036                     "Can't exit pinned mode if it's not pinned already.");
3037         }
3038 
3039         mWmService.inSurfaceTransaction(() -> {
3040             final Task task = getBottomMostTask();
3041             setWindowingMode(WINDOWING_MODE_UNDEFINED);
3042 
3043             getDisplayArea().positionStackAtTop(this, false /* includingParents */);
3044 
3045             mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
3046         });
3047     }
3048 
prepareFreezingTaskBounds()3049     void prepareFreezingTaskBounds() {
3050         forAllLeafTasks(Task::prepareFreezingBounds, true /* traverseTopToBottom */);
3051     }
3052 
3053     @Override
setBounds(Rect bounds)3054     public int setBounds(Rect bounds) {
3055         // Calling Task#setBounds() for leaf task since this is the a specialization of
3056         // {@link #setBounds(int)} for ActivityStack.
3057         if (!isRootTask()) {
3058             return super.setBounds(bounds);
3059         } else {
3060             return setBounds(getRequestedOverrideBounds(), bounds);
3061         }
3062     }
3063 
setBounds(Rect existing, Rect bounds)3064     private int setBounds(Rect existing, Rect bounds) {
3065         if (equivalentBounds(existing, bounds)) {
3066             return BOUNDS_CHANGE_NONE;
3067         }
3068 
3069         final int result = super.setBounds(!inMultiWindowMode() ? null : bounds);
3070 
3071         updateSurfaceBounds();
3072         return result;
3073     }
3074 
3075     /** Bounds of the stack without adjusting for other factors in the system like visibility
3076      * of docked stack.
3077      * Most callers should be using {@link ConfigurationContainer#getRequestedOverrideBounds} a
3078      * it takes into consideration other system factors. */
getRawBounds(Rect out)3079     void getRawBounds(Rect out) {
3080         out.set(getRawBounds());
3081     }
3082 
getRawBounds()3083     private Rect getRawBounds() {
3084         return super.getBounds();
3085     }
3086 
3087     @Override
getBounds(Rect bounds)3088     public void getBounds(Rect bounds) {
3089         bounds.set(getBounds());
3090     }
3091 
3092     /**
3093      * @return the final bounds for the bounds animation.
3094      */
getFinalAnimationBounds(Rect outBounds)3095     void getFinalAnimationBounds(Rect outBounds) {
3096         outBounds.set(mBoundsAnimationTarget);
3097     }
3098 
3099     /**
3100      * @return the final source bounds for the bounds animation.
3101      */
getFinalAnimationSourceHintBounds(Rect outBounds)3102     void getFinalAnimationSourceHintBounds(Rect outBounds) {
3103         outBounds.set(mBoundsAnimationSourceHintBounds);
3104     }
3105 
3106     /** Bounds of the stack with other system factors taken into consideration. */
getDimBounds(Rect out)3107     void getDimBounds(Rect out) {
3108         getBounds(out);
3109     }
3110 
3111     /**
3112      * Put a Task in this stack. Used for adding only.
3113      * When task is added to top of the stack, the entire branch of the hierarchy (including stack
3114      * and display) will be brought to top.
3115      * @param child The child to add.
3116      * @param position Target position to add the task to.
3117      */
addChild(WindowContainer child, int position, boolean moveParents)3118     private void addChild(WindowContainer child, int position, boolean moveParents) {
3119         // Add child task.
3120         addChild(child, null);
3121 
3122         // Move child to a proper position, as some restriction for position might apply.
3123         positionChildAt(position, child, moveParents /* includingParents */);
3124     }
3125 
positionChildAtTop(Task child)3126     void positionChildAtTop(Task child) {
3127         if (child == null) {
3128             // TODO: Fix the call-points that cause this to happen.
3129             return;
3130         }
3131 
3132         if (child == this) {
3133             // TODO: Fix call-points
3134             moveToFront("positionChildAtTop");
3135             return;
3136         }
3137 
3138         positionChildAt(POSITION_TOP, child, true /* includingParents */);
3139         child.updateTaskMovement(true);
3140 
3141         final DisplayContent displayContent = getDisplayContent();
3142         displayContent.layoutAndAssignWindowLayersIfNeeded();
3143     }
3144 
positionChildAtBottom(Task child)3145     void positionChildAtBottom(Task child) {
3146         // If there are other focusable stacks on the display, the z-order of the display should not
3147         // be changed just because a task was placed at the bottom. E.g. if it is moving the topmost
3148         // task to bottom, the next focusable stack on the same display should be focused.
3149         final ActivityStack nextFocusableStack = getDisplayArea().getNextFocusableStack(
3150                 child.getStack(), true /* ignoreCurrent */);
3151         positionChildAtBottom(child, nextFocusableStack == null /* includingParents */);
3152         child.updateTaskMovement(true);
3153     }
3154 
3155     @VisibleForTesting
positionChildAtBottom(Task child, boolean includingParents)3156     void positionChildAtBottom(Task child, boolean includingParents) {
3157         if (child == null) {
3158             // TODO: Fix the call-points that cause this to happen.
3159             return;
3160         }
3161 
3162         positionChildAt(POSITION_BOTTOM, child, includingParents);
3163         getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
3164     }
3165 
3166     @Override
onChildPositionChanged(WindowContainer child)3167     void onChildPositionChanged(WindowContainer child) {
3168         if (isOrganized()) {
3169             mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */);
3170         }
3171 
3172         if (!mChildren.contains(child)) {
3173             return;
3174         }
3175 
3176         final boolean isTop = getTopChild() == child;
3177 
3178         final Task task = child.asTask();
3179         if (task != null) {
3180             task.updateTaskMovement(isTop);
3181         }
3182 
3183         if (isTop) {
3184             final DisplayContent displayContent = getDisplayContent();
3185             displayContent.layoutAndAssignWindowLayersIfNeeded();
3186         }
3187     }
3188 
3189     @Override
onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent)3190     void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
3191         final DisplayContent display = newParent != null
3192                 ? ((WindowContainer) newParent).getDisplayContent() : null;
3193         final DisplayContent oldDisplay = oldParent != null
3194                 ? ((WindowContainer) oldParent).getDisplayContent() : null;
3195         super.onParentChanged(newParent, oldParent);
3196 
3197         // Resume next focusable stack after reparenting to another display if we aren't removing
3198         // the prevous display.
3199         if (oldDisplay != null && oldDisplay.isRemoving()) {
3200             postReparent();
3201         }
3202     }
3203 
reparent(TaskDisplayArea newParent, boolean onTop)3204     void reparent(TaskDisplayArea newParent, boolean onTop) {
3205         reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM);
3206     }
3207 
updateSurfaceBounds()3208     private void updateSurfaceBounds() {
3209         updateSurfaceSize(getSyncTransaction());
3210         updateSurfacePosition();
3211         scheduleAnimation();
3212     }
3213 
3214     @Override
getRelativePosition(Point outPos)3215     void getRelativePosition(Point outPos) {
3216         super.getRelativePosition(outPos);
3217         final int outset = getTaskOutset();
3218         outPos.x -= outset;
3219         outPos.y -= outset;
3220     }
3221 
3222     @Override
onDisplayChanged(DisplayContent dc)3223     void onDisplayChanged(DisplayContent dc) {
3224         super.onDisplayChanged(dc);
3225         if (isRootTask()) {
3226             updateSurfaceBounds();
3227         }
3228     }
3229 
shouldIgnoreInput()3230     boolean shouldIgnoreInput() {
3231         if (inSplitScreenPrimaryWindowingMode() && !isFocusable()) {
3232             return true;
3233         }
3234         if (mAtmService.mHasLeanbackFeature && inPinnedWindowingMode()
3235                 && !isFocusedStackOnDisplay()) {
3236             // Preventing Picture-in-Picture stack from receiving input on TVs.
3237             return true;
3238         }
3239         return false;
3240     }
3241 
3242     @Override
dump(PrintWriter pw, String prefix, boolean dumpAll)3243     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
3244         super.dump(pw, prefix, dumpAll);
3245         if (!mExitingActivities.isEmpty()) {
3246             pw.println();
3247             pw.println(prefix + "Exiting application tokens:");
3248             final String doublePrefix = prefix + "  ";
3249             for (int i = mExitingActivities.size() - 1; i >= 0; i--) {
3250                 WindowToken token = mExitingActivities.get(i);
3251                 pw.print(doublePrefix + "Exiting App #" + i);
3252                 pw.print(' '); pw.print(token);
3253                 pw.println(':');
3254                 token.dump(pw, doublePrefix, dumpAll);
3255             }
3256             pw.println();
3257         }
3258         mAnimatingActivityRegistry.dump(pw, "AnimatingApps:", prefix);
3259     }
3260 
3261     /**
3262      * Sets the current picture-in-picture aspect ratio.
3263      */
setPictureInPictureAspectRatio(float aspectRatio)3264     void setPictureInPictureAspectRatio(float aspectRatio) {
3265         if (!mWmService.mAtmService.mSupportsPictureInPicture) {
3266             return;
3267         }
3268 
3269         final DisplayContent displayContent = getDisplayContent();
3270         if (displayContent == null) {
3271             return;
3272         }
3273 
3274         if (!inPinnedWindowingMode()) {
3275             return;
3276         }
3277 
3278         final PinnedStackController pinnedStackController =
3279                 getDisplayContent().getPinnedStackController();
3280 
3281         if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) == 0) {
3282             return;
3283         }
3284 
3285         // Notify the pinned stack controller about aspect ratio change.
3286         // This would result a callback delivered from SystemUI to WM to start animation,
3287         // if the bounds are ought to be altered due to aspect ratio change.
3288         pinnedStackController.setAspectRatio(
3289                 pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
3290                         ? aspectRatio : -1f);
3291     }
3292 
3293     /**
3294      * Sets the current picture-in-picture actions.
3295      */
setPictureInPictureActions(List<RemoteAction> actions)3296     void setPictureInPictureActions(List<RemoteAction> actions) {
3297         if (!mWmService.mAtmService.mSupportsPictureInPicture) {
3298             return;
3299         }
3300 
3301         if (!inPinnedWindowingMode()) {
3302             return;
3303         }
3304 
3305         getDisplayContent().getPinnedStackController().setActions(actions);
3306     }
3307 
isForceScaled()3308     public boolean isForceScaled() {
3309         return mBoundsAnimating;
3310     }
3311 
3312     /** Returns true if a removal action is still being deferred. */
handleCompleteDeferredRemoval()3313     boolean handleCompleteDeferredRemoval() {
3314         if (isAnimating(TRANSITION | CHILDREN)) {
3315             return true;
3316         }
3317 
3318         return super.handleCompleteDeferredRemoval();
3319     }
3320 
getDisplayInfo()3321     public DisplayInfo getDisplayInfo() {
3322         return mDisplayContent.getDisplayInfo();
3323     }
3324 
getAnimatingActivityRegistry()3325     AnimatingActivityRegistry getAnimatingActivityRegistry() {
3326         return mAnimatingActivityRegistry;
3327     }
3328 
executeAppTransition(ActivityOptions options)3329     void executeAppTransition(ActivityOptions options) {
3330         getDisplay().mDisplayContent.executeAppTransition();
3331         ActivityOptions.abort(options);
3332     }
3333 
shouldSleepActivities()3334     boolean shouldSleepActivities() {
3335         final DisplayContent display = getDisplay();
3336 
3337         // Do not sleep activities in this stack if we're marked as focused and the keyguard
3338         // is in the process of going away.
3339         if (isFocusedStackOnDisplay()
3340                 && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()
3341                 // Avoid resuming activities on secondary displays since we don't want bubble
3342                 // activities to be resumed while bubble is still collapsed.
3343                 // TODO(b/113840485): Having keyguard going away state for secondary displays.
3344                 && display.isDefaultDisplay) {
3345             return false;
3346         }
3347 
3348         return display != null ? display.isSleeping() : mAtmService.isSleepingLocked();
3349     }
3350 
shouldSleepOrShutDownActivities()3351     boolean shouldSleepOrShutDownActivities() {
3352         return shouldSleepActivities() || mAtmService.mShuttingDown;
3353     }
3354 
3355     @Override
dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTraceLogLevel int logLevel)3356     public void dumpDebug(ProtoOutputStream proto, long fieldId,
3357             @WindowTraceLogLevel int logLevel) {
3358         if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
3359             return;
3360         }
3361 
3362         final long token = proto.start(fieldId);
3363         super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
3364 
3365         proto.write(TaskProto.ID, mTaskId);
3366         proto.write(DISPLAY_ID, getDisplayId());
3367         proto.write(ROOT_TASK_ID, getRootTaskId());
3368 
3369         if (mResumedActivity != null) {
3370             mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
3371         }
3372         if (realActivity != null) {
3373             proto.write(REAL_ACTIVITY, realActivity.flattenToShortString());
3374         }
3375         if (origActivity != null) {
3376             proto.write(ORIG_ACTIVITY, origActivity.flattenToShortString());
3377         }
3378         proto.write(ACTIVITY_TYPE, getActivityType());
3379         proto.write(RESIZE_MODE, mResizeMode);
3380         proto.write(MIN_WIDTH, mMinWidth);
3381         proto.write(MIN_HEIGHT, mMinHeight);
3382 
3383         proto.write(FILLS_PARENT, matchParentBounds());
3384         getRawBounds().dumpDebug(proto, BOUNDS);
3385 
3386         if (mLastNonFullscreenBounds != null) {
3387             mLastNonFullscreenBounds.dumpDebug(proto, LAST_NON_FULLSCREEN_BOUNDS);
3388         }
3389 
3390         proto.write(ANIMATING_BOUNDS, mBoundsAnimating);
3391 
3392         if (mSurfaceControl != null) {
3393             proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
3394             proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
3395         }
3396 
3397         proto.write(CREATED_BY_ORGANIZER, mCreatedByOrganizer);
3398 
3399         proto.end(token);
3400     }
3401 }
3402