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