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.am; 18 19 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 20 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 21 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 22 import static android.app.ActivityManager.StackId.HOME_STACK_ID; 23 import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 24 import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 25 import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; 26 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; 27 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; 28 import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; 29 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING; 30 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; 31 import static android.content.res.Configuration.SCREENLAYOUT_UNDEFINED; 32 import static android.view.Display.DEFAULT_DISPLAY; 33 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE; 34 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 35 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP; 36 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP; 37 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; 38 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS; 39 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN; 40 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE; 41 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; 42 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS; 43 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE; 44 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SCREENSHOTS; 45 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 46 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; 47 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 48 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 49 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TRANSITION; 50 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING; 51 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY; 52 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE; 53 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_APP; 54 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP; 55 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION; 56 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS; 57 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE; 58 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; 59 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS; 60 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SAVED_STATE; 61 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SCREENSHOTS; 62 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 63 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES; 64 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 65 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; 66 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TRANSITION; 67 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING; 68 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY; 69 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 70 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 71 import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN; 72 import static com.android.server.am.ActivityManagerService.TAKE_FULLSCREEN_SCREENSHOTS; 73 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; 74 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; 75 import static com.android.server.am.ActivityRecord.STARTING_WINDOW_REMOVED; 76 import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN; 77 import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; 78 import static com.android.server.am.ActivityStackSupervisor.ON_TOP; 79 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; 80 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE; 81 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; 82 import static com.android.server.wm.AppTransition.TRANSIT_NONE; 83 import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE; 84 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN; 85 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN_BEHIND; 86 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_BACK; 87 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT; 88 89 import android.app.Activity; 90 import android.app.ActivityManager; 91 import android.app.ActivityManager.RunningTaskInfo; 92 import android.app.ActivityManager.StackId; 93 import android.app.ActivityOptions; 94 import android.app.AppGlobals; 95 import android.app.IActivityController; 96 import android.app.ResultInfo; 97 import android.content.ComponentName; 98 import android.content.Intent; 99 import android.content.pm.ActivityInfo; 100 import android.content.pm.ApplicationInfo; 101 import android.content.res.Configuration; 102 import android.graphics.Bitmap; 103 import android.graphics.Point; 104 import android.graphics.Rect; 105 import android.net.Uri; 106 import android.os.Binder; 107 import android.os.Bundle; 108 import android.os.Debug; 109 import android.os.Handler; 110 import android.os.IBinder; 111 import android.os.Looper; 112 import android.os.Message; 113 import android.os.PersistableBundle; 114 import android.os.RemoteException; 115 import android.os.SystemClock; 116 import android.os.Trace; 117 import android.os.UserHandle; 118 import android.service.voice.IVoiceInteractionSession; 119 import android.util.ArraySet; 120 import android.util.EventLog; 121 import android.util.Log; 122 import android.util.Slog; 123 import android.view.Display; 124 125 import com.android.internal.app.IVoiceInteractor; 126 import com.android.internal.content.ReferrerIntent; 127 import com.android.internal.os.BatteryStatsImpl; 128 import com.android.server.Watchdog; 129 import com.android.server.am.ActivityManagerService.ItemMatcher; 130 import com.android.server.am.ActivityStackSupervisor.ActivityContainer; 131 import com.android.server.wm.TaskGroup; 132 import com.android.server.wm.WindowManagerService; 133 134 import java.io.FileDescriptor; 135 import java.io.PrintWriter; 136 import java.lang.ref.WeakReference; 137 import java.util.ArrayList; 138 import java.util.Iterator; 139 import java.util.List; 140 import java.util.Objects; 141 import java.util.Set; 142 143 /** 144 * State and management of a single stack of activities. 145 */ 146 final class ActivityStack { 147 148 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM; 149 private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE; 150 private static final String TAG_APP = TAG + POSTFIX_APP; 151 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP; 152 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; 153 private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS; 154 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; 155 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 156 private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS; 157 private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE; 158 private static final String TAG_SCREENSHOTS = TAG + POSTFIX_SCREENSHOTS; 159 private static final String TAG_STACK = TAG + POSTFIX_STACK; 160 private static final String TAG_STATES = TAG + POSTFIX_STATES; 161 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 162 private static final String TAG_TASKS = TAG + POSTFIX_TASKS; 163 private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION; 164 private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING; 165 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; 166 167 private static final boolean VALIDATE_TOKENS = false; 168 169 // Ticks during which we check progress while waiting for an app to launch. 170 static final int LAUNCH_TICK = 500; 171 172 // How long we wait until giving up on the last activity to pause. This 173 // is short because it directly impacts the responsiveness of starting the 174 // next activity. 175 static final int PAUSE_TIMEOUT = 500; 176 177 // How long we wait for the activity to tell us it has stopped before 178 // giving up. This is a good amount of time because we really need this 179 // from the application in order to get its saved state. 180 static final int STOP_TIMEOUT = 10 * 1000; 181 182 // How long we wait until giving up on an activity telling us it has 183 // finished destroying itself. 184 static final int DESTROY_TIMEOUT = 10 * 1000; 185 186 // How long until we reset a task when the user returns to it. Currently 187 // disabled. 188 static final long ACTIVITY_INACTIVE_RESET_TIME = 0; 189 190 // How long between activity launches that we consider safe to not warn 191 // the user about an unexpected activity being launched on top. 192 static final long START_WARN_TIME = 5 * 1000; 193 194 // Set to false to disable the preview that is shown while a new activity 195 // is being started. 196 static final boolean SHOW_APP_STARTING_PREVIEW = true; 197 198 // How long to wait for all background Activities to redraw following a call to 199 // convertToTranslucent(). 200 static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000; 201 202 // How many activities have to be scheduled to stop to force a stop pass. 203 private static final int MAX_STOPPING_TO_FORCE = 3; 204 205 enum ActivityState { 206 INITIALIZING, 207 RESUMED, 208 PAUSING, 209 PAUSED, 210 STOPPING, 211 STOPPED, 212 FINISHING, 213 DESTROYING, 214 DESTROYED 215 } 216 217 // Stack is not considered visible. 218 static final int STACK_INVISIBLE = 0; 219 // Stack is considered visible 220 static final int STACK_VISIBLE = 1; 221 // Stack is considered visible, but only becuase it has activity that is visible behind other 222 // activities and there is a specific combination of stacks. 223 static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2; 224 225 /* The various modes for the method {@link #removeTask}. */ 226 // Task is being completely removed from all stacks in the system. 227 static final int REMOVE_TASK_MODE_DESTROYING = 0; 228 // Task is being removed from this stack so we can add it to another stack. In the case we are 229 // moving we don't want to perform some operations on the task like removing it from window 230 // manager or recents. 231 static final int REMOVE_TASK_MODE_MOVING = 1; 232 // Similar to {@link #REMOVE_TASK_MODE_MOVING} and the task will be added to the top of its new 233 // stack and the new stack will be on top of all stacks. 234 static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2; 235 236 final ActivityManagerService mService; 237 final WindowManagerService mWindowManager; 238 private final RecentTasks mRecentTasks; 239 240 /** 241 * The back history of all previous (and possibly still 242 * running) activities. It contains #TaskRecord objects. 243 */ 244 private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>(); 245 246 /** 247 * Used for validating app tokens with window manager. 248 */ 249 final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<>(); 250 251 /** 252 * List of running activities, sorted by recent usage. 253 * The first entry in the list is the least recently used. 254 * It contains HistoryRecord objects. 255 */ 256 final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>(); 257 258 /** 259 * Animations that for the current transition have requested not to 260 * be considered for the transition animation. 261 */ 262 final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>(); 263 264 /** 265 * When we are in the process of pausing an activity, before starting the 266 * next one, this variable holds the activity that is currently being paused. 267 */ 268 ActivityRecord mPausingActivity = null; 269 270 /** 271 * This is the last activity that we put into the paused state. This is 272 * used to determine if we need to do an activity transition while sleeping, 273 * when we normally hold the top activity paused. 274 */ 275 ActivityRecord mLastPausedActivity = null; 276 277 /** 278 * Activities that specify No History must be removed once the user navigates away from them. 279 * If the device goes to sleep with such an activity in the paused state then we save it here 280 * and finish it later if another activity replaces it on wakeup. 281 */ 282 ActivityRecord mLastNoHistoryActivity = null; 283 284 /** 285 * Current activity that is resumed, or null if there is none. 286 */ 287 ActivityRecord mResumedActivity = null; 288 289 /** 290 * This is the last activity that has been started. It is only used to 291 * identify when multiple activities are started at once so that the user 292 * can be warned they may not be in the activity they think they are. 293 */ 294 ActivityRecord mLastStartedActivity = null; 295 296 // The topmost Activity passed to convertToTranslucent(). When non-null it means we are 297 // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they 298 // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the 299 // Activity in mTranslucentActivityWaiting is notified via 300 // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last 301 // background activity being drawn then the same call will be made with a true value. 302 ActivityRecord mTranslucentActivityWaiting = null; 303 private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = new ArrayList<>(); 304 305 /** 306 * Set when we know we are going to be calling updateConfiguration() 307 * soon, so want to skip intermediate config checks. 308 */ 309 boolean mConfigWillChange; 310 311 // Whether or not this stack covers the entire screen; by default stacks are fullscreen 312 boolean mFullscreen = true; 313 // Current bounds of the stack or null if fullscreen. 314 Rect mBounds = null; 315 316 boolean mUpdateBoundsDeferred; 317 boolean mUpdateBoundsDeferredCalled; 318 final Rect mDeferredBounds = new Rect(); 319 final Rect mDeferredTaskBounds = new Rect(); 320 final Rect mDeferredTaskInsetBounds = new Rect(); 321 322 long mLaunchStartTime = 0; 323 long mFullyDrawnStartTime = 0; 324 325 int mCurrentUser; 326 327 final int mStackId; 328 final ActivityContainer mActivityContainer; 329 /** The other stacks, in order, on the attached display. Updated at attach/detach time. */ 330 ArrayList<ActivityStack> mStacks; 331 /** The attached Display's unique identifier, or -1 if detached */ 332 int mDisplayId; 333 334 /** Run all ActivityStacks through this */ 335 final ActivityStackSupervisor mStackSupervisor; 336 337 private final LaunchingTaskPositioner mTaskPositioner; 338 339 static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1; 340 static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2; 341 static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3; 342 static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4; 343 static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5; 344 static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; 345 static final int RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG = 346 ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7; 347 348 static class ScheduleDestroyArgs { 349 final ProcessRecord mOwner; 350 final String mReason; 351 ScheduleDestroyArgs(ProcessRecord owner, String reason) { 352 mOwner = owner; 353 mReason = reason; 354 } 355 } 356 357 final Handler mHandler; 358 359 final class ActivityStackHandler extends Handler { 360 361 ActivityStackHandler(Looper looper) { 362 super(looper); 363 } 364 365 @Override 366 public void handleMessage(Message msg) { 367 switch (msg.what) { 368 case PAUSE_TIMEOUT_MSG: { 369 ActivityRecord r = (ActivityRecord)msg.obj; 370 // We don't at this point know if the activity is fullscreen, 371 // so we need to be conservative and assume it isn't. 372 Slog.w(TAG, "Activity pause timeout for " + r); 373 synchronized (mService) { 374 if (r.app != null) { 375 mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r); 376 } 377 activityPausedLocked(r.appToken, true); 378 } 379 } break; 380 case LAUNCH_TICK_MSG: { 381 ActivityRecord r = (ActivityRecord)msg.obj; 382 synchronized (mService) { 383 if (r.continueLaunchTickingLocked()) { 384 mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r); 385 } 386 } 387 } break; 388 case DESTROY_TIMEOUT_MSG: { 389 ActivityRecord r = (ActivityRecord)msg.obj; 390 // We don't at this point know if the activity is fullscreen, 391 // so we need to be conservative and assume it isn't. 392 Slog.w(TAG, "Activity destroy timeout for " + r); 393 synchronized (mService) { 394 activityDestroyedLocked(r != null ? r.appToken : null, "destroyTimeout"); 395 } 396 } break; 397 case STOP_TIMEOUT_MSG: { 398 ActivityRecord r = (ActivityRecord)msg.obj; 399 // We don't at this point know if the activity is fullscreen, 400 // so we need to be conservative and assume it isn't. 401 Slog.w(TAG, "Activity stop timeout for " + r); 402 synchronized (mService) { 403 if (r.isInHistory()) { 404 activityStoppedLocked(r, null, null, null); 405 } 406 } 407 } break; 408 case DESTROY_ACTIVITIES_MSG: { 409 ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj; 410 synchronized (mService) { 411 destroyActivitiesLocked(args.mOwner, args.mReason); 412 } 413 } break; 414 case TRANSLUCENT_TIMEOUT_MSG: { 415 synchronized (mService) { 416 notifyActivityDrawnLocked(null); 417 } 418 } break; 419 case RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG: { 420 synchronized (mService) { 421 final ActivityRecord r = getVisibleBehindActivity(); 422 Slog.e(TAG, "Timeout waiting for cancelVisibleBehind player=" + r); 423 if (r != null) { 424 mService.killAppAtUsersRequest(r.app, null); 425 } 426 } 427 } break; 428 } 429 } 430 } 431 432 int numActivities() { 433 int count = 0; 434 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 435 count += mTaskHistory.get(taskNdx).mActivities.size(); 436 } 437 return count; 438 } 439 440 ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer, 441 RecentTasks recentTasks) { 442 mActivityContainer = activityContainer; 443 mStackSupervisor = activityContainer.getOuter(); 444 mService = mStackSupervisor.mService; 445 mHandler = new ActivityStackHandler(mService.mHandler.getLooper()); 446 mWindowManager = mService.mWindowManager; 447 mStackId = activityContainer.mStackId; 448 mCurrentUser = mService.mUserController.getCurrentUserIdLocked(); 449 mRecentTasks = recentTasks; 450 mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID 451 ? new LaunchingTaskPositioner() : null; 452 } 453 454 void attachDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) { 455 mDisplayId = activityDisplay.mDisplayId; 456 mStacks = activityDisplay.mStacks; 457 mBounds = mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop); 458 mFullscreen = mBounds == null; 459 if (mTaskPositioner != null) { 460 mTaskPositioner.setDisplay(activityDisplay.mDisplay); 461 mTaskPositioner.configure(mBounds); 462 } 463 464 if (mStackId == DOCKED_STACK_ID) { 465 // If we created a docked stack we want to resize it so it resizes all other stacks 466 // in the system. 467 mStackSupervisor.resizeDockedStackLocked( 468 mBounds, null, null, null, null, PRESERVE_WINDOWS); 469 } 470 } 471 472 void detachDisplay() { 473 mDisplayId = Display.INVALID_DISPLAY; 474 mStacks = null; 475 if (mTaskPositioner != null) { 476 mTaskPositioner.reset(); 477 } 478 mWindowManager.detachStack(mStackId); 479 if (mStackId == DOCKED_STACK_ID) { 480 // If we removed a docked stack we want to resize it so it resizes all other stacks 481 // in the system to fullscreen. 482 mStackSupervisor.resizeDockedStackLocked( 483 null, null, null, null, null, PRESERVE_WINDOWS); 484 } 485 } 486 487 public void getDisplaySize(Point out) { 488 mActivityContainer.mActivityDisplay.mDisplay.getSize(out); 489 } 490 491 /** 492 * Defers updating the bounds of the stack. If the stack was resized/repositioned while 493 * deferring, the bounds will update in {@link #continueUpdateBounds()}. 494 */ 495 void deferUpdateBounds() { 496 if (!mUpdateBoundsDeferred) { 497 mUpdateBoundsDeferred = true; 498 mUpdateBoundsDeferredCalled = false; 499 } 500 } 501 502 /** 503 * Continues updating bounds after updates have been deferred. If there was a resize attempt 504 * between {@link #deferUpdateBounds()} and {@link #continueUpdateBounds()}, the stack will 505 * be resized to that bounds. 506 */ 507 void continueUpdateBounds() { 508 final boolean wasDeferred = mUpdateBoundsDeferred; 509 mUpdateBoundsDeferred = false; 510 if (wasDeferred && mUpdateBoundsDeferredCalled) { 511 mStackSupervisor.resizeStackUncheckedLocked(this, 512 mDeferredBounds.isEmpty() ? null : mDeferredBounds, 513 mDeferredTaskBounds.isEmpty() ? null : mDeferredTaskBounds, 514 mDeferredTaskInsetBounds.isEmpty() ? null : mDeferredTaskInsetBounds); 515 } 516 } 517 518 boolean updateBoundsAllowed(Rect bounds, Rect tempTaskBounds, 519 Rect tempTaskInsetBounds) { 520 if (!mUpdateBoundsDeferred) { 521 return true; 522 } 523 if (bounds != null) { 524 mDeferredBounds.set(bounds); 525 } else { 526 mDeferredBounds.setEmpty(); 527 } 528 if (tempTaskBounds != null) { 529 mDeferredTaskBounds.set(tempTaskBounds); 530 } else { 531 mDeferredTaskBounds.setEmpty(); 532 } 533 if (tempTaskInsetBounds != null) { 534 mDeferredTaskInsetBounds.set(tempTaskInsetBounds); 535 } else { 536 mDeferredTaskInsetBounds.setEmpty(); 537 } 538 mUpdateBoundsDeferredCalled = true; 539 return false; 540 } 541 542 void setBounds(Rect bounds) { 543 mBounds = mFullscreen ? null : new Rect(bounds); 544 if (mTaskPositioner != null) { 545 mTaskPositioner.configure(bounds); 546 } 547 } 548 549 boolean okToShowLocked(ActivityRecord r) { 550 return mStackSupervisor.okToShowLocked(r); 551 } 552 553 final ActivityRecord topRunningActivityLocked() { 554 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 555 ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked(); 556 if (r != null) { 557 return r; 558 } 559 } 560 return null; 561 } 562 563 final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) { 564 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 565 final TaskRecord task = mTaskHistory.get(taskNdx); 566 final ArrayList<ActivityRecord> activities = task.mActivities; 567 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 568 ActivityRecord r = activities.get(activityNdx); 569 if (!r.finishing && !r.delayedResume && r != notTop && okToShowLocked(r)) { 570 return r; 571 } 572 } 573 } 574 return null; 575 } 576 577 /** 578 * This is a simplified version of topRunningActivityLocked that provides a number of 579 * optional skip-over modes. It is intended for use with the ActivityController hook only. 580 * 581 * @param token If non-null, any history records matching this token will be skipped. 582 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 583 * 584 * @return Returns the HistoryRecord of the next activity on the stack. 585 */ 586 final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) { 587 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 588 TaskRecord task = mTaskHistory.get(taskNdx); 589 if (task.taskId == taskId) { 590 continue; 591 } 592 ArrayList<ActivityRecord> activities = task.mActivities; 593 for (int i = activities.size() - 1; i >= 0; --i) { 594 final ActivityRecord r = activities.get(i); 595 // Note: the taskId check depends on real taskId fields being non-zero 596 if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) { 597 return r; 598 } 599 } 600 } 601 return null; 602 } 603 604 final ActivityRecord topActivity() { 605 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 606 ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 607 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 608 final ActivityRecord r = activities.get(activityNdx); 609 if (!r.finishing) { 610 return r; 611 } 612 } 613 } 614 return null; 615 } 616 617 final TaskRecord topTask() { 618 final int size = mTaskHistory.size(); 619 if (size > 0) { 620 return mTaskHistory.get(size - 1); 621 } 622 return null; 623 } 624 625 TaskRecord taskForIdLocked(int id) { 626 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 627 final TaskRecord task = mTaskHistory.get(taskNdx); 628 if (task.taskId == id) { 629 return task; 630 } 631 } 632 return null; 633 } 634 635 ActivityRecord isInStackLocked(IBinder token) { 636 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 637 return isInStackLocked(r); 638 } 639 640 ActivityRecord isInStackLocked(ActivityRecord r) { 641 if (r == null) { 642 return null; 643 } 644 final TaskRecord task = r.task; 645 if (task != null && task.stack != null 646 && task.mActivities.contains(r) && mTaskHistory.contains(task)) { 647 if (task.stack != this) Slog.w(TAG, 648 "Illegal state! task does not point to stack it is in."); 649 return r; 650 } 651 return null; 652 } 653 654 final boolean updateLRUListLocked(ActivityRecord r) { 655 final boolean hadit = mLRUActivities.remove(r); 656 mLRUActivities.add(r); 657 return hadit; 658 } 659 660 final boolean isHomeStack() { 661 return mStackId == HOME_STACK_ID; 662 } 663 664 final boolean isDockedStack() { 665 return mStackId == DOCKED_STACK_ID; 666 } 667 668 final boolean isPinnedStack() { 669 return mStackId == PINNED_STACK_ID; 670 } 671 672 final boolean isOnHomeDisplay() { 673 return isAttached() && 674 mActivityContainer.mActivityDisplay.mDisplayId == DEFAULT_DISPLAY; 675 } 676 677 void moveToFront(String reason) { 678 moveToFront(reason, null); 679 } 680 681 /** 682 * @param reason The reason for moving the stack to the front. 683 * @param task If non-null, the task will be moved to the top of the stack. 684 * */ 685 void moveToFront(String reason, TaskRecord task) { 686 if (!isAttached()) { 687 return; 688 } 689 690 mStacks.remove(this); 691 int addIndex = mStacks.size(); 692 693 if (addIndex > 0) { 694 final ActivityStack topStack = mStacks.get(addIndex - 1); 695 if (StackId.isAlwaysOnTop(topStack.mStackId) && topStack != this) { 696 // If the top stack is always on top, we move this stack just below it. 697 addIndex--; 698 } 699 } 700 701 mStacks.add(addIndex, this); 702 703 // TODO(multi-display): Needs to also work if focus is moving to the non-home display. 704 if (isOnHomeDisplay()) { 705 mStackSupervisor.setFocusStackUnchecked(reason, this); 706 } 707 if (task != null) { 708 insertTaskAtTop(task, null); 709 } else { 710 task = topTask(); 711 } 712 if (task != null) { 713 mWindowManager.moveTaskToTop(task.taskId); 714 } 715 } 716 717 boolean isFocusable() { 718 if (StackId.canReceiveKeys(mStackId)) { 719 return true; 720 } 721 // The stack isn't focusable. See if its top activity is focusable to force focus on the 722 // stack. 723 final ActivityRecord r = topRunningActivityLocked(); 724 return r != null && r.isFocusable(); 725 } 726 727 final boolean isAttached() { 728 return mStacks != null; 729 } 730 731 /** 732 * Returns the top activity in any existing task matching the given Intent in the input result. 733 * Returns null if no such task is found. 734 */ 735 void findTaskLocked(ActivityRecord target, FindTaskResult result) { 736 Intent intent = target.intent; 737 ActivityInfo info = target.info; 738 ComponentName cls = intent.getComponent(); 739 if (info.targetActivity != null) { 740 cls = new ComponentName(info.packageName, info.targetActivity); 741 } 742 final int userId = UserHandle.getUserId(info.applicationInfo.uid); 743 boolean isDocument = intent != null & intent.isDocument(); 744 // If documentData is non-null then it must match the existing task data. 745 Uri documentData = isDocument ? intent.getData() : null; 746 747 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + this); 748 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 749 final TaskRecord task = mTaskHistory.get(taskNdx); 750 if (task.voiceSession != null) { 751 // We never match voice sessions; those always run independently. 752 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session"); 753 continue; 754 } 755 if (task.userId != userId) { 756 // Looking for a different task. 757 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user"); 758 continue; 759 } 760 final ActivityRecord r = task.getTopActivity(); 761 if (r == null || r.finishing || r.userId != userId || 762 r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 763 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r); 764 continue; 765 } 766 if (r.mActivityType != target.mActivityType) { 767 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type"); 768 continue; 769 } 770 771 final Intent taskIntent = task.intent; 772 final Intent affinityIntent = task.affinityIntent; 773 final boolean taskIsDocument; 774 final Uri taskDocumentData; 775 if (taskIntent != null && taskIntent.isDocument()) { 776 taskIsDocument = true; 777 taskDocumentData = taskIntent.getData(); 778 } else if (affinityIntent != null && affinityIntent.isDocument()) { 779 taskIsDocument = true; 780 taskDocumentData = affinityIntent.getData(); 781 } else { 782 taskIsDocument = false; 783 taskDocumentData = null; 784 } 785 786 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls=" 787 + taskIntent.getComponent().flattenToShortString() 788 + "/aff=" + r.task.rootAffinity + " to new cls=" 789 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity); 790 // TODO Refactor to remove duplications. Check if logic can be simplified. 791 if (taskIntent != null && taskIntent.getComponent() != null && 792 taskIntent.getComponent().compareTo(cls) == 0 && 793 Objects.equals(documentData, taskDocumentData)) { 794 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!"); 795 //dump(); 796 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 797 "For Intent " + intent + " bringing to top: " + r.intent); 798 result.r = r; 799 result.matchedByRootAffinity = false; 800 break; 801 } else if (affinityIntent != null && affinityIntent.getComponent() != null && 802 affinityIntent.getComponent().compareTo(cls) == 0 && 803 Objects.equals(documentData, taskDocumentData)) { 804 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!"); 805 //dump(); 806 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 807 "For Intent " + intent + " bringing to top: " + r.intent); 808 result.r = r; 809 result.matchedByRootAffinity = false; 810 break; 811 } else if (!isDocument && !taskIsDocument 812 && result.r == null && task.canMatchRootAffinity()) { 813 if (task.rootAffinity.equals(target.taskAffinity)) { 814 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!"); 815 // It is possible for multiple tasks to have the same root affinity especially 816 // if they are in separate stacks. We save off this candidate, but keep looking 817 // to see if there is a better candidate. 818 result.r = r; 819 result.matchedByRootAffinity = true; 820 } 821 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task); 822 } 823 } 824 825 /** 826 * Returns the first activity (starting from the top of the stack) that 827 * is the same as the given activity. Returns null if no such activity 828 * is found. 829 */ 830 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info, 831 boolean compareIntentFilters) { 832 ComponentName cls = intent.getComponent(); 833 if (info.targetActivity != null) { 834 cls = new ComponentName(info.packageName, info.targetActivity); 835 } 836 final int userId = UserHandle.getUserId(info.applicationInfo.uid); 837 838 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 839 final TaskRecord task = mTaskHistory.get(taskNdx); 840 final boolean notCurrentUserTask = 841 !mStackSupervisor.isCurrentProfileLocked(task.userId); 842 final ArrayList<ActivityRecord> activities = task.mActivities; 843 844 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 845 ActivityRecord r = activities.get(activityNdx); 846 if (notCurrentUserTask && (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) { 847 continue; 848 } 849 if (!r.finishing && r.userId == userId) { 850 if (compareIntentFilters) { 851 if (r.intent.filterEquals(intent)) { 852 return r; 853 } 854 } else { 855 if (r.intent.getComponent().equals(cls)) { 856 return r; 857 } 858 } 859 } 860 } 861 } 862 863 return null; 864 } 865 866 /* 867 * Move the activities around in the stack to bring a user to the foreground. 868 */ 869 final void switchUserLocked(int userId) { 870 if (mCurrentUser == userId) { 871 return; 872 } 873 mCurrentUser = userId; 874 875 // Move userId's tasks to the top. 876 int index = mTaskHistory.size(); 877 for (int i = 0; i < index; ) { 878 final TaskRecord task = mTaskHistory.get(i); 879 880 // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is 881 // okay to show the activity when locked. 882 if (mStackSupervisor.isCurrentProfileLocked(task.userId) 883 || task.topRunningActivityLocked() != null) { 884 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "switchUserLocked: stack=" + getStackId() + 885 " moving " + task + " to top"); 886 mTaskHistory.remove(i); 887 mTaskHistory.add(task); 888 --index; 889 // Use same value for i. 890 } else { 891 ++i; 892 } 893 } 894 if (VALIDATE_TOKENS) { 895 validateAppTokensLocked(); 896 } 897 } 898 899 void minimalResumeActivityLocked(ActivityRecord r) { 900 r.state = ActivityState.RESUMED; 901 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)" 902 + " callers=" + Debug.getCallers(5)); 903 mResumedActivity = r; 904 r.task.touchActiveTime(); 905 mRecentTasks.addLocked(r.task); 906 completeResumeLocked(r); 907 mStackSupervisor.checkReadyForSleepLocked(); 908 setLaunchTime(r); 909 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, 910 "Launch completed; removing icicle of " + r.icicle); 911 } 912 913 void addRecentActivityLocked(ActivityRecord r) { 914 if (r != null) { 915 mRecentTasks.addLocked(r.task); 916 r.task.touchActiveTime(); 917 } 918 } 919 920 private void startLaunchTraces(String packageName) { 921 if (mFullyDrawnStartTime != 0) { 922 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0); 923 } 924 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0); 925 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0); 926 } 927 928 private void stopFullyDrawnTraceIfNeeded() { 929 if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) { 930 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0); 931 mFullyDrawnStartTime = 0; 932 } 933 } 934 935 void setLaunchTime(ActivityRecord r) { 936 if (r.displayStartTime == 0) { 937 r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis(); 938 if (mLaunchStartTime == 0) { 939 startLaunchTraces(r.packageName); 940 mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime; 941 } 942 } else if (mLaunchStartTime == 0) { 943 startLaunchTraces(r.packageName); 944 mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis(); 945 } 946 } 947 948 void clearLaunchTime(ActivityRecord r) { 949 // Make sure that there is no activity waiting for this to launch. 950 if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) { 951 r.displayStartTime = r.fullyDrawnStartTime = 0; 952 } else { 953 mStackSupervisor.removeTimeoutsForActivityLocked(r); 954 mStackSupervisor.scheduleIdleTimeoutLocked(r); 955 } 956 } 957 958 void awakeFromSleepingLocked() { 959 // Ensure activities are no longer sleeping. 960 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 961 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 962 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 963 activities.get(activityNdx).setSleeping(false); 964 } 965 } 966 if (mPausingActivity != null) { 967 Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause"); 968 activityPausedLocked(mPausingActivity.appToken, true); 969 } 970 } 971 972 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) { 973 final String packageName = aInfo.packageName; 974 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 975 final List<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 976 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 977 if (packageName.equals(activities.get(activityNdx).packageName)) { 978 activities.get(activityNdx).info.applicationInfo = aInfo; 979 } 980 } 981 } 982 } 983 984 /** 985 * @return true if something must be done before going to sleep. 986 */ 987 boolean checkReadyForSleepLocked() { 988 if (mResumedActivity != null) { 989 // Still have something resumed; can't sleep until it is paused. 990 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity); 991 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, 992 "Sleep => pause with userLeaving=false"); 993 startPausingLocked(false, true, null, false); 994 return true; 995 } 996 if (mPausingActivity != null) { 997 // Still waiting for something to pause; can't sleep yet. 998 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity); 999 return true; 1000 } 1001 1002 if (hasVisibleBehindActivity()) { 1003 // Stop visible behind activity before going to sleep. 1004 final ActivityRecord r = getVisibleBehindActivity(); 1005 mStackSupervisor.mStoppingActivities.add(r); 1006 if (DEBUG_STATES) Slog.v(TAG_STATES, "Sleep still waiting to stop visible behind " + r); 1007 return true; 1008 } 1009 1010 return false; 1011 } 1012 1013 void goToSleep() { 1014 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1015 1016 // Make sure any paused or stopped but visible activities are now sleeping. 1017 // This ensures that the activity's onStop() is called. 1018 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 1019 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 1020 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 1021 final ActivityRecord r = activities.get(activityNdx); 1022 if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED 1023 || r.state == ActivityState.PAUSED || r.state == ActivityState.PAUSING) { 1024 r.setSleeping(true); 1025 } 1026 } 1027 } 1028 } 1029 1030 public final Bitmap screenshotActivitiesLocked(ActivityRecord who) { 1031 if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "screenshotActivitiesLocked: " + who); 1032 if (who.noDisplay) { 1033 if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tNo display"); 1034 return null; 1035 } 1036 1037 if (isHomeStack()) { 1038 // This is an optimization -- since we never show Home or Recents within Recents itself, 1039 // we can just go ahead and skip taking the screenshot if this is the home stack. 1040 if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tHome stack"); 1041 return null; 1042 } 1043 1044 int w = mService.mThumbnailWidth; 1045 int h = mService.mThumbnailHeight; 1046 1047 if (w <= 0) { 1048 Slog.e(TAG, "\tInvalid thumbnail dimensions: " + w + "x" + h); 1049 return null; 1050 } 1051 1052 if (mStackId == DOCKED_STACK_ID && mStackSupervisor.mIsDockMinimized) { 1053 // When the docked stack is minimized its app windows are cropped significantly so any 1054 // screenshot taken will not display the apps contain. So, we avoid taking a screenshot 1055 // in that case. 1056 if (DEBUG_SCREENSHOTS) Slog.e(TAG, "\tIn minimized docked stack"); 1057 return null; 1058 } 1059 1060 float scale = 1f; 1061 if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tTaking screenshot"); 1062 1063 // When this flag is set, we currently take the fullscreen screenshot of the activity but 1064 // scaled to half the size. This gives us a "good-enough" fullscreen thumbnail to use within 1065 // SystemUI while keeping memory usage low. 1066 if (TAKE_FULLSCREEN_SCREENSHOTS) { 1067 w = h = -1; 1068 scale = mService.mFullscreenThumbnailScale; 1069 } 1070 1071 return mWindowManager.screenshotApplications(who.appToken, DEFAULT_DISPLAY, w, h, scale); 1072 } 1073 1074 /** 1075 * Start pausing the currently resumed activity. It is an error to call this if there 1076 * is already an activity being paused or there is no resumed activity. 1077 * 1078 * @param userLeaving True if this should result in an onUserLeaving to the current activity. 1079 * @param uiSleeping True if this is happening with the user interface going to sleep (the 1080 * screen turning off). 1081 * @param resuming The activity we are currently trying to resume or null if this is not being 1082 * called as part of resuming the top activity, so we shouldn't try to instigate 1083 * a resume here if not null. 1084 * @param dontWait True if the caller does not want to wait for the pause to complete. If 1085 * set to true, we will immediately complete the pause here before returning. 1086 * @return Returns true if an activity now is in the PAUSING state, and we are waiting for 1087 * it to tell us when it is done. 1088 */ 1089 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, 1090 ActivityRecord resuming, boolean dontWait) { 1091 if (mPausingActivity != null) { 1092 Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity 1093 + " state=" + mPausingActivity.state); 1094 if (!mService.isSleepingLocked()) { 1095 // Avoid recursion among check for sleep and complete pause during sleeping. 1096 // Because activity will be paused immediately after resume, just let pause 1097 // be completed by the order of activity paused from clients. 1098 completePauseLocked(false, resuming); 1099 } 1100 } 1101 ActivityRecord prev = mResumedActivity; 1102 if (prev == null) { 1103 if (resuming == null) { 1104 Slog.wtf(TAG, "Trying to pause when nothing is resumed"); 1105 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 1106 } 1107 return false; 1108 } 1109 1110 if (mActivityContainer.mParentActivity == null) { 1111 // Top level stack, not a child. Look for child stacks. 1112 mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait); 1113 } 1114 1115 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); 1116 else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev); 1117 mResumedActivity = null; 1118 mPausingActivity = prev; 1119 mLastPausedActivity = prev; 1120 mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 1121 || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null; 1122 prev.state = ActivityState.PAUSING; 1123 prev.task.touchActiveTime(); 1124 clearLaunchTime(prev); 1125 final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(); 1126 if (mService.mHasRecents 1127 && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) { 1128 prev.mUpdateTaskThumbnailWhenHidden = true; 1129 } 1130 stopFullyDrawnTraceIfNeeded(); 1131 1132 mService.updateCpuStats(); 1133 1134 if (prev.app != null && prev.app.thread != null) { 1135 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); 1136 try { 1137 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, 1138 prev.userId, System.identityHashCode(prev), 1139 prev.shortComponentName); 1140 mService.updateUsageStats(prev, false); 1141 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, 1142 userLeaving, prev.configChangeFlags, dontWait); 1143 } catch (Exception e) { 1144 // Ignore exception, if process died other code will cleanup. 1145 Slog.w(TAG, "Exception thrown during pause", e); 1146 mPausingActivity = null; 1147 mLastPausedActivity = null; 1148 mLastNoHistoryActivity = null; 1149 } 1150 } else { 1151 mPausingActivity = null; 1152 mLastPausedActivity = null; 1153 mLastNoHistoryActivity = null; 1154 } 1155 1156 // If we are not going to sleep, we want to ensure the device is 1157 // awake until the next activity is started. 1158 if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) { 1159 mStackSupervisor.acquireLaunchWakelock(); 1160 } 1161 1162 if (mPausingActivity != null) { 1163 // Have the window manager pause its key dispatching until the new 1164 // activity has started. If we're pausing the activity just because 1165 // the screen is being turned off and the UI is sleeping, don't interrupt 1166 // key dispatch; the same activity will pick it up again on wakeup. 1167 if (!uiSleeping) { 1168 prev.pauseKeyDispatchingLocked(); 1169 } else if (DEBUG_PAUSE) { 1170 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off"); 1171 } 1172 1173 if (dontWait) { 1174 // If the caller said they don't want to wait for the pause, then complete 1175 // the pause now. 1176 completePauseLocked(false, resuming); 1177 return false; 1178 1179 } else { 1180 // Schedule a pause timeout in case the app doesn't respond. 1181 // We don't give it much time because this directly impacts the 1182 // responsiveness seen by the user. 1183 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 1184 msg.obj = prev; 1185 prev.pauseTime = SystemClock.uptimeMillis(); 1186 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 1187 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete..."); 1188 return true; 1189 } 1190 1191 } else { 1192 // This activity failed to schedule the 1193 // pause, so just treat it as being paused now. 1194 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next."); 1195 if (resuming == null) { 1196 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 1197 } 1198 return false; 1199 } 1200 } 1201 1202 final void activityPausedLocked(IBinder token, boolean timeout) { 1203 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, 1204 "Activity paused: token=" + token + ", timeout=" + timeout); 1205 1206 final ActivityRecord r = isInStackLocked(token); 1207 if (r != null) { 1208 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 1209 if (mPausingActivity == r) { 1210 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r 1211 + (timeout ? " (due to timeout)" : " (pause complete)")); 1212 completePauseLocked(true, null); 1213 return; 1214 } else { 1215 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, 1216 r.userId, System.identityHashCode(r), r.shortComponentName, 1217 mPausingActivity != null 1218 ? mPausingActivity.shortComponentName : "(none)"); 1219 if (r.state == ActivityState.PAUSING) { 1220 r.state = ActivityState.PAUSED; 1221 if (r.finishing) { 1222 if (DEBUG_PAUSE) Slog.v(TAG, 1223 "Executing finish of failed to pause activity: " + r); 1224 finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false); 1225 } 1226 } 1227 } 1228 } 1229 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1230 } 1231 1232 final void activityResumedLocked(IBinder token) { 1233 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 1234 if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r); 1235 r.icicle = null; 1236 r.haveState = false; 1237 } 1238 1239 final void activityStoppedLocked(ActivityRecord r, Bundle icicle, 1240 PersistableBundle persistentState, CharSequence description) { 1241 if (r.state != ActivityState.STOPPING) { 1242 Slog.i(TAG, "Activity reported stop, but no longer stopping: " + r); 1243 mHandler.removeMessages(STOP_TIMEOUT_MSG, r); 1244 return; 1245 } 1246 if (persistentState != null) { 1247 r.persistentState = persistentState; 1248 mService.notifyTaskPersisterLocked(r.task, false); 1249 } 1250 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + r + ": " + icicle); 1251 if (icicle != null) { 1252 // If icicle is null, this is happening due to a timeout, so we 1253 // haven't really saved the state. 1254 r.icicle = icicle; 1255 r.haveState = true; 1256 r.launchCount = 0; 1257 r.updateThumbnailLocked(null, description); 1258 } 1259 if (!r.stopped) { 1260 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + r + " (stop complete)"); 1261 mHandler.removeMessages(STOP_TIMEOUT_MSG, r); 1262 r.stopped = true; 1263 r.state = ActivityState.STOPPED; 1264 1265 mWindowManager.notifyAppStopped(r.appToken); 1266 1267 if (getVisibleBehindActivity() == r) { 1268 mStackSupervisor.requestVisibleBehindLocked(r, false); 1269 } 1270 if (r.finishing) { 1271 r.clearOptionsLocked(); 1272 } else { 1273 if (r.deferRelaunchUntilPaused) { 1274 destroyActivityLocked(r, true, "stop-config"); 1275 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 1276 } else { 1277 mStackSupervisor.updatePreviousProcessLocked(r); 1278 } 1279 } 1280 } 1281 } 1282 1283 private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) { 1284 ActivityRecord prev = mPausingActivity; 1285 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); 1286 1287 if (prev != null) { 1288 final boolean wasStopping = prev.state == ActivityState.STOPPING; 1289 prev.state = ActivityState.PAUSED; 1290 if (prev.finishing) { 1291 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev); 1292 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false); 1293 } else if (prev.app != null) { 1294 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev 1295 + " wasStopping=" + wasStopping + " visible=" + prev.visible); 1296 if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) { 1297 if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE, 1298 "Complete pause, no longer waiting: " + prev); 1299 } 1300 if (prev.deferRelaunchUntilPaused) { 1301 // Complete the deferred relaunch that was waiting for pause to complete. 1302 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); 1303 relaunchActivityLocked(prev, prev.configChangeFlags, false, 1304 prev.preserveWindowOnDeferredRelaunch); 1305 } else if (wasStopping) { 1306 // We are also stopping, the stop request must have gone soon after the pause. 1307 // We can't clobber it, because the stop confirmation will not be handled. 1308 // We don't need to schedule another stop, we only need to let it happen. 1309 prev.state = ActivityState.STOPPING; 1310 } else if ((!prev.visible && !hasVisibleBehindActivity()) 1311 || mService.isSleepingOrShuttingDownLocked()) { 1312 // If we were visible then resumeTopActivities will release resources before 1313 // stopping. 1314 addToStopping(prev, true /* immediate */); 1315 } 1316 } else { 1317 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev); 1318 prev = null; 1319 } 1320 // It is possible the activity was freezing the screen before it was paused. 1321 // In that case go ahead and remove the freeze this activity has on the screen 1322 // since it is no longer visible. 1323 if (prev != null) { 1324 prev.stopFreezingScreenLocked(true /*force*/); 1325 } 1326 mPausingActivity = null; 1327 } 1328 1329 if (resumeNext) { 1330 final ActivityStack topStack = mStackSupervisor.getFocusedStack(); 1331 if (!mService.isSleepingOrShuttingDownLocked()) { 1332 mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); 1333 } else { 1334 mStackSupervisor.checkReadyForSleepLocked(); 1335 ActivityRecord top = topStack.topRunningActivityLocked(); 1336 if (top == null || (prev != null && top != prev)) { 1337 // If there are no more activities available to run, do resume anyway to start 1338 // something. Also if the top activity on the stack is not the just paused 1339 // activity, we need to go ahead and resume it to ensure we complete an 1340 // in-flight app switch. 1341 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 1342 } 1343 } 1344 } 1345 1346 if (prev != null) { 1347 prev.resumeKeyDispatchingLocked(); 1348 1349 if (prev.app != null && prev.cpuTimeAtResume > 0 1350 && mService.mBatteryStatsService.isOnBattery()) { 1351 long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid) 1352 - prev.cpuTimeAtResume; 1353 if (diff > 0) { 1354 BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics(); 1355 synchronized (bsi) { 1356 BatteryStatsImpl.Uid.Proc ps = 1357 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 1358 prev.info.packageName); 1359 if (ps != null) { 1360 ps.addForegroundTimeLocked(diff); 1361 } 1362 } 1363 } 1364 } 1365 prev.cpuTimeAtResume = 0; // reset it 1366 } 1367 1368 // Notify when the task stack has changed, but only if visibilities changed (not just 1369 // focus). Also if there is an active pinned stack - we always want to notify it about 1370 // task stack changes, because its positioning may depend on it. 1371 if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause 1372 || mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) { 1373 mService.notifyTaskStackChangedLocked(); 1374 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false; 1375 } 1376 1377 mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS); 1378 } 1379 1380 private void addToStopping(ActivityRecord r, boolean immediate) { 1381 if (!mStackSupervisor.mStoppingActivities.contains(r)) { 1382 mStackSupervisor.mStoppingActivities.add(r); 1383 } 1384 1385 // If we already have a few activities waiting to stop, then give up 1386 // on things going idle and start clearing them out. Or if r is the 1387 // last of activity of the last task the stack will be empty and must 1388 // be cleared immediately. 1389 boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE 1390 || (r.frontOfTask && mTaskHistory.size() <= 1); 1391 1392 if (immediate || forceIdle) { 1393 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle=" 1394 + forceIdle + "immediate=" + immediate); 1395 mStackSupervisor.scheduleIdleLocked(); 1396 } else { 1397 mStackSupervisor.checkReadyForSleepLocked(); 1398 } 1399 } 1400 1401 /** 1402 * Once we know that we have asked an application to put an activity in 1403 * the resumed state (either by launching it or explicitly telling it), 1404 * this function updates the rest of our state to match that fact. 1405 */ 1406 private void completeResumeLocked(ActivityRecord next) { 1407 next.visible = true; 1408 next.idle = false; 1409 next.results = null; 1410 next.newIntents = null; 1411 next.stopped = false; 1412 1413 if (next.isHomeActivity()) { 1414 ProcessRecord app = next.task.mActivities.get(0).app; 1415 if (app != null && app != mService.mHomeProcess) { 1416 mService.mHomeProcess = app; 1417 } 1418 } 1419 1420 if (next.nowVisible) { 1421 // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now. 1422 mStackSupervisor.reportActivityVisibleLocked(next); 1423 mStackSupervisor.notifyActivityDrawnForKeyguard(); 1424 } 1425 1426 // schedule an idle timeout in case the app doesn't do it for us. 1427 mStackSupervisor.scheduleIdleTimeoutLocked(next); 1428 1429 mStackSupervisor.reportResumedActivityLocked(next); 1430 1431 next.resumeKeyDispatchingLocked(); 1432 mNoAnimActivities.clear(); 1433 1434 // Mark the point when the activity is resuming 1435 // TODO: To be more accurate, the mark should be before the onCreate, 1436 // not after the onResume. But for subsequent starts, onResume is fine. 1437 if (next.app != null) { 1438 next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid); 1439 } else { 1440 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 1441 } 1442 1443 next.returningOptions = null; 1444 1445 if (getVisibleBehindActivity() == next) { 1446 // When resuming an activity, require it to call requestVisibleBehind() again. 1447 setVisibleBehindActivity(null); 1448 } 1449 } 1450 1451 private void setVisible(ActivityRecord r, boolean visible) { 1452 r.visible = visible; 1453 if (!visible && r.mUpdateTaskThumbnailWhenHidden) { 1454 r.updateThumbnailLocked(r.task.stack.screenshotActivitiesLocked(r), null); 1455 r.mUpdateTaskThumbnailWhenHidden = false; 1456 } 1457 mWindowManager.setAppVisibility(r.appToken, visible); 1458 final ArrayList<ActivityContainer> containers = r.mChildContainers; 1459 for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) { 1460 ActivityContainer container = containers.get(containerNdx); 1461 container.setVisible(visible); 1462 } 1463 mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true; 1464 } 1465 1466 // Find the first visible activity above the passed activity and if it is translucent return it 1467 // otherwise return null; 1468 ActivityRecord findNextTranslucentActivity(ActivityRecord r) { 1469 TaskRecord task = r.task; 1470 if (task == null) { 1471 return null; 1472 } 1473 1474 ActivityStack stack = task.stack; 1475 if (stack == null) { 1476 return null; 1477 } 1478 1479 int stackNdx = mStacks.indexOf(stack); 1480 1481 ArrayList<TaskRecord> tasks = stack.mTaskHistory; 1482 int taskNdx = tasks.indexOf(task); 1483 1484 ArrayList<ActivityRecord> activities = task.mActivities; 1485 int activityNdx = activities.indexOf(r) + 1; 1486 1487 final int numStacks = mStacks.size(); 1488 while (stackNdx < numStacks) { 1489 final ActivityStack historyStack = mStacks.get(stackNdx); 1490 tasks = historyStack.mTaskHistory; 1491 final int numTasks = tasks.size(); 1492 while (taskNdx < numTasks) { 1493 final TaskRecord currentTask = tasks.get(taskNdx); 1494 activities = currentTask.mActivities; 1495 final int numActivities = activities.size(); 1496 while (activityNdx < numActivities) { 1497 final ActivityRecord activity = activities.get(activityNdx); 1498 if (!activity.finishing) { 1499 return historyStack.mFullscreen 1500 && currentTask.mFullscreen && activity.fullscreen ? null : activity; 1501 } 1502 ++activityNdx; 1503 } 1504 activityNdx = 0; 1505 ++taskNdx; 1506 } 1507 taskNdx = 0; 1508 ++stackNdx; 1509 } 1510 1511 return null; 1512 } 1513 1514 ActivityStack getNextFocusableStackLocked() { 1515 ArrayList<ActivityStack> stacks = mStacks; 1516 final ActivityRecord parent = mActivityContainer.mParentActivity; 1517 if (parent != null) { 1518 stacks = parent.task.stack.mStacks; 1519 } 1520 if (stacks != null) { 1521 for (int i = stacks.size() - 1; i >= 0; --i) { 1522 ActivityStack stack = stacks.get(i); 1523 if (stack != this && stack.isFocusable() 1524 && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) { 1525 return stack; 1526 } 1527 } 1528 } 1529 return null; 1530 } 1531 1532 /** Returns true if the stack contains a fullscreen task. */ 1533 private boolean hasFullscreenTask() { 1534 for (int i = mTaskHistory.size() - 1; i >= 0; --i) { 1535 final TaskRecord task = mTaskHistory.get(i); 1536 if (task.mFullscreen) { 1537 return true; 1538 } 1539 } 1540 return false; 1541 } 1542 1543 /** 1544 * Returns true if the stack is translucent and can have other contents visible behind it if 1545 * needed. A stack is considered translucent if it don't contain a visible or 1546 * starting (about to be visible) activity that is fullscreen (opaque). 1547 * @param starting The currently starting activity or null if there is none. 1548 * @param stackBehindId The id of the stack directly behind this one. 1549 */ 1550 private boolean isStackTranslucent(ActivityRecord starting, int stackBehindId) { 1551 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 1552 final TaskRecord task = mTaskHistory.get(taskNdx); 1553 final ArrayList<ActivityRecord> activities = task.mActivities; 1554 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 1555 final ActivityRecord r = activities.get(activityNdx); 1556 1557 if (r.finishing) { 1558 // We don't factor in finishing activities when determining translucency since 1559 // they will be gone soon. 1560 continue; 1561 } 1562 1563 if (!r.visible && r != starting) { 1564 // Also ignore invisible activities that are not the currently starting 1565 // activity (about to be visible). 1566 continue; 1567 } 1568 1569 if (r.fullscreen) { 1570 // Stack isn't translucent if it has at least one fullscreen activity 1571 // that is visible. 1572 return false; 1573 } 1574 1575 if (!isHomeStack() && r.frontOfTask 1576 && task.isOverHomeStack() && stackBehindId != HOME_STACK_ID) { 1577 // Stack isn't translucent if it's top activity should have the home stack 1578 // behind it and the stack currently behind it isn't the home stack. 1579 return false; 1580 } 1581 } 1582 } 1583 return true; 1584 } 1585 1586 /** 1587 * Returns stack's visibility: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE} or 1588 * {@link #STACK_VISIBLE_ACTIVITY_BEHIND}. 1589 * @param starting The currently starting activity or null if there is none. 1590 */ 1591 int getStackVisibilityLocked(ActivityRecord starting) { 1592 if (!isAttached()) { 1593 return STACK_INVISIBLE; 1594 } 1595 1596 if (mStackSupervisor.isFrontStack(this) || mStackSupervisor.isFocusedStack(this)) { 1597 return STACK_VISIBLE; 1598 } 1599 1600 final int stackIndex = mStacks.indexOf(this); 1601 1602 if (stackIndex == mStacks.size() - 1) { 1603 Slog.wtf(TAG, 1604 "Stack=" + this + " isn't front stack but is at the top of the stack list"); 1605 return STACK_INVISIBLE; 1606 } 1607 1608 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack(); 1609 final int focusedStackId = focusedStack.mStackId; 1610 1611 if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID 1612 && hasVisibleBehindActivity() && focusedStackId == HOME_STACK_ID 1613 && !focusedStack.topActivity().fullscreen) { 1614 // The fullscreen stack should be visible if it has a visible behind activity behind 1615 // the home stack that is translucent. 1616 return STACK_VISIBLE_ACTIVITY_BEHIND; 1617 } 1618 1619 if (mStackId == DOCKED_STACK_ID) { 1620 // Docked stack is always visible, except in the case where the top running activity 1621 // task in the focus stack doesn't support any form of resizing but we show it for the 1622 // home task even though it's not resizable. 1623 final ActivityRecord r = focusedStack.topRunningActivityLocked(); 1624 final TaskRecord task = r != null ? r.task : null; 1625 return task == null || task.canGoInDockedStack() || task.isHomeTask() ? STACK_VISIBLE 1626 : STACK_INVISIBLE; 1627 } 1628 1629 // Find the first stack behind focused stack that actually got something visible. 1630 int stackBehindFocusedIndex = mStacks.indexOf(focusedStack) - 1; 1631 while (stackBehindFocusedIndex >= 0 && 1632 mStacks.get(stackBehindFocusedIndex).topRunningActivityLocked() == null) { 1633 stackBehindFocusedIndex--; 1634 } 1635 if ((focusedStackId == DOCKED_STACK_ID || focusedStackId == PINNED_STACK_ID) 1636 && stackIndex == stackBehindFocusedIndex) { 1637 // Stacks directly behind the docked or pinned stack are always visible. 1638 return STACK_VISIBLE; 1639 } 1640 1641 final int stackBehindFocusedId = (stackBehindFocusedIndex >= 0) 1642 ? mStacks.get(stackBehindFocusedIndex).mStackId : INVALID_STACK_ID; 1643 1644 if (focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID 1645 && focusedStack.isStackTranslucent(starting, stackBehindFocusedId)) { 1646 // Stacks behind the fullscreen stack with a translucent activity are always 1647 // visible so they can act as a backdrop to the translucent activity. 1648 // For example, dialog activities 1649 if (stackIndex == stackBehindFocusedIndex) { 1650 return STACK_VISIBLE; 1651 } 1652 if (stackBehindFocusedIndex >= 0) { 1653 if ((stackBehindFocusedId == DOCKED_STACK_ID 1654 || stackBehindFocusedId == PINNED_STACK_ID) 1655 && stackIndex == (stackBehindFocusedIndex - 1)) { 1656 // The stack behind the docked or pinned stack is also visible so we can have a 1657 // complete backdrop to the translucent activity when the docked stack is up. 1658 return STACK_VISIBLE; 1659 } 1660 } 1661 } 1662 1663 if (StackId.isStaticStack(mStackId)) { 1664 // Visibility of any static stack should have been determined by the conditions above. 1665 return STACK_INVISIBLE; 1666 } 1667 1668 for (int i = stackIndex + 1; i < mStacks.size(); i++) { 1669 final ActivityStack stack = mStacks.get(i); 1670 1671 if (!stack.mFullscreen && !stack.hasFullscreenTask()) { 1672 continue; 1673 } 1674 1675 if (!StackId.isDynamicStacksVisibleBehindAllowed(stack.mStackId)) { 1676 // These stacks can't have any dynamic stacks visible behind them. 1677 return STACK_INVISIBLE; 1678 } 1679 1680 if (!stack.isStackTranslucent(starting, INVALID_STACK_ID)) { 1681 return STACK_INVISIBLE; 1682 } 1683 } 1684 1685 return STACK_VISIBLE; 1686 } 1687 1688 final int rankTaskLayers(int baseLayer) { 1689 int layer = 0; 1690 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 1691 final TaskRecord task = mTaskHistory.get(taskNdx); 1692 ActivityRecord r = task.topRunningActivityLocked(); 1693 if (r == null || r.finishing || !r.visible) { 1694 task.mLayerRank = -1; 1695 } else { 1696 task.mLayerRank = baseLayer + layer++; 1697 } 1698 } 1699 return layer; 1700 } 1701 1702 /** 1703 * Make sure that all activities that need to be visible (that is, they 1704 * currently can be seen by the user) actually are. 1705 */ 1706 final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, 1707 boolean preserveWindows) { 1708 ActivityRecord top = topRunningActivityLocked(); 1709 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top 1710 + " configChanges=0x" + Integer.toHexString(configChanges)); 1711 if (top != null) { 1712 checkTranslucentActivityWaiting(top); 1713 } 1714 1715 // If the top activity is not fullscreen, then we need to 1716 // make sure any activities under it are now visible. 1717 boolean aboveTop = top != null; 1718 final int stackVisibility = getStackVisibilityLocked(starting); 1719 final boolean stackInvisible = stackVisibility != STACK_VISIBLE; 1720 final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND; 1721 boolean behindFullscreenActivity = stackInvisible; 1722 boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this) 1723 && (isInStackLocked(starting) == null); 1724 boolean behindTranslucentActivity = false; 1725 final ActivityRecord visibleBehind = getVisibleBehindActivity(); 1726 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 1727 final TaskRecord task = mTaskHistory.get(taskNdx); 1728 final ArrayList<ActivityRecord> activities = task.mActivities; 1729 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 1730 final ActivityRecord r = activities.get(activityNdx); 1731 if (r.finishing) { 1732 // Normally the screenshot will be taken in makeInvisible(). When an activity 1733 // is finishing, we no longer change its visibility, but we still need to take 1734 // the screenshots if startPausingLocked decided it should be taken. 1735 if (r.mUpdateTaskThumbnailWhenHidden) { 1736 r.updateThumbnailLocked(screenshotActivitiesLocked(r), null); 1737 r.mUpdateTaskThumbnailWhenHidden = false; 1738 } 1739 continue; 1740 } 1741 final boolean isTop = r == top; 1742 if (aboveTop && !isTop) { 1743 continue; 1744 } 1745 aboveTop = false; 1746 1747 if (shouldBeVisible(r, behindTranslucentActivity, stackVisibleBehind, 1748 visibleBehind, behindFullscreenActivity)) { 1749 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r 1750 + " finishing=" + r.finishing + " state=" + r.state); 1751 // First: if this is not the current activity being started, make 1752 // sure it matches the current configuration. 1753 if (r != starting) { 1754 ensureActivityConfigurationLocked(r, 0, preserveWindows); 1755 } 1756 1757 if (r.app == null || r.app.thread == null) { 1758 if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop, 1759 resumeNextActivity, r)) { 1760 if (activityNdx >= activities.size()) { 1761 // Record may be removed if its process needs to restart. 1762 activityNdx = activities.size() - 1; 1763 } else { 1764 resumeNextActivity = false; 1765 } 1766 } 1767 } else if (r.visible) { 1768 // If this activity is already visible, then there is nothing to do here. 1769 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, 1770 "Skipping: already visible at " + r); 1771 1772 if (handleAlreadyVisible(r)) { 1773 resumeNextActivity = false; 1774 } 1775 } else { 1776 makeVisibleIfNeeded(starting, r); 1777 } 1778 // Aggregate current change flags. 1779 configChanges |= r.configChangeFlags; 1780 behindFullscreenActivity = updateBehindFullscreen(stackInvisible, 1781 behindFullscreenActivity, task, r); 1782 if (behindFullscreenActivity && !r.fullscreen) { 1783 behindTranslucentActivity = true; 1784 } 1785 } else { 1786 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r 1787 + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible=" 1788 + stackInvisible + " behindFullscreenActivity=" 1789 + behindFullscreenActivity + " mLaunchTaskBehind=" 1790 + r.mLaunchTaskBehind); 1791 makeInvisible(r, visibleBehind); 1792 } 1793 } 1794 if (mStackId == FREEFORM_WORKSPACE_STACK_ID) { 1795 // The visibility of tasks and the activities they contain in freeform stack are 1796 // determined individually unlike other stacks where the visibility or fullscreen 1797 // status of an activity in a previous task affects other. 1798 behindFullscreenActivity = stackVisibility == STACK_INVISIBLE; 1799 } else if (mStackId == HOME_STACK_ID) { 1800 if (task.isHomeTask()) { 1801 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task 1802 + " stackInvisible=" + stackInvisible 1803 + " behindFullscreenActivity=" + behindFullscreenActivity); 1804 // No other task in the home stack should be visible behind the home activity. 1805 // Home activities is usually a translucent activity with the wallpaper behind 1806 // them. However, when they don't have the wallpaper behind them, we want to 1807 // show activities in the next application stack behind them vs. another 1808 // task in the home stack like recents. 1809 behindFullscreenActivity = true; 1810 } else if (task.isRecentsTask() 1811 && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) { 1812 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, 1813 "Recents task returning to app: at " + task 1814 + " stackInvisible=" + stackInvisible 1815 + " behindFullscreenActivity=" + behindFullscreenActivity); 1816 // We don't want any other tasks in the home stack visible if the recents 1817 // activity is going to be returning to an application activity type. 1818 // We do this to preserve the visible order the user used to get into the 1819 // recents activity. The recents activity is normally translucent and if it 1820 // doesn't have the wallpaper behind it the next activity in the home stack 1821 // shouldn't be visible when the home stack is brought to the front to display 1822 // the recents activity from an app. 1823 behindFullscreenActivity = true; 1824 } 1825 1826 } 1827 } 1828 1829 if (mTranslucentActivityWaiting != null && 1830 mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { 1831 // Nothing is getting drawn or everything was already visible, don't wait for timeout. 1832 notifyActivityDrawnLocked(null); 1833 } 1834 } 1835 1836 /** Return true if the input activity should be made visible */ 1837 private boolean shouldBeVisible(ActivityRecord r, boolean behindTranslucentActivity, 1838 boolean stackVisibleBehind, ActivityRecord visibleBehind, 1839 boolean behindFullscreenActivity) { 1840 1841 if (!okToShowLocked(r)) { 1842 return false; 1843 } 1844 1845 // mLaunchingBehind: Activities launching behind are at the back of the task stack 1846 // but must be drawn initially for the animation as though they were visible. 1847 final boolean activityVisibleBehind = 1848 (behindTranslucentActivity || stackVisibleBehind) && visibleBehind == r; 1849 1850 boolean isVisible = 1851 !behindFullscreenActivity || r.mLaunchTaskBehind || activityVisibleBehind; 1852 1853 if (mService.mSupportsLeanbackOnly && isVisible && r.isRecentsActivity()) { 1854 // On devices that support leanback only (Android TV), Recents activity can only be 1855 // visible if the home stack is the focused stack or we are in split-screen mode. 1856 isVisible = mStackSupervisor.getStack(DOCKED_STACK_ID) != null 1857 || mStackSupervisor.isFocusedStack(this); 1858 } 1859 1860 return isVisible; 1861 } 1862 1863 private void checkTranslucentActivityWaiting(ActivityRecord top) { 1864 if (mTranslucentActivityWaiting != top) { 1865 mUndrawnActivitiesBelowTopTranslucent.clear(); 1866 if (mTranslucentActivityWaiting != null) { 1867 // Call the callback with a timeout indication. 1868 notifyActivityDrawnLocked(null); 1869 mTranslucentActivityWaiting = null; 1870 } 1871 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); 1872 } 1873 } 1874 1875 private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges, 1876 boolean isTop, boolean andResume, ActivityRecord r) { 1877 // We need to make sure the app is running if it's the top, or it is just made visible from 1878 // invisible. If the app is already visible, it must have died while it was visible. In this 1879 // case, we'll show the dead window but will not restart the app. Otherwise we could end up 1880 // thrashing. 1881 if (isTop || !r.visible) { 1882 // This activity needs to be visible, but isn't even running... 1883 // get it started and resume if no other stack in this stack is resumed. 1884 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r); 1885 if (r != starting) { 1886 r.startFreezingScreenLocked(r.app, configChanges); 1887 } 1888 if (!r.visible || r.mLaunchTaskBehind) { 1889 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r); 1890 setVisible(r, true); 1891 } 1892 if (r != starting) { 1893 mStackSupervisor.startSpecificActivityLocked(r, andResume, false); 1894 return true; 1895 } 1896 } 1897 return false; 1898 } 1899 1900 private void makeInvisible(ActivityRecord r, ActivityRecord visibleBehind) { 1901 if (!r.visible) { 1902 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r); 1903 return; 1904 } 1905 // Now for any activities that aren't visible to the user, make sure they no longer are 1906 // keeping the screen frozen. 1907 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.state); 1908 try { 1909 setVisible(r, false); 1910 switch (r.state) { 1911 case STOPPING: 1912 case STOPPED: 1913 if (r.app != null && r.app.thread != null) { 1914 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, 1915 "Scheduling invisibility: " + r); 1916 r.app.thread.scheduleWindowVisibility(r.appToken, false); 1917 } 1918 break; 1919 1920 case INITIALIZING: 1921 case RESUMED: 1922 case PAUSING: 1923 case PAUSED: 1924 // This case created for transitioning activities from 1925 // translucent to opaque {@link Activity#convertToOpaque}. 1926 if (visibleBehind == r) { 1927 releaseBackgroundResources(r); 1928 } else { 1929 addToStopping(r, true /* immediate */); 1930 } 1931 break; 1932 1933 default: 1934 break; 1935 } 1936 } catch (Exception e) { 1937 // Just skip on any failure; we'll make it visible when it next restarts. 1938 Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e); 1939 } 1940 } 1941 1942 private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity, 1943 TaskRecord task, ActivityRecord r) { 1944 if (r.fullscreen) { 1945 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r 1946 + " stackInvisible=" + stackInvisible 1947 + " behindFullscreenActivity=" + behindFullscreenActivity); 1948 // At this point, nothing else needs to be shown in this task. 1949 behindFullscreenActivity = true; 1950 } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) { 1951 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r 1952 + " stackInvisible=" + stackInvisible 1953 + " behindFullscreenActivity=" + behindFullscreenActivity); 1954 behindFullscreenActivity = true; 1955 } 1956 return behindFullscreenActivity; 1957 } 1958 1959 private void makeVisibleIfNeeded(ActivityRecord starting, ActivityRecord r) { 1960 1961 // This activity is not currently visible, but is running. Tell it to become visible. 1962 if (r.state == ActivityState.RESUMED || r == starting) { 1963 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, 1964 "Not making visible, r=" + r + " state=" + r.state + " starting=" + starting); 1965 return; 1966 } 1967 1968 // If this activity is paused, tell it to now show its window. 1969 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, 1970 "Making visible and scheduling visibility: " + r); 1971 try { 1972 if (mTranslucentActivityWaiting != null) { 1973 r.updateOptionsLocked(r.returningOptions); 1974 mUndrawnActivitiesBelowTopTranslucent.add(r); 1975 } 1976 setVisible(r, true); 1977 r.sleeping = false; 1978 r.app.pendingUiClean = true; 1979 r.app.thread.scheduleWindowVisibility(r.appToken, true); 1980 // The activity may be waiting for stop, but that is no longer 1981 // appropriate for it. 1982 mStackSupervisor.mStoppingActivities.remove(r); 1983 mStackSupervisor.mGoingToSleepActivities.remove(r); 1984 } catch (Exception e) { 1985 // Just skip on any failure; we'll make it 1986 // visible when it next restarts. 1987 Slog.w(TAG, "Exception thrown making visibile: " + r.intent.getComponent(), e); 1988 } 1989 handleAlreadyVisible(r); 1990 } 1991 1992 private boolean handleAlreadyVisible(ActivityRecord r) { 1993 r.stopFreezingScreenLocked(false); 1994 try { 1995 if (r.returningOptions != null) { 1996 r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions); 1997 } 1998 } catch(RemoteException e) { 1999 } 2000 return r.state == ActivityState.RESUMED; 2001 } 2002 2003 void convertActivityToTranslucent(ActivityRecord r) { 2004 mTranslucentActivityWaiting = r; 2005 mUndrawnActivitiesBelowTopTranslucent.clear(); 2006 mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT); 2007 } 2008 2009 void clearOtherAppTimeTrackers(AppTimeTracker except) { 2010 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 2011 final TaskRecord task = mTaskHistory.get(taskNdx); 2012 final ArrayList<ActivityRecord> activities = task.mActivities; 2013 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2014 final ActivityRecord r = activities.get(activityNdx); 2015 if ( r.appTimeTracker != except) { 2016 r.appTimeTracker = null; 2017 } 2018 } 2019 } 2020 } 2021 2022 /** 2023 * Called as activities below the top translucent activity are redrawn. When the last one is 2024 * redrawn notify the top activity by calling 2025 * {@link Activity#onTranslucentConversionComplete}. 2026 * 2027 * @param r The most recent background activity to be drawn. Or, if r is null then a timeout 2028 * occurred and the activity will be notified immediately. 2029 */ 2030 void notifyActivityDrawnLocked(ActivityRecord r) { 2031 mActivityContainer.setDrawn(); 2032 if ((r == null) 2033 || (mUndrawnActivitiesBelowTopTranslucent.remove(r) && 2034 mUndrawnActivitiesBelowTopTranslucent.isEmpty())) { 2035 // The last undrawn activity below the top has just been drawn. If there is an 2036 // opaque activity at the top, notify it that it can become translucent safely now. 2037 final ActivityRecord waitingActivity = mTranslucentActivityWaiting; 2038 mTranslucentActivityWaiting = null; 2039 mUndrawnActivitiesBelowTopTranslucent.clear(); 2040 mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); 2041 2042 if (waitingActivity != null) { 2043 mWindowManager.setWindowOpaque(waitingActivity.appToken, false); 2044 if (waitingActivity.app != null && waitingActivity.app.thread != null) { 2045 try { 2046 waitingActivity.app.thread.scheduleTranslucentConversionComplete( 2047 waitingActivity.appToken, r != null); 2048 } catch (RemoteException e) { 2049 } 2050 } 2051 } 2052 } 2053 } 2054 2055 /** If any activities below the top running one are in the INITIALIZING state and they have a 2056 * starting window displayed then remove that starting window. It is possible that the activity 2057 * in this state will never resumed in which case that starting window will be orphaned. */ 2058 void cancelInitializingActivities() { 2059 final ActivityRecord topActivity = topRunningActivityLocked(); 2060 boolean aboveTop = true; 2061 // We don't want to clear starting window for activities that aren't behind fullscreen 2062 // activities as we need to display their starting window until they are done initializing. 2063 boolean behindFullscreenActivity = false; 2064 2065 if (getStackVisibilityLocked(null) == STACK_INVISIBLE) { 2066 // The stack is not visible, so no activity in it should be displaying a starting 2067 // window. Mark all activities below top and behind fullscreen. 2068 aboveTop = false; 2069 behindFullscreenActivity = true; 2070 } 2071 2072 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 2073 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 2074 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2075 final ActivityRecord r = activities.get(activityNdx); 2076 if (aboveTop) { 2077 if (r == topActivity) { 2078 aboveTop = false; 2079 } 2080 behindFullscreenActivity |= r.fullscreen; 2081 continue; 2082 } 2083 2084 if (r.state == ActivityState.INITIALIZING 2085 && r.mStartingWindowState == STARTING_WINDOW_SHOWN 2086 && behindFullscreenActivity) { 2087 if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, 2088 "Found orphaned starting window " + r); 2089 r.mStartingWindowState = STARTING_WINDOW_REMOVED; 2090 mWindowManager.removeAppStartingWindow(r.appToken); 2091 } 2092 2093 behindFullscreenActivity |= r.fullscreen; 2094 } 2095 } 2096 } 2097 2098 /** 2099 * Ensure that the top activity in the stack is resumed. 2100 * 2101 * @param prev The previously resumed activity, for when in the process 2102 * of pausing; can be null to call from elsewhere. 2103 * @param options Activity options. 2104 * 2105 * @return Returns true if something is being resumed, or false if 2106 * nothing happened. 2107 * 2108 * NOTE: It is not safe to call this method directly as it can cause an activity in a 2109 * non-focused stack to be resumed. 2110 * Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the 2111 * right activity for the current system state. 2112 */ 2113 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { 2114 if (mStackSupervisor.inResumeTopActivity) { 2115 // Don't even start recursing. 2116 return false; 2117 } 2118 2119 boolean result = false; 2120 try { 2121 // Protect against recursion. 2122 mStackSupervisor.inResumeTopActivity = true; 2123 if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) { 2124 mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN; 2125 mService.updateSleepIfNeededLocked(); 2126 } 2127 result = resumeTopActivityInnerLocked(prev, options); 2128 } finally { 2129 mStackSupervisor.inResumeTopActivity = false; 2130 } 2131 return result; 2132 } 2133 2134 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { 2135 if (DEBUG_LOCKSCREEN) mService.logLockScreen(""); 2136 2137 if (!mService.mBooting && !mService.mBooted) { 2138 // Not ready yet! 2139 return false; 2140 } 2141 2142 ActivityRecord parent = mActivityContainer.mParentActivity; 2143 if ((parent != null && parent.state != ActivityState.RESUMED) || 2144 !mActivityContainer.isAttachedLocked()) { 2145 // Do not resume this stack if its parent is not resumed. 2146 // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st. 2147 return false; 2148 } 2149 2150 mStackSupervisor.cancelInitializingActivities(); 2151 2152 // Find the first activity that is not finishing. 2153 final ActivityRecord next = topRunningActivityLocked(); 2154 2155 // Remember how we'll process this pause/resume situation, and ensure 2156 // that the state is reset however we wind up proceeding. 2157 final boolean userLeaving = mStackSupervisor.mUserLeaving; 2158 mStackSupervisor.mUserLeaving = false; 2159 2160 final TaskRecord prevTask = prev != null ? prev.task : null; 2161 if (next == null) { 2162 // There are no more activities! 2163 final String reason = "noMoreActivities"; 2164 final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() 2165 ? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); 2166 if (!mFullscreen && adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) { 2167 // Try to move focus to the next visible stack with a running activity if this 2168 // stack is not covering the entire screen. 2169 return mStackSupervisor.resumeFocusedStackTopActivityLocked( 2170 mStackSupervisor.getFocusedStack(), prev, null); 2171 } 2172 2173 // Let's just start up the Launcher... 2174 ActivityOptions.abort(options); 2175 if (DEBUG_STATES) Slog.d(TAG_STATES, 2176 "resumeTopActivityLocked: No more activities go home"); 2177 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2178 // Only resume home if on home display 2179 return isOnHomeDisplay() && 2180 mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason); 2181 } 2182 2183 next.delayedResume = false; 2184 2185 // If the top activity is the resumed one, nothing to do. 2186 if (mResumedActivity == next && next.state == ActivityState.RESUMED && 2187 mStackSupervisor.allResumedActivitiesComplete()) { 2188 // Make sure we have executed any pending transitions, since there 2189 // should be nothing left to do at this point. 2190 mWindowManager.executeAppTransition(); 2191 mNoAnimActivities.clear(); 2192 ActivityOptions.abort(options); 2193 if (DEBUG_STATES) Slog.d(TAG_STATES, 2194 "resumeTopActivityLocked: Top activity resumed " + next); 2195 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2196 return false; 2197 } 2198 2199 final TaskRecord nextTask = next.task; 2200 if (prevTask != null && prevTask.stack == this && 2201 prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) { 2202 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2203 if (prevTask == nextTask) { 2204 prevTask.setFrontOfTask(); 2205 } else if (prevTask != topTask()) { 2206 // This task is going away but it was supposed to return to the home stack. 2207 // Now the task above it has to return to the home task instead. 2208 final int taskNdx = mTaskHistory.indexOf(prevTask) + 1; 2209 mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE); 2210 } else if (!isOnHomeDisplay()) { 2211 return false; 2212 } else if (!isHomeStack()){ 2213 if (DEBUG_STATES) Slog.d(TAG_STATES, 2214 "resumeTopActivityLocked: Launching home next"); 2215 final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? 2216 HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); 2217 return isOnHomeDisplay() && 2218 mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished"); 2219 } 2220 } 2221 2222 // If we are sleeping, and there is no resumed activity, and the top 2223 // activity is paused, well that is the state we want. 2224 if (mService.isSleepingOrShuttingDownLocked() 2225 && mLastPausedActivity == next 2226 && mStackSupervisor.allPausedActivitiesComplete()) { 2227 // Make sure we have executed any pending transitions, since there 2228 // should be nothing left to do at this point. 2229 mWindowManager.executeAppTransition(); 2230 mNoAnimActivities.clear(); 2231 ActivityOptions.abort(options); 2232 if (DEBUG_STATES) Slog.d(TAG_STATES, 2233 "resumeTopActivityLocked: Going to sleep and all paused"); 2234 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2235 return false; 2236 } 2237 2238 // Make sure that the user who owns this activity is started. If not, 2239 // we will just leave it as is because someone should be bringing 2240 // another user's activities to the top of the stack. 2241 if (!mService.mUserController.hasStartedUserState(next.userId)) { 2242 Slog.w(TAG, "Skipping resume of top activity " + next 2243 + ": user " + next.userId + " is stopped"); 2244 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2245 return false; 2246 } 2247 2248 // The activity may be waiting for stop, but that is no longer 2249 // appropriate for it. 2250 mStackSupervisor.mStoppingActivities.remove(next); 2251 mStackSupervisor.mGoingToSleepActivities.remove(next); 2252 next.sleeping = false; 2253 mStackSupervisor.mWaitingVisibleActivities.remove(next); 2254 2255 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next); 2256 2257 // If we are currently pausing an activity, then don't do anything until that is done. 2258 if (!mStackSupervisor.allPausedActivitiesComplete()) { 2259 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, 2260 "resumeTopActivityLocked: Skip resume: some activity pausing."); 2261 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2262 return false; 2263 } 2264 2265 mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid); 2266 2267 // We need to start pausing the current activity so the top one can be resumed... 2268 final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0; 2269 boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause); 2270 if (mResumedActivity != null) { 2271 if (DEBUG_STATES) Slog.d(TAG_STATES, 2272 "resumeTopActivityLocked: Pausing " + mResumedActivity); 2273 pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause); 2274 } 2275 if (pausing) { 2276 if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES, 2277 "resumeTopActivityLocked: Skip resume: need to start pausing"); 2278 // At this point we want to put the upcoming activity's process 2279 // at the top of the LRU list, since we know we will be needing it 2280 // very soon and it would be a waste to let it get killed if it 2281 // happens to be sitting towards the end. 2282 if (next.app != null && next.app.thread != null) { 2283 mService.updateLruProcessLocked(next.app, true, null); 2284 } 2285 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2286 return true; 2287 } else if (mResumedActivity == next && next.state == ActivityState.RESUMED && 2288 mStackSupervisor.allResumedActivitiesComplete()) { 2289 // It is possible for the activity to be resumed when we paused back stacks above if the 2290 // next activity doesn't have to wait for pause to complete. 2291 // So, nothing else to-do except: 2292 // Make sure we have executed any pending transitions, since there 2293 // should be nothing left to do at this point. 2294 mWindowManager.executeAppTransition(); 2295 mNoAnimActivities.clear(); 2296 ActivityOptions.abort(options); 2297 if (DEBUG_STATES) Slog.d(TAG_STATES, 2298 "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next); 2299 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2300 return true; 2301 } 2302 2303 // If the most recent activity was noHistory but was only stopped rather 2304 // than stopped+finished because the device went to sleep, we need to make 2305 // sure to finish it as we're making a new activity topmost. 2306 if (mService.isSleepingLocked() && mLastNoHistoryActivity != null && 2307 !mLastNoHistoryActivity.finishing) { 2308 if (DEBUG_STATES) Slog.d(TAG_STATES, 2309 "no-history finish of " + mLastNoHistoryActivity + " on new resume"); 2310 requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED, 2311 null, "resume-no-history", false); 2312 mLastNoHistoryActivity = null; 2313 } 2314 2315 if (prev != null && prev != next) { 2316 if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev) 2317 && next != null && !next.nowVisible) { 2318 mStackSupervisor.mWaitingVisibleActivities.add(prev); 2319 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 2320 "Resuming top, waiting visible to hide: " + prev); 2321 } else { 2322 // The next activity is already visible, so hide the previous 2323 // activity's windows right now so we can show the new one ASAP. 2324 // We only do this if the previous is finishing, which should mean 2325 // it is on top of the one being resumed so hiding it quickly 2326 // is good. Otherwise, we want to do the normal route of allowing 2327 // the resumed activity to be shown so we can decide if the 2328 // previous should actually be hidden depending on whether the 2329 // new one is found to be full-screen or not. 2330 if (prev.finishing) { 2331 mWindowManager.setAppVisibility(prev.appToken, false); 2332 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 2333 "Not waiting for visible to hide: " + prev + ", waitingVisible=" 2334 + mStackSupervisor.mWaitingVisibleActivities.contains(prev) 2335 + ", nowVisible=" + next.nowVisible); 2336 } else { 2337 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 2338 "Previous already visible but still waiting to hide: " + prev 2339 + ", waitingVisible=" 2340 + mStackSupervisor.mWaitingVisibleActivities.contains(prev) 2341 + ", nowVisible=" + next.nowVisible); 2342 } 2343 } 2344 } 2345 2346 // Launching this app's activity, make sure the app is no longer 2347 // considered stopped. 2348 try { 2349 AppGlobals.getPackageManager().setPackageStoppedState( 2350 next.packageName, false, next.userId); /* TODO: Verify if correct userid */ 2351 } catch (RemoteException e1) { 2352 } catch (IllegalArgumentException e) { 2353 Slog.w(TAG, "Failed trying to unstop package " 2354 + next.packageName + ": " + e); 2355 } 2356 2357 // We are starting up the next activity, so tell the window manager 2358 // that the previous one will be hidden soon. This way it can know 2359 // to ignore it when computing the desired screen orientation. 2360 boolean anim = true; 2361 if (prev != null) { 2362 if (prev.finishing) { 2363 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, 2364 "Prepare close transition: prev=" + prev); 2365 if (mNoAnimActivities.contains(prev)) { 2366 anim = false; 2367 mWindowManager.prepareAppTransition(TRANSIT_NONE, false); 2368 } else { 2369 mWindowManager.prepareAppTransition(prev.task == next.task 2370 ? TRANSIT_ACTIVITY_CLOSE 2371 : TRANSIT_TASK_CLOSE, false); 2372 } 2373 mWindowManager.setAppVisibility(prev.appToken, false); 2374 } else { 2375 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, 2376 "Prepare open transition: prev=" + prev); 2377 if (mNoAnimActivities.contains(next)) { 2378 anim = false; 2379 mWindowManager.prepareAppTransition(TRANSIT_NONE, false); 2380 } else { 2381 mWindowManager.prepareAppTransition(prev.task == next.task 2382 ? TRANSIT_ACTIVITY_OPEN 2383 : next.mLaunchTaskBehind 2384 ? TRANSIT_TASK_OPEN_BEHIND 2385 : TRANSIT_TASK_OPEN, false); 2386 } 2387 } 2388 } else { 2389 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous"); 2390 if (mNoAnimActivities.contains(next)) { 2391 anim = false; 2392 mWindowManager.prepareAppTransition(TRANSIT_NONE, false); 2393 } else { 2394 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false); 2395 } 2396 } 2397 2398 Bundle resumeAnimOptions = null; 2399 if (anim) { 2400 ActivityOptions opts = next.getOptionsForTargetActivityLocked(); 2401 if (opts != null) { 2402 resumeAnimOptions = opts.toBundle(); 2403 } 2404 next.applyOptionsLocked(); 2405 } else { 2406 next.clearOptionsLocked(); 2407 } 2408 2409 ActivityStack lastStack = mStackSupervisor.getLastStack(); 2410 if (next.app != null && next.app.thread != null) { 2411 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next 2412 + " stopped=" + next.stopped + " visible=" + next.visible); 2413 2414 // If the previous activity is translucent, force a visibility update of 2415 // the next activity, so that it's added to WM's opening app list, and 2416 // transition animation can be set up properly. 2417 // For example, pressing Home button with a translucent activity in focus. 2418 // Launcher is already visible in this case. If we don't add it to opening 2419 // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a 2420 // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation. 2421 final boolean lastActivityTranslucent = lastStack != null 2422 && (!lastStack.mFullscreen 2423 || (lastStack.mLastPausedActivity != null 2424 && !lastStack.mLastPausedActivity.fullscreen)); 2425 2426 // This activity is now becoming visible. 2427 if (!next.visible || next.stopped || lastActivityTranslucent) { 2428 mWindowManager.setAppVisibility(next.appToken, true); 2429 } 2430 2431 // schedule launch ticks to collect information about slow apps. 2432 next.startLaunchTickingLocked(); 2433 2434 ActivityRecord lastResumedActivity = 2435 lastStack == null ? null :lastStack.mResumedActivity; 2436 ActivityState lastState = next.state; 2437 2438 mService.updateCpuStats(); 2439 2440 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)"); 2441 next.state = ActivityState.RESUMED; 2442 mResumedActivity = next; 2443 next.task.touchActiveTime(); 2444 mRecentTasks.addLocked(next.task); 2445 mService.updateLruProcessLocked(next.app, true, null); 2446 updateLRUListLocked(next); 2447 mService.updateOomAdjLocked(); 2448 2449 // Have the window manager re-evaluate the orientation of 2450 // the screen based on the new activity order. 2451 boolean notUpdated = true; 2452 if (mStackSupervisor.isFocusedStack(this)) { 2453 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2454 mService.mConfiguration, 2455 next.mayFreezeScreenLocked(next.app) ? next.appToken : null); 2456 if (config != null) { 2457 next.frozenBeforeDestroy = true; 2458 } 2459 notUpdated = !mService.updateConfigurationLocked(config, next, false); 2460 } 2461 2462 if (notUpdated) { 2463 // The configuration update wasn't able to keep the existing 2464 // instance of the activity, and instead started a new one. 2465 // We should be all done, but let's just make sure our activity 2466 // is still at the top and schedule another run if something 2467 // weird happened. 2468 ActivityRecord nextNext = topRunningActivityLocked(); 2469 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES, 2470 "Activity config changed during resume: " + next 2471 + ", new next: " + nextNext); 2472 if (nextNext != next) { 2473 // Do over! 2474 mStackSupervisor.scheduleResumeTopActivities(); 2475 } 2476 if (mStackSupervisor.reportResumedActivityLocked(next)) { 2477 mNoAnimActivities.clear(); 2478 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2479 return true; 2480 } 2481 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2482 return false; 2483 } 2484 2485 try { 2486 // Deliver all pending results. 2487 ArrayList<ResultInfo> a = next.results; 2488 if (a != null) { 2489 final int N = a.size(); 2490 if (!next.finishing && N > 0) { 2491 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, 2492 "Delivering results to " + next + ": " + a); 2493 next.app.thread.scheduleSendResult(next.appToken, a); 2494 } 2495 } 2496 2497 boolean allowSavedSurface = true; 2498 if (next.newIntents != null) { 2499 // Restrict saved surface to launcher start, or there is no intent at all 2500 // (eg. task being brought to front). If the intent is something else, 2501 // likely the app is going to show some specific page or view, instead of 2502 // what's left last time. 2503 for (int i = next.newIntents.size() - 1; i >= 0; i--) { 2504 final Intent intent = next.newIntents.get(i); 2505 if (intent != null && !ActivityRecord.isMainIntent(intent)) { 2506 allowSavedSurface = false; 2507 break; 2508 } 2509 } 2510 next.app.thread.scheduleNewIntent( 2511 next.newIntents, next.appToken, false /* andPause */); 2512 } 2513 2514 // Well the app will no longer be stopped. 2515 // Clear app token stopped state in window manager if needed. 2516 mWindowManager.notifyAppResumed(next.appToken, next.stopped, allowSavedSurface); 2517 2518 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, 2519 System.identityHashCode(next), next.task.taskId, next.shortComponentName); 2520 2521 next.sleeping = false; 2522 mService.showUnsupportedZoomDialogIfNeededLocked(next); 2523 mService.showAskCompatModeDialogLocked(next); 2524 next.app.pendingUiClean = true; 2525 next.app.forceProcessStateUpTo(mService.mTopProcessState); 2526 next.clearOptionsLocked(); 2527 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, 2528 mService.isNextTransitionForward(), resumeAnimOptions); 2529 2530 mStackSupervisor.checkReadyForSleepLocked(); 2531 2532 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " + next); 2533 } catch (Exception e) { 2534 // Whoops, need to restart this activity! 2535 if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to " 2536 + lastState + ": " + next); 2537 next.state = lastState; 2538 if (lastStack != null) { 2539 lastStack.mResumedActivity = lastResumedActivity; 2540 } 2541 Slog.i(TAG, "Restarting because process died: " + next); 2542 if (!next.hasBeenLaunched) { 2543 next.hasBeenLaunched = true; 2544 } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null && 2545 mStackSupervisor.isFrontStack(lastStack)) { 2546 next.showStartingWindow(null, true); 2547 } 2548 mStackSupervisor.startSpecificActivityLocked(next, true, false); 2549 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2550 return true; 2551 } 2552 2553 // From this point on, if something goes wrong there is no way 2554 // to recover the activity. 2555 try { 2556 completeResumeLocked(next); 2557 } catch (Exception e) { 2558 // If any exception gets thrown, toss away this 2559 // activity and try the next one. 2560 Slog.w(TAG, "Exception thrown during resume of " + next, e); 2561 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null, 2562 "resume-exception", true); 2563 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2564 return true; 2565 } 2566 } else { 2567 // Whoops, need to restart this activity! 2568 if (!next.hasBeenLaunched) { 2569 next.hasBeenLaunched = true; 2570 } else { 2571 if (SHOW_APP_STARTING_PREVIEW) { 2572 next.showStartingWindow(null, true); 2573 } 2574 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next); 2575 } 2576 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); 2577 mStackSupervisor.startSpecificActivityLocked(next, true, true); 2578 } 2579 2580 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2581 return true; 2582 } 2583 2584 private TaskRecord getNextTask(TaskRecord targetTask) { 2585 final int index = mTaskHistory.indexOf(targetTask); 2586 if (index >= 0) { 2587 final int numTasks = mTaskHistory.size(); 2588 for (int i = index + 1; i < numTasks; ++i) { 2589 TaskRecord task = mTaskHistory.get(i); 2590 if (task.userId == targetTask.userId) { 2591 return task; 2592 } 2593 } 2594 } 2595 return null; 2596 } 2597 2598 private void insertTaskAtPosition(TaskRecord task, int position) { 2599 if (position >= mTaskHistory.size()) { 2600 insertTaskAtTop(task, null); 2601 return; 2602 } 2603 // Calculate maximum possible position for this task. 2604 int maxPosition = mTaskHistory.size(); 2605 if (!mStackSupervisor.isCurrentProfileLocked(task.userId) 2606 && task.topRunningActivityLocked() == null) { 2607 // Put non-current user tasks below current user tasks. 2608 while (maxPosition > 0) { 2609 final TaskRecord tmpTask = mTaskHistory.get(maxPosition - 1); 2610 if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId) 2611 || tmpTask.topRunningActivityLocked() == null) { 2612 break; 2613 } 2614 maxPosition--; 2615 } 2616 } 2617 position = Math.min(position, maxPosition); 2618 mTaskHistory.remove(task); 2619 mTaskHistory.add(position, task); 2620 updateTaskMovement(task, true); 2621 } 2622 2623 private void insertTaskAtTop(TaskRecord task, ActivityRecord newActivity) { 2624 boolean isLastTaskOverHome = false; 2625 // If the moving task is over home stack, transfer its return type to next task 2626 if (task.isOverHomeStack()) { 2627 final TaskRecord nextTask = getNextTask(task); 2628 if (nextTask != null) { 2629 nextTask.setTaskToReturnTo(task.getTaskToReturnTo()); 2630 } else { 2631 isLastTaskOverHome = true; 2632 } 2633 } 2634 2635 // If this is being moved to the top by another activity or being launched from the home 2636 // activity, set mTaskToReturnTo accordingly. 2637 if (isOnHomeDisplay()) { 2638 ActivityStack lastStack = mStackSupervisor.getLastStack(); 2639 final boolean fromHome = lastStack.isHomeStack(); 2640 if (!isHomeStack() && (fromHome || topTask() != task)) { 2641 // If it's a last task over home - we default to keep its return to type not to 2642 // make underlying task focused when this one will be finished. 2643 int returnToType = isLastTaskOverHome 2644 ? task.getTaskToReturnTo() : APPLICATION_ACTIVITY_TYPE; 2645 if (fromHome && StackId.allowTopTaskToReturnHome(mStackId)) { 2646 returnToType = lastStack.topTask() == null 2647 ? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType; 2648 } 2649 task.setTaskToReturnTo(returnToType); 2650 } 2651 } else { 2652 task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); 2653 } 2654 2655 mTaskHistory.remove(task); 2656 // Now put task at top. 2657 int taskNdx = mTaskHistory.size(); 2658 final boolean notShownWhenLocked = 2659 (newActivity != null && (newActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) 2660 || (newActivity == null && task.topRunningActivityLocked() == null); 2661 if (!mStackSupervisor.isCurrentProfileLocked(task.userId) && notShownWhenLocked) { 2662 // Put non-current user tasks below current user tasks. 2663 while (--taskNdx >= 0) { 2664 final TaskRecord tmpTask = mTaskHistory.get(taskNdx); 2665 if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId) 2666 || tmpTask.topRunningActivityLocked() == null) { 2667 break; 2668 } 2669 } 2670 ++taskNdx; 2671 } 2672 mTaskHistory.add(taskNdx, task); 2673 updateTaskMovement(task, true); 2674 } 2675 2676 final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition, 2677 ActivityOptions options) { 2678 TaskRecord rTask = r.task; 2679 final int taskId = rTask.taskId; 2680 // mLaunchTaskBehind tasks get placed at the back of the task stack. 2681 if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) { 2682 // Last activity in task had been removed or ActivityManagerService is reusing task. 2683 // Insert or replace. 2684 // Might not even be in. 2685 insertTaskAtTop(rTask, r); 2686 mWindowManager.moveTaskToTop(taskId); 2687 } 2688 TaskRecord task = null; 2689 if (!newTask) { 2690 // If starting in an existing task, find where that is... 2691 boolean startIt = true; 2692 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 2693 task = mTaskHistory.get(taskNdx); 2694 if (task.getTopActivity() == null) { 2695 // All activities in task are finishing. 2696 continue; 2697 } 2698 if (task == r.task) { 2699 // Here it is! Now, if this is not yet visible to the 2700 // user, then just add it without starting; it will 2701 // get started when the user navigates back to it. 2702 if (!startIt) { 2703 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " 2704 + task, new RuntimeException("here").fillInStackTrace()); 2705 task.addActivityToTop(r); 2706 r.putInHistory(); 2707 addConfigOverride(r, task); 2708 if (VALIDATE_TOKENS) { 2709 validateAppTokensLocked(); 2710 } 2711 ActivityOptions.abort(options); 2712 return; 2713 } 2714 break; 2715 } else if (task.numFullscreen > 0) { 2716 startIt = false; 2717 } 2718 } 2719 } 2720 2721 // Place a new activity at top of stack, so it is next to interact 2722 // with the user. 2723 2724 // If we are not placing the new activity frontmost, we do not want 2725 // to deliver the onUserLeaving callback to the actual frontmost 2726 // activity 2727 if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) { 2728 mStackSupervisor.mUserLeaving = false; 2729 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, 2730 "startActivity() behind front, mUserLeaving=false"); 2731 } 2732 2733 task = r.task; 2734 2735 // Slot the activity into the history stack and proceed 2736 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task, 2737 new RuntimeException("here").fillInStackTrace()); 2738 task.addActivityToTop(r); 2739 task.setFrontOfTask(); 2740 2741 r.putInHistory(); 2742 if (!isHomeStack() || numActivities() > 0) { 2743 // We want to show the starting preview window if we are 2744 // switching to a new task, or the next activity's process is 2745 // not currently running. 2746 boolean showStartingIcon = newTask; 2747 ProcessRecord proc = r.app; 2748 if (proc == null) { 2749 proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2750 } 2751 if (proc == null || proc.thread == null) { 2752 showStartingIcon = true; 2753 } 2754 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, 2755 "Prepare open transition: starting " + r); 2756 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 2757 mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition); 2758 mNoAnimActivities.add(r); 2759 } else { 2760 mWindowManager.prepareAppTransition(newTask 2761 ? r.mLaunchTaskBehind 2762 ? TRANSIT_TASK_OPEN_BEHIND 2763 : TRANSIT_TASK_OPEN 2764 : TRANSIT_ACTIVITY_OPEN, keepCurTransition); 2765 mNoAnimActivities.remove(r); 2766 } 2767 addConfigOverride(r, task); 2768 boolean doShow = true; 2769 if (newTask) { 2770 // Even though this activity is starting fresh, we still need 2771 // to reset it to make sure we apply affinities to move any 2772 // existing activities from other tasks in to it. 2773 // If the caller has requested that the target task be 2774 // reset, then do so. 2775 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2776 resetTaskIfNeededLocked(r, r); 2777 doShow = topRunningNonDelayedActivityLocked(null) == r; 2778 } 2779 } else if (options != null && options.getAnimationType() 2780 == ActivityOptions.ANIM_SCENE_TRANSITION) { 2781 doShow = false; 2782 } 2783 if (r.mLaunchTaskBehind) { 2784 // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we 2785 // tell WindowManager that r is visible even though it is at the back of the stack. 2786 mWindowManager.setAppVisibility(r.appToken, true); 2787 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2788 } else if (SHOW_APP_STARTING_PREVIEW && doShow) { 2789 // Figure out if we are transitioning from another activity that is 2790 // "has the same starting icon" as the next one. This allows the 2791 // window manager to keep the previous window it had previously 2792 // created, if it still had one. 2793 ActivityRecord prev = r.task.topRunningActivityWithStartingWindowLocked(); 2794 if (prev != null) { 2795 // We don't want to reuse the previous starting preview if: 2796 // (1) The current activity is in a different task. 2797 if (prev.task != r.task) { 2798 prev = null; 2799 } 2800 // (2) The current activity is already displayed. 2801 else if (prev.nowVisible) { 2802 prev = null; 2803 } 2804 } 2805 r.showStartingWindow(prev, showStartingIcon); 2806 } 2807 } else { 2808 // If this is the first activity, don't do any fancy animations, 2809 // because there is nothing for it to animate on top of. 2810 addConfigOverride(r, task); 2811 ActivityOptions.abort(options); 2812 options = null; 2813 } 2814 if (VALIDATE_TOKENS) { 2815 validateAppTokensLocked(); 2816 } 2817 } 2818 2819 final void validateAppTokensLocked() { 2820 mValidateAppTokens.clear(); 2821 mValidateAppTokens.ensureCapacity(numActivities()); 2822 final int numTasks = mTaskHistory.size(); 2823 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { 2824 TaskRecord task = mTaskHistory.get(taskNdx); 2825 final ArrayList<ActivityRecord> activities = task.mActivities; 2826 if (activities.isEmpty()) { 2827 continue; 2828 } 2829 TaskGroup group = new TaskGroup(); 2830 group.taskId = task.taskId; 2831 mValidateAppTokens.add(group); 2832 final int numActivities = activities.size(); 2833 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { 2834 final ActivityRecord r = activities.get(activityNdx); 2835 group.tokens.add(r.appToken); 2836 } 2837 } 2838 mWindowManager.validateAppTokens(mStackId, mValidateAppTokens); 2839 } 2840 2841 /** 2842 * Perform a reset of the given task, if needed as part of launching it. 2843 * Returns the new HistoryRecord at the top of the task. 2844 */ 2845 /** 2846 * Helper method for #resetTaskIfNeededLocked. 2847 * We are inside of the task being reset... we'll either finish this activity, push it out 2848 * for another task, or leave it as-is. 2849 * @param task The task containing the Activity (taskTop) that might be reset. 2850 * @param forceReset 2851 * @return An ActivityOptions that needs to be processed. 2852 */ 2853 final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) { 2854 ActivityOptions topOptions = null; 2855 2856 int replyChainEnd = -1; 2857 boolean canMoveOptions = true; 2858 2859 // We only do this for activities that are not the root of the task (since if we finish 2860 // the root, we may no longer have the task!). 2861 final ArrayList<ActivityRecord> activities = task.mActivities; 2862 final int numActivities = activities.size(); 2863 final int rootActivityNdx = task.findEffectiveRootIndex(); 2864 for (int i = numActivities - 1; i > rootActivityNdx; --i ) { 2865 ActivityRecord target = activities.get(i); 2866 if (target.frontOfTask) 2867 break; 2868 2869 final int flags = target.info.flags; 2870 final boolean finishOnTaskLaunch = 2871 (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 2872 final boolean allowTaskReparenting = 2873 (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 2874 final boolean clearWhenTaskReset = 2875 (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 2876 2877 if (!finishOnTaskLaunch 2878 && !clearWhenTaskReset 2879 && target.resultTo != null) { 2880 // If this activity is sending a reply to a previous 2881 // activity, we can't do anything with it now until 2882 // we reach the start of the reply chain. 2883 // XXX note that we are assuming the result is always 2884 // to the previous activity, which is almost always 2885 // the case but we really shouldn't count on. 2886 if (replyChainEnd < 0) { 2887 replyChainEnd = i; 2888 } 2889 } else if (!finishOnTaskLaunch 2890 && !clearWhenTaskReset 2891 && allowTaskReparenting 2892 && target.taskAffinity != null 2893 && !target.taskAffinity.equals(task.affinity)) { 2894 // If this activity has an affinity for another 2895 // task, then we need to move it out of here. We will 2896 // move it as far out of the way as possible, to the 2897 // bottom of the activity stack. This also keeps it 2898 // correctly ordered with any activities we previously 2899 // moved. 2900 final TaskRecord targetTask; 2901 final ActivityRecord bottom = 2902 !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ? 2903 mTaskHistory.get(0).mActivities.get(0) : null; 2904 if (bottom != null && target.taskAffinity != null 2905 && target.taskAffinity.equals(bottom.task.affinity)) { 2906 // If the activity currently at the bottom has the 2907 // same task affinity as the one we are moving, 2908 // then merge it into the same task. 2909 targetTask = bottom.task; 2910 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target 2911 + " out to bottom task " + bottom.task); 2912 } else { 2913 targetTask = createTaskRecord( 2914 mStackSupervisor.getNextTaskIdForUserLocked(target.userId), 2915 target.info, null, null, null, false); 2916 targetTask.affinityIntent = target.intent; 2917 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target 2918 + " out to new task " + target.task); 2919 } 2920 2921 setAppTask(target, targetTask); 2922 2923 boolean noOptions = canMoveOptions; 2924 final int start = replyChainEnd < 0 ? i : replyChainEnd; 2925 for (int srcPos = start; srcPos >= i; --srcPos) { 2926 final ActivityRecord p = activities.get(srcPos); 2927 if (p.finishing) { 2928 continue; 2929 } 2930 2931 canMoveOptions = false; 2932 if (noOptions && topOptions == null) { 2933 topOptions = p.takeOptionsLocked(); 2934 if (topOptions != null) { 2935 noOptions = false; 2936 } 2937 } 2938 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE, 2939 "Removing activity " + p + " from task=" + task + " adding to task=" 2940 + targetTask + " Callers=" + Debug.getCallers(4)); 2941 if (DEBUG_TASKS) Slog.v(TAG_TASKS, 2942 "Pushing next activity " + p + " out to target's task " + target.task); 2943 p.setTask(targetTask, null); 2944 targetTask.addActivityAtBottom(p); 2945 2946 setAppTask(p, targetTask); 2947 } 2948 2949 mWindowManager.moveTaskToBottom(targetTask.taskId); 2950 if (VALIDATE_TOKENS) { 2951 validateAppTokensLocked(); 2952 } 2953 2954 replyChainEnd = -1; 2955 } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) { 2956 // If the activity should just be removed -- either 2957 // because it asks for it, or the task should be 2958 // cleared -- then finish it and anything that is 2959 // part of its reply chain. 2960 int end; 2961 if (clearWhenTaskReset) { 2962 // In this case, we want to finish this activity 2963 // and everything above it, so be sneaky and pretend 2964 // like these are all in the reply chain. 2965 end = activities.size() - 1; 2966 } else if (replyChainEnd < 0) { 2967 end = i; 2968 } else { 2969 end = replyChainEnd; 2970 } 2971 boolean noOptions = canMoveOptions; 2972 for (int srcPos = i; srcPos <= end; srcPos++) { 2973 ActivityRecord p = activities.get(srcPos); 2974 if (p.finishing) { 2975 continue; 2976 } 2977 canMoveOptions = false; 2978 if (noOptions && topOptions == null) { 2979 topOptions = p.takeOptionsLocked(); 2980 if (topOptions != null) { 2981 noOptions = false; 2982 } 2983 } 2984 if (DEBUG_TASKS) Slog.w(TAG_TASKS, 2985 "resetTaskIntendedTask: calling finishActivity on " + p); 2986 if (finishActivityLocked( 2987 p, Activity.RESULT_CANCELED, null, "reset-task", false)) { 2988 end--; 2989 srcPos--; 2990 } 2991 } 2992 replyChainEnd = -1; 2993 } else { 2994 // If we were in the middle of a chain, well the 2995 // activity that started it all doesn't want anything 2996 // special, so leave it all as-is. 2997 replyChainEnd = -1; 2998 } 2999 } 3000 3001 return topOptions; 3002 } 3003 3004 /** 3005 * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given 3006 * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop. 3007 * @param affinityTask The task we are looking for an affinity to. 3008 * @param task Task that resetTaskIfNeededLocked.taskTop belongs to. 3009 * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked. 3010 * @param forceReset Flag passed in to resetTaskIfNeededLocked. 3011 */ 3012 private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task, 3013 boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) { 3014 int replyChainEnd = -1; 3015 final int taskId = task.taskId; 3016 final String taskAffinity = task.affinity; 3017 3018 final ArrayList<ActivityRecord> activities = affinityTask.mActivities; 3019 final int numActivities = activities.size(); 3020 final int rootActivityNdx = affinityTask.findEffectiveRootIndex(); 3021 3022 // Do not operate on or below the effective root Activity. 3023 for (int i = numActivities - 1; i > rootActivityNdx; --i) { 3024 ActivityRecord target = activities.get(i); 3025 if (target.frontOfTask) 3026 break; 3027 3028 final int flags = target.info.flags; 3029 boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 3030 boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 3031 3032 if (target.resultTo != null) { 3033 // If this activity is sending a reply to a previous 3034 // activity, we can't do anything with it now until 3035 // we reach the start of the reply chain. 3036 // XXX note that we are assuming the result is always 3037 // to the previous activity, which is almost always 3038 // the case but we really shouldn't count on. 3039 if (replyChainEnd < 0) { 3040 replyChainEnd = i; 3041 } 3042 } else if (topTaskIsHigher 3043 && allowTaskReparenting 3044 && taskAffinity != null 3045 && taskAffinity.equals(target.taskAffinity)) { 3046 // This activity has an affinity for our task. Either remove it if we are 3047 // clearing or move it over to our task. Note that 3048 // we currently punt on the case where we are resetting a 3049 // task that is not at the top but who has activities above 3050 // with an affinity to it... this is really not a normal 3051 // case, and we will need to later pull that task to the front 3052 // and usually at that point we will do the reset and pick 3053 // up those remaining activities. (This only happens if 3054 // someone starts an activity in a new task from an activity 3055 // in a task that is not currently on top.) 3056 if (forceReset || finishOnTaskLaunch) { 3057 final int start = replyChainEnd >= 0 ? replyChainEnd : i; 3058 if (DEBUG_TASKS) Slog.v(TAG_TASKS, 3059 "Finishing task at index " + start + " to " + i); 3060 for (int srcPos = start; srcPos >= i; --srcPos) { 3061 final ActivityRecord p = activities.get(srcPos); 3062 if (p.finishing) { 3063 continue; 3064 } 3065 finishActivityLocked( 3066 p, Activity.RESULT_CANCELED, null, "move-affinity", false); 3067 } 3068 } else { 3069 if (taskInsertionPoint < 0) { 3070 taskInsertionPoint = task.mActivities.size(); 3071 3072 } 3073 3074 final int start = replyChainEnd >= 0 ? replyChainEnd : i; 3075 if (DEBUG_TASKS) Slog.v(TAG_TASKS, 3076 "Reparenting from task=" + affinityTask + ":" + start + "-" + i 3077 + " to task=" + task + ":" + taskInsertionPoint); 3078 for (int srcPos = start; srcPos >= i; --srcPos) { 3079 final ActivityRecord p = activities.get(srcPos); 3080 p.setTask(task, null); 3081 task.addActivityAtIndex(taskInsertionPoint, p); 3082 3083 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE, 3084 "Removing and adding activity " + p + " to stack at " + task 3085 + " callers=" + Debug.getCallers(3)); 3086 if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Pulling activity " + p 3087 + " from " + srcPos + " in to resetting task " + task); 3088 setAppTask(p, task); 3089 } 3090 mWindowManager.moveTaskToTop(taskId); 3091 if (VALIDATE_TOKENS) { 3092 validateAppTokensLocked(); 3093 } 3094 3095 // Now we've moved it in to place... but what if this is 3096 // a singleTop activity and we have put it on top of another 3097 // instance of the same activity? Then we drop the instance 3098 // below so it remains singleTop. 3099 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 3100 ArrayList<ActivityRecord> taskActivities = task.mActivities; 3101 int targetNdx = taskActivities.indexOf(target); 3102 if (targetNdx > 0) { 3103 ActivityRecord p = taskActivities.get(targetNdx - 1); 3104 if (p.intent.getComponent().equals(target.intent.getComponent())) { 3105 finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace", 3106 false); 3107 } 3108 } 3109 } 3110 } 3111 3112 replyChainEnd = -1; 3113 } 3114 } 3115 return taskInsertionPoint; 3116 } 3117 3118 final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop, 3119 ActivityRecord newActivity) { 3120 boolean forceReset = 3121 (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 3122 if (ACTIVITY_INACTIVE_RESET_TIME > 0 3123 && taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 3124 if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 3125 forceReset = true; 3126 } 3127 } 3128 3129 final TaskRecord task = taskTop.task; 3130 3131 /** False until we evaluate the TaskRecord associated with taskTop. Switches to true 3132 * for remaining tasks. Used for later tasks to reparent to task. */ 3133 boolean taskFound = false; 3134 3135 /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */ 3136 ActivityOptions topOptions = null; 3137 3138 // Preserve the location for reparenting in the new task. 3139 int reparentInsertionPoint = -1; 3140 3141 for (int i = mTaskHistory.size() - 1; i >= 0; --i) { 3142 final TaskRecord targetTask = mTaskHistory.get(i); 3143 3144 if (targetTask == task) { 3145 topOptions = resetTargetTaskIfNeededLocked(task, forceReset); 3146 taskFound = true; 3147 } else { 3148 reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task, 3149 taskFound, forceReset, reparentInsertionPoint); 3150 } 3151 } 3152 3153 int taskNdx = mTaskHistory.indexOf(task); 3154 if (taskNdx >= 0) { 3155 do { 3156 taskTop = mTaskHistory.get(taskNdx--).getTopActivity(); 3157 } while (taskTop == null && taskNdx >= 0); 3158 } 3159 3160 if (topOptions != null) { 3161 // If we got some ActivityOptions from an activity on top that 3162 // was removed from the task, propagate them to the new real top. 3163 if (taskTop != null) { 3164 taskTop.updateOptionsLocked(topOptions); 3165 } else { 3166 topOptions.abort(); 3167 } 3168 } 3169 3170 return taskTop; 3171 } 3172 3173 void sendActivityResultLocked(int callingUid, ActivityRecord r, 3174 String resultWho, int requestCode, int resultCode, Intent data) { 3175 3176 if (callingUid > 0) { 3177 mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3178 data, r.getUriPermissionsLocked(), r.userId); 3179 } 3180 3181 if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r 3182 + " : who=" + resultWho + " req=" + requestCode 3183 + " res=" + resultCode + " data=" + data); 3184 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 3185 try { 3186 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 3187 list.add(new ResultInfo(resultWho, requestCode, 3188 resultCode, data)); 3189 r.app.thread.scheduleSendResult(r.appToken, list); 3190 return; 3191 } catch (Exception e) { 3192 Slog.w(TAG, "Exception thrown sending result to " + r, e); 3193 } 3194 } 3195 3196 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 3197 } 3198 3199 private void adjustFocusedActivityLocked(ActivityRecord r, String reason) { 3200 if (!mStackSupervisor.isFocusedStack(this) || mService.mFocusedActivity != r) { 3201 return; 3202 } 3203 3204 final ActivityRecord next = topRunningActivityLocked(); 3205 final String myReason = reason + " adjustFocus"; 3206 if (next != r) { 3207 if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) { 3208 // For freeform, docked, and pinned stacks we always keep the focus within the 3209 // stack as long as there is a running activity in the stack that we can adjust 3210 // focus to. 3211 mService.setFocusedActivityLocked(next, myReason); 3212 return; 3213 } else { 3214 final TaskRecord task = r.task; 3215 if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) { 3216 final int taskToReturnTo = task.getTaskToReturnTo(); 3217 3218 // For non-fullscreen stack, we want to move the focus to the next visible 3219 // stack to prevent the home screen from moving to the top and obscuring 3220 // other visible stacks. 3221 if (!mFullscreen 3222 && adjustFocusToNextFocusableStackLocked(taskToReturnTo, myReason)) { 3223 return; 3224 } 3225 // Move the home stack to the top if this stack is fullscreen or there is no 3226 // other visible stack. 3227 if (mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, myReason)) { 3228 // Activity focus was already adjusted. Nothing else to do... 3229 return; 3230 } 3231 } 3232 } 3233 } 3234 3235 mService.setFocusedActivityLocked(mStackSupervisor.topRunningActivityLocked(), myReason); 3236 } 3237 3238 private boolean adjustFocusToNextFocusableStackLocked(int taskToReturnTo, String reason) { 3239 final ActivityStack stack = getNextFocusableStackLocked(); 3240 final String myReason = reason + " adjustFocusToNextFocusableStack"; 3241 if (stack == null) { 3242 return false; 3243 } 3244 3245 final ActivityRecord top = stack.topRunningActivityLocked(); 3246 3247 if (stack.isHomeStack() && (top == null || !top.visible)) { 3248 // If we will be focusing on the home stack next and its current top activity isn't 3249 // visible, then use the task return to value to determine the home task to display next. 3250 return mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, reason); 3251 } 3252 return mService.setFocusedActivityLocked(top, myReason); 3253 } 3254 3255 final void stopActivityLocked(ActivityRecord r) { 3256 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r); 3257 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 3258 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 3259 if (!r.finishing) { 3260 if (!mService.isSleepingLocked()) { 3261 if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r); 3262 if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 3263 "stop-no-history", false)) { 3264 // Activity was finished, no need to continue trying to schedule stop. 3265 adjustFocusedActivityLocked(r, "stopActivityFinished"); 3266 r.resumeKeyDispatchingLocked(); 3267 return; 3268 } 3269 } else { 3270 if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r 3271 + " on stop because we're just sleeping"); 3272 } 3273 } 3274 } 3275 3276 if (r.app != null && r.app.thread != null) { 3277 adjustFocusedActivityLocked(r, "stopActivity"); 3278 r.resumeKeyDispatchingLocked(); 3279 try { 3280 r.stopped = false; 3281 if (DEBUG_STATES) Slog.v(TAG_STATES, 3282 "Moving to STOPPING: " + r + " (stop requested)"); 3283 r.state = ActivityState.STOPPING; 3284 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, 3285 "Stopping visible=" + r.visible + " for " + r); 3286 if (!r.visible) { 3287 mWindowManager.setAppVisibility(r.appToken, false); 3288 } 3289 EventLogTags.writeAmStopActivity( 3290 r.userId, System.identityHashCode(r), r.shortComponentName); 3291 r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags); 3292 if (mService.isSleepingOrShuttingDownLocked()) { 3293 r.setSleeping(true); 3294 } 3295 Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r); 3296 mHandler.sendMessageDelayed(msg, STOP_TIMEOUT); 3297 } catch (Exception e) { 3298 // Maybe just ignore exceptions here... if the process 3299 // has crashed, our death notification will clean things 3300 // up. 3301 Slog.w(TAG, "Exception thrown during pause", e); 3302 // Just in case, assume it to be stopped. 3303 r.stopped = true; 3304 if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r); 3305 r.state = ActivityState.STOPPED; 3306 if (r.deferRelaunchUntilPaused) { 3307 destroyActivityLocked(r, true, "stop-except"); 3308 } 3309 } 3310 } 3311 } 3312 3313 /** 3314 * @return Returns true if the activity is being finished, false if for 3315 * some reason it is being left as-is. 3316 */ 3317 final boolean requestFinishActivityLocked(IBinder token, int resultCode, 3318 Intent resultData, String reason, boolean oomAdj) { 3319 ActivityRecord r = isInStackLocked(token); 3320 if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES, 3321 "Finishing activity token=" + token + " r=" 3322 + ", result=" + resultCode + ", data=" + resultData 3323 + ", reason=" + reason); 3324 if (r == null) { 3325 return false; 3326 } 3327 3328 finishActivityLocked(r, resultCode, resultData, reason, oomAdj); 3329 return true; 3330 } 3331 3332 final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) { 3333 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 3334 ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 3335 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 3336 ActivityRecord r = activities.get(activityNdx); 3337 if (r.resultTo == self && r.requestCode == requestCode) { 3338 if ((r.resultWho == null && resultWho == null) || 3339 (r.resultWho != null && r.resultWho.equals(resultWho))) { 3340 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub", 3341 false); 3342 } 3343 } 3344 } 3345 } 3346 mService.updateOomAdjLocked(); 3347 } 3348 3349 final TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) { 3350 ActivityRecord r = topRunningActivityLocked(); 3351 TaskRecord finishedTask = null; 3352 if (r == null || r.app != app) { 3353 return null; 3354 } 3355 Slog.w(TAG, " Force finishing activity " 3356 + r.intent.getComponent().flattenToShortString()); 3357 int taskNdx = mTaskHistory.indexOf(r.task); 3358 int activityNdx = r.task.mActivities.indexOf(r); 3359 finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false); 3360 finishedTask = r.task; 3361 // Also terminate any activities below it that aren't yet 3362 // stopped, to avoid a situation where one will get 3363 // re-start our crashing activity once it gets resumed again. 3364 --activityNdx; 3365 if (activityNdx < 0) { 3366 do { 3367 --taskNdx; 3368 if (taskNdx < 0) { 3369 break; 3370 } 3371 activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1; 3372 } while (activityNdx < 0); 3373 } 3374 if (activityNdx >= 0) { 3375 r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx); 3376 if (r.state == ActivityState.RESUMED 3377 || r.state == ActivityState.PAUSING 3378 || r.state == ActivityState.PAUSED) { 3379 if (!r.isHomeActivity() || mService.mHomeProcess != r.app) { 3380 Slog.w(TAG, " Force finishing activity " 3381 + r.intent.getComponent().flattenToShortString()); 3382 finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false); 3383 } 3384 } 3385 } 3386 return finishedTask; 3387 } 3388 3389 final void finishVoiceTask(IVoiceInteractionSession session) { 3390 IBinder sessionBinder = session.asBinder(); 3391 boolean didOne = false; 3392 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 3393 TaskRecord tr = mTaskHistory.get(taskNdx); 3394 if (tr.voiceSession != null && tr.voiceSession.asBinder() == sessionBinder) { 3395 for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3396 ActivityRecord r = tr.mActivities.get(activityNdx); 3397 if (!r.finishing) { 3398 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice", 3399 false); 3400 didOne = true; 3401 } 3402 } 3403 } else { 3404 // Check if any of the activities are using voice 3405 for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3406 ActivityRecord r = tr.mActivities.get(activityNdx); 3407 if (r.voiceSession != null 3408 && r.voiceSession.asBinder() == sessionBinder) { 3409 // Inform of cancellation 3410 r.clearVoiceSessionLocked(); 3411 try { 3412 r.app.thread.scheduleLocalVoiceInteractionStarted((IBinder) r.appToken, 3413 null); 3414 } catch (RemoteException re) { 3415 // Ok 3416 } 3417 mService.finishRunningVoiceLocked(); 3418 break; 3419 } 3420 } 3421 } 3422 } 3423 3424 if (didOne) { 3425 mService.updateOomAdjLocked(); 3426 } 3427 } 3428 3429 final boolean finishActivityAffinityLocked(ActivityRecord r) { 3430 ArrayList<ActivityRecord> activities = r.task.mActivities; 3431 for (int index = activities.indexOf(r); index >= 0; --index) { 3432 ActivityRecord cur = activities.get(index); 3433 if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) { 3434 break; 3435 } 3436 finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true); 3437 } 3438 return true; 3439 } 3440 3441 final void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) { 3442 // send the result 3443 ActivityRecord resultTo = r.resultTo; 3444 if (resultTo != null) { 3445 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo 3446 + " who=" + r.resultWho + " req=" + r.requestCode 3447 + " res=" + resultCode + " data=" + resultData); 3448 if (resultTo.userId != r.userId) { 3449 if (resultData != null) { 3450 resultData.prepareToLeaveUser(r.userId); 3451 } 3452 } 3453 if (r.info.applicationInfo.uid > 0) { 3454 mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 3455 resultTo.packageName, resultData, 3456 resultTo.getUriPermissionsLocked(), resultTo.userId); 3457 } 3458 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 3459 resultData); 3460 r.resultTo = null; 3461 } 3462 else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r); 3463 3464 // Make sure this HistoryRecord is not holding on to other resources, 3465 // because clients have remote IPC references to this object so we 3466 // can't assume that will go away and want to avoid circular IPC refs. 3467 r.results = null; 3468 r.pendingResults = null; 3469 r.newIntents = null; 3470 r.icicle = null; 3471 } 3472 3473 /** 3474 * @return Returns true if this activity has been removed from the history 3475 * list, or false if it is still in the list and will be removed later. 3476 */ 3477 final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, 3478 String reason, boolean oomAdj) { 3479 if (r.finishing) { 3480 Slog.w(TAG, "Duplicate finish request for " + r); 3481 return false; 3482 } 3483 3484 r.makeFinishingLocked(); 3485 final TaskRecord task = r.task; 3486 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 3487 r.userId, System.identityHashCode(r), 3488 task.taskId, r.shortComponentName, reason); 3489 final ArrayList<ActivityRecord> activities = task.mActivities; 3490 final int index = activities.indexOf(r); 3491 if (index < (activities.size() - 1)) { 3492 task.setFrontOfTask(); 3493 if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 3494 // If the caller asked that this activity (and all above it) 3495 // be cleared when the task is reset, don't lose that information, 3496 // but propagate it up to the next activity. 3497 ActivityRecord next = activities.get(index+1); 3498 next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 3499 } 3500 } 3501 3502 r.pauseKeyDispatchingLocked(); 3503 3504 adjustFocusedActivityLocked(r, "finishActivity"); 3505 3506 finishActivityResultsLocked(r, resultCode, resultData); 3507 3508 final boolean endTask = index <= 0; 3509 final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE; 3510 if (mResumedActivity == r) { 3511 3512 if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, 3513 "Prepare close transition: finishing " + r); 3514 mWindowManager.prepareAppTransition(transit, false); 3515 3516 // Tell window manager to prepare for this one to be removed. 3517 mWindowManager.setAppVisibility(r.appToken, false); 3518 3519 if (mPausingActivity == null) { 3520 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r); 3521 if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, 3522 "finish() => pause with userLeaving=false"); 3523 startPausingLocked(false, false, null, false); 3524 } 3525 3526 if (endTask) { 3527 mStackSupervisor.removeLockedTaskLocked(task); 3528 } 3529 } else if (r.state != ActivityState.PAUSING) { 3530 // If the activity is PAUSING, we will complete the finish once 3531 // it is done pausing; else we can just directly finish it here. 3532 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r); 3533 if (r.visible) { 3534 mWindowManager.prepareAppTransition(transit, false); 3535 mWindowManager.setAppVisibility(r.appToken, false); 3536 mWindowManager.executeAppTransition(); 3537 if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) { 3538 mStackSupervisor.mWaitingVisibleActivities.add(r); 3539 } 3540 } 3541 return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ? 3542 FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null; 3543 } else { 3544 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r); 3545 } 3546 3547 return false; 3548 } 3549 3550 static final int FINISH_IMMEDIATELY = 0; 3551 static final int FINISH_AFTER_PAUSE = 1; 3552 static final int FINISH_AFTER_VISIBLE = 2; 3553 3554 final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) { 3555 // First things first: if this activity is currently visible, 3556 // and the resumed activity is not yet visible, then hold off on 3557 // finishing until the resumed one becomes visible. 3558 3559 final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(); 3560 3561 if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible) 3562 && next != null && !next.nowVisible) { 3563 if (!mStackSupervisor.mStoppingActivities.contains(r)) { 3564 addToStopping(r, false /* immediate */); 3565 } 3566 if (DEBUG_STATES) Slog.v(TAG_STATES, 3567 "Moving to STOPPING: "+ r + " (finish requested)"); 3568 r.state = ActivityState.STOPPING; 3569 if (oomAdj) { 3570 mService.updateOomAdjLocked(); 3571 } 3572 return r; 3573 } 3574 3575 // make sure the record is cleaned out of other places. 3576 mStackSupervisor.mStoppingActivities.remove(r); 3577 mStackSupervisor.mGoingToSleepActivities.remove(r); 3578 mStackSupervisor.mWaitingVisibleActivities.remove(r); 3579 if (mResumedActivity == r) { 3580 mResumedActivity = null; 3581 } 3582 final ActivityState prevState = r.state; 3583 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r); 3584 r.state = ActivityState.FINISHING; 3585 final boolean finishingActivityInNonFocusedStack 3586 = r.task.stack != mStackSupervisor.getFocusedStack() 3587 && prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE; 3588 3589 if (mode == FINISH_IMMEDIATELY 3590 || (prevState == ActivityState.PAUSED 3591 && (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID)) 3592 || finishingActivityInNonFocusedStack 3593 || prevState == ActivityState.STOPPED 3594 || prevState == ActivityState.INITIALIZING) { 3595 r.makeFinishingLocked(); 3596 boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm"); 3597 3598 if (finishingActivityInNonFocusedStack) { 3599 // Finishing activity that was in paused state and it was in not currently focused 3600 // stack, need to make something visible in its place. 3601 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 3602 } 3603 if (activityRemoved) { 3604 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3605 } 3606 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 3607 "destroyActivityLocked: finishCurrentActivityLocked r=" + r + 3608 " destroy returned removed=" + activityRemoved); 3609 return activityRemoved ? null : r; 3610 } 3611 3612 // Need to go through the full pause cycle to get this 3613 // activity into the stopped state and then finish it. 3614 if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r); 3615 mStackSupervisor.mFinishingActivities.add(r); 3616 r.resumeKeyDispatchingLocked(); 3617 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3618 return r; 3619 } 3620 3621 void finishAllActivitiesLocked(boolean immediately) { 3622 boolean noActivitiesInStack = true; 3623 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 3624 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 3625 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 3626 final ActivityRecord r = activities.get(activityNdx); 3627 noActivitiesInStack = false; 3628 if (r.finishing && !immediately) { 3629 continue; 3630 } 3631 Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r + " immediately"); 3632 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false); 3633 } 3634 } 3635 if (noActivitiesInStack) { 3636 mActivityContainer.onTaskListEmptyLocked(); 3637 } 3638 } 3639 3640 final boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) { 3641 // Basic case: for simple app-centric recents, we need to recreate 3642 // the task if the affinity has changed. 3643 if (srec == null || srec.task.affinity == null || 3644 !srec.task.affinity.equals(destAffinity)) { 3645 return true; 3646 } 3647 // Document-centric case: an app may be split in to multiple documents; 3648 // they need to re-create their task if this current activity is the root 3649 // of a document, unless simply finishing it will return them to the the 3650 // correct app behind. 3651 if (srec.frontOfTask && srec.task != null && srec.task.getBaseIntent() != null 3652 && srec.task.getBaseIntent().isDocument()) { 3653 // Okay, this activity is at the root of its task. What to do, what to do... 3654 if (srec.task.getTaskToReturnTo() != ActivityRecord.APPLICATION_ACTIVITY_TYPE) { 3655 // Finishing won't return to an application, so we need to recreate. 3656 return true; 3657 } 3658 // We now need to get the task below it to determine what to do. 3659 int taskIdx = mTaskHistory.indexOf(srec.task); 3660 if (taskIdx <= 0) { 3661 Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec); 3662 return false; 3663 } 3664 if (taskIdx == 0) { 3665 // At the bottom of the stack, nothing to go back to. 3666 return true; 3667 } 3668 TaskRecord prevTask = mTaskHistory.get(taskIdx); 3669 if (!srec.task.affinity.equals(prevTask.affinity)) { 3670 // These are different apps, so need to recreate. 3671 return true; 3672 } 3673 } 3674 return false; 3675 } 3676 3677 final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, 3678 Intent resultData) { 3679 final TaskRecord task = srec.task; 3680 final ArrayList<ActivityRecord> activities = task.mActivities; 3681 final int start = activities.indexOf(srec); 3682 if (!mTaskHistory.contains(task) || (start < 0)) { 3683 return false; 3684 } 3685 int finishTo = start - 1; 3686 ActivityRecord parent = finishTo < 0 ? null : activities.get(finishTo); 3687 boolean foundParentInTask = false; 3688 final ComponentName dest = destIntent.getComponent(); 3689 if (start > 0 && dest != null) { 3690 for (int i = finishTo; i >= 0; i--) { 3691 ActivityRecord r = activities.get(i); 3692 if (r.info.packageName.equals(dest.getPackageName()) && 3693 r.info.name.equals(dest.getClassName())) { 3694 finishTo = i; 3695 parent = r; 3696 foundParentInTask = true; 3697 break; 3698 } 3699 } 3700 } 3701 3702 IActivityController controller = mService.mController; 3703 if (controller != null) { 3704 ActivityRecord next = topRunningActivityLocked(srec.appToken, 0); 3705 if (next != null) { 3706 // ask watcher if this is allowed 3707 boolean resumeOK = true; 3708 try { 3709 resumeOK = controller.activityResuming(next.packageName); 3710 } catch (RemoteException e) { 3711 mService.mController = null; 3712 Watchdog.getInstance().setActivityController(null); 3713 } 3714 3715 if (!resumeOK) { 3716 return false; 3717 } 3718 } 3719 } 3720 final long origId = Binder.clearCallingIdentity(); 3721 for (int i = start; i > finishTo; i--) { 3722 ActivityRecord r = activities.get(i); 3723 requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true); 3724 // Only return the supplied result for the first activity finished 3725 resultCode = Activity.RESULT_CANCELED; 3726 resultData = null; 3727 } 3728 3729 if (parent != null && foundParentInTask) { 3730 final int parentLaunchMode = parent.info.launchMode; 3731 final int destIntentFlags = destIntent.getFlags(); 3732 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 3733 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 3734 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 3735 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3736 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, 3737 srec.packageName); 3738 } else { 3739 try { 3740 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 3741 destIntent.getComponent(), 0, srec.userId); 3742 int res = mService.mActivityStarter.startActivityLocked(srec.app.thread, 3743 destIntent, null /*ephemeralIntent*/, null, aInfo, null /*rInfo*/, null, 3744 null, parent.appToken, null, 0, -1, parent.launchedFromUid, 3745 parent.launchedFromPackage, -1, parent.launchedFromUid, 0, null, 3746 false, true, null, null, null); 3747 foundParentInTask = res == ActivityManager.START_SUCCESS; 3748 } catch (RemoteException e) { 3749 foundParentInTask = false; 3750 } 3751 requestFinishActivityLocked(parent.appToken, resultCode, 3752 resultData, "navigate-top", true); 3753 } 3754 } 3755 Binder.restoreCallingIdentity(origId); 3756 return foundParentInTask; 3757 } 3758 /** 3759 * Perform the common clean-up of an activity record. This is called both 3760 * as part of destroyActivityLocked() (when destroying the client-side 3761 * representation) and cleaning things up as a result of its hosting 3762 * processing going away, in which case there is no remaining client-side 3763 * state to destroy so only the cleanup here is needed. 3764 * 3765 * Note: Call before #removeActivityFromHistoryLocked. 3766 */ 3767 final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, 3768 boolean setState) { 3769 if (mResumedActivity == r) { 3770 mResumedActivity = null; 3771 } 3772 if (mPausingActivity == r) { 3773 mPausingActivity = null; 3774 } 3775 mService.resetFocusedActivityIfNeededLocked(r); 3776 3777 r.deferRelaunchUntilPaused = false; 3778 r.frozenBeforeDestroy = false; 3779 3780 if (setState) { 3781 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)"); 3782 r.state = ActivityState.DESTROYED; 3783 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r); 3784 r.app = null; 3785 } 3786 3787 // Make sure this record is no longer in the pending finishes list. 3788 // This could happen, for example, if we are trimming activities 3789 // down to the max limit while they are still waiting to finish. 3790 mStackSupervisor.mFinishingActivities.remove(r); 3791 mStackSupervisor.mWaitingVisibleActivities.remove(r); 3792 3793 // Remove any pending results. 3794 if (r.finishing && r.pendingResults != null) { 3795 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 3796 PendingIntentRecord rec = apr.get(); 3797 if (rec != null) { 3798 mService.cancelIntentSenderLocked(rec, false); 3799 } 3800 } 3801 r.pendingResults = null; 3802 } 3803 3804 if (cleanServices) { 3805 cleanUpActivityServicesLocked(r); 3806 } 3807 3808 // Get rid of any pending idle timeouts. 3809 removeTimeoutsForActivityLocked(r); 3810 if (getVisibleBehindActivity() == r) { 3811 mStackSupervisor.requestVisibleBehindLocked(r, false); 3812 } 3813 3814 // Clean-up activities are no longer relaunching (e.g. app process died). Notify window 3815 // manager so it can update its bookkeeping. 3816 mWindowManager.notifyAppRelaunchesCleared(r.appToken); 3817 } 3818 3819 private void removeTimeoutsForActivityLocked(ActivityRecord r) { 3820 mStackSupervisor.removeTimeoutsForActivityLocked(r); 3821 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 3822 mHandler.removeMessages(STOP_TIMEOUT_MSG, r); 3823 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); 3824 r.finishLaunchTickingLocked(); 3825 } 3826 3827 private void removeActivityFromHistoryLocked( 3828 ActivityRecord r, TaskRecord oldTop, String reason) { 3829 mStackSupervisor.removeChildActivityContainers(r); 3830 finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null); 3831 r.makeFinishingLocked(); 3832 if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE, 3833 "Removing activity " + r + " from stack callers=" + Debug.getCallers(5)); 3834 3835 r.takeFromHistory(); 3836 removeTimeoutsForActivityLocked(r); 3837 if (DEBUG_STATES) Slog.v(TAG_STATES, 3838 "Moving to DESTROYED: " + r + " (removed from history)"); 3839 r.state = ActivityState.DESTROYED; 3840 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r); 3841 r.app = null; 3842 mWindowManager.removeAppToken(r.appToken); 3843 if (VALIDATE_TOKENS) { 3844 validateAppTokensLocked(); 3845 } 3846 final TaskRecord task = r.task; 3847 final TaskRecord topTask = oldTop != null ? oldTop : topTask(); 3848 if (task != null && task.removeActivity(r)) { 3849 if (DEBUG_STACK) Slog.i(TAG_STACK, 3850 "removeActivityFromHistoryLocked: last activity removed from " + this); 3851 if (mStackSupervisor.isFocusedStack(this) && task == topTask && 3852 task.isOverHomeStack()) { 3853 mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason); 3854 } 3855 removeTask(task, reason); 3856 } 3857 cleanUpActivityServicesLocked(r); 3858 r.removeUriPermissionsLocked(); 3859 } 3860 3861 /** 3862 * Perform clean-up of service connections in an activity record. 3863 */ 3864 final void cleanUpActivityServicesLocked(ActivityRecord r) { 3865 // Throw away any services that have been bound by this activity. 3866 if (r.connections != null) { 3867 Iterator<ConnectionRecord> it = r.connections.iterator(); 3868 while (it.hasNext()) { 3869 ConnectionRecord c = it.next(); 3870 mService.mServices.removeConnectionLocked(c, null, r); 3871 } 3872 r.connections = null; 3873 } 3874 } 3875 3876 final void scheduleDestroyActivities(ProcessRecord owner, String reason) { 3877 Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG); 3878 msg.obj = new ScheduleDestroyArgs(owner, reason); 3879 mHandler.sendMessage(msg); 3880 } 3881 3882 final void destroyActivitiesLocked(ProcessRecord owner, String reason) { 3883 boolean lastIsOpaque = false; 3884 boolean activityRemoved = false; 3885 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 3886 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 3887 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 3888 final ActivityRecord r = activities.get(activityNdx); 3889 if (r.finishing) { 3890 continue; 3891 } 3892 if (r.fullscreen) { 3893 lastIsOpaque = true; 3894 } 3895 if (owner != null && r.app != owner) { 3896 continue; 3897 } 3898 if (!lastIsOpaque) { 3899 continue; 3900 } 3901 if (r.isDestroyable()) { 3902 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.state 3903 + " resumed=" + mResumedActivity 3904 + " pausing=" + mPausingActivity + " for reason " + reason); 3905 if (destroyActivityLocked(r, true, reason)) { 3906 activityRemoved = true; 3907 } 3908 } 3909 } 3910 } 3911 if (activityRemoved) { 3912 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3913 } 3914 } 3915 3916 final boolean safelyDestroyActivityLocked(ActivityRecord r, String reason) { 3917 if (r.isDestroyable()) { 3918 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 3919 "Destroying " + r + " in state " + r.state + " resumed=" + mResumedActivity 3920 + " pausing=" + mPausingActivity + " for reason " + reason); 3921 return destroyActivityLocked(r, true, reason); 3922 } 3923 return false; 3924 } 3925 3926 final int releaseSomeActivitiesLocked(ProcessRecord app, ArraySet<TaskRecord> tasks, 3927 String reason) { 3928 // Iterate over tasks starting at the back (oldest) first. 3929 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); 3930 int maxTasks = tasks.size() / 4; 3931 if (maxTasks < 1) { 3932 maxTasks = 1; 3933 } 3934 int numReleased = 0; 3935 for (int taskNdx = 0; taskNdx < mTaskHistory.size() && maxTasks > 0; taskNdx++) { 3936 final TaskRecord task = mTaskHistory.get(taskNdx); 3937 if (!tasks.contains(task)) { 3938 continue; 3939 } 3940 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Looking for activities to release in " + task); 3941 int curNum = 0; 3942 final ArrayList<ActivityRecord> activities = task.mActivities; 3943 for (int actNdx = 0; actNdx < activities.size(); actNdx++) { 3944 final ActivityRecord activity = activities.get(actNdx); 3945 if (activity.app == app && activity.isDestroyable()) { 3946 if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + activity 3947 + " in state " + activity.state + " resumed=" + mResumedActivity 3948 + " pausing=" + mPausingActivity + " for reason " + reason); 3949 destroyActivityLocked(activity, true, reason); 3950 if (activities.get(actNdx) != activity) { 3951 // Was removed from list, back up so we don't miss the next one. 3952 actNdx--; 3953 } 3954 curNum++; 3955 } 3956 } 3957 if (curNum > 0) { 3958 numReleased += curNum; 3959 maxTasks--; 3960 if (mTaskHistory.get(taskNdx) != task) { 3961 // The entire task got removed, back up so we don't miss the next one. 3962 taskNdx--; 3963 } 3964 } 3965 } 3966 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, 3967 "Done releasing: did " + numReleased + " activities"); 3968 return numReleased; 3969 } 3970 3971 /** 3972 * Destroy the current CLIENT SIDE instance of an activity. This may be 3973 * called both when actually finishing an activity, or when performing 3974 * a configuration switch where we destroy the current client-side object 3975 * but then create a new client-side object for this same HistoryRecord. 3976 */ 3977 final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) { 3978 if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(TAG_SWITCH, 3979 "Removing activity from " + reason + ": token=" + r 3980 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 3981 EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY, 3982 r.userId, System.identityHashCode(r), 3983 r.task.taskId, r.shortComponentName, reason); 3984 3985 boolean removedFromHistory = false; 3986 3987 // If the activity is finishing, it's no longer considered in topRunningActivityLocked, 3988 // and cleanUpActivityLocked() may change focus to another activity (or task). 3989 // Get the current top task now, as removeActivityFromHistoryLocked() below need this 3990 // to decide whether to return to home stack after removal. 3991 final TaskRecord topTask = topTask(); 3992 3993 cleanUpActivityLocked(r, false, false); 3994 3995 final boolean hadApp = r.app != null; 3996 3997 if (hadApp) { 3998 if (removeFromApp) { 3999 r.app.activities.remove(r); 4000 if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) { 4001 mService.mHeavyWeightProcess = null; 4002 mService.mHandler.sendEmptyMessage( 4003 ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG); 4004 } 4005 if (r.app.activities.isEmpty()) { 4006 // Update any services we are bound to that might care about whether 4007 // their client may have activities. 4008 mService.mServices.updateServiceConnectionActivitiesLocked(r.app); 4009 // No longer have activities, so update LRU list and oom adj. 4010 mService.updateLruProcessLocked(r.app, false, null); 4011 mService.updateOomAdjLocked(); 4012 } 4013 } 4014 4015 boolean skipDestroy = false; 4016 4017 try { 4018 if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r); 4019 r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing, 4020 r.configChangeFlags); 4021 } catch (Exception e) { 4022 // We can just ignore exceptions here... if the process 4023 // has crashed, our death notification will clean things 4024 // up. 4025 //Slog.w(TAG, "Exception thrown during finish", e); 4026 if (r.finishing) { 4027 removeActivityFromHistoryLocked( 4028 r, topTask, reason + " exceptionInScheduleDestroy"); 4029 removedFromHistory = true; 4030 skipDestroy = true; 4031 } 4032 } 4033 4034 r.nowVisible = false; 4035 4036 // If the activity is finishing, we need to wait on removing it 4037 // from the list to give it a chance to do its cleanup. During 4038 // that time it may make calls back with its token so we need to 4039 // be able to find it on the list and so we don't want to remove 4040 // it from the list yet. Otherwise, we can just immediately put 4041 // it in the destroyed state since we are not removing it from the 4042 // list. 4043 if (r.finishing && !skipDestroy) { 4044 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r 4045 + " (destroy requested)"); 4046 r.state = ActivityState.DESTROYING; 4047 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r); 4048 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4049 } else { 4050 if (DEBUG_STATES) Slog.v(TAG_STATES, 4051 "Moving to DESTROYED: " + r + " (destroy skipped)"); 4052 r.state = ActivityState.DESTROYED; 4053 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r); 4054 r.app = null; 4055 } 4056 } else { 4057 // remove this record from the history. 4058 if (r.finishing) { 4059 removeActivityFromHistoryLocked(r, topTask, reason + " hadNoApp"); 4060 removedFromHistory = true; 4061 } else { 4062 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)"); 4063 r.state = ActivityState.DESTROYED; 4064 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r); 4065 r.app = null; 4066 } 4067 } 4068 4069 r.configChangeFlags = 0; 4070 4071 if (!mLRUActivities.remove(r) && hadApp) { 4072 Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4073 } 4074 4075 return removedFromHistory; 4076 } 4077 4078 final void activityDestroyedLocked(IBinder token, String reason) { 4079 final long origId = Binder.clearCallingIdentity(); 4080 try { 4081 ActivityRecord r = ActivityRecord.forTokenLocked(token); 4082 if (r != null) { 4083 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); 4084 } 4085 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + r); 4086 4087 if (isInStackLocked(r) != null) { 4088 if (r.state == ActivityState.DESTROYING) { 4089 cleanUpActivityLocked(r, true, false); 4090 removeActivityFromHistoryLocked(r, null, reason); 4091 } 4092 } 4093 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 4094 } finally { 4095 Binder.restoreCallingIdentity(origId); 4096 } 4097 } 4098 4099 void releaseBackgroundResources(ActivityRecord r) { 4100 if (hasVisibleBehindActivity() && 4101 !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) { 4102 if (r == topRunningActivityLocked() 4103 && getStackVisibilityLocked(null) == STACK_VISIBLE) { 4104 // Don't release the top activity if it has requested to run behind the next 4105 // activity and the stack is currently visible. 4106 return; 4107 } 4108 if (DEBUG_STATES) Slog.d(TAG_STATES, "releaseBackgroundResources activtyDisplay=" + 4109 mActivityContainer.mActivityDisplay + " visibleBehind=" + r + " app=" + r.app + 4110 " thread=" + r.app.thread); 4111 if (r != null && r.app != null && r.app.thread != null) { 4112 try { 4113 r.app.thread.scheduleCancelVisibleBehind(r.appToken); 4114 } catch (RemoteException e) { 4115 } 4116 mHandler.sendEmptyMessageDelayed(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG, 500); 4117 } else { 4118 Slog.e(TAG, "releaseBackgroundResources: activity " + r + " no longer running"); 4119 backgroundResourcesReleased(); 4120 } 4121 } 4122 } 4123 4124 final void backgroundResourcesReleased() { 4125 mHandler.removeMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG); 4126 final ActivityRecord r = getVisibleBehindActivity(); 4127 if (r != null) { 4128 mStackSupervisor.mStoppingActivities.add(r); 4129 setVisibleBehindActivity(null); 4130 mStackSupervisor.scheduleIdleTimeoutLocked(null); 4131 } 4132 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 4133 } 4134 4135 boolean hasVisibleBehindActivity() { 4136 return isAttached() && mActivityContainer.mActivityDisplay.hasVisibleBehindActivity(); 4137 } 4138 4139 void setVisibleBehindActivity(ActivityRecord r) { 4140 if (isAttached()) { 4141 mActivityContainer.mActivityDisplay.setVisibleBehindActivity(r); 4142 } 4143 } 4144 4145 ActivityRecord getVisibleBehindActivity() { 4146 return isAttached() ? mActivityContainer.mActivityDisplay.mVisibleBehindActivity : null; 4147 } 4148 4149 private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list, 4150 ProcessRecord app, String listName) { 4151 int i = list.size(); 4152 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 4153 "Removing app " + app + " from list " + listName + " with " + i + " entries"); 4154 while (i > 0) { 4155 i--; 4156 ActivityRecord r = list.get(i); 4157 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record #" + i + " " + r); 4158 if (r.app == app) { 4159 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "---> REMOVING this entry!"); 4160 list.remove(i); 4161 removeTimeoutsForActivityLocked(r); 4162 } 4163 } 4164 } 4165 4166 boolean removeHistoryRecordsForAppLocked(ProcessRecord app) { 4167 removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities"); 4168 removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app, 4169 "mStoppingActivities"); 4170 removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app, 4171 "mGoingToSleepActivities"); 4172 removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app, 4173 "mWaitingVisibleActivities"); 4174 removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app, 4175 "mFinishingActivities"); 4176 4177 boolean hasVisibleActivities = false; 4178 4179 // Clean out the history list. 4180 int i = numActivities(); 4181 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 4182 "Removing app " + app + " from history with " + i + " entries"); 4183 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 4184 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 4185 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 4186 final ActivityRecord r = activities.get(activityNdx); 4187 --i; 4188 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 4189 "Record #" + i + " " + r + ": app=" + r.app); 4190 if (r.app == app) { 4191 if (r.visible) { 4192 hasVisibleActivities = true; 4193 } 4194 final boolean remove; 4195 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4196 // Don't currently have state for the activity, or 4197 // it is finishing -- always remove it. 4198 remove = true; 4199 } else if (!r.visible && r.launchCount > 2 && 4200 r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) { 4201 // We have launched this activity too many times since it was 4202 // able to run, so give up and remove it. 4203 // (Note if the activity is visible, we don't remove the record. 4204 // We leave the dead window on the screen but the process will 4205 // not be restarted unless user explicitly tap on it.) 4206 remove = true; 4207 } else { 4208 // The process may be gone, but the activity lives on! 4209 remove = false; 4210 } 4211 if (remove) { 4212 if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE, 4213 "Removing activity " + r + " from stack at " + i 4214 + ": haveState=" + r.haveState 4215 + " stateNotNeeded=" + r.stateNotNeeded 4216 + " finishing=" + r.finishing 4217 + " state=" + r.state + " callers=" + Debug.getCallers(5)); 4218 if (!r.finishing) { 4219 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 4220 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 4221 r.userId, System.identityHashCode(r), 4222 r.task.taskId, r.shortComponentName, 4223 "proc died without state saved"); 4224 if (r.state == ActivityState.RESUMED) { 4225 mService.updateUsageStats(r, false); 4226 } 4227 } 4228 } else { 4229 // We have the current state for this activity, so 4230 // it can be restarted later when needed. 4231 if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null"); 4232 if (DEBUG_APP) Slog.v(TAG_APP, 4233 "Clearing app during removeHistory for activity " + r); 4234 r.app = null; 4235 // Set nowVisible to previous visible state. If the app was visible while 4236 // it died, we leave the dead window on screen so it's basically visible. 4237 // This is needed when user later tap on the dead window, we need to stop 4238 // other apps when user transfers focus to the restarted activity. 4239 r.nowVisible = r.visible; 4240 if (!r.haveState) { 4241 if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, 4242 "App died, clearing saved state of " + r); 4243 r.icicle = null; 4244 } 4245 } 4246 cleanUpActivityLocked(r, true, true); 4247 if (remove) { 4248 removeActivityFromHistoryLocked(r, null, "appDied"); 4249 } 4250 } 4251 } 4252 } 4253 4254 return hasVisibleActivities; 4255 } 4256 4257 final void updateTransitLocked(int transit, ActivityOptions options) { 4258 if (options != null) { 4259 ActivityRecord r = topRunningActivityLocked(); 4260 if (r != null && r.state != ActivityState.RESUMED) { 4261 r.updateOptionsLocked(options); 4262 } else { 4263 ActivityOptions.abort(options); 4264 } 4265 } 4266 mWindowManager.prepareAppTransition(transit, false); 4267 } 4268 4269 void updateTaskMovement(TaskRecord task, boolean toFront) { 4270 if (task.isPersistable) { 4271 task.mLastTimeMoved = System.currentTimeMillis(); 4272 // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most 4273 // recently will be most negative, tasks sent to the bottom before that will be less 4274 // negative. Similarly for recent tasks moved to the top which will be most positive. 4275 if (!toFront) { 4276 task.mLastTimeMoved *= -1; 4277 } 4278 } 4279 mStackSupervisor.invalidateTaskLayers(); 4280 } 4281 4282 void moveHomeStackTaskToTop(int homeStackTaskType) { 4283 final int top = mTaskHistory.size() - 1; 4284 for (int taskNdx = top; taskNdx >= 0; --taskNdx) { 4285 final TaskRecord task = mTaskHistory.get(taskNdx); 4286 if (task.taskType == homeStackTaskType) { 4287 if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK, 4288 "moveHomeStackTaskToTop: moving " + task); 4289 mTaskHistory.remove(taskNdx); 4290 mTaskHistory.add(top, task); 4291 updateTaskMovement(task, true); 4292 return; 4293 } 4294 } 4295 } 4296 4297 final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, ActivityOptions options, 4298 AppTimeTracker timeTracker, String reason) { 4299 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr); 4300 4301 final int numTasks = mTaskHistory.size(); 4302 final int index = mTaskHistory.indexOf(tr); 4303 if (numTasks == 0 || index < 0) { 4304 // nothing to do! 4305 if (noAnimation) { 4306 ActivityOptions.abort(options); 4307 } else { 4308 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options); 4309 } 4310 return; 4311 } 4312 4313 if (timeTracker != null) { 4314 // The caller wants a time tracker associated with this task. 4315 for (int i = tr.mActivities.size() - 1; i >= 0; i--) { 4316 tr.mActivities.get(i).appTimeTracker = timeTracker; 4317 } 4318 } 4319 4320 // Shift all activities with this task up to the top 4321 // of the stack, keeping them in the same internal order. 4322 insertTaskAtTop(tr, null); 4323 4324 // Don't refocus if invisible to current user 4325 ActivityRecord top = tr.getTopActivity(); 4326 if (!okToShowLocked(top)) { 4327 addRecentActivityLocked(top); 4328 ActivityOptions.abort(options); 4329 return; 4330 } 4331 4332 // Set focus to the top running activity of this stack. 4333 ActivityRecord r = topRunningActivityLocked(); 4334 mService.setFocusedActivityLocked(r, reason); 4335 4336 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); 4337 if (noAnimation) { 4338 mWindowManager.prepareAppTransition(TRANSIT_NONE, false); 4339 if (r != null) { 4340 mNoAnimActivities.add(r); 4341 } 4342 ActivityOptions.abort(options); 4343 } else { 4344 updateTransitLocked(TRANSIT_TASK_TO_FRONT, options); 4345 } 4346 4347 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 4348 EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); 4349 4350 if (VALIDATE_TOKENS) { 4351 validateAppTokensLocked(); 4352 } 4353 } 4354 4355 /** 4356 * Worker method for rearranging history stack. Implements the function of moving all 4357 * activities for a specific task (gathering them if disjoint) into a single group at the 4358 * bottom of the stack. 4359 * 4360 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 4361 * to premeptively cancel the move. 4362 * 4363 * @param taskId The taskId to collect and move to the bottom. 4364 * @return Returns true if the move completed, false if not. 4365 */ 4366 final boolean moveTaskToBackLocked(int taskId) { 4367 final TaskRecord tr = taskForIdLocked(taskId); 4368 if (tr == null) { 4369 Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId); 4370 return false; 4371 } 4372 4373 Slog.i(TAG, "moveTaskToBack: " + tr); 4374 mStackSupervisor.removeLockedTaskLocked(tr); 4375 4376 // If we have a watcher, preflight the move before committing to it. First check 4377 // for *other* available tasks, but if none are available, then try again allowing the 4378 // current task to be selected. 4379 if (mStackSupervisor.isFrontStack(this) && mService.mController != null) { 4380 ActivityRecord next = topRunningActivityLocked(null, taskId); 4381 if (next == null) { 4382 next = topRunningActivityLocked(null, 0); 4383 } 4384 if (next != null) { 4385 // ask watcher if this is allowed 4386 boolean moveOK = true; 4387 try { 4388 moveOK = mService.mController.activityResuming(next.packageName); 4389 } catch (RemoteException e) { 4390 mService.mController = null; 4391 Watchdog.getInstance().setActivityController(null); 4392 } 4393 if (!moveOK) { 4394 return false; 4395 } 4396 } 4397 } 4398 4399 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId); 4400 4401 if (mStackId == HOME_STACK_ID && topTask().isHomeTask()) { 4402 // For the case where we are moving the home task back and there is an activity visible 4403 // behind it on the fullscreen stack, we want to move the focus to the visible behind 4404 // activity to maintain order with what the user is seeing. 4405 final ActivityStack fullscreenStack = 4406 mStackSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID); 4407 if (fullscreenStack != null && fullscreenStack.hasVisibleBehindActivity()) { 4408 final ActivityRecord visibleBehind = fullscreenStack.getVisibleBehindActivity(); 4409 mService.setFocusedActivityLocked(visibleBehind, "moveHomeTaskToBack"); 4410 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 4411 return true; 4412 } 4413 } 4414 4415 boolean prevIsHome = false; 4416 4417 // If true, we should resume the home activity next if the task we are moving to the 4418 // back is over the home stack. We force to false if the task we are moving to back 4419 // is the home task and we don't want it resumed after moving to the back. 4420 final boolean canGoHome = !tr.isHomeTask() && tr.isOverHomeStack(); 4421 if (canGoHome) { 4422 final TaskRecord nextTask = getNextTask(tr); 4423 if (nextTask != null) { 4424 nextTask.setTaskToReturnTo(tr.getTaskToReturnTo()); 4425 } else { 4426 prevIsHome = true; 4427 } 4428 } 4429 mTaskHistory.remove(tr); 4430 mTaskHistory.add(0, tr); 4431 updateTaskMovement(tr, false); 4432 4433 // There is an assumption that moving a task to the back moves it behind the home activity. 4434 // We make sure here that some activity in the stack will launch home. 4435 int numTasks = mTaskHistory.size(); 4436 for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) { 4437 final TaskRecord task = mTaskHistory.get(taskNdx); 4438 if (task.isOverHomeStack()) { 4439 break; 4440 } 4441 if (taskNdx == 1) { 4442 // Set the last task before tr to go to home. 4443 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 4444 } 4445 } 4446 4447 mWindowManager.prepareAppTransition(TRANSIT_TASK_TO_BACK, false); 4448 mWindowManager.moveTaskToBottom(taskId); 4449 4450 if (VALIDATE_TOKENS) { 4451 validateAppTokensLocked(); 4452 } 4453 4454 final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null; 4455 if (prevIsHome || (task == tr && canGoHome) || (numTasks <= 1 && isOnHomeDisplay())) { 4456 if (!mService.mBooting && !mService.mBooted) { 4457 // Not ready yet! 4458 return false; 4459 } 4460 final int taskToReturnTo = tr.getTaskToReturnTo(); 4461 tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); 4462 return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null, 4463 "moveTaskToBackAndShowHome"); 4464 } 4465 4466 // Using currently focused activity value from service instead of mResumedActivity, 4467 // because if this happens when device is locked the mResumedActivity will be null. 4468 adjustFocusedActivityLocked(mService.mFocusedActivity, "moveTaskToBack"); 4469 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 4470 return true; 4471 } 4472 4473 static final void logStartActivity(int tag, ActivityRecord r, 4474 TaskRecord task) { 4475 final Uri data = r.intent.getData(); 4476 final String strData = data != null ? data.toSafeString() : null; 4477 4478 EventLog.writeEvent(tag, 4479 r.userId, System.identityHashCode(r), task.taskId, 4480 r.shortComponentName, r.intent.getAction(), 4481 r.intent.getType(), strData, r.intent.getFlags()); 4482 } 4483 4484 /** 4485 * Ensures all visible activities at or below the input activity have the right configuration. 4486 */ 4487 void ensureVisibleActivitiesConfigurationLocked(ActivityRecord start, boolean preserveWindow) { 4488 if (start == null || !start.visible) { 4489 return; 4490 } 4491 4492 final TaskRecord startTask = start.task; 4493 boolean behindFullscreen = false; 4494 boolean updatedConfig = false; 4495 4496 for (int taskIndex = mTaskHistory.indexOf(startTask); taskIndex >= 0; --taskIndex) { 4497 final TaskRecord task = mTaskHistory.get(taskIndex); 4498 final ArrayList<ActivityRecord> activities = task.mActivities; 4499 int activityIndex = 4500 (start.task == task) ? activities.indexOf(start) : activities.size() - 1; 4501 for (; activityIndex >= 0; --activityIndex) { 4502 final ActivityRecord r = activities.get(activityIndex); 4503 updatedConfig |= ensureActivityConfigurationLocked(r, 0, preserveWindow); 4504 if (r.fullscreen) { 4505 behindFullscreen = true; 4506 break; 4507 } 4508 } 4509 if (behindFullscreen) { 4510 break; 4511 } 4512 } 4513 if (updatedConfig) { 4514 // Ensure the resumed state of the focus activity if we updated the configuration of 4515 // any activity. 4516 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 4517 } 4518 } 4519 4520 /** 4521 * Make sure the given activity matches the current configuration. Returns false if the activity 4522 * had to be destroyed. Returns true if the configuration is the same, or the activity will 4523 * remain running as-is for whatever reason. Ensures the HistoryRecord is updated with the 4524 * correct configuration and all other bookkeeping is handled. 4525 */ 4526 boolean ensureActivityConfigurationLocked( 4527 ActivityRecord r, int globalChanges, boolean preserveWindow) { 4528 if (mConfigWillChange) { 4529 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4530 "Skipping config check (will change): " + r); 4531 return true; 4532 } 4533 4534 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4535 "Ensuring correct configuration: " + r); 4536 4537 // Short circuit: if the two configurations are equal (the common case), then there is 4538 // nothing to do. 4539 final Configuration newConfig = mService.mConfiguration; 4540 r.task.sanitizeOverrideConfiguration(newConfig); 4541 final Configuration taskConfig = r.task.mOverrideConfig; 4542 if (r.configuration.equals(newConfig) 4543 && r.taskConfigOverride.equals(taskConfig) 4544 && !r.forceNewConfig) { 4545 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4546 "Configuration unchanged in " + r); 4547 return true; 4548 } 4549 4550 // We don't worry about activities that are finishing. 4551 if (r.finishing) { 4552 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4553 "Configuration doesn't matter in finishing " + r); 4554 r.stopFreezingScreenLocked(false); 4555 return true; 4556 } 4557 4558 // Okay we now are going to make this activity have the new config. 4559 // But then we need to figure out how it needs to deal with that. 4560 final Configuration oldConfig = r.configuration; 4561 final Configuration oldTaskOverride = r.taskConfigOverride; 4562 r.configuration = newConfig; 4563 r.taskConfigOverride = taskConfig; 4564 4565 int taskChanges = getTaskConfigurationChanges(r, taskConfig, oldTaskOverride); 4566 final int changes = oldConfig.diff(newConfig) | taskChanges; 4567 if (changes == 0 && !r.forceNewConfig) { 4568 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4569 "Configuration no differences in " + r); 4570 // There are no significant differences, so we won't relaunch but should still deliver 4571 // the new configuration to the client process. 4572 r.scheduleConfigurationChanged(taskConfig, true); 4573 return true; 4574 } 4575 4576 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4577 "Configuration changes for " + r + " ; taskChanges=" 4578 + Configuration.configurationDiffToString(taskChanges) + ", allChanges=" 4579 + Configuration.configurationDiffToString(changes)); 4580 4581 // If the activity isn't currently running, just leave the new 4582 // configuration and it will pick that up next time it starts. 4583 if (r.app == null || r.app.thread == null) { 4584 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4585 "Configuration doesn't matter not running " + r); 4586 r.stopFreezingScreenLocked(false); 4587 r.forceNewConfig = false; 4588 return true; 4589 } 4590 4591 // Figure out how to handle the changes between the configurations. 4592 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4593 "Checking to restart " + r.info.name + ": changed=0x" 4594 + Integer.toHexString(changes) + ", handles=0x" 4595 + Integer.toHexString(r.info.getRealConfigChanged()) + ", newConfig=" + newConfig 4596 + ", taskConfig=" + taskConfig); 4597 4598 if ((changes&(~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) { 4599 // Aha, the activity isn't handling the change, so DIE DIE DIE. 4600 r.configChangeFlags |= changes; 4601 r.startFreezingScreenLocked(r.app, globalChanges); 4602 r.forceNewConfig = false; 4603 preserveWindow &= isResizeOnlyChange(changes); 4604 if (r.app == null || r.app.thread == null) { 4605 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4606 "Config is destroying non-running " + r); 4607 destroyActivityLocked(r, true, "config"); 4608 } else if (r.state == ActivityState.PAUSING) { 4609 // A little annoying: we are waiting for this activity to finish pausing. Let's not 4610 // do anything now, but just flag that it needs to be restarted when done pausing. 4611 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4612 "Config is skipping already pausing " + r); 4613 r.deferRelaunchUntilPaused = true; 4614 r.preserveWindowOnDeferredRelaunch = preserveWindow; 4615 return true; 4616 } else if (r.state == ActivityState.RESUMED) { 4617 // Try to optimize this case: the configuration is changing and we need to restart 4618 // the top, resumed activity. Instead of doing the normal handshaking, just say 4619 // "restart!". 4620 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4621 "Config is relaunching resumed " + r); 4622 4623 if (DEBUG_STATES && !r.visible) { 4624 Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + r 4625 + " called by " + Debug.getCallers(4)); 4626 } 4627 4628 relaunchActivityLocked(r, r.configChangeFlags, true, preserveWindow); 4629 } else { 4630 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, 4631 "Config is relaunching non-resumed " + r); 4632 relaunchActivityLocked(r, r.configChangeFlags, false, preserveWindow); 4633 } 4634 4635 // All done... tell the caller we weren't able to keep this activity around. 4636 return false; 4637 } 4638 4639 // Default case: the activity can handle this new configuration, so hand it over. 4640 // NOTE: We only forward the task override configuration as the system level configuration 4641 // changes is always sent to all processes when they happen so it can just use whatever 4642 // system level configuration it last got. 4643 r.scheduleConfigurationChanged(taskConfig, true); 4644 r.stopFreezingScreenLocked(false); 4645 4646 return true; 4647 } 4648 4649 private int getTaskConfigurationChanges(ActivityRecord record, Configuration taskConfig, 4650 Configuration oldTaskOverride) { 4651 4652 // If we went from full-screen to non-full-screen, make sure to use the correct 4653 // configuration task diff, so the diff stays as small as possible. 4654 if (Configuration.EMPTY.equals(oldTaskOverride) 4655 && !Configuration.EMPTY.equals(taskConfig)) { 4656 oldTaskOverride = record.task.extractOverrideConfig(record.configuration); 4657 } 4658 4659 // Conversely, do the same when going the other direction. 4660 if (Configuration.EMPTY.equals(taskConfig) 4661 && !Configuration.EMPTY.equals(oldTaskOverride)) { 4662 taskConfig = record.task.extractOverrideConfig(record.configuration); 4663 } 4664 4665 // Determine what has changed. May be nothing, if this is a config 4666 // that has come back from the app after going idle. In that case 4667 // we just want to leave the official config object now in the 4668 // activity and do nothing else. 4669 int taskChanges = oldTaskOverride.diff(taskConfig); 4670 // We don't want to use size changes if they don't cross boundaries that are important to 4671 // the app. 4672 if ((taskChanges & CONFIG_SCREEN_SIZE) != 0) { 4673 final boolean crosses = record.crossesHorizontalSizeThreshold( 4674 oldTaskOverride.screenWidthDp, taskConfig.screenWidthDp) 4675 || record.crossesVerticalSizeThreshold( 4676 oldTaskOverride.screenHeightDp, taskConfig.screenHeightDp); 4677 if (!crosses) { 4678 taskChanges &= ~CONFIG_SCREEN_SIZE; 4679 } 4680 } 4681 if ((taskChanges & CONFIG_SMALLEST_SCREEN_SIZE) != 0) { 4682 final int oldSmallest = oldTaskOverride.smallestScreenWidthDp; 4683 final int newSmallest = taskConfig.smallestScreenWidthDp; 4684 if (!record.crossesSmallestSizeThreshold(oldSmallest, newSmallest)) { 4685 taskChanges &= ~CONFIG_SMALLEST_SCREEN_SIZE; 4686 } 4687 } 4688 return catchConfigChangesFromUnset(taskConfig, oldTaskOverride, taskChanges); 4689 } 4690 4691 private static int catchConfigChangesFromUnset(Configuration taskConfig, 4692 Configuration oldTaskOverride, int taskChanges) { 4693 if (taskChanges == 0) { 4694 // {@link Configuration#diff} doesn't catch changes from unset values. 4695 // Check for changes we care about. 4696 if (oldTaskOverride.orientation != taskConfig.orientation) { 4697 taskChanges |= CONFIG_ORIENTATION; 4698 } 4699 // We want to explicitly track situations where the size configuration goes from 4700 // undefined to defined. We don't care about crossing the threshold in that case, 4701 // because there is no threshold. 4702 final int oldHeight = oldTaskOverride.screenHeightDp; 4703 final int newHeight = taskConfig.screenHeightDp; 4704 final int undefinedHeight = Configuration.SCREEN_HEIGHT_DP_UNDEFINED; 4705 if ((oldHeight == undefinedHeight && newHeight != undefinedHeight) 4706 || (oldHeight != undefinedHeight && newHeight == undefinedHeight)) { 4707 taskChanges |= CONFIG_SCREEN_SIZE; 4708 } 4709 final int oldWidth = oldTaskOverride.screenWidthDp; 4710 final int newWidth = taskConfig.screenWidthDp; 4711 final int undefinedWidth = Configuration.SCREEN_WIDTH_DP_UNDEFINED; 4712 if ((oldWidth == undefinedWidth && newWidth != undefinedWidth) 4713 || (oldWidth != undefinedWidth && newWidth == undefinedWidth)) { 4714 taskChanges |= CONFIG_SCREEN_SIZE; 4715 } 4716 final int oldSmallest = oldTaskOverride.smallestScreenWidthDp; 4717 final int newSmallest = taskConfig.smallestScreenWidthDp; 4718 final int undefinedSmallest = Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; 4719 if ((oldSmallest == undefinedSmallest && newSmallest != undefinedSmallest) 4720 || (oldSmallest != undefinedSmallest && newSmallest == undefinedSmallest)) { 4721 taskChanges |= CONFIG_SMALLEST_SCREEN_SIZE; 4722 } 4723 final int oldLayout = oldTaskOverride.screenLayout; 4724 final int newLayout = taskConfig.screenLayout; 4725 if ((oldLayout == SCREENLAYOUT_UNDEFINED && newLayout != SCREENLAYOUT_UNDEFINED) 4726 || (oldLayout != SCREENLAYOUT_UNDEFINED && newLayout == SCREENLAYOUT_UNDEFINED)) { 4727 taskChanges |= CONFIG_SCREEN_LAYOUT; 4728 } 4729 } 4730 return taskChanges; 4731 } 4732 4733 private static boolean isResizeOnlyChange(int change) { 4734 return (change & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION 4735 | CONFIG_SCREEN_LAYOUT)) == 0; 4736 } 4737 4738 private void relaunchActivityLocked( 4739 ActivityRecord r, int changes, boolean andResume, boolean preserveWindow) { 4740 if (mService.mSuppressResizeConfigChanges && preserveWindow) { 4741 r.configChangeFlags = 0; 4742 return; 4743 } 4744 4745 List<ResultInfo> results = null; 4746 List<ReferrerIntent> newIntents = null; 4747 if (andResume) { 4748 results = r.results; 4749 newIntents = r.newIntents; 4750 } 4751 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 4752 "Relaunching: " + r + " with results=" + results + " newIntents=" + newIntents 4753 + " andResume=" + andResume + " preserveWindow=" + preserveWindow); 4754 EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY 4755 : EventLogTags.AM_RELAUNCH_ACTIVITY, r.userId, System.identityHashCode(r), 4756 r.task.taskId, r.shortComponentName); 4757 4758 r.startFreezingScreenLocked(r.app, 0); 4759 4760 mStackSupervisor.removeChildActivityContainers(r); 4761 4762 try { 4763 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, 4764 "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r 4765 + " callers=" + Debug.getCallers(6)); 4766 r.forceNewConfig = false; 4767 mStackSupervisor.activityRelaunchingLocked(r); 4768 r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes, 4769 !andResume, new Configuration(mService.mConfiguration), 4770 new Configuration(r.task.mOverrideConfig), preserveWindow); 4771 // Note: don't need to call pauseIfSleepingLocked() here, because 4772 // the caller will only pass in 'andResume' if this activity is 4773 // currently resumed, which implies we aren't sleeping. 4774 } catch (RemoteException e) { 4775 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH, "Relaunch failed", e); 4776 } 4777 4778 if (andResume) { 4779 if (DEBUG_STATES) { 4780 Slog.d(TAG_STATES, "Resumed after relaunch " + r); 4781 } 4782 r.state = ActivityState.RESUMED; 4783 // Relaunch-resume could happen either when the app is already in the front, 4784 // or while it's being brought to front. In the latter case, it's marked RESUMED 4785 // but not yet visible (or stopped). We need to complete the resume here as the 4786 // code in resumeTopActivityInnerLocked to complete the resume might be skipped. 4787 if (!r.visible || r.stopped) { 4788 mWindowManager.setAppVisibility(r.appToken, true); 4789 completeResumeLocked(r); 4790 } else { 4791 r.results = null; 4792 r.newIntents = null; 4793 } 4794 mService.showUnsupportedZoomDialogIfNeededLocked(r); 4795 mService.showAskCompatModeDialogLocked(r); 4796 } else { 4797 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 4798 r.state = ActivityState.PAUSED; 4799 } 4800 4801 r.configChangeFlags = 0; 4802 r.deferRelaunchUntilPaused = false; 4803 r.preserveWindowOnDeferredRelaunch = false; 4804 } 4805 4806 boolean willActivityBeVisibleLocked(IBinder token) { 4807 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 4808 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 4809 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 4810 final ActivityRecord r = activities.get(activityNdx); 4811 if (r.appToken == token) { 4812 return true; 4813 } 4814 if (r.fullscreen && !r.finishing) { 4815 return false; 4816 } 4817 } 4818 } 4819 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 4820 if (r == null) { 4821 return false; 4822 } 4823 if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false," 4824 + " would have returned true for r=" + r); 4825 return !r.finishing; 4826 } 4827 4828 void closeSystemDialogsLocked() { 4829 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 4830 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 4831 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 4832 final ActivityRecord r = activities.get(activityNdx); 4833 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 4834 finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true); 4835 } 4836 } 4837 } 4838 } 4839 4840 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, 4841 boolean doit, boolean evenPersistent, int userId) { 4842 boolean didSomething = false; 4843 TaskRecord lastTask = null; 4844 ComponentName homeActivity = null; 4845 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 4846 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 4847 int numActivities = activities.size(); 4848 for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { 4849 ActivityRecord r = activities.get(activityNdx); 4850 final boolean sameComponent = 4851 (r.packageName.equals(packageName) && (filterByClasses == null 4852 || filterByClasses.contains(r.realActivity.getClassName()))) 4853 || (packageName == null && r.userId == userId); 4854 if ((userId == UserHandle.USER_ALL || r.userId == userId) 4855 && (sameComponent || r.task == lastTask) 4856 && (r.app == null || evenPersistent || !r.app.persistent)) { 4857 if (!doit) { 4858 if (r.finishing) { 4859 // If this activity is just finishing, then it is not 4860 // interesting as far as something to stop. 4861 continue; 4862 } 4863 return true; 4864 } 4865 if (r.isHomeActivity()) { 4866 if (homeActivity != null && homeActivity.equals(r.realActivity)) { 4867 Slog.i(TAG, "Skip force-stop again " + r); 4868 continue; 4869 } else { 4870 homeActivity = r.realActivity; 4871 } 4872 } 4873 didSomething = true; 4874 Slog.i(TAG, " Force finishing activity " + r); 4875 if (sameComponent) { 4876 if (r.app != null) { 4877 r.app.removed = true; 4878 } 4879 r.app = null; 4880 } 4881 lastTask = r.task; 4882 if (finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop", 4883 true)) { 4884 // r has been deleted from mActivities, accommodate. 4885 --numActivities; 4886 --activityNdx; 4887 } 4888 } 4889 } 4890 } 4891 return didSomething; 4892 } 4893 4894 void getTasksLocked(List<RunningTaskInfo> list, int callingUid, boolean allowed) { 4895 boolean focusedStack = mStackSupervisor.getFocusedStack() == this; 4896 boolean topTask = true; 4897 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 4898 final TaskRecord task = mTaskHistory.get(taskNdx); 4899 if (task.getTopActivity() == null) { 4900 continue; 4901 } 4902 ActivityRecord r = null; 4903 ActivityRecord top = null; 4904 ActivityRecord tmp; 4905 int numActivities = 0; 4906 int numRunning = 0; 4907 final ArrayList<ActivityRecord> activities = task.mActivities; 4908 if (!allowed && !task.isHomeTask() && task.effectiveUid != callingUid) { 4909 continue; 4910 } 4911 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 4912 tmp = activities.get(activityNdx); 4913 if (tmp.finishing) { 4914 continue; 4915 } 4916 r = tmp; 4917 4918 // Initialize state for next task if needed. 4919 if (top == null || (top.state == ActivityState.INITIALIZING)) { 4920 top = r; 4921 numActivities = numRunning = 0; 4922 } 4923 4924 // Add 'r' into the current task. 4925 numActivities++; 4926 if (r.app != null && r.app.thread != null) { 4927 numRunning++; 4928 } 4929 4930 if (DEBUG_ALL) Slog.v( 4931 TAG, r.intent.getComponent().flattenToShortString() 4932 + ": task=" + r.task); 4933 } 4934 4935 RunningTaskInfo ci = new RunningTaskInfo(); 4936 ci.id = task.taskId; 4937 ci.stackId = mStackId; 4938 ci.baseActivity = r.intent.getComponent(); 4939 ci.topActivity = top.intent.getComponent(); 4940 ci.lastActiveTime = task.lastActiveTime; 4941 if (focusedStack && topTask) { 4942 // Give the latest time to ensure foreground task can be sorted 4943 // at the first, because lastActiveTime of creating task is 0. 4944 ci.lastActiveTime = System.currentTimeMillis(); 4945 topTask = false; 4946 } 4947 4948 if (top.task != null) { 4949 ci.description = top.task.lastDescription; 4950 } 4951 ci.numActivities = numActivities; 4952 ci.numRunning = numRunning; 4953 ci.isDockable = task.canGoInDockedStack(); 4954 ci.resizeMode = task.mResizeMode; 4955 list.add(ci); 4956 } 4957 } 4958 4959 public void unhandledBackLocked() { 4960 final int top = mTaskHistory.size() - 1; 4961 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Performing unhandledBack(): top activity at " + top); 4962 if (top >= 0) { 4963 final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities; 4964 int activityTop = activities.size() - 1; 4965 if (activityTop > 0) { 4966 finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null, 4967 "unhandled-back", true); 4968 } 4969 } 4970 } 4971 4972 /** 4973 * Reset local parameters because an app's activity died. 4974 * @param app The app of the activity that died. 4975 * @return result from removeHistoryRecordsForAppLocked. 4976 */ 4977 boolean handleAppDiedLocked(ProcessRecord app) { 4978 if (mPausingActivity != null && mPausingActivity.app == app) { 4979 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, 4980 "App died while pausing: " + mPausingActivity); 4981 mPausingActivity = null; 4982 } 4983 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4984 mLastPausedActivity = null; 4985 mLastNoHistoryActivity = null; 4986 } 4987 4988 return removeHistoryRecordsForAppLocked(app); 4989 } 4990 4991 void handleAppCrashLocked(ProcessRecord app) { 4992 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 4993 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 4994 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 4995 final ActivityRecord r = activities.get(activityNdx); 4996 if (r.app == app) { 4997 Slog.w(TAG, " Force finishing activity " 4998 + r.intent.getComponent().flattenToShortString()); 4999 // Force the destroy to skip right to removal. 5000 r.app = null; 5001 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false); 5002 } 5003 } 5004 } 5005 } 5006 5007 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 5008 boolean dumpClient, String dumpPackage, boolean needSep, String header) { 5009 boolean printed = false; 5010 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 5011 final TaskRecord task = mTaskHistory.get(taskNdx); 5012 printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw, 5013 mTaskHistory.get(taskNdx).mActivities, " ", "Hist", true, !dumpAll, 5014 dumpClient, dumpPackage, needSep, header, 5015 " Task id #" + task.taskId + "\n" + 5016 " mFullscreen=" + task.mFullscreen + "\n" + 5017 " mBounds=" + task.mBounds + "\n" + 5018 " mMinWidth=" + task.mMinWidth + "\n" + 5019 " mMinHeight=" + task.mMinHeight + "\n" + 5020 " mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds); 5021 if (printed) { 5022 header = null; 5023 } 5024 } 5025 return printed; 5026 } 5027 5028 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 5029 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 5030 5031 if ("all".equals(name)) { 5032 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 5033 activities.addAll(mTaskHistory.get(taskNdx).mActivities); 5034 } 5035 } else if ("top".equals(name)) { 5036 final int top = mTaskHistory.size() - 1; 5037 if (top >= 0) { 5038 final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities; 5039 int listTop = list.size() - 1; 5040 if (listTop >= 0) { 5041 activities.add(list.get(listTop)); 5042 } 5043 } 5044 } else { 5045 ItemMatcher matcher = new ItemMatcher(); 5046 matcher.build(name); 5047 5048 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 5049 for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) { 5050 if (matcher.match(r1, r1.intent.getComponent())) { 5051 activities.add(r1); 5052 } 5053 } 5054 } 5055 } 5056 5057 return activities; 5058 } 5059 5060 ActivityRecord restartPackage(String packageName) { 5061 ActivityRecord starting = topRunningActivityLocked(); 5062 5063 // All activities that came from the package must be 5064 // restarted as if there was a config change. 5065 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 5066 final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; 5067 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 5068 final ActivityRecord a = activities.get(activityNdx); 5069 if (a.info.packageName.equals(packageName)) { 5070 a.forceNewConfig = true; 5071 if (starting != null && a == starting && a.visible) { 5072 a.startFreezingScreenLocked(starting.app, 5073 CONFIG_SCREEN_LAYOUT); 5074 } 5075 } 5076 } 5077 } 5078 5079 return starting; 5080 } 5081 5082 void removeTask(TaskRecord task, String reason) { 5083 removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); 5084 } 5085 5086 /** 5087 * Removes the input task from this stack. 5088 * @param task to remove. 5089 * @param reason for removal. 5090 * @param mode task removal mode. Either {@link #REMOVE_TASK_MODE_DESTROYING}, 5091 * {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}. 5092 */ 5093 void removeTask(TaskRecord task, String reason, int mode) { 5094 if (mode == REMOVE_TASK_MODE_DESTROYING) { 5095 mStackSupervisor.removeLockedTaskLocked(task); 5096 mWindowManager.removeTask(task.taskId); 5097 if (!StackId.persistTaskBounds(mStackId)) { 5098 // Reset current bounds for task whose bounds shouldn't be persisted so it uses 5099 // default configuration the next time it launches. 5100 task.updateOverrideConfiguration(null); 5101 } 5102 } 5103 5104 final ActivityRecord r = mResumedActivity; 5105 if (r != null && r.task == task) { 5106 mResumedActivity = null; 5107 } 5108 5109 final int taskNdx = mTaskHistory.indexOf(task); 5110 final int topTaskNdx = mTaskHistory.size() - 1; 5111 if (task.isOverHomeStack() && taskNdx < topTaskNdx) { 5112 final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1); 5113 if (!nextTask.isOverHomeStack()) { 5114 nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 5115 } 5116 } 5117 mTaskHistory.remove(task); 5118 updateTaskMovement(task, true); 5119 5120 if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) { 5121 // TODO: VI what about activity? 5122 final boolean isVoiceSession = task.voiceSession != null; 5123 if (isVoiceSession) { 5124 try { 5125 task.voiceSession.taskFinished(task.intent, task.taskId); 5126 } catch (RemoteException e) { 5127 } 5128 } 5129 if (task.autoRemoveFromRecents() || isVoiceSession) { 5130 // Task creator asked to remove this when done, or this task was a voice 5131 // interaction, so it should not remain on the recent tasks list. 5132 mRecentTasks.remove(task); 5133 task.removedFromRecents(); 5134 } 5135 } 5136 5137 if (mTaskHistory.isEmpty()) { 5138 if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this); 5139 // We only need to adjust focused stack if this stack is in focus and we are not in the 5140 // process of moving the task to the top of the stack that will be focused. 5141 if (isOnHomeDisplay() && mode != REMOVE_TASK_MODE_MOVING_TO_TOP 5142 && mStackSupervisor.isFocusedStack(this)) { 5143 String myReason = reason + " leftTaskHistoryEmpty"; 5144 if (mFullscreen 5145 || !adjustFocusToNextFocusableStackLocked( 5146 task.getTaskToReturnTo(), myReason)) { 5147 mStackSupervisor.moveHomeStackToFront(myReason); 5148 } 5149 } 5150 if (mStacks != null) { 5151 mStacks.remove(this); 5152 mStacks.add(0, this); 5153 } 5154 if (!isHomeStack()) { 5155 mActivityContainer.onTaskListEmptyLocked(); 5156 } 5157 } 5158 5159 task.stack = null; 5160 } 5161 5162 TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, 5163 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 5164 boolean toTop) { 5165 TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession, 5166 voiceInteractor); 5167 // add the task to stack first, mTaskPositioner might need the stack association 5168 addTask(task, toTop, "createTaskRecord"); 5169 final boolean isLockscreenShown = mService.mLockScreenShown == LOCK_SCREEN_SHOWN; 5170 if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable() 5171 && !isLockscreenShown) { 5172 task.updateOverrideConfiguration(mBounds); 5173 } 5174 return task; 5175 } 5176 5177 boolean layoutTaskInStack(TaskRecord task, ActivityInfo.WindowLayout windowLayout) { 5178 if (mTaskPositioner == null) { 5179 return false; 5180 } 5181 mTaskPositioner.updateDefaultBounds(task, mTaskHistory, windowLayout); 5182 return true; 5183 } 5184 5185 ArrayList<TaskRecord> getAllTasks() { 5186 return new ArrayList<>(mTaskHistory); 5187 } 5188 5189 void addTask(final TaskRecord task, final boolean toTop, String reason) { 5190 final ActivityStack prevStack = preAddTask(task, reason, toTop); 5191 5192 task.stack = this; 5193 if (toTop) { 5194 insertTaskAtTop(task, null); 5195 } else { 5196 mTaskHistory.add(0, task); 5197 updateTaskMovement(task, false); 5198 } 5199 postAddTask(task, prevStack); 5200 } 5201 5202 void positionTask(final TaskRecord task, int position) { 5203 final ActivityRecord topRunningActivity = task.topRunningActivityLocked(); 5204 final boolean wasResumed = topRunningActivity == task.stack.mResumedActivity; 5205 final ActivityStack prevStack = preAddTask(task, "positionTask", !ON_TOP); 5206 task.stack = this; 5207 insertTaskAtPosition(task, position); 5208 postAddTask(task, prevStack); 5209 if (wasResumed) { 5210 if (mResumedActivity != null) { 5211 Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from" 5212 + " other stack to this stack mResumedActivity=" + mResumedActivity 5213 + " other mResumedActivity=" + topRunningActivity); 5214 } 5215 mResumedActivity = topRunningActivity; 5216 } 5217 } 5218 5219 private ActivityStack preAddTask(TaskRecord task, String reason, boolean toTop) { 5220 final ActivityStack prevStack = task.stack; 5221 if (prevStack != null && prevStack != this) { 5222 prevStack.removeTask(task, reason, 5223 toTop ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING); 5224 } 5225 return prevStack; 5226 } 5227 5228 private void postAddTask(TaskRecord task, ActivityStack prevStack) { 5229 if (prevStack != null) { 5230 mStackSupervisor.scheduleReportPictureInPictureModeChangedIfNeeded(task, prevStack); 5231 } else if (task.voiceSession != null) { 5232 try { 5233 task.voiceSession.taskStarted(task.intent, task.taskId); 5234 } catch (RemoteException e) { 5235 } 5236 } 5237 } 5238 5239 void addConfigOverride(ActivityRecord r, TaskRecord task) { 5240 final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds(); 5241 // TODO: VI deal with activity 5242 mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, 5243 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, 5244 (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges, 5245 task.voiceSession != null, r.mLaunchTaskBehind, bounds, task.mOverrideConfig, 5246 task.mResizeMode, r.isAlwaysFocusable(), task.isHomeTask(), 5247 r.appInfo.targetSdkVersion, r.mRotationAnimationHint); 5248 r.taskConfigOverride = task.mOverrideConfig; 5249 } 5250 5251 void moveToFrontAndResumeStateIfNeeded( 5252 ActivityRecord r, boolean moveToFront, boolean setResume, String reason) { 5253 if (!moveToFront) { 5254 return; 5255 } 5256 5257 // If the activity owns the last resumed activity, transfer that together, 5258 // so that we don't resume the same activity again in the new stack. 5259 // Apps may depend on onResume()/onPause() being called in pairs. 5260 if (setResume) { 5261 mResumedActivity = r; 5262 } 5263 // Move the stack in which we are placing the activity to the front. The call will also 5264 // make sure the activity focus is set. 5265 moveToFront(reason); 5266 } 5267 5268 /** 5269 * Moves the input activity from its current stack to this one. 5270 * NOTE: The current task of the activity isn't moved to this stack. Instead a new task is 5271 * created on this stack which the activity is added to. 5272 * */ 5273 void moveActivityToStack(ActivityRecord r) { 5274 final ActivityStack prevStack = r.task.stack; 5275 if (prevStack.mStackId == mStackId) { 5276 // You are already in the right stack silly... 5277 return; 5278 } 5279 5280 final boolean wasFocused = mStackSupervisor.isFocusedStack(prevStack) 5281 && (mStackSupervisor.topRunningActivityLocked() == r); 5282 final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r); 5283 5284 final TaskRecord task = createTaskRecord( 5285 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), 5286 r.info, r.intent, null, null, true); 5287 r.setTask(task, null); 5288 task.addActivityToTop(r); 5289 setAppTask(r, task); 5290 mStackSupervisor.scheduleReportPictureInPictureModeChangedIfNeeded(task, prevStack); 5291 moveToFrontAndResumeStateIfNeeded(r, wasFocused, wasResumed, "moveActivityToStack"); 5292 if (wasResumed) { 5293 prevStack.mResumedActivity = null; 5294 } 5295 } 5296 5297 private void setAppTask(ActivityRecord r, TaskRecord task) { 5298 final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds(); 5299 mWindowManager.setAppTask(r.appToken, task.taskId, mStackId, bounds, task.mOverrideConfig, 5300 task.mResizeMode, task.isHomeTask()); 5301 r.taskConfigOverride = task.mOverrideConfig; 5302 } 5303 5304 public int getStackId() { 5305 return mStackId; 5306 } 5307 5308 @Override 5309 public String toString() { 5310 return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this)) 5311 + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}"; 5312 } 5313 5314 void onLockTaskPackagesUpdatedLocked() { 5315 for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { 5316 mTaskHistory.get(taskNdx).setLockTaskAuth(); 5317 } 5318 } 5319 } 5320