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