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