1 /* 2 * Copyright (C) 2013 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.Manifest.permission.ACTIVITY_EMBEDDING; 20 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; 21 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 22 import static android.Manifest.permission.START_ANY_ACTIVITY; 23 import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 24 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; 25 import static android.app.ActivityManager.START_DELIVERED_TO_TOP; 26 import static android.app.ActivityManager.START_TASK_TO_FRONT; 27 import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 28 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY; 29 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; 30 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; 31 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 32 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; 33 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 34 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 35 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 36 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 37 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; 38 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 39 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; 40 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; 41 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 42 import static android.app.WindowConfiguration.activityTypeToString; 43 import static android.app.WindowConfiguration.windowingModeToString; 44 import static android.content.pm.PackageManager.PERMISSION_DENIED; 45 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 46 import static android.graphics.Rect.copyOrNull; 47 import static android.os.PowerManager.PARTIAL_WAKE_LOCK; 48 import static android.os.Process.SYSTEM_UID; 49 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 50 import static android.view.Display.DEFAULT_DISPLAY; 51 import static android.view.Display.INVALID_DISPLAY; 52 import static android.view.Display.TYPE_VIRTUAL; 53 54 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN; 55 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 56 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS; 57 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE; 58 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE; 59 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 60 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; 61 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 62 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; 63 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 64 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 65 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS; 66 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE; 67 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE; 68 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 69 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; 70 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 71 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES; 72 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 73 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; 74 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 75 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 76 import static com.android.server.am.ActivityManagerService.ANIMATE; 77 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 78 import static com.android.server.am.ActivityStack.ActivityState.DESTROYED; 79 import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; 80 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING; 81 import static com.android.server.am.ActivityStack.ActivityState.PAUSED; 82 import static com.android.server.am.ActivityStack.ActivityState.PAUSING; 83 import static com.android.server.am.ActivityStack.ActivityState.RESUMED; 84 import static com.android.server.am.ActivityStack.ActivityState.STOPPED; 85 import static com.android.server.am.ActivityStack.ActivityState.STOPPING; 86 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING; 87 import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 88 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; 89 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 90 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; 91 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; 92 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; 93 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT; 94 import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER; 95 import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS; 96 import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID; 97 import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT; 98 import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER; 99 import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY; 100 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS; 101 102 import static java.lang.Integer.MAX_VALUE; 103 104 import android.Manifest; 105 import android.annotation.IntDef; 106 import android.annotation.NonNull; 107 import android.annotation.Nullable; 108 import android.annotation.UserIdInt; 109 import android.app.Activity; 110 import android.app.ActivityManager; 111 import android.app.ActivityManager.RunningTaskInfo; 112 import android.app.ActivityManager.StackInfo; 113 import android.app.ActivityManagerInternal.SleepToken; 114 import android.app.ActivityOptions; 115 import android.app.AppOpsManager; 116 import android.app.ProfilerInfo; 117 import android.app.ResultInfo; 118 import android.app.WaitResult; 119 import android.app.WindowConfiguration.ActivityType; 120 import android.app.WindowConfiguration.WindowingMode; 121 import android.app.servertransaction.ActivityLifecycleItem; 122 import android.app.servertransaction.ClientTransaction; 123 import android.app.servertransaction.LaunchActivityItem; 124 import android.app.servertransaction.PauseActivityItem; 125 import android.app.servertransaction.ResumeActivityItem; 126 import android.content.ComponentName; 127 import android.content.Context; 128 import android.content.Intent; 129 import android.content.pm.ActivityInfo; 130 import android.content.pm.ApplicationInfo; 131 import android.content.pm.PackageInfo; 132 import android.content.pm.PackageManager; 133 import android.content.pm.ResolveInfo; 134 import android.content.pm.UserInfo; 135 import android.content.res.Configuration; 136 import android.graphics.Rect; 137 import android.hardware.display.DisplayManager; 138 import android.hardware.display.DisplayManager.DisplayListener; 139 import android.hardware.display.DisplayManagerInternal; 140 import android.hardware.power.V1_0.PowerHint; 141 import android.os.Binder; 142 import android.os.Bundle; 143 import android.os.Debug; 144 import android.os.Handler; 145 import android.os.IBinder; 146 import android.os.Looper; 147 import android.os.Message; 148 import android.os.PowerManager; 149 import android.os.Process; 150 import android.os.RemoteException; 151 import android.os.SystemClock; 152 import android.os.Trace; 153 import android.os.UserHandle; 154 import android.os.UserManager; 155 import android.os.WorkSource; 156 import android.provider.MediaStore; 157 import android.service.voice.IVoiceInteractionSession; 158 import android.util.ArrayMap; 159 import android.util.ArraySet; 160 import android.util.EventLog; 161 import android.util.IntArray; 162 import android.util.MergedConfiguration; 163 import android.util.Slog; 164 import android.util.SparseArray; 165 import android.util.SparseIntArray; 166 import android.util.TimeUtils; 167 import android.util.proto.ProtoOutputStream; 168 import android.view.Display; 169 170 import com.android.internal.annotations.GuardedBy; 171 import com.android.internal.annotations.VisibleForTesting; 172 import com.android.internal.content.ReferrerIntent; 173 import com.android.internal.os.logging.MetricsLoggerWrapper; 174 import com.android.internal.os.TransferPipe; 175 import com.android.internal.util.ArrayUtils; 176 import com.android.server.LocalServices; 177 import com.android.server.am.ActivityStack.ActivityState; 178 import com.android.server.wm.ConfigurationContainer; 179 import com.android.server.wm.PinnedStackWindowController; 180 import com.android.server.wm.WindowManagerService; 181 182 import java.io.FileDescriptor; 183 import java.io.IOException; 184 import java.io.PrintWriter; 185 import java.lang.annotation.Retention; 186 import java.lang.annotation.RetentionPolicy; 187 import java.util.ArrayList; 188 import java.util.Iterator; 189 import java.util.List; 190 import java.util.Set; 191 192 public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener, 193 RecentTasks.Callbacks { 194 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; 195 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; 196 private static final String TAG_IDLE = TAG + POSTFIX_IDLE; 197 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; 198 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 199 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 200 private static final String TAG_STACK = TAG + POSTFIX_STACK; 201 private static final String TAG_STATES = TAG + POSTFIX_STATES; 202 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 203 static final String TAG_TASKS = TAG + POSTFIX_TASKS; 204 205 /** How long we wait until giving up on the last activity telling us it is idle. */ 206 static final int IDLE_TIMEOUT = 10 * 1000; 207 208 /** How long we can hold the sleep wake lock before giving up. */ 209 static final int SLEEP_TIMEOUT = 5 * 1000; 210 211 // How long we can hold the launch wake lock before giving up. 212 static final int LAUNCH_TIMEOUT = 10 * 1000; 213 214 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 215 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 216 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 217 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 218 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; 219 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; 220 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; 221 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; 222 static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12; 223 static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14; 224 static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15; 225 226 private static final String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; 227 228 // Used to indicate if an object (e.g. stack) that we are trying to get 229 // should be created if it doesn't exist already. 230 static final boolean CREATE_IF_NEEDED = true; 231 232 // Used to indicate that windows of activities should be preserved during the resize. 233 static final boolean PRESERVE_WINDOWS = true; 234 235 // Used to indicate if an object (e.g. task) should be moved/created 236 // at the top of its container (e.g. stack). 237 static final boolean ON_TOP = true; 238 239 // Don't execute any calls to resume. 240 static final boolean DEFER_RESUME = true; 241 242 // Used to indicate that a task is removed it should also be removed from recents. 243 static final boolean REMOVE_FROM_RECENTS = true; 244 245 // Used to indicate that pausing an activity should occur immediately without waiting for 246 // the activity callback indicating that it has completed pausing 247 static final boolean PAUSE_IMMEDIATELY = true; 248 249 /** True if the docked stack is currently being resized. */ 250 private boolean mDockedStackResizing; 251 252 /** 253 * True if there are pending docked bounds that need to be applied after 254 * {@link #mDockedStackResizing} is reset to false. 255 */ 256 private boolean mHasPendingDockedBounds; 257 private Rect mPendingDockedBounds; 258 private Rect mPendingTempDockedTaskBounds; 259 private Rect mPendingTempDockedTaskInsetBounds; 260 private Rect mPendingTempOtherTaskBounds; 261 private Rect mPendingTempOtherTaskInsetBounds; 262 263 /** 264 * The modes which affect which tasks are returned when calling 265 * {@link ActivityStackSupervisor#anyTaskForIdLocked(int)}. 266 */ 267 @Retention(RetentionPolicy.SOURCE) 268 @IntDef({ 269 MATCH_TASK_IN_STACKS_ONLY, 270 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, 271 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 272 }) 273 public @interface AnyTaskForIdMatchTaskMode {} 274 // Match only tasks in the current stacks 275 static final int MATCH_TASK_IN_STACKS_ONLY = 0; 276 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks 277 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1; 278 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the 279 // provided stack id 280 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2; 281 282 // Activity actions an app cannot start if it uses a permission which is not granted. 283 private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION = 284 new ArrayMap<>(); 285 286 static { ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, Manifest.permission.CAMERA)287 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, 288 Manifest.permission.CAMERA); ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, Manifest.permission.CAMERA)289 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, 290 Manifest.permission.CAMERA); ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, Manifest.permission.CALL_PHONE)291 ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, 292 Manifest.permission.CALL_PHONE); 293 } 294 295 /** Action restriction: launching the activity is not restricted. */ 296 private static final int ACTIVITY_RESTRICTION_NONE = 0; 297 /** Action restriction: launching the activity is restricted by a permission. */ 298 private static final int ACTIVITY_RESTRICTION_PERMISSION = 1; 299 /** Action restriction: launching the activity is restricted by an app op. */ 300 private static final int ACTIVITY_RESTRICTION_APPOP = 2; 301 302 // For debugging to make sure the caller when acquiring/releasing our 303 // wake lock is the system process. 304 static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 305 /** The number of distinct task ids that can be assigned to the tasks of a single user */ 306 private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE; 307 308 final ActivityManagerService mService; 309 310 /** The historial list of recent tasks including inactive tasks */ 311 RecentTasks mRecentTasks; 312 313 /** Helper class to abstract out logic for fetching the set of currently running tasks */ 314 private RunningTasks mRunningTasks; 315 316 final ActivityStackSupervisorHandler mHandler; 317 final Looper mLooper; 318 319 /** Short cut */ 320 WindowManagerService mWindowManager; 321 DisplayManager mDisplayManager; 322 323 private LaunchParamsController mLaunchParamsController; 324 325 /** 326 * Maps the task identifier that activities are currently being started in to the userId of the 327 * task. Each time a new task is created, the entry for the userId of the task is incremented 328 */ 329 private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20); 330 331 /** The current user */ 332 int mCurrentUser; 333 334 /** The stack containing the launcher app. Assumed to always be attached to 335 * Display.DEFAULT_DISPLAY. */ 336 ActivityStack mHomeStack; 337 338 /** The stack currently receiving input or launching the next activity. */ 339 ActivityStack mFocusedStack; 340 341 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 342 * been resumed. If stacks are changing position this will hold the old stack until the new 343 * stack becomes resumed after which it will be set to mFocusedStack. */ 344 private ActivityStack mLastFocusedStack; 345 346 /** List of activities that are waiting for a new activity to become visible before completing 347 * whatever operation they are supposed to do. */ 348 // TODO: Remove mActivitiesWaitingForVisibleActivity list and just remove activity from 349 // mStoppingActivities when something else comes up. 350 final ArrayList<ActivityRecord> mActivitiesWaitingForVisibleActivity = new ArrayList<>(); 351 352 /** List of processes waiting to find out when a specific activity becomes visible. */ 353 private final ArrayList<WaitInfo> mWaitingForActivityVisible = new ArrayList<>(); 354 355 /** List of processes waiting to find out about the next launched activity. */ 356 final ArrayList<WaitResult> mWaitingActivityLaunched = new ArrayList<>(); 357 358 /** List of activities that are ready to be stopped, but waiting for the next activity to 359 * settle down before doing so. */ 360 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>(); 361 362 /** List of activities that are ready to be finished, but waiting for the previous activity to 363 * settle down before doing so. It contains ActivityRecord objects. */ 364 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>(); 365 366 /** List of activities that are in the process of going to sleep. */ 367 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>(); 368 369 /** List of activities whose multi-window mode changed that we need to report to the 370 * application */ 371 final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>(); 372 373 /** List of activities whose picture-in-picture mode changed that we need to report to the 374 * application */ 375 final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>(); 376 377 /** 378 * Animations that for the current transition have requested not to 379 * be considered for the transition animation. 380 */ 381 final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>(); 382 383 /** The target stack bounds for the picture-in-picture mode changed that we need to report to 384 * the application */ 385 Rect mPipModeChangedTargetStackBounds; 386 387 /** Used on user changes */ 388 final ArrayList<UserState> mStartingUsers = new ArrayList<>(); 389 390 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 391 * is being brought in front of us. */ 392 boolean mUserLeaving = false; 393 394 /** Set when a power hint has started, but not ended. */ 395 private boolean mPowerHintSent; 396 397 /** 398 * We don't want to allow the device to go to sleep while in the process 399 * of launching an activity. This is primarily to allow alarm intent 400 * receivers to launch an activity and get that to run before the device 401 * goes back to sleep. 402 */ 403 PowerManager.WakeLock mLaunchingActivity; 404 405 /** 406 * Set when the system is going to sleep, until we have 407 * successfully paused the current activity and released our wake lock. 408 * At that point the system is allowed to actually sleep. 409 */ 410 PowerManager.WakeLock mGoingToSleep; 411 412 /** 413 * A list of tokens that cause the top activity to be put to sleep. 414 * They are used by components that may hide and block interaction with underlying 415 * activities. 416 */ 417 final ArrayList<SleepToken> mSleepTokens = new ArrayList<>(); 418 419 /** Stack id of the front stack when user switched, indexed by userId. */ 420 SparseIntArray mUserStackInFront = new SparseIntArray(2); 421 422 // TODO: There should be an ActivityDisplayController coordinating am/wm interaction. 423 /** Mapping from displayId to display current state */ 424 private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>(); 425 426 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 427 428 private DisplayManagerInternal mDisplayManagerInternal; 429 430 /** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */ 431 boolean inResumeTopActivity; 432 433 /** 434 * Temporary rect used during docked stack resize calculation so we don't need to create a new 435 * object each time. 436 */ 437 private final Rect tempRect = new Rect(); 438 private final ActivityOptions mTmpOptions = ActivityOptions.makeBasic(); 439 440 // The default minimal size that will be used if the activity doesn't specify its minimal size. 441 // It will be calculated when the default display gets added. 442 int mDefaultMinSizeOfResizeableTask = -1; 443 444 // Whether tasks have moved and we need to rank the tasks before next OOM scoring 445 private boolean mTaskLayersChanged = true; 446 447 private ActivityMetricsLogger mActivityMetricsLogger; 448 private LaunchTimeTracker mLaunchTimeTracker = new LaunchTimeTracker(); 449 450 private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>(); 451 452 @Override getChildCount()453 protected int getChildCount() { 454 return mActivityDisplays.size(); 455 } 456 457 @Override getChildAt(int index)458 protected ActivityDisplay getChildAt(int index) { 459 return mActivityDisplays.valueAt(index); 460 } 461 462 @Override getParent()463 protected ConfigurationContainer getParent() { 464 return null; 465 } 466 getDisplayOverrideConfiguration(int displayId)467 Configuration getDisplayOverrideConfiguration(int displayId) { 468 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 469 if (activityDisplay == null) { 470 throw new IllegalArgumentException("No display found with id: " + displayId); 471 } 472 473 return activityDisplay.getOverrideConfiguration(); 474 } 475 setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId)476 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) { 477 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 478 if (activityDisplay == null) { 479 throw new IllegalArgumentException("No display found with id: " + displayId); 480 } 481 482 activityDisplay.onOverrideConfigurationChanged(overrideConfiguration); 483 } 484 485 /** Check if placing task or activity on specified display is allowed. */ canPlaceEntityOnDisplay(int displayId, boolean resizeable, int callingPid, int callingUid, ActivityInfo activityInfo)486 boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable, int callingPid, 487 int callingUid, ActivityInfo activityInfo) { 488 if (displayId == DEFAULT_DISPLAY) { 489 // No restrictions for the default display. 490 return true; 491 } 492 if (!mService.mSupportsMultiDisplay) { 493 // Can't launch on secondary displays if feature is not supported. 494 return false; 495 } 496 if (!resizeable && !displayConfigMatchesGlobal(displayId)) { 497 // Can't apply wrong configuration to non-resizeable activities. 498 return false; 499 } 500 if (!isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, displayId, activityInfo)) { 501 // Can't place activities to a display that has restricted launch rules. 502 // In this case the request should be made by explicitly adding target display id and 503 // by caller with corresponding permissions. See #isCallerAllowedToLaunchOnDisplay(). 504 return false; 505 } 506 return true; 507 } 508 509 /** 510 * Check if configuration of specified display matches current global config. 511 * Used to check if we can put a non-resizeable activity on a secondary display and it will get 512 * the same config as on the default display. 513 * @param displayId Id of the display to check. 514 * @return {@code true} if configuration matches. 515 */ displayConfigMatchesGlobal(int displayId)516 private boolean displayConfigMatchesGlobal(int displayId) { 517 if (displayId == DEFAULT_DISPLAY) { 518 return true; 519 } 520 if (displayId == INVALID_DISPLAY) { 521 return false; 522 } 523 final ActivityDisplay targetDisplay = getActivityDisplayOrCreateLocked(displayId); 524 if (targetDisplay == null) { 525 throw new IllegalArgumentException("No display found with id: " + displayId); 526 } 527 return getConfiguration().equals(targetDisplay.getConfiguration()); 528 } 529 530 static class FindTaskResult { 531 ActivityRecord r; 532 boolean matchedByRootAffinity; 533 } 534 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); 535 536 /** 537 * Temp storage for display ids sorted in focus order. 538 * Maps position to id. Using {@link SparseIntArray} instead of {@link ArrayList} because 539 * it's more efficient, as the number of displays is usually small. 540 */ 541 private SparseIntArray mTmpOrderedDisplayIds = new SparseIntArray(); 542 543 /** 544 * Used to keep track whether app visibilities got changed since the last pause. Useful to 545 * determine whether to invoke the task stack change listener after pausing. 546 */ 547 boolean mAppVisibilitiesChangedSinceLastPause; 548 549 /** 550 * Set of tasks that are in resizing mode during an app transition to fill the "void". 551 */ 552 private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>(); 553 554 555 /** 556 * If set to {@code false} all calls to resize the docked stack {@link #resizeDockedStackLocked} 557 * will be ignored. Useful for the case where the caller is handling resizing of other stack and 558 * moving tasks around and doesn't want dock stack to be resized due to an automatic trigger 559 * like the docked stack going empty. 560 */ 561 private boolean mAllowDockedStackResize = true; 562 563 /** 564 * Is dock currently minimized. 565 */ 566 boolean mIsDockMinimized; 567 568 private KeyguardController mKeyguardController; 569 570 private PowerManager mPowerManager; 571 private int mDeferResumeCount; 572 573 private boolean mInitialized; 574 575 /** 576 * Description of a request to start a new activity, which has been held 577 * due to app switches being disabled. 578 */ 579 static class PendingActivityLaunch { 580 final ActivityRecord r; 581 final ActivityRecord sourceRecord; 582 final int startFlags; 583 final ActivityStack stack; 584 final ProcessRecord callerApp; 585 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, int _startFlags, ActivityStack _stack, ProcessRecord _callerApp)586 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 587 int _startFlags, ActivityStack _stack, ProcessRecord _callerApp) { 588 r = _r; 589 sourceRecord = _sourceRecord; 590 startFlags = _startFlags; 591 stack = _stack; 592 callerApp = _callerApp; 593 } 594 sendErrorResult(String message)595 void sendErrorResult(String message) { 596 try { 597 if (callerApp.thread != null) { 598 callerApp.thread.scheduleCrash(message); 599 } 600 } catch (RemoteException e) { 601 Slog.e(TAG, "Exception scheduling crash of failed " 602 + "activity launcher sourceRecord=" + sourceRecord, e); 603 } 604 } 605 } 606 ActivityStackSupervisor(ActivityManagerService service, Looper looper)607 public ActivityStackSupervisor(ActivityManagerService service, Looper looper) { 608 mService = service; 609 mLooper = looper; 610 mHandler = new ActivityStackSupervisorHandler(looper); 611 } 612 initialize()613 public void initialize() { 614 if (mInitialized) { 615 return; 616 } 617 618 mInitialized = true; 619 mRunningTasks = createRunningTasks(); 620 mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, 621 mHandler.getLooper()); 622 mKeyguardController = new KeyguardController(mService, this); 623 624 mLaunchParamsController = new LaunchParamsController(mService); 625 mLaunchParamsController.registerDefaultModifiers(this); 626 } 627 628 getActivityMetricsLogger()629 public ActivityMetricsLogger getActivityMetricsLogger() { 630 return mActivityMetricsLogger; 631 } 632 getLaunchTimeTracker()633 LaunchTimeTracker getLaunchTimeTracker() { 634 return mLaunchTimeTracker; 635 } 636 getKeyguardController()637 public KeyguardController getKeyguardController() { 638 return mKeyguardController; 639 } 640 setRecentTasks(RecentTasks recentTasks)641 void setRecentTasks(RecentTasks recentTasks) { 642 mRecentTasks = recentTasks; 643 mRecentTasks.registerCallback(this); 644 } 645 646 @VisibleForTesting createRunningTasks()647 RunningTasks createRunningTasks() { 648 return new RunningTasks(); 649 } 650 651 /** 652 * At the time when the constructor runs, the power manager has not yet been 653 * initialized. So we initialize our wakelocks afterwards. 654 */ initPowerManagement()655 void initPowerManagement() { 656 mPowerManager = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); 657 mGoingToSleep = mPowerManager 658 .newWakeLock(PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 659 mLaunchingActivity = mPowerManager.newWakeLock(PARTIAL_WAKE_LOCK, "*launch*"); 660 mLaunchingActivity.setReferenceCounted(false); 661 } 662 setWindowManager(WindowManagerService wm)663 void setWindowManager(WindowManagerService wm) { 664 synchronized (mService) { 665 mWindowManager = wm; 666 getKeyguardController().setWindowManager(wm); 667 668 mDisplayManager = 669 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); 670 mDisplayManager.registerDisplayListener(this, null); 671 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 672 673 Display[] displays = mDisplayManager.getDisplays(); 674 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { 675 final Display display = displays[displayNdx]; 676 ActivityDisplay activityDisplay = new ActivityDisplay(this, display); 677 mActivityDisplays.put(display.getDisplayId(), activityDisplay); 678 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 679 } 680 681 mHomeStack = mFocusedStack = mLastFocusedStack = getDefaultDisplay().getOrCreateStack( 682 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); 683 } 684 } 685 getFocusedStack()686 ActivityStack getFocusedStack() { 687 return mFocusedStack; 688 } 689 isFocusable(ConfigurationContainer container, boolean alwaysFocusable)690 boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) { 691 if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) { 692 return false; 693 } 694 695 return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable; 696 } 697 getLastStack()698 ActivityStack getLastStack() { 699 return mLastFocusedStack; 700 } 701 isFocusedStack(ActivityStack stack)702 boolean isFocusedStack(ActivityStack stack) { 703 return stack != null && stack == mFocusedStack; 704 } 705 706 /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */ setFocusStackUnchecked(String reason, ActivityStack focusCandidate)707 void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) { 708 if (!focusCandidate.isFocusable()) { 709 // The focus candidate isn't focusable. Move focus to the top stack that is focusable. 710 focusCandidate = getNextFocusableStackLocked(focusCandidate, false /* ignoreCurrent */); 711 } 712 713 if (focusCandidate != mFocusedStack) { 714 mLastFocusedStack = mFocusedStack; 715 mFocusedStack = focusCandidate; 716 717 EventLogTags.writeAmFocusedStack( 718 mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(), 719 mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason); 720 } 721 722 final ActivityRecord r = topRunningActivityLocked(); 723 if (mService.mBooting || !mService.mBooted) { 724 if (r != null && r.idle) { 725 checkFinishBootingLocked(); 726 } 727 } 728 } 729 moveHomeStackToFront(String reason)730 void moveHomeStackToFront(String reason) { 731 mHomeStack.moveToFront(reason); 732 } 733 moveRecentsStackToFront(String reason)734 void moveRecentsStackToFront(String reason) { 735 final ActivityStack recentsStack = getDefaultDisplay().getStack( 736 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS); 737 if (recentsStack != null) { 738 recentsStack.moveToFront(reason); 739 } 740 } 741 742 /** Returns true if the focus activity was adjusted to the home stack top activity. */ moveHomeStackTaskToTop(String reason)743 boolean moveHomeStackTaskToTop(String reason) { 744 mHomeStack.moveHomeStackTaskToTop(); 745 746 final ActivityRecord top = getHomeActivity(); 747 if (top == null) { 748 return false; 749 } 750 moveFocusableActivityStackToFrontLocked(top, reason); 751 return true; 752 } 753 resumeHomeStackTask(ActivityRecord prev, String reason)754 boolean resumeHomeStackTask(ActivityRecord prev, String reason) { 755 if (!mService.mBooting && !mService.mBooted) { 756 // Not ready yet! 757 return false; 758 } 759 760 mHomeStack.moveHomeStackTaskToTop(); 761 ActivityRecord r = getHomeActivity(); 762 final String myReason = reason + " resumeHomeStackTask"; 763 764 // Only resume home activity if isn't finishing. 765 if (r != null && !r.finishing) { 766 moveFocusableActivityStackToFrontLocked(r, myReason); 767 return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null); 768 } 769 return mService.startHomeActivityLocked(mCurrentUser, myReason); 770 } 771 anyTaskForIdLocked(int id)772 TaskRecord anyTaskForIdLocked(int id) { 773 return anyTaskForIdLocked(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE); 774 } 775 anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode)776 TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode) { 777 return anyTaskForIdLocked(id, matchMode, null, !ON_TOP); 778 } 779 780 /** 781 * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise. 782 * @param id Id of the task we would like returned. 783 * @param matchMode The mode to match the given task id in. 784 * @param aOptions The activity options to use for restoration. Can be null. 785 * @param onTop If the stack for the task should be the topmost on the display. 786 */ anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode, @Nullable ActivityOptions aOptions, boolean onTop)787 TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode, 788 @Nullable ActivityOptions aOptions, boolean onTop) { 789 // If options are set, ensure that we are attempting to actually restore a task 790 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) { 791 throw new IllegalArgumentException("Should not specify activity options for non-restore" 792 + " lookup"); 793 } 794 795 int numDisplays = mActivityDisplays.size(); 796 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 797 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 798 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 799 final ActivityStack stack = display.getChildAt(stackNdx); 800 final TaskRecord task = stack.taskForIdLocked(id); 801 if (task == null) { 802 continue; 803 } 804 if (aOptions != null) { 805 // Resolve the stack the task should be placed in now based on options 806 // and reparent if needed. 807 final ActivityStack launchStack = getLaunchStack(null, aOptions, task, onTop); 808 if (launchStack != null && stack != launchStack) { 809 final int reparentMode = onTop 810 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE; 811 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME, 812 "anyTaskForIdLocked"); 813 } 814 } 815 return task; 816 } 817 } 818 819 // If we are matching stack tasks only, return now 820 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) { 821 return null; 822 } 823 824 // Otherwise, check the recent tasks and return if we find it there and we are not restoring 825 // the task from recents 826 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents"); 827 final TaskRecord task = mRecentTasks.getTask(id); 828 829 if (task == null) { 830 if (DEBUG_RECENTS) { 831 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents"); 832 } 833 834 return null; 835 } 836 837 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) { 838 return task; 839 } 840 841 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 842 if (!restoreRecentTaskLocked(task, aOptions, onTop)) { 843 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, 844 "Couldn't restore task id=" + id + " found in recents"); 845 return null; 846 } 847 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents"); 848 return task; 849 } 850 isInAnyStackLocked(IBinder token)851 ActivityRecord isInAnyStackLocked(IBinder token) { 852 int numDisplays = mActivityDisplays.size(); 853 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 854 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 855 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 856 final ActivityStack stack = display.getChildAt(stackNdx); 857 final ActivityRecord r = stack.isInStackLocked(token); 858 if (r != null) { 859 return r; 860 } 861 } 862 } 863 return null; 864 } 865 866 /** 867 * Detects whether we should show a lock screen in front of this task for a locked user. 868 * <p> 869 * We'll do this if either of the following holds: 870 * <ul> 871 * <li>The top activity explicitly belongs to {@param userId}.</li> 872 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li> 873 * </ul> 874 * 875 * @return {@code true} if the top activity looks like it belongs to {@param userId}. 876 */ taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId)877 private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) { 878 // To handle the case that work app is in the task but just is not the top one. 879 final ActivityRecord activityRecord = task.getTopActivity(); 880 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null); 881 882 return (activityRecord != null && activityRecord.userId == userId) 883 || (resultTo != null && resultTo.userId == userId); 884 } 885 886 /** 887 * Find all visible task stacks containing {@param userId} and intercept them with an activity 888 * to block out the contents and possibly start a credential-confirming intent. 889 * 890 * @param userId user handle for the locked managed profile. 891 */ lockAllProfileTasks(@serIdInt int userId)892 void lockAllProfileTasks(@UserIdInt int userId) { 893 mWindowManager.deferSurfaceLayout(); 894 try { 895 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 896 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 897 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 898 final ActivityStack stack = display.getChildAt(stackNdx); 899 final List<TaskRecord> tasks = stack.getAllTasks(); 900 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) { 901 final TaskRecord task = tasks.get(taskNdx); 902 903 // Check the task for a top activity belonging to userId, or returning a 904 // result to an activity belonging to userId. Example case: a document 905 // picker for personal files, opened by a work app, should still get locked. 906 if (taskTopActivityIsUser(task, userId)) { 907 mService.mTaskChangeNotificationController.notifyTaskProfileLocked( 908 task.taskId, userId); 909 } 910 } 911 } 912 } 913 } finally { 914 mWindowManager.continueSurfaceLayout(); 915 } 916 } 917 setNextTaskIdForUserLocked(int taskId, int userId)918 void setNextTaskIdForUserLocked(int taskId, int userId) { 919 final int currentTaskId = mCurTaskIdForUser.get(userId, -1); 920 if (taskId > currentTaskId) { 921 mCurTaskIdForUser.put(userId, taskId); 922 } 923 } 924 nextTaskIdForUser(int taskId, int userId)925 static int nextTaskIdForUser(int taskId, int userId) { 926 int nextTaskId = taskId + 1; 927 if (nextTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) { 928 // Wrap around as there will be smaller task ids that are available now. 929 nextTaskId -= MAX_TASK_IDS_PER_USER; 930 } 931 return nextTaskId; 932 } 933 getNextTaskIdForUserLocked(int userId)934 int getNextTaskIdForUserLocked(int userId) { 935 final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER); 936 // for a userId u, a taskId can only be in the range 937 // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER 938 // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on. 939 int candidateTaskId = nextTaskIdForUser(currentTaskId, userId); 940 while (mRecentTasks.containsTaskId(candidateTaskId, userId) 941 || anyTaskForIdLocked( 942 candidateTaskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) != null) { 943 candidateTaskId = nextTaskIdForUser(candidateTaskId, userId); 944 if (candidateTaskId == currentTaskId) { 945 // Something wrong! 946 // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user 947 throw new IllegalStateException("Cannot get an available task id." 948 + " Reached limit of " + MAX_TASK_IDS_PER_USER 949 + " running tasks per user."); 950 } 951 } 952 mCurTaskIdForUser.put(userId, candidateTaskId); 953 return candidateTaskId; 954 } 955 getResumedActivityLocked()956 ActivityRecord getResumedActivityLocked() { 957 ActivityStack stack = mFocusedStack; 958 if (stack == null) { 959 return null; 960 } 961 ActivityRecord resumedActivity = stack.getResumedActivity(); 962 if (resumedActivity == null || resumedActivity.app == null) { 963 resumedActivity = stack.mPausingActivity; 964 if (resumedActivity == null || resumedActivity.app == null) { 965 resumedActivity = stack.topRunningActivityLocked(); 966 } 967 } 968 return resumedActivity; 969 } 970 attachApplicationLocked(ProcessRecord app)971 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { 972 final String processName = app.processName; 973 boolean didSomething = false; 974 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 975 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 976 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 977 final ActivityStack stack = display.getChildAt(stackNdx); 978 if (!isFocusedStack(stack)) { 979 continue; 980 } 981 stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); 982 final ActivityRecord top = stack.topRunningActivityLocked(); 983 final int size = mTmpActivityList.size(); 984 for (int i = 0; i < size; i++) { 985 final ActivityRecord activity = mTmpActivityList.get(i); 986 if (activity.app == null && app.uid == activity.info.applicationInfo.uid 987 && processName.equals(activity.processName)) { 988 try { 989 if (realStartActivityLocked(activity, app, 990 top == activity /* andResume */, true /* checkConfig */)) { 991 didSomething = true; 992 } 993 } catch (RemoteException e) { 994 Slog.w(TAG, "Exception in new application when starting activity " 995 + top.intent.getComponent().flattenToShortString(), e); 996 throw e; 997 } 998 } 999 } 1000 } 1001 } 1002 if (!didSomething) { 1003 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1004 } 1005 return didSomething; 1006 } 1007 allResumedActivitiesIdle()1008 boolean allResumedActivitiesIdle() { 1009 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1010 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 1011 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1012 final ActivityStack stack = display.getChildAt(stackNdx); 1013 if (!isFocusedStack(stack) || stack.numActivities() == 0) { 1014 continue; 1015 } 1016 final ActivityRecord resumedActivity = stack.getResumedActivity(); 1017 if (resumedActivity == null || !resumedActivity.idle) { 1018 if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack=" 1019 + stack.mStackId + " " + resumedActivity + " not idle"); 1020 return false; 1021 } 1022 } 1023 } 1024 // Send launch end powerhint when idle 1025 sendPowerHintForLaunchEndIfNeeded(); 1026 return true; 1027 } 1028 allResumedActivitiesComplete()1029 boolean allResumedActivitiesComplete() { 1030 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1031 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 1032 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1033 final ActivityStack stack = display.getChildAt(stackNdx); 1034 if (isFocusedStack(stack)) { 1035 final ActivityRecord r = stack.getResumedActivity(); 1036 if (r != null && !r.isState(RESUMED)) { 1037 return false; 1038 } 1039 } 1040 } 1041 } 1042 // TODO: Not sure if this should check if all Paused are complete too. 1043 if (DEBUG_STACK) Slog.d(TAG_STACK, 1044 "allResumedActivitiesComplete: mLastFocusedStack changing from=" + 1045 mLastFocusedStack + " to=" + mFocusedStack); 1046 mLastFocusedStack = mFocusedStack; 1047 return true; 1048 } 1049 allResumedActivitiesVisible()1050 private boolean allResumedActivitiesVisible() { 1051 boolean foundResumed = false; 1052 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1053 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 1054 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1055 final ActivityStack stack = display.getChildAt(stackNdx); 1056 final ActivityRecord r = stack.getResumedActivity(); 1057 if (r != null) { 1058 if (!r.nowVisible || mActivitiesWaitingForVisibleActivity.contains(r)) { 1059 return false; 1060 } 1061 foundResumed = true; 1062 } 1063 } 1064 } 1065 return foundResumed; 1066 } 1067 1068 /** 1069 * Pause all activities in either all of the stacks or just the back stacks. 1070 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). 1071 * @param resuming The resuming activity. 1072 * @param dontWait The resuming activity isn't going to wait for all activities to be paused 1073 * before resuming. 1074 * @return true if any activity was paused as a result of this call. 1075 */ pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait)1076 boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) { 1077 boolean someActivityPaused = false; 1078 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1079 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 1080 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1081 final ActivityStack stack = display.getChildAt(stackNdx); 1082 if (!isFocusedStack(stack) && stack.getResumedActivity() != null) { 1083 if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack + 1084 " mResumedActivity=" + stack.getResumedActivity()); 1085 someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, 1086 dontWait); 1087 } 1088 } 1089 } 1090 return someActivityPaused; 1091 } 1092 allPausedActivitiesComplete()1093 boolean allPausedActivitiesComplete() { 1094 boolean pausing = true; 1095 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1096 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 1097 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1098 final ActivityStack stack = display.getChildAt(stackNdx); 1099 final ActivityRecord r = stack.mPausingActivity; 1100 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) { 1101 if (DEBUG_STATES) { 1102 Slog.d(TAG_STATES, 1103 "allPausedActivitiesComplete: r=" + r + " state=" + r.getState()); 1104 pausing = false; 1105 } else { 1106 return false; 1107 } 1108 } 1109 } 1110 } 1111 return pausing; 1112 } 1113 cancelInitializingActivities()1114 void cancelInitializingActivities() { 1115 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1116 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 1117 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1118 final ActivityStack stack = display.getChildAt(stackNdx); 1119 stack.cancelInitializingActivities(); 1120 } 1121 } 1122 } 1123 waitActivityVisible(ComponentName name, WaitResult result)1124 void waitActivityVisible(ComponentName name, WaitResult result) { 1125 final WaitInfo waitInfo = new WaitInfo(name, result); 1126 mWaitingForActivityVisible.add(waitInfo); 1127 } 1128 cleanupActivity(ActivityRecord r)1129 void cleanupActivity(ActivityRecord r) { 1130 // Make sure this record is no longer in the pending finishes list. 1131 // This could happen, for example, if we are trimming activities 1132 // down to the max limit while they are still waiting to finish. 1133 mFinishingActivities.remove(r); 1134 mActivitiesWaitingForVisibleActivity.remove(r); 1135 1136 for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) { 1137 if (mWaitingForActivityVisible.get(i).matches(r.realActivity)) { 1138 mWaitingForActivityVisible.remove(i); 1139 } 1140 } 1141 } 1142 reportActivityVisibleLocked(ActivityRecord r)1143 void reportActivityVisibleLocked(ActivityRecord r) { 1144 sendWaitingVisibleReportLocked(r); 1145 } 1146 sendWaitingVisibleReportLocked(ActivityRecord r)1147 void sendWaitingVisibleReportLocked(ActivityRecord r) { 1148 boolean changed = false; 1149 for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) { 1150 final WaitInfo w = mWaitingForActivityVisible.get(i); 1151 if (w.matches(r.realActivity)) { 1152 final WaitResult result = w.getResult(); 1153 changed = true; 1154 result.timeout = false; 1155 result.who = w.getComponent(); 1156 result.totalTime = SystemClock.uptimeMillis() - result.thisTime; 1157 result.thisTime = result.totalTime; 1158 mWaitingForActivityVisible.remove(w); 1159 } 1160 } 1161 if (changed) { 1162 mService.notifyAll(); 1163 } 1164 } 1165 reportWaitingActivityLaunchedIfNeeded(ActivityRecord r, int result)1166 void reportWaitingActivityLaunchedIfNeeded(ActivityRecord r, int result) { 1167 if (mWaitingActivityLaunched.isEmpty()) { 1168 return; 1169 } 1170 1171 if (result != START_DELIVERED_TO_TOP && result != START_TASK_TO_FRONT) { 1172 return; 1173 } 1174 1175 boolean changed = false; 1176 1177 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 1178 WaitResult w = mWaitingActivityLaunched.remove(i); 1179 if (w.who == null) { 1180 changed = true; 1181 w.result = result; 1182 1183 // Unlike START_TASK_TO_FRONT, When an intent is delivered to top, there 1184 // will be no followup launch signals. Assign the result and launched component. 1185 if (result == START_DELIVERED_TO_TOP) { 1186 w.who = r.realActivity; 1187 } 1188 } 1189 } 1190 1191 if (changed) { 1192 mService.notifyAll(); 1193 } 1194 } 1195 reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, long thisTime, long totalTime)1196 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 1197 long thisTime, long totalTime) { 1198 boolean changed = false; 1199 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 1200 WaitResult w = mWaitingActivityLaunched.remove(i); 1201 if (w.who == null) { 1202 changed = true; 1203 w.timeout = timeout; 1204 if (r != null) { 1205 w.who = new ComponentName(r.info.packageName, r.info.name); 1206 } 1207 w.thisTime = thisTime; 1208 w.totalTime = totalTime; 1209 // Do not modify w.result. 1210 } 1211 } 1212 if (changed) { 1213 mService.notifyAll(); 1214 } 1215 } 1216 topRunningActivityLocked()1217 ActivityRecord topRunningActivityLocked() { 1218 return topRunningActivityLocked(false /* considerKeyguardState */); 1219 } 1220 1221 /** 1222 * Returns the top running activity in the focused stack. In the case the focused stack has no 1223 * such activity, the next focusable stack on top of a display is returned. 1224 * @param considerKeyguardState Indicates whether the locked state should be considered. if 1225 * {@code true} and the keyguard is locked, only activities that 1226 * can be shown on top of the keyguard will be considered. 1227 * @return The top running activity. {@code null} if none is available. 1228 */ topRunningActivityLocked(boolean considerKeyguardState)1229 ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) { 1230 final ActivityStack focusedStack = mFocusedStack; 1231 ActivityRecord r = focusedStack.topRunningActivityLocked(); 1232 if (r != null && isValidTopRunningActivity(r, considerKeyguardState)) { 1233 return r; 1234 } 1235 1236 // Look in other non-focused and non-home stacks. 1237 mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds); 1238 1239 for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) { 1240 final int displayId = mTmpOrderedDisplayIds.get(i); 1241 final ActivityDisplay display = mActivityDisplays.get(displayId); 1242 1243 // If WindowManagerService has encountered the display before we have, ignore as there 1244 // will be no stacks present and therefore no activities. 1245 if (display == null) { 1246 continue; 1247 } 1248 1249 // TODO: We probably want to consider the top fullscreen stack as we could have a pinned 1250 // stack on top. 1251 final ActivityStack topStack = display.getTopStack(); 1252 1253 // Only consider focusable top stacks other than the current focused one. 1254 if (topStack == null || !topStack.isFocusable() || topStack == focusedStack) { 1255 continue; 1256 } 1257 1258 final ActivityRecord topActivity = topStack.topRunningActivityLocked(); 1259 1260 // Skip if no top activity. 1261 if (topActivity == null) { 1262 continue; 1263 } 1264 1265 1266 // This activity can be considered the top running activity if we are not 1267 // considering the locked state, the keyguard isn't locked, or we can show when 1268 // locked. 1269 if (isValidTopRunningActivity(topActivity, considerKeyguardState)) { 1270 return topActivity; 1271 } 1272 } 1273 1274 return null; 1275 } 1276 1277 /** 1278 * Verifies an {@link ActivityRecord} can be the top activity based on keyguard state and 1279 * whether we are considering it. 1280 */ isValidTopRunningActivity(ActivityRecord record, boolean considerKeyguardState)1281 private boolean isValidTopRunningActivity(ActivityRecord record, 1282 boolean considerKeyguardState) { 1283 if (!considerKeyguardState) { 1284 return true; 1285 } 1286 1287 final boolean keyguardLocked = getKeyguardController().isKeyguardLocked(); 1288 1289 if (!keyguardLocked) { 1290 return true; 1291 } 1292 1293 return record.canShowWhenLocked(); 1294 } 1295 1296 @VisibleForTesting getRunningTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed)1297 void getRunningTasks(int maxNum, List<RunningTaskInfo> list, 1298 @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode, 1299 int callingUid, boolean allowed) { 1300 mRunningTasks.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, 1301 mActivityDisplays, callingUid, allowed); 1302 } 1303 resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, ProfilerInfo profilerInfo)1304 ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, 1305 ProfilerInfo profilerInfo) { 1306 final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null; 1307 if (aInfo != null) { 1308 // Store the found target back into the intent, because now that 1309 // we have it we never want to do this again. For example, if the 1310 // user navigates back to this point in the history, we should 1311 // always restart the exact same activity. 1312 intent.setComponent(new ComponentName( 1313 aInfo.applicationInfo.packageName, aInfo.name)); 1314 1315 // Don't debug things in the system process 1316 if (!aInfo.processName.equals("system")) { 1317 if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) { 1318 mService.setDebugApp(aInfo.processName, true, false); 1319 } 1320 1321 if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) { 1322 mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName); 1323 } 1324 1325 if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) { 1326 mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName); 1327 } 1328 1329 if (profilerInfo != null) { 1330 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo); 1331 } 1332 } 1333 final String intentLaunchToken = intent.getLaunchToken(); 1334 if (aInfo.launchToken == null && intentLaunchToken != null) { 1335 aInfo.launchToken = intentLaunchToken; 1336 } 1337 } 1338 return aInfo; 1339 } 1340 resolveIntent(Intent intent, String resolvedType, int userId, int flags, int filterCallingUid)1341 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags, 1342 int filterCallingUid) { 1343 synchronized (mService) { 1344 try { 1345 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "resolveIntent"); 1346 int modifiedFlags = flags 1347 | PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS; 1348 if (intent.isWebIntent() 1349 || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) { 1350 modifiedFlags |= PackageManager.MATCH_INSTANT; 1351 } 1352 1353 // In order to allow cross-profile lookup, we clear the calling identity here. 1354 // Note the binder identity won't affect the result, but filterCallingUid will. 1355 1356 // Cross-user/profile call check are done at the entry points 1357 // (e.g. AMS.startActivityAsUser). 1358 final long token = Binder.clearCallingIdentity(); 1359 try { 1360 return mService.getPackageManagerInternalLocked().resolveIntent( 1361 intent, resolvedType, modifiedFlags, userId, true, filterCallingUid); 1362 } finally { 1363 Binder.restoreCallingIdentity(token); 1364 } 1365 } finally { 1366 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 1367 } 1368 } 1369 } 1370 resolveActivity(Intent intent, String resolvedType, int startFlags, ProfilerInfo profilerInfo, int userId, int filterCallingUid)1371 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 1372 ProfilerInfo profilerInfo, int userId, int filterCallingUid) { 1373 final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId, 0, filterCallingUid); 1374 return resolveActivity(intent, rInfo, startFlags, profilerInfo); 1375 } 1376 realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig)1377 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, 1378 boolean andResume, boolean checkConfig) throws RemoteException { 1379 1380 if (!allPausedActivitiesComplete()) { 1381 // While there are activities pausing we skipping starting any new activities until 1382 // pauses are complete. NOTE: that we also do this for activities that are starting in 1383 // the paused state because they will first be resumed then paused on the client side. 1384 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, 1385 "realStartActivityLocked: Skipping start of r=" + r 1386 + " some activities pausing..."); 1387 return false; 1388 } 1389 1390 final TaskRecord task = r.getTask(); 1391 final ActivityStack stack = task.getStack(); 1392 1393 beginDeferResume(); 1394 1395 try { 1396 r.startFreezingScreenLocked(app, 0); 1397 1398 // schedule launch ticks to collect information about slow apps. 1399 r.startLaunchTickingLocked(); 1400 1401 r.setProcess(app); 1402 1403 if (getKeyguardController().isKeyguardLocked()) { 1404 r.notifyUnknownVisibilityLaunched(); 1405 } 1406 1407 // Have the window manager re-evaluate the orientation of the screen based on the new 1408 // activity order. Note that as a result of this, it can call back into the activity 1409 // manager with a new orientation. We don't care about that, because the activity is 1410 // not currently running so we are just restarting it anyway. 1411 if (checkConfig) { 1412 // Deferring resume here because we're going to launch new activity shortly. 1413 // We don't want to perform a redundant launch of the same record while ensuring 1414 // configurations and trying to resume top activity of focused stack. 1415 ensureVisibilityAndConfig(r, r.getDisplayId(), 1416 false /* markFrozenIfConfigChanged */, true /* deferResume */); 1417 } 1418 1419 if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */, 1420 true /* isTop */)) { 1421 // We only set the visibility to true if the activity is allowed to be visible 1422 // based on 1423 // keyguard state. This avoids setting this into motion in window manager that is 1424 // later cancelled due to later calls to ensure visible activities that set 1425 // visibility back to false. 1426 r.setVisibility(true); 1427 } 1428 1429 final int applicationInfoUid = 1430 (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1; 1431 if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) { 1432 Slog.wtf(TAG, 1433 "User ID for activity changing for " + r 1434 + " appInfo.uid=" + r.appInfo.uid 1435 + " info.ai.uid=" + applicationInfoUid 1436 + " old=" + r.app + " new=" + app); 1437 } 1438 1439 app.waitingToKill = null; 1440 r.launchCount++; 1441 r.lastLaunchTime = SystemClock.uptimeMillis(); 1442 1443 if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r); 1444 1445 int idx = app.activities.indexOf(r); 1446 if (idx < 0) { 1447 app.activities.add(r); 1448 } 1449 mService.updateLruProcessLocked(app, true, null); 1450 mService.updateOomAdjLocked(); 1451 1452 final LockTaskController lockTaskController = mService.getLockTaskController(); 1453 if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE 1454 || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV 1455 || (task.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED 1456 && lockTaskController.getLockTaskModeState() 1457 == LOCK_TASK_MODE_LOCKED)) { 1458 lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */); 1459 } 1460 1461 try { 1462 if (app.thread == null) { 1463 throw new RemoteException(); 1464 } 1465 List<ResultInfo> results = null; 1466 List<ReferrerIntent> newIntents = null; 1467 if (andResume) { 1468 // We don't need to deliver new intents and/or set results if activity is going 1469 // to pause immediately after launch. 1470 results = r.results; 1471 newIntents = r.newIntents; 1472 } 1473 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 1474 "Launching: " + r + " icicle=" + r.icicle + " with results=" + results 1475 + " newIntents=" + newIntents + " andResume=" + andResume); 1476 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId, 1477 System.identityHashCode(r), task.taskId, r.shortComponentName); 1478 if (r.isActivityTypeHome()) { 1479 // Home process is the root process of the task. 1480 mService.mHomeProcess = task.mActivities.get(0).app; 1481 } 1482 mService.notifyPackageUse(r.intent.getComponent().getPackageName(), 1483 PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY); 1484 r.sleeping = false; 1485 r.forceNewConfig = false; 1486 mService.getAppWarningsLocked().onStartActivity(r); 1487 mService.showAskCompatModeDialogLocked(r); 1488 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 1489 ProfilerInfo profilerInfo = null; 1490 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 1491 if (mService.mProfileProc == null || mService.mProfileProc == app) { 1492 mService.mProfileProc = app; 1493 ProfilerInfo profilerInfoSvc = mService.mProfilerInfo; 1494 if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) { 1495 if (profilerInfoSvc.profileFd != null) { 1496 try { 1497 profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup(); 1498 } catch (IOException e) { 1499 profilerInfoSvc.closeFd(); 1500 } 1501 } 1502 1503 profilerInfo = new ProfilerInfo(profilerInfoSvc); 1504 } 1505 } 1506 } 1507 1508 app.hasShownUi = true; 1509 app.pendingUiClean = true; 1510 app.forceProcessStateUpTo(mService.mTopProcessState); 1511 // Because we could be starting an Activity in the system process this may not go 1512 // across a Binder interface which would create a new Configuration. Consequently 1513 // we have to always create a new Configuration here. 1514 1515 final MergedConfiguration mergedConfiguration = new MergedConfiguration( 1516 mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration()); 1517 r.setLastReportedConfiguration(mergedConfiguration); 1518 1519 logIfTransactionTooLarge(r.intent, r.icicle); 1520 1521 1522 // Create activity launch transaction. 1523 final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, 1524 r.appToken); 1525 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), 1526 System.identityHashCode(r), r.info, 1527 // TODO: Have this take the merged configuration instead of separate global 1528 // and override configs. 1529 mergedConfiguration.getGlobalConfiguration(), 1530 mergedConfiguration.getOverrideConfiguration(), r.compat, 1531 r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, 1532 r.persistentState, results, newIntents, mService.isNextTransitionForward(), 1533 profilerInfo)); 1534 1535 // Set desired final state. 1536 final ActivityLifecycleItem lifecycleItem; 1537 if (andResume) { 1538 lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); 1539 } else { 1540 lifecycleItem = PauseActivityItem.obtain(); 1541 } 1542 clientTransaction.setLifecycleStateRequest(lifecycleItem); 1543 1544 // Schedule transaction. 1545 mService.getLifecycleManager().scheduleTransaction(clientTransaction); 1546 1547 1548 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 1549 && mService.mHasHeavyWeightFeature) { 1550 // This may be a heavy-weight process! Note that the package 1551 // manager will ensure that only activity can run in the main 1552 // process of the .apk, which is the only thing that will be 1553 // considered heavy-weight. 1554 if (app.processName.equals(app.info.packageName)) { 1555 if (mService.mHeavyWeightProcess != null 1556 && mService.mHeavyWeightProcess != app) { 1557 Slog.w(TAG, "Starting new heavy weight process " + app 1558 + " when already running " 1559 + mService.mHeavyWeightProcess); 1560 } 1561 mService.mHeavyWeightProcess = app; 1562 Message msg = mService.mHandler.obtainMessage( 1563 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1564 msg.obj = r; 1565 mService.mHandler.sendMessage(msg); 1566 } 1567 } 1568 1569 } catch (RemoteException e) { 1570 if (r.launchFailed) { 1571 // This is the second time we failed -- finish activity 1572 // and give up. 1573 Slog.e(TAG, "Second failure launching " 1574 + r.intent.getComponent().flattenToShortString() 1575 + ", giving up", e); 1576 mService.appDiedLocked(app); 1577 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1578 "2nd-crash", false); 1579 return false; 1580 } 1581 1582 // This is the first time we failed -- restart process and 1583 // retry. 1584 r.launchFailed = true; 1585 app.activities.remove(r); 1586 throw e; 1587 } 1588 } finally { 1589 endDeferResume(); 1590 } 1591 1592 r.launchFailed = false; 1593 if (stack.updateLRUListLocked(r)) { 1594 Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); 1595 } 1596 1597 // TODO(lifecycler): Resume or pause requests are done as part of launch transaction, 1598 // so updating the state should be done accordingly. 1599 if (andResume && readyToResume()) { 1600 // As part of the process of launching, ActivityThread also performs 1601 // a resume. 1602 stack.minimalResumeActivityLocked(r); 1603 } else { 1604 // This activity is not starting in the resumed state... which should look like we asked 1605 // it to pause+stop (but remain visible), and it has done so and reported back the 1606 // current icicle and other state. 1607 if (DEBUG_STATES) Slog.v(TAG_STATES, 1608 "Moving to PAUSED: " + r + " (starting in paused state)"); 1609 r.setState(PAUSED, "realStartActivityLocked"); 1610 } 1611 1612 // Launch the new version setup screen if needed. We do this -after- 1613 // launching the initial activity (that is, home), so that it can have 1614 // a chance to initialize itself while in the background, making the 1615 // switch back to it faster and look better. 1616 if (isFocusedStack(stack)) { 1617 mService.getActivityStartController().startSetupActivity(); 1618 } 1619 1620 // Update any services we are bound to that might care about whether 1621 // their client may have activities. 1622 if (r.app != null) { 1623 mService.mServices.updateServiceConnectionActivitiesLocked(r.app); 1624 } 1625 1626 return true; 1627 } 1628 1629 /** 1630 * Ensure all activities visibility, update orientation and configuration. 1631 * 1632 * @param starting The currently starting activity or {@code null} if there is none. 1633 * @param displayId The id of the display where operation is executed. 1634 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to 1635 * {@code true} if config changed. 1636 * @param deferResume Whether to defer resume while updating config. 1637 */ ensureVisibilityAndConfig(ActivityRecord starting, int displayId, boolean markFrozenIfConfigChanged, boolean deferResume)1638 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId, 1639 boolean markFrozenIfConfigChanged, boolean deferResume) { 1640 // First ensure visibility without updating the config just yet. We need this to know what 1641 // activities are affecting configuration now. 1642 // Passing null here for 'starting' param value, so that visibility of actual starting 1643 // activity will be properly updated. 1644 ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */, 1645 false /* preserveWindows */, false /* notifyClients */); 1646 1647 // Force-update the orientation from the WindowManager, since we need the true configuration 1648 // to send to the client now. 1649 final Configuration config = mWindowManager.updateOrientationFromAppTokens( 1650 getDisplayOverrideConfiguration(displayId), 1651 starting != null && starting.mayFreezeScreenLocked(starting.app) 1652 ? starting.appToken : null, 1653 displayId, true /* forceUpdate */); 1654 if (starting != null && markFrozenIfConfigChanged && config != null) { 1655 starting.frozenBeforeDestroy = true; 1656 } 1657 1658 // Update the configuration of the activities on the display. 1659 return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume, 1660 displayId); 1661 } 1662 logIfTransactionTooLarge(Intent intent, Bundle icicle)1663 private void logIfTransactionTooLarge(Intent intent, Bundle icicle) { 1664 int extrasSize = 0; 1665 if (intent != null) { 1666 final Bundle extras = intent.getExtras(); 1667 if (extras != null) { 1668 extrasSize = extras.getSize(); 1669 } 1670 } 1671 int icicleSize = (icicle == null ? 0 : icicle.getSize()); 1672 if (extrasSize + icicleSize > 200000) { 1673 Slog.e(TAG, "Transaction too large, intent: " + intent + ", extras size: " + extrasSize 1674 + ", icicle size: " + icicleSize); 1675 } 1676 } 1677 startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig)1678 void startSpecificActivityLocked(ActivityRecord r, 1679 boolean andResume, boolean checkConfig) { 1680 // Is this activity's application already running? 1681 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1682 r.info.applicationInfo.uid, true); 1683 1684 getLaunchTimeTracker().setLaunchTime(r); 1685 1686 if (app != null && app.thread != null) { 1687 try { 1688 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1689 || !"android".equals(r.info.packageName)) { 1690 // Don't add this if it is a platform component that is marked 1691 // to run in multiple processes, because this is actually 1692 // part of the framework so doesn't make sense to track as a 1693 // separate apk in the process. 1694 app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode, 1695 mService.mProcessStats); 1696 } 1697 realStartActivityLocked(r, app, andResume, checkConfig); 1698 return; 1699 } catch (RemoteException e) { 1700 Slog.w(TAG, "Exception when starting activity " 1701 + r.intent.getComponent().flattenToShortString(), e); 1702 } 1703 1704 // If a dead object exception was thrown -- fall through to 1705 // restart the application. 1706 } 1707 1708 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1709 "activity", r.intent.getComponent(), false, false, true); 1710 } 1711 sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity)1712 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) { 1713 boolean sendHint = forceSend; 1714 1715 if (!sendHint) { 1716 // If not forced, send power hint when the activity's process is different than the 1717 // current resumed activity. 1718 final ActivityRecord resumedActivity = getResumedActivityLocked(); 1719 sendHint = resumedActivity == null 1720 || resumedActivity.app == null 1721 || !resumedActivity.app.equals(targetActivity.app); 1722 } 1723 1724 if (sendHint && mService.mLocalPowerManager != null) { 1725 mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 1); 1726 mPowerHintSent = true; 1727 } 1728 } 1729 sendPowerHintForLaunchEndIfNeeded()1730 void sendPowerHintForLaunchEndIfNeeded() { 1731 // Trigger launch power hint if activity is launched 1732 if (mPowerHintSent && mService.mLocalPowerManager != null) { 1733 mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 0); 1734 mPowerHintSent = false; 1735 } 1736 } 1737 checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, boolean ignoreTargetSecurity, boolean launchingInTask, ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack)1738 boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, 1739 String resultWho, int requestCode, int callingPid, int callingUid, 1740 String callingPackage, boolean ignoreTargetSecurity, boolean launchingInTask, 1741 ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack) { 1742 final boolean isCallerRecents = mService.getRecentTasks() != null && 1743 mService.getRecentTasks().isCallerRecents(callingUid); 1744 final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, 1745 callingUid); 1746 if (startAnyPerm == PERMISSION_GRANTED || (isCallerRecents && launchingInTask)) { 1747 // If the caller has START_ANY_ACTIVITY, ignore all checks below. In addition, if the 1748 // caller is the recents component and we are specifically starting an activity in an 1749 // existing task, then also allow the activity to be fully relaunched. 1750 return true; 1751 } 1752 final int componentRestriction = getComponentRestrictionForCallingPackage( 1753 aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity); 1754 final int actionRestriction = getActionRestrictionForCallingPackage( 1755 intent.getAction(), callingPackage, callingPid, callingUid); 1756 if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION 1757 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1758 if (resultRecord != null) { 1759 resultStack.sendActivityResultLocked(-1, 1760 resultRecord, resultWho, requestCode, 1761 Activity.RESULT_CANCELED, null); 1762 } 1763 final String msg; 1764 if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1765 msg = "Permission Denial: starting " + intent.toString() 1766 + " from " + callerApp + " (pid=" + callingPid 1767 + ", uid=" + callingUid + ")" + " with revoked permission " 1768 + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); 1769 } else if (!aInfo.exported) { 1770 msg = "Permission Denial: starting " + intent.toString() 1771 + " from " + callerApp + " (pid=" + callingPid 1772 + ", uid=" + callingUid + ")" 1773 + " not exported from uid " + aInfo.applicationInfo.uid; 1774 } else { 1775 msg = "Permission Denial: starting " + intent.toString() 1776 + " from " + callerApp + " (pid=" + callingPid 1777 + ", uid=" + callingUid + ")" 1778 + " requires " + aInfo.permission; 1779 } 1780 Slog.w(TAG, msg); 1781 throw new SecurityException(msg); 1782 } 1783 1784 if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) { 1785 final String message = "Appop Denial: starting " + intent.toString() 1786 + " from " + callerApp + " (pid=" + callingPid 1787 + ", uid=" + callingUid + ")" 1788 + " requires " + AppOpsManager.permissionToOp( 1789 ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction())); 1790 Slog.w(TAG, message); 1791 return false; 1792 } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) { 1793 final String message = "Appop Denial: starting " + intent.toString() 1794 + " from " + callerApp + " (pid=" + callingPid 1795 + ", uid=" + callingUid + ")" 1796 + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission); 1797 Slog.w(TAG, message); 1798 return false; 1799 } 1800 1801 return true; 1802 } 1803 1804 /** Check if caller is allowed to launch activities on specified display. */ isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, ActivityInfo aInfo)1805 boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId, 1806 ActivityInfo aInfo) { 1807 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId 1808 + " callingPid=" + callingPid + " callingUid=" + callingUid); 1809 1810 if (callingPid == -1 && callingUid == -1) { 1811 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: no caller info, skip check"); 1812 return true; 1813 } 1814 1815 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(launchDisplayId); 1816 if (activityDisplay == null) { 1817 Slog.w(TAG, "Launch on display check: display not found"); 1818 return false; 1819 } 1820 1821 // Check if the caller has enough privileges to embed activities and launch to private 1822 // displays. 1823 final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid, 1824 callingUid); 1825 if (startAnyPerm == PERMISSION_GRANTED) { 1826 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1827 + " allow launch any on display"); 1828 return true; 1829 } 1830 1831 // Check if caller is already present on display 1832 final boolean uidPresentOnDisplay = activityDisplay.isUidPresent(callingUid); 1833 1834 final int displayOwnerUid = activityDisplay.mDisplay.getOwnerUid(); 1835 if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL && displayOwnerUid != SYSTEM_UID 1836 && displayOwnerUid != aInfo.applicationInfo.uid) { 1837 // Limit launching on virtual displays, because their contents can be read from Surface 1838 // by apps that created them. 1839 if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 1840 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1841 + " disallow launch on virtual display for not-embedded activity."); 1842 return false; 1843 } 1844 // Check if the caller is allowed to embed activities from other apps. 1845 if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid) 1846 == PERMISSION_DENIED && !uidPresentOnDisplay) { 1847 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1848 + " disallow activity embedding without permission."); 1849 return false; 1850 } 1851 } 1852 1853 if (!activityDisplay.isPrivate()) { 1854 // Anyone can launch on a public display. 1855 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1856 + " allow launch on public display"); 1857 return true; 1858 } 1859 1860 // Check if the caller is the owner of the display. 1861 if (displayOwnerUid == callingUid) { 1862 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1863 + " allow launch for owner of the display"); 1864 return true; 1865 } 1866 1867 if (uidPresentOnDisplay) { 1868 if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:" 1869 + " allow launch for caller present on the display"); 1870 return true; 1871 } 1872 1873 Slog.w(TAG, "Launch on display check: denied"); 1874 return false; 1875 } 1876 1877 /** Update lists of UIDs that are present on displays and have access to them. */ updateUIDsPresentOnDisplay()1878 void updateUIDsPresentOnDisplay() { 1879 mDisplayAccessUIDs.clear(); 1880 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1881 final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 1882 // Only bother calculating the whitelist for private displays 1883 if (activityDisplay.isPrivate()) { 1884 mDisplayAccessUIDs.append( 1885 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs()); 1886 } 1887 } 1888 // Store updated lists in DisplayManager. Callers from outside of AM should get them there. 1889 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs); 1890 } 1891 getUserInfo(int userId)1892 UserInfo getUserInfo(int userId) { 1893 final long identity = Binder.clearCallingIdentity(); 1894 try { 1895 return UserManager.get(mService.mContext).getUserInfo(userId); 1896 } finally { 1897 Binder.restoreCallingIdentity(identity); 1898 } 1899 } 1900 getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity)1901 private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, 1902 String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { 1903 if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, 1904 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) 1905 == PERMISSION_DENIED) { 1906 return ACTIVITY_RESTRICTION_PERMISSION; 1907 } 1908 1909 if (activityInfo.permission == null) { 1910 return ACTIVITY_RESTRICTION_NONE; 1911 } 1912 1913 final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); 1914 if (opCode == AppOpsManager.OP_NONE) { 1915 return ACTIVITY_RESTRICTION_NONE; 1916 } 1917 1918 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1919 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1920 if (!ignoreTargetSecurity) { 1921 return ACTIVITY_RESTRICTION_APPOP; 1922 } 1923 } 1924 1925 return ACTIVITY_RESTRICTION_NONE; 1926 } 1927 getActionRestrictionForCallingPackage(String action, String callingPackage, int callingPid, int callingUid)1928 private int getActionRestrictionForCallingPackage(String action, 1929 String callingPackage, int callingPid, int callingUid) { 1930 if (action == null) { 1931 return ACTIVITY_RESTRICTION_NONE; 1932 } 1933 1934 String permission = ACTION_TO_RUNTIME_PERMISSION.get(action); 1935 if (permission == null) { 1936 return ACTIVITY_RESTRICTION_NONE; 1937 } 1938 1939 final PackageInfo packageInfo; 1940 try { 1941 packageInfo = mService.mContext.getPackageManager() 1942 .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS); 1943 } catch (PackageManager.NameNotFoundException e) { 1944 Slog.i(TAG, "Cannot find package info for " + callingPackage); 1945 return ACTIVITY_RESTRICTION_NONE; 1946 } 1947 1948 if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) { 1949 return ACTIVITY_RESTRICTION_NONE; 1950 } 1951 1952 if (mService.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) { 1953 return ACTIVITY_RESTRICTION_PERMISSION; 1954 } 1955 1956 final int opCode = AppOpsManager.permissionToOpCode(permission); 1957 if (opCode == AppOpsManager.OP_NONE) { 1958 return ACTIVITY_RESTRICTION_NONE; 1959 } 1960 1961 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1962 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1963 return ACTIVITY_RESTRICTION_APPOP; 1964 } 1965 1966 return ACTIVITY_RESTRICTION_NONE; 1967 } 1968 setLaunchSource(int uid)1969 void setLaunchSource(int uid) { 1970 mLaunchingActivity.setWorkSource(new WorkSource(uid)); 1971 } 1972 acquireLaunchWakelock()1973 void acquireLaunchWakelock() { 1974 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1975 throw new IllegalStateException("Calling must be system uid"); 1976 } 1977 mLaunchingActivity.acquire(); 1978 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1979 // To be safe, don't allow the wake lock to be held for too long. 1980 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1981 } 1982 } 1983 1984 /** 1985 * Called when the frontmost task is idle. 1986 * @return the state of mService.mBooting before this was called. 1987 */ 1988 @GuardedBy("mService") checkFinishBootingLocked()1989 private boolean checkFinishBootingLocked() { 1990 final boolean booting = mService.mBooting; 1991 boolean enableScreen = false; 1992 mService.mBooting = false; 1993 if (!mService.mBooted) { 1994 mService.mBooted = true; 1995 enableScreen = true; 1996 } 1997 if (booting || enableScreen) { 1998 mService.postFinishBooting(booting, enableScreen); 1999 } 2000 return booting; 2001 } 2002 2003 // Checked. 2004 @GuardedBy("mService") activityIdleInternalLocked(final IBinder token, boolean fromTimeout, boolean processPausingActivities, Configuration config)2005 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 2006 boolean processPausingActivities, Configuration config) { 2007 if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token); 2008 2009 ArrayList<ActivityRecord> finishes = null; 2010 ArrayList<UserState> startingUsers = null; 2011 int NS = 0; 2012 int NF = 0; 2013 boolean booting = false; 2014 boolean activityRemoved = false; 2015 2016 ActivityRecord r = ActivityRecord.forTokenLocked(token); 2017 if (r != null) { 2018 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers=" 2019 + Debug.getCallers(4)); 2020 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 2021 r.finishLaunchTickingLocked(); 2022 if (fromTimeout) { 2023 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 2024 } 2025 2026 // This is a hack to semi-deal with a race condition 2027 // in the client where it can be constructed with a 2028 // newer configuration from when we asked it to launch. 2029 // We'll update with whatever configuration it now says 2030 // it used to launch. 2031 if (config != null) { 2032 r.setLastReportedGlobalConfiguration(config); 2033 } 2034 2035 // We are now idle. If someone is waiting for a thumbnail from 2036 // us, we can now deliver. 2037 r.idle = true; 2038 2039 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 2040 if (isFocusedStack(r.getStack()) || fromTimeout) { 2041 booting = checkFinishBootingLocked(); 2042 } 2043 } 2044 2045 if (allResumedActivitiesIdle()) { 2046 if (r != null) { 2047 mService.scheduleAppGcsLocked(); 2048 } 2049 2050 if (mLaunchingActivity.isHeld()) { 2051 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2052 if (VALIDATE_WAKE_LOCK_CALLER && 2053 Binder.getCallingUid() != Process.myUid()) { 2054 throw new IllegalStateException("Calling must be system uid"); 2055 } 2056 mLaunchingActivity.release(); 2057 } 2058 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2059 } 2060 2061 // Atomically retrieve all of the other things to do. 2062 final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r, 2063 true /* remove */, processPausingActivities); 2064 NS = stops != null ? stops.size() : 0; 2065 if ((NF = mFinishingActivities.size()) > 0) { 2066 finishes = new ArrayList<>(mFinishingActivities); 2067 mFinishingActivities.clear(); 2068 } 2069 2070 if (mStartingUsers.size() > 0) { 2071 startingUsers = new ArrayList<>(mStartingUsers); 2072 mStartingUsers.clear(); 2073 } 2074 2075 // Stop any activities that are scheduled to do so but have been 2076 // waiting for the next one to start. 2077 for (int i = 0; i < NS; i++) { 2078 r = stops.get(i); 2079 final ActivityStack stack = r.getStack(); 2080 if (stack != null) { 2081 if (r.finishing) { 2082 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false, 2083 "activityIdleInternalLocked"); 2084 } else { 2085 stack.stopActivityLocked(r); 2086 } 2087 } 2088 } 2089 2090 // Finish any activities that are scheduled to do so but have been 2091 // waiting for the next one to start. 2092 for (int i = 0; i < NF; i++) { 2093 r = finishes.get(i); 2094 final ActivityStack stack = r.getStack(); 2095 if (stack != null) { 2096 activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle"); 2097 } 2098 } 2099 2100 if (!booting) { 2101 // Complete user switch 2102 if (startingUsers != null) { 2103 for (int i = 0; i < startingUsers.size(); i++) { 2104 mService.mUserController.finishUserSwitch(startingUsers.get(i)); 2105 } 2106 } 2107 } 2108 2109 mService.trimApplications(); 2110 //dump(); 2111 //mWindowManager.dump(); 2112 2113 if (activityRemoved) { 2114 resumeFocusedStackTopActivityLocked(); 2115 } 2116 2117 return r; 2118 } 2119 handleAppDiedLocked(ProcessRecord app)2120 boolean handleAppDiedLocked(ProcessRecord app) { 2121 boolean hasVisibleActivities = false; 2122 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2123 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 2124 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2125 final ActivityStack stack = display.getChildAt(stackNdx); 2126 hasVisibleActivities |= stack.handleAppDiedLocked(app); 2127 } 2128 } 2129 return hasVisibleActivities; 2130 } 2131 closeSystemDialogsLocked()2132 void closeSystemDialogsLocked() { 2133 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2134 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 2135 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2136 final ActivityStack stack = display.getChildAt(stackNdx); 2137 stack.closeSystemDialogsLocked(); 2138 } 2139 } 2140 } 2141 removeUserLocked(int userId)2142 void removeUserLocked(int userId) { 2143 mUserStackInFront.delete(userId); 2144 } 2145 2146 /** 2147 * Update the last used stack id for non-current user (current user's last 2148 * used stack is the focused stack) 2149 */ updateUserStackLocked(int userId, ActivityStack stack)2150 void updateUserStackLocked(int userId, ActivityStack stack) { 2151 if (userId != mCurrentUser) { 2152 mUserStackInFront.put(userId, stack != null ? stack.getStackId() : mHomeStack.mStackId); 2153 } 2154 } 2155 2156 /** 2157 * @return true if some activity was finished (or would have finished if doit were true). 2158 */ finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId)2159 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, 2160 boolean doit, boolean evenPersistent, int userId) { 2161 boolean didSomething = false; 2162 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2163 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 2164 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2165 final ActivityStack stack = display.getChildAt(stackNdx); 2166 if (stack.finishDisabledPackageActivitiesLocked( 2167 packageName, filterByClasses, doit, evenPersistent, userId)) { 2168 didSomething = true; 2169 } 2170 } 2171 } 2172 return didSomething; 2173 } 2174 updatePreviousProcessLocked(ActivityRecord r)2175 void updatePreviousProcessLocked(ActivityRecord r) { 2176 // Now that this process has stopped, we may want to consider 2177 // it to be the previous app to try to keep around in case 2178 // the user wants to return to it. 2179 2180 // First, found out what is currently the foreground app, so that 2181 // we don't blow away the previous app if this activity is being 2182 // hosted by the process that is actually still the foreground. 2183 ProcessRecord fgApp = null; 2184 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2185 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 2186 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2187 final ActivityStack stack = display.getChildAt(stackNdx); 2188 if (isFocusedStack(stack)) { 2189 final ActivityRecord resumedActivity = stack.getResumedActivity(); 2190 if (resumedActivity != null) { 2191 fgApp = resumedActivity.app; 2192 } else if (stack.mPausingActivity != null) { 2193 fgApp = stack.mPausingActivity.app; 2194 } 2195 break; 2196 } 2197 } 2198 } 2199 2200 // Now set this one as the previous process, only if that really 2201 // makes sense to. 2202 if (r.app != null && fgApp != null && r.app != fgApp 2203 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 2204 && r.app != mService.mHomeProcess) { 2205 mService.mPreviousProcess = r.app; 2206 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 2207 } 2208 } 2209 resumeFocusedStackTopActivityLocked()2210 boolean resumeFocusedStackTopActivityLocked() { 2211 return resumeFocusedStackTopActivityLocked(null, null, null); 2212 } 2213 resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions)2214 boolean resumeFocusedStackTopActivityLocked( 2215 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 2216 2217 if (!readyToResume()) { 2218 return false; 2219 } 2220 2221 if (targetStack != null && isFocusedStack(targetStack)) { 2222 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 2223 } 2224 2225 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); 2226 if (r == null || !r.isState(RESUMED)) { 2227 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); 2228 } else if (r.isState(RESUMED)) { 2229 // Kick off any lingering app transitions form the MoveTaskToFront operation. 2230 mFocusedStack.executeAppTransition(targetOptions); 2231 } 2232 2233 return false; 2234 } 2235 updateActivityApplicationInfoLocked(ApplicationInfo aInfo)2236 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) { 2237 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2238 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 2239 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2240 final ActivityStack stack = display.getChildAt(stackNdx); 2241 stack.updateActivityApplicationInfoLocked(aInfo); 2242 } 2243 } 2244 } 2245 2246 /** 2247 * Finish the topmost activities in all stacks that belong to the crashed app. 2248 * @param app The app that crashed. 2249 * @param reason Reason to perform this action. 2250 * @return The task that was finished in this stack, {@code null} if haven't found any. 2251 */ finishTopCrashedActivitiesLocked(ProcessRecord app, String reason)2252 TaskRecord finishTopCrashedActivitiesLocked(ProcessRecord app, String reason) { 2253 TaskRecord finishedTask = null; 2254 ActivityStack focusedStack = getFocusedStack(); 2255 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2256 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 2257 // It is possible that request to finish activity might also remove its task and stack, 2258 // so we need to be careful with indexes in the loop and check child count every time. 2259 for (int stackNdx = 0; stackNdx < display.getChildCount(); ++stackNdx) { 2260 final ActivityStack stack = display.getChildAt(stackNdx); 2261 final TaskRecord t = stack.finishTopCrashedActivityLocked(app, reason); 2262 if (stack == focusedStack || finishedTask == null) { 2263 finishedTask = t; 2264 } 2265 } 2266 } 2267 return finishedTask; 2268 } 2269 finishVoiceTask(IVoiceInteractionSession session)2270 void finishVoiceTask(IVoiceInteractionSession session) { 2271 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2272 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 2273 final int numStacks = display.getChildCount(); 2274 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2275 final ActivityStack stack = display.getChildAt(stackNdx); 2276 stack.finishVoiceTask(session); 2277 } 2278 } 2279 } 2280 findTaskToMoveToFront(TaskRecord task, int flags, ActivityOptions options, String reason, boolean forceNonResizeable)2281 void findTaskToMoveToFront(TaskRecord task, int flags, ActivityOptions options, String reason, 2282 boolean forceNonResizeable) { 2283 final ActivityStack currentStack = task.getStack(); 2284 if (currentStack == null) { 2285 Slog.e(TAG, "findTaskToMoveToFront: can't move task=" 2286 + task + " to front. Stack is null"); 2287 return; 2288 } 2289 2290 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 2291 mUserLeaving = true; 2292 } 2293 2294 final ActivityRecord prev = topRunningActivityLocked(); 2295 2296 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0 2297 || (prev != null && prev.isActivityTypeRecents())) { 2298 // Caller wants the home activity moved with it or the previous task is recents in which 2299 // case we always return home from the task we are moving to the front. 2300 moveHomeStackToFront("findTaskToMoveToFront"); 2301 } 2302 2303 if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) { 2304 final Rect bounds = options.getLaunchBounds(); 2305 task.updateOverrideConfiguration(bounds); 2306 2307 ActivityStack stack = getLaunchStack(null, options, task, ON_TOP); 2308 2309 if (stack != currentStack) { 2310 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME, 2311 "findTaskToMoveToFront"); 2312 stack = currentStack; 2313 // moveTaskToStackUncheckedLocked() should already placed the task on top, 2314 // still need moveTaskToFrontLocked() below for any transition settings. 2315 } 2316 if (stack.resizeStackWithLaunchBounds()) { 2317 resizeStackLocked(stack, bounds, null /* tempTaskBounds */, 2318 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, 2319 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2320 } else { 2321 // WM resizeTask must be done after the task is moved to the correct stack, 2322 // because Task's setBounds() also updates dim layer's bounds, but that has 2323 // dependency on the stack. 2324 task.resizeWindowContainer(); 2325 } 2326 } 2327 2328 final ActivityRecord r = task.getTopActivity(); 2329 currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options, 2330 r == null ? null : r.appTimeTracker, reason); 2331 2332 if (DEBUG_STACK) Slog.d(TAG_STACK, 2333 "findTaskToMoveToFront: moved to front of stack=" + currentStack); 2334 2335 handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED, DEFAULT_DISPLAY, 2336 currentStack, forceNonResizeable); 2337 } 2338 canUseActivityOptionsLaunchBounds(ActivityOptions options)2339 boolean canUseActivityOptionsLaunchBounds(ActivityOptions options) { 2340 // We use the launch bounds in the activity options is the device supports freeform 2341 // window management or is launching into the pinned stack. 2342 if (options == null || options.getLaunchBounds() == null) { 2343 return false; 2344 } 2345 return (mService.mSupportsPictureInPicture 2346 && options.getLaunchWindowingMode() == WINDOWING_MODE_PINNED) 2347 || mService.mSupportsFreeformWindowManagement; 2348 } 2349 getLaunchParamsController()2350 LaunchParamsController getLaunchParamsController() { 2351 return mLaunchParamsController; 2352 } 2353 getStack(int stackId)2354 protected <T extends ActivityStack> T getStack(int stackId) { 2355 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 2356 final T stack = mActivityDisplays.valueAt(i).getStack(stackId); 2357 if (stack != null) { 2358 return stack; 2359 } 2360 } 2361 return null; 2362 } 2363 2364 /** @see ActivityDisplay#getStack(int, int) */ getStack(int windowingMode, int activityType)2365 private <T extends ActivityStack> T getStack(int windowingMode, int activityType) { 2366 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 2367 final T stack = mActivityDisplays.valueAt(i).getStack(windowingMode, activityType); 2368 if (stack != null) { 2369 return stack; 2370 } 2371 } 2372 return null; 2373 } 2374 resolveActivityType(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord task)2375 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options, 2376 @Nullable TaskRecord task) { 2377 // Preference is given to the activity type for the activity then the task since the type 2378 // once set shouldn't change. 2379 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED; 2380 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) { 2381 activityType = task.getActivityType(); 2382 } 2383 if (activityType != ACTIVITY_TYPE_UNDEFINED) { 2384 return activityType; 2385 } 2386 if (options != null) { 2387 activityType = options.getLaunchActivityType(); 2388 } 2389 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD; 2390 } 2391 getLaunchStack(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop)2392 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, 2393 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) { 2394 return getLaunchStack(r, options, candidateTask, onTop, INVALID_DISPLAY); 2395 } 2396 2397 /** 2398 * Returns the right stack to use for launching factoring in all the input parameters. 2399 * 2400 * @param r The activity we are trying to launch. Can be null. 2401 * @param options The activity options used to the launch. Can be null. 2402 * @param candidateTask The possible task the activity might be launched in. Can be null. 2403 * 2404 * @return The stack to use for the launch or INVALID_STACK_ID. 2405 */ getLaunchStack(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop, int candidateDisplayId)2406 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, 2407 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop, 2408 int candidateDisplayId) { 2409 int taskId = INVALID_TASK_ID; 2410 int displayId = INVALID_DISPLAY; 2411 //Rect bounds = null; 2412 2413 // We give preference to the launch preference in activity options. 2414 if (options != null) { 2415 taskId = options.getLaunchTaskId(); 2416 displayId = options.getLaunchDisplayId(); 2417 // TODO: Need to work this into the equation... 2418 //bounds = options.getLaunchBounds(); 2419 } 2420 2421 // First preference for stack goes to the task Id set in the activity options. Use the stack 2422 // associated with that if possible. 2423 if (taskId != INVALID_TASK_ID) { 2424 // Temporarily set the task id to invalid in case in re-entry. 2425 options.setLaunchTaskId(INVALID_TASK_ID); 2426 final TaskRecord task = anyTaskForIdLocked(taskId, 2427 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop); 2428 options.setLaunchTaskId(taskId); 2429 if (task != null) { 2430 return task.getStack(); 2431 } 2432 } 2433 2434 final int activityType = resolveActivityType(r, options, candidateTask); 2435 T stack = null; 2436 2437 // Next preference for stack goes to the display Id set in the activity options or the 2438 // candidate display. 2439 if (displayId == INVALID_DISPLAY) { 2440 displayId = candidateDisplayId; 2441 } 2442 if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) { 2443 if (r != null) { 2444 // TODO: This should also take in the windowing mode and activity type into account. 2445 stack = (T) getValidLaunchStackOnDisplay(displayId, r); 2446 if (stack != null) { 2447 return stack; 2448 } 2449 } 2450 final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId); 2451 if (display != null) { 2452 stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop); 2453 if (stack != null) { 2454 return stack; 2455 } 2456 } 2457 } 2458 2459 // Give preference to the stack and display of the input task and activity if they match the 2460 // mode we want to launch into. 2461 stack = null; 2462 ActivityDisplay display = null; 2463 if (candidateTask != null) { 2464 stack = candidateTask.getStack(); 2465 } 2466 if (stack == null && r != null) { 2467 stack = r.getStack(); 2468 } 2469 if (stack != null) { 2470 display = stack.getDisplay(); 2471 if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) { 2472 final int windowingMode = 2473 display.resolveWindowingMode(r, options, candidateTask, activityType); 2474 if (stack.isCompatible(windowingMode, activityType)) { 2475 return stack; 2476 } 2477 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY 2478 && display.getSplitScreenPrimaryStack() == stack 2479 && candidateTask == stack.topTask()) { 2480 // This is a special case when we try to launch an activity that is currently on 2481 // top of split-screen primary stack, but is targeting split-screen secondary. 2482 // In this case we don't want to move it to another stack. 2483 // TODO(b/78788972): Remove after differentiating between preferred and required 2484 // launch options. 2485 return stack; 2486 } 2487 } 2488 } 2489 2490 if (display == null 2491 || !canLaunchOnDisplay(r, display.mDisplayId) 2492 // TODO: Can be removed once we figure-out how non-standard types should launch 2493 // outside the default display. 2494 || (activityType != ACTIVITY_TYPE_STANDARD 2495 && activityType != ACTIVITY_TYPE_UNDEFINED)) { 2496 display = getDefaultDisplay(); 2497 } 2498 2499 return display.getOrCreateStack(r, options, candidateTask, activityType, onTop); 2500 } 2501 2502 /** @return true if activity record is null or can be launched on provided display. */ canLaunchOnDisplay(ActivityRecord r, int displayId)2503 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) { 2504 if (r == null) { 2505 return true; 2506 } 2507 return r.canBeLaunchedOnDisplay(displayId); 2508 } 2509 2510 /** 2511 * Get a topmost stack on the display, that is a valid launch stack for specified activity. 2512 * If there is no such stack, new dynamic stack can be created. 2513 * @param displayId Target display. 2514 * @param r Activity that should be launched there. 2515 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. 2516 */ getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r)2517 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r) { 2518 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 2519 if (activityDisplay == null) { 2520 throw new IllegalArgumentException( 2521 "Display with displayId=" + displayId + " not found."); 2522 } 2523 2524 if (!r.canBeLaunchedOnDisplay(displayId)) { 2525 return null; 2526 } 2527 2528 // Return the topmost valid stack on the display. 2529 for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) { 2530 final ActivityStack stack = activityDisplay.getChildAt(i); 2531 if (isValidLaunchStack(stack, displayId, r)) { 2532 return stack; 2533 } 2534 } 2535 2536 // If there is no valid stack on the external display - check if new dynamic stack will do. 2537 if (displayId != DEFAULT_DISPLAY) { 2538 return activityDisplay.createStack( 2539 r.getWindowingMode(), r.getActivityType(), true /*onTop*/); 2540 } 2541 2542 Slog.w(TAG, "getValidLaunchStackOnDisplay: can't launch on displayId " + displayId); 2543 return null; 2544 } 2545 2546 // TODO: Can probably be consolidated into getLaunchStack()... isValidLaunchStack(ActivityStack stack, int displayId, ActivityRecord r)2547 private boolean isValidLaunchStack(ActivityStack stack, int displayId, ActivityRecord r) { 2548 switch (stack.getActivityType()) { 2549 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome(); 2550 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents(); 2551 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant(); 2552 } 2553 switch (stack.getWindowingMode()) { 2554 case WINDOWING_MODE_FULLSCREEN: return true; 2555 case WINDOWING_MODE_FREEFORM: return r.supportsFreeform(); 2556 case WINDOWING_MODE_PINNED: return r.supportsPictureInPicture(); 2557 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: return r.supportsSplitScreenWindowingMode(); 2558 case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return r.supportsSplitScreenWindowingMode(); 2559 } 2560 2561 if (!stack.isOnHomeDisplay()) { 2562 return r.canBeLaunchedOnDisplay(displayId); 2563 } 2564 Slog.e(TAG, "isValidLaunchStack: Unexpected stack=" + stack); 2565 return false; 2566 } 2567 2568 /** 2569 * Get next focusable stack in the system. This will search across displays and stacks 2570 * in last-focused order for a focusable and visible stack, different from the target stack. 2571 * 2572 * @param currentFocus The stack that previously had focus. 2573 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next 2574 * candidate. 2575 * @return Next focusable {@link ActivityStack}, null if not found. 2576 */ getNextFocusableStackLocked(ActivityStack currentFocus, boolean ignoreCurrent)2577 ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus, boolean ignoreCurrent) { 2578 mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds); 2579 2580 final int currentWindowingMode = currentFocus != null 2581 ? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED; 2582 ActivityStack candidate = null; 2583 for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) { 2584 final int displayId = mTmpOrderedDisplayIds.get(i); 2585 // If a display is registered in WM, it must also be available in AM. 2586 final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId); 2587 if (display == null) { 2588 // Looks like the display no longer exists in the system... 2589 continue; 2590 } 2591 for (int j = display.getChildCount() - 1; j >= 0; --j) { 2592 final ActivityStack stack = display.getChildAt(j); 2593 if (ignoreCurrent && stack == currentFocus) { 2594 continue; 2595 } 2596 if (!stack.isFocusable() || !stack.shouldBeVisible(null)) { 2597 continue; 2598 } 2599 2600 if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY 2601 && candidate == null && stack.inSplitScreenPrimaryWindowingMode()) { 2602 // If the currently focused stack is in split-screen secondary we save off the 2603 // top primary split-screen stack as a candidate for focus because we might 2604 // prefer focus to move to an other stack to avoid primary split-screen stack 2605 // overlapping with a fullscreen stack when a fullscreen stack is higher in z 2606 // than the next split-screen stack. Assistant stack, I am looking at you... 2607 // We only move the focus to the primary-split screen stack if there isn't a 2608 // better alternative. 2609 candidate = stack; 2610 continue; 2611 } 2612 if (candidate != null && stack.inSplitScreenSecondaryWindowingMode()) { 2613 // Use the candidate stack since we are now at the secondary split-screen. 2614 return candidate; 2615 } 2616 return stack; 2617 } 2618 } 2619 2620 return candidate; 2621 } 2622 2623 /** 2624 * Get next valid stack for launching provided activity in the system. This will search across 2625 * displays and stacks in last-focused order for a focusable and visible stack, except those 2626 * that are on a currently focused display. 2627 * 2628 * @param r The activity that is being launched. 2629 * @param currentFocus The display that previously had focus and thus needs to be ignored when 2630 * searching for the next candidate. 2631 * @return Next valid {@link ActivityStack}, null if not found. 2632 */ getNextValidLaunchStackLocked(@onNull ActivityRecord r, int currentFocus)2633 ActivityStack getNextValidLaunchStackLocked(@NonNull ActivityRecord r, int currentFocus) { 2634 mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds); 2635 for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) { 2636 final int displayId = mTmpOrderedDisplayIds.get(i); 2637 if (displayId == currentFocus) { 2638 continue; 2639 } 2640 final ActivityStack stack = getValidLaunchStackOnDisplay(displayId, r); 2641 if (stack != null) { 2642 return stack; 2643 } 2644 } 2645 return null; 2646 } 2647 getHomeActivity()2648 ActivityRecord getHomeActivity() { 2649 return getHomeActivityForUser(mCurrentUser); 2650 } 2651 getHomeActivityForUser(int userId)2652 ActivityRecord getHomeActivityForUser(int userId) { 2653 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 2654 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 2655 final TaskRecord task = tasks.get(taskNdx); 2656 if (task.isActivityTypeHome()) { 2657 final ArrayList<ActivityRecord> activities = task.mActivities; 2658 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2659 final ActivityRecord r = activities.get(activityNdx); 2660 if (r.isActivityTypeHome() 2661 && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) { 2662 return r; 2663 } 2664 } 2665 } 2666 } 2667 return null; 2668 } 2669 resizeStackLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume)2670 void resizeStackLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds, 2671 Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode, 2672 boolean deferResume) { 2673 2674 if (stack.inSplitScreenPrimaryWindowingMode()) { 2675 resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null, 2676 preserveWindows, deferResume); 2677 return; 2678 } 2679 2680 final boolean splitScreenActive = getDefaultDisplay().hasSplitScreenPrimaryStack(); 2681 if (!allowResizeInDockedMode 2682 && !stack.getWindowConfiguration().tasksAreFloating() && splitScreenActive) { 2683 // If the docked stack exists, don't resize non-floating stacks independently of the 2684 // size computed from the docked stack size (otherwise they will be out of sync) 2685 return; 2686 } 2687 2688 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stack.mStackId); 2689 mWindowManager.deferSurfaceLayout(); 2690 try { 2691 if (stack.affectedBySplitScreenResize()) { 2692 if (bounds == null && stack.inSplitScreenWindowingMode()) { 2693 // null bounds = fullscreen windowing mode...at least for now. 2694 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); 2695 } else if (splitScreenActive) { 2696 // If we are in split-screen mode and this stack support split-screen, then 2697 // it should be split-screen secondary mode. i.e. adjacent to the docked stack. 2698 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); 2699 } 2700 } 2701 stack.resize(bounds, tempTaskBounds, tempTaskInsetBounds); 2702 if (!deferResume) { 2703 stack.ensureVisibleActivitiesConfigurationLocked( 2704 stack.topRunningActivityLocked(), preserveWindows); 2705 } 2706 } finally { 2707 mWindowManager.continueSurfaceLayout(); 2708 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2709 } 2710 } 2711 deferUpdateRecentsHomeStackBounds()2712 void deferUpdateRecentsHomeStackBounds() { 2713 deferUpdateBounds(ACTIVITY_TYPE_RECENTS); 2714 deferUpdateBounds(ACTIVITY_TYPE_HOME); 2715 } 2716 deferUpdateBounds(int activityType)2717 void deferUpdateBounds(int activityType) { 2718 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); 2719 if (stack != null) { 2720 stack.deferUpdateBounds(); 2721 } 2722 } 2723 continueUpdateRecentsHomeStackBounds()2724 void continueUpdateRecentsHomeStackBounds() { 2725 continueUpdateBounds(ACTIVITY_TYPE_RECENTS); 2726 continueUpdateBounds(ACTIVITY_TYPE_HOME); 2727 } 2728 continueUpdateBounds(int activityType)2729 void continueUpdateBounds(int activityType) { 2730 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); 2731 if (stack != null) { 2732 stack.continueUpdateBounds(); 2733 } 2734 } 2735 notifyAppTransitionDone()2736 void notifyAppTransitionDone() { 2737 continueUpdateRecentsHomeStackBounds(); 2738 for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) { 2739 final int taskId = mResizingTasksDuringAnimation.valueAt(i); 2740 final TaskRecord task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_ONLY); 2741 if (task != null) { 2742 task.setTaskDockedResizing(false); 2743 } 2744 } 2745 mResizingTasksDuringAnimation.clear(); 2746 } 2747 2748 /** 2749 * TODO: This should just change the windowing mode and resize vs. actually moving task around. 2750 * Can do that once we are no longer using static stack ids. 2751 */ moveTasksToFullscreenStackInSurfaceTransaction(ActivityStack fromStack, int toDisplayId, boolean onTop)2752 private void moveTasksToFullscreenStackInSurfaceTransaction(ActivityStack fromStack, 2753 int toDisplayId, boolean onTop) { 2754 2755 mWindowManager.deferSurfaceLayout(); 2756 try { 2757 final int windowingMode = fromStack.getWindowingMode(); 2758 final boolean inPinnedWindowingMode = windowingMode == WINDOWING_MODE_PINNED; 2759 final ActivityDisplay toDisplay = getActivityDisplay(toDisplayId); 2760 2761 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { 2762 // Tell the display we are exiting split-screen mode. 2763 toDisplay.onExitingSplitScreenMode(); 2764 // We are moving all tasks from the docked stack to the fullscreen stack, 2765 // which is dismissing the docked stack, so resize all other stacks to 2766 // fullscreen here already so we don't end up with resize trashing. 2767 for (int i = toDisplay.getChildCount() - 1; i >= 0; --i) { 2768 final ActivityStack otherStack = toDisplay.getChildAt(i); 2769 if (!otherStack.inSplitScreenSecondaryWindowingMode()) { 2770 continue; 2771 } 2772 resizeStackLocked(otherStack, null, null, null, PRESERVE_WINDOWS, 2773 true /* allowResizeInDockedMode */, DEFER_RESUME); 2774 } 2775 2776 // Also disable docked stack resizing since we have manually adjusted the 2777 // size of other stacks above and we don't want to trigger a docked stack 2778 // resize when we remove task from it below and it is detached from the 2779 // display because it no longer contains any tasks. 2780 mAllowDockedStackResize = false; 2781 } 2782 2783 // If we are moving from the pinned stack, then the animation takes care of updating 2784 // the picture-in-picture mode. 2785 final boolean schedulePictureInPictureModeChange = inPinnedWindowingMode; 2786 final ArrayList<TaskRecord> tasks = fromStack.getAllTasks(); 2787 2788 if (!tasks.isEmpty()) { 2789 mTmpOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); 2790 final int size = tasks.size(); 2791 for (int i = 0; i < size; ++i) { 2792 final TaskRecord task = tasks.get(i); 2793 final ActivityStack toStack = toDisplay.getOrCreateStack( 2794 null, mTmpOptions, task, task.getActivityType(), onTop); 2795 2796 if (onTop) { 2797 final boolean isTopTask = i == (size - 1); 2798 // Defer resume until all the tasks have been moved to the fullscreen stack 2799 task.reparent(toStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, 2800 isTopTask /* animate */, DEFER_RESUME, 2801 schedulePictureInPictureModeChange, 2802 "moveTasksToFullscreenStack - onTop"); 2803 MetricsLoggerWrapper.logPictureInPictureFullScreen(mService.mContext, 2804 task.effectiveUid, task.realActivity.flattenToString()); 2805 } else { 2806 // Position the tasks in the fullscreen stack in order at the bottom of the 2807 // stack. Also defer resume until all the tasks have been moved to the 2808 // fullscreen stack. 2809 task.reparent(toStack, ON_TOP, 2810 REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME, 2811 schedulePictureInPictureModeChange, 2812 "moveTasksToFullscreenStack - NOT_onTop"); 2813 } 2814 } 2815 } 2816 2817 ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); 2818 resumeFocusedStackTopActivityLocked(); 2819 } finally { 2820 mAllowDockedStackResize = true; 2821 mWindowManager.continueSurfaceLayout(); 2822 } 2823 } 2824 moveTasksToFullscreenStackLocked(ActivityStack fromStack, boolean onTop)2825 void moveTasksToFullscreenStackLocked(ActivityStack fromStack, boolean onTop) { 2826 moveTasksToFullscreenStackLocked(fromStack, DEFAULT_DISPLAY, onTop); 2827 } 2828 moveTasksToFullscreenStackLocked(ActivityStack fromStack, int toDisplayId, boolean onTop)2829 void moveTasksToFullscreenStackLocked(ActivityStack fromStack, int toDisplayId, boolean onTop) { 2830 mWindowManager.inSurfaceTransaction(() -> 2831 moveTasksToFullscreenStackInSurfaceTransaction(fromStack, toDisplayId, onTop)); 2832 } 2833 setSplitScreenResizing(boolean resizing)2834 void setSplitScreenResizing(boolean resizing) { 2835 if (resizing == mDockedStackResizing) { 2836 return; 2837 } 2838 2839 mDockedStackResizing = resizing; 2840 mWindowManager.setDockedStackResizing(resizing); 2841 2842 if (!resizing && mHasPendingDockedBounds) { 2843 resizeDockedStackLocked(mPendingDockedBounds, mPendingTempDockedTaskBounds, 2844 mPendingTempDockedTaskInsetBounds, mPendingTempOtherTaskBounds, 2845 mPendingTempOtherTaskInsetBounds, PRESERVE_WINDOWS); 2846 2847 mHasPendingDockedBounds = false; 2848 mPendingDockedBounds = null; 2849 mPendingTempDockedTaskBounds = null; 2850 mPendingTempDockedTaskInsetBounds = null; 2851 mPendingTempOtherTaskBounds = null; 2852 mPendingTempOtherTaskInsetBounds = null; 2853 } 2854 } 2855 resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows)2856 void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, 2857 Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, 2858 boolean preserveWindows) { 2859 resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds, 2860 tempOtherTaskBounds, tempOtherTaskInsetBounds, preserveWindows, 2861 false /* deferResume */); 2862 } 2863 resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows, boolean deferResume)2864 private void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, 2865 Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, 2866 boolean preserveWindows, boolean deferResume) { 2867 2868 if (!mAllowDockedStackResize) { 2869 // Docked stack resize currently disabled. 2870 return; 2871 } 2872 2873 final ActivityStack stack = getDefaultDisplay().getSplitScreenPrimaryStack(); 2874 if (stack == null) { 2875 Slog.w(TAG, "resizeDockedStackLocked: docked stack not found"); 2876 return; 2877 } 2878 2879 if (mDockedStackResizing) { 2880 mHasPendingDockedBounds = true; 2881 mPendingDockedBounds = copyOrNull(dockedBounds); 2882 mPendingTempDockedTaskBounds = copyOrNull(tempDockedTaskBounds); 2883 mPendingTempDockedTaskInsetBounds = copyOrNull(tempDockedTaskInsetBounds); 2884 mPendingTempOtherTaskBounds = copyOrNull(tempOtherTaskBounds); 2885 mPendingTempOtherTaskInsetBounds = copyOrNull(tempOtherTaskInsetBounds); 2886 } 2887 2888 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack"); 2889 mWindowManager.deferSurfaceLayout(); 2890 try { 2891 // Don't allow re-entry while resizing. E.g. due to docked stack detaching. 2892 mAllowDockedStackResize = false; 2893 ActivityRecord r = stack.topRunningActivityLocked(); 2894 stack.resize(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds); 2895 2896 // TODO: Checking for isAttached might not be needed as if the user passes in null 2897 // dockedBounds then they want the docked stack to be dismissed. 2898 if (stack.getWindowingMode() == WINDOWING_MODE_FULLSCREEN 2899 || (dockedBounds == null && !stack.isAttached())) { 2900 // The dock stack either was dismissed or went fullscreen, which is kinda the same. 2901 // In this case we make all other static stacks fullscreen and move all 2902 // docked stack tasks to the fullscreen stack. 2903 moveTasksToFullscreenStackLocked(stack, ON_TOP); 2904 2905 // stack shouldn't contain anymore activities, so nothing to resume. 2906 r = null; 2907 } else { 2908 // Docked stacks occupy a dedicated region on screen so the size of all other 2909 // static stacks need to be adjusted so they don't overlap with the docked stack. 2910 // We get the bounds to use from window manager which has been adjusted for any 2911 // screen controls and is also the same for all stacks. 2912 final ActivityDisplay display = getDefaultDisplay(); 2913 final Rect otherTaskRect = new Rect(); 2914 for (int i = display.getChildCount() - 1; i >= 0; --i) { 2915 final ActivityStack current = display.getChildAt(i); 2916 if (current.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { 2917 continue; 2918 } 2919 if (!current.affectedBySplitScreenResize()) { 2920 continue; 2921 } 2922 if (mDockedStackResizing && !current.isTopActivityVisible()) { 2923 // Non-visible stacks get resized once we're done with the resize 2924 // interaction. 2925 continue; 2926 } 2927 // Need to set windowing mode here before we try to get the dock bounds. 2928 current.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); 2929 current.getStackDockedModeBounds( 2930 tempOtherTaskBounds /* currentTempTaskBounds */, 2931 tempRect /* outStackBounds */, 2932 otherTaskRect /* outTempTaskBounds */, true /* ignoreVisibility */); 2933 2934 resizeStackLocked(current, !tempRect.isEmpty() ? tempRect : null, 2935 !otherTaskRect.isEmpty() ? otherTaskRect : tempOtherTaskBounds, 2936 tempOtherTaskInsetBounds, preserveWindows, 2937 true /* allowResizeInDockedMode */, deferResume); 2938 } 2939 } 2940 if (!deferResume) { 2941 stack.ensureVisibleActivitiesConfigurationLocked(r, preserveWindows); 2942 } 2943 } finally { 2944 mAllowDockedStackResize = true; 2945 mWindowManager.continueSurfaceLayout(); 2946 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2947 } 2948 } 2949 resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds)2950 void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 2951 // TODO(multi-display): Pinned stack display should be passed in. 2952 final PinnedActivityStack stack = getDefaultDisplay().getPinnedStack(); 2953 if (stack == null) { 2954 Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found"); 2955 return; 2956 } 2957 2958 // It is possible for the bounds animation from the WM to call this but be delayed by 2959 // another AM call that is holding the AMS lock. In such a case, the pinnedBounds may be 2960 // incorrect if AMS.resizeStackWithBoundsFromWindowManager() is already called while waiting 2961 // for the AMS lock to be freed. So check and make sure these bounds are still good. 2962 final PinnedStackWindowController stackController = stack.getWindowContainerController(); 2963 if (stackController.pinnedStackResizeDisallowed()) { 2964 return; 2965 } 2966 2967 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack"); 2968 mWindowManager.deferSurfaceLayout(); 2969 try { 2970 ActivityRecord r = stack.topRunningActivityLocked(); 2971 Rect insetBounds = null; 2972 if (tempPinnedTaskBounds != null && stack.isAnimatingBoundsToFullscreen()) { 2973 // Use 0,0 as the position for the inset rect because we are headed for fullscreen. 2974 insetBounds = tempRect; 2975 insetBounds.top = 0; 2976 insetBounds.left = 0; 2977 insetBounds.right = tempPinnedTaskBounds.width(); 2978 insetBounds.bottom = tempPinnedTaskBounds.height(); 2979 } 2980 if (pinnedBounds != null && tempPinnedTaskBounds == null) { 2981 // We have finished the animation into PiP, and are resizing the tasks to match the 2982 // stack bounds, while layouts are deferred, update any task state as a part of 2983 // transitioning it from fullscreen into a floating state. 2984 stack.onPipAnimationEndResize(); 2985 } 2986 stack.resize(pinnedBounds, tempPinnedTaskBounds, insetBounds); 2987 stack.ensureVisibleActivitiesConfigurationLocked(r, false); 2988 } finally { 2989 mWindowManager.continueSurfaceLayout(); 2990 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2991 } 2992 } 2993 removeStackInSurfaceTransaction(ActivityStack stack)2994 private void removeStackInSurfaceTransaction(ActivityStack stack) { 2995 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2996 if (stack.getWindowingMode() == WINDOWING_MODE_PINNED) { 2997 /** 2998 * Workaround: Force-stop all the activities in the pinned stack before we reparent them 2999 * to the fullscreen stack. This is to guarantee that when we are removing a stack, 3000 * that the client receives onStop() before it is reparented. We do this by detaching 3001 * the stack from the display so that it will be considered invisible when 3002 * ensureActivitiesVisibleLocked() is called, and all of its activitys will be marked 3003 * invisible as well and added to the stopping list. After which we process the 3004 * stopping list by handling the idle. 3005 */ 3006 final PinnedActivityStack pinnedStack = (PinnedActivityStack) stack; 3007 pinnedStack.mForceHidden = true; 3008 pinnedStack.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); 3009 pinnedStack.mForceHidden = false; 3010 activityIdleInternalLocked(null, false /* fromTimeout */, 3011 true /* processPausingActivites */, null /* configuration */); 3012 3013 // Move all the tasks to the bottom of the fullscreen stack 3014 moveTasksToFullscreenStackLocked(pinnedStack, !ON_TOP); 3015 } else { 3016 for (int i = tasks.size() - 1; i >= 0; i--) { 3017 removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */, 3018 REMOVE_FROM_RECENTS, "remove-stack"); 3019 } 3020 } 3021 } 3022 3023 /** 3024 * Removes the stack associated with the given {@param stack}. If the {@param stack} is the 3025 * pinned stack, then its tasks are not explicitly removed when the stack is destroyed, but 3026 * instead moved back onto the fullscreen stack. 3027 */ removeStack(ActivityStack stack)3028 void removeStack(ActivityStack stack) { 3029 mWindowManager.inSurfaceTransaction(() -> removeStackInSurfaceTransaction(stack)); 3030 } 3031 3032 /** 3033 * Removes stacks in the input windowing modes from the system if they are of activity type 3034 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED 3035 */ removeStacksInWindowingModes(int... windowingModes)3036 void removeStacksInWindowingModes(int... windowingModes) { 3037 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 3038 mActivityDisplays.valueAt(i).removeStacksInWindowingModes(windowingModes); 3039 } 3040 } 3041 removeStacksWithActivityTypes(int... activityTypes)3042 void removeStacksWithActivityTypes(int... activityTypes) { 3043 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 3044 mActivityDisplays.valueAt(i).removeStacksWithActivityTypes(activityTypes); 3045 } 3046 } 3047 3048 /** 3049 * See {@link #removeTaskByIdLocked(int, boolean, boolean, boolean)} 3050 */ removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, String reason)3051 boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, 3052 String reason) { 3053 return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY, 3054 reason); 3055 } 3056 3057 /** 3058 * Removes the task with the specified task id. 3059 * 3060 * @param taskId Identifier of the task to be removed. 3061 * @param killProcess Kill any process associated with the task if possible. 3062 * @param removeFromRecents Whether to also remove the task from recents. 3063 * @param pauseImmediately Pauses all task activities immediately without waiting for the 3064 * pause-complete callback from the activity. 3065 * @return Returns true if the given task was found and removed. 3066 */ removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, boolean pauseImmediately, String reason)3067 boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents, 3068 boolean pauseImmediately, String reason) { 3069 final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS); 3070 if (tr != null) { 3071 tr.removeTaskActivitiesLocked(pauseImmediately, reason); 3072 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents); 3073 mService.getLockTaskController().clearLockedTask(tr); 3074 if (tr.isPersistable) { 3075 mService.notifyTaskPersisterLocked(null, true); 3076 } 3077 return true; 3078 } 3079 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 3080 return false; 3081 } 3082 cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents)3083 void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents) { 3084 if (removeFromRecents) { 3085 mRecentTasks.remove(tr); 3086 } 3087 ComponentName component = tr.getBaseIntent().getComponent(); 3088 if (component == null) { 3089 Slog.w(TAG, "No component for base intent of task: " + tr); 3090 return; 3091 } 3092 3093 // Find any running services associated with this app and stop if needed. 3094 mService.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 3095 3096 if (!killProcess) { 3097 return; 3098 } 3099 3100 // Determine if the process(es) for this task should be killed. 3101 final String pkg = component.getPackageName(); 3102 ArrayList<ProcessRecord> procsToKill = new ArrayList<>(); 3103 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mService.mProcessNames.getMap(); 3104 for (int i = 0; i < pmap.size(); i++) { 3105 3106 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 3107 for (int j = 0; j < uids.size(); j++) { 3108 ProcessRecord proc = uids.valueAt(j); 3109 if (proc.userId != tr.userId) { 3110 // Don't kill process for a different user. 3111 continue; 3112 } 3113 if (proc == mService.mHomeProcess) { 3114 // Don't kill the home process along with tasks from the same package. 3115 continue; 3116 } 3117 if (!proc.pkgList.containsKey(pkg)) { 3118 // Don't kill process that is not associated with this task. 3119 continue; 3120 } 3121 3122 for (int k = 0; k < proc.activities.size(); k++) { 3123 TaskRecord otherTask = proc.activities.get(k).getTask(); 3124 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 3125 // Don't kill process(es) that has an activity in a different task that is 3126 // also in recents. 3127 return; 3128 } 3129 } 3130 3131 if (proc.foregroundServices) { 3132 // Don't kill process(es) with foreground service. 3133 return; 3134 } 3135 3136 // Add process to kill list. 3137 procsToKill.add(proc); 3138 } 3139 } 3140 3141 // Kill the running processes. 3142 for (int i = 0; i < procsToKill.size(); i++) { 3143 ProcessRecord pr = procsToKill.get(i); 3144 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND 3145 && pr.curReceivers.isEmpty()) { 3146 pr.kill("remove task", true); 3147 } else { 3148 // We delay killing processes that are not in the background or running a receiver. 3149 pr.waitingToKill = "remove task"; 3150 } 3151 } 3152 } 3153 3154 /** 3155 * Called to restore the state of the task into the stack that it's supposed to go into. 3156 * 3157 * @param task The recent task to be restored. 3158 * @param aOptions The activity options to use for restoration. 3159 * @param onTop If the stack for the task should be the topmost on the display. 3160 * @return true if the task has been restored successfully. 3161 */ restoreRecentTaskLocked(TaskRecord task, ActivityOptions aOptions, boolean onTop)3162 boolean restoreRecentTaskLocked(TaskRecord task, ActivityOptions aOptions, boolean onTop) { 3163 final ActivityStack stack = getLaunchStack(null, aOptions, task, onTop); 3164 final ActivityStack currentStack = task.getStack(); 3165 if (currentStack != null) { 3166 // Task has already been restored once. See if we need to do anything more 3167 if (currentStack == stack) { 3168 // Nothing else to do since it is already restored in the right stack. 3169 return true; 3170 } 3171 // Remove current stack association, so we can re-associate the task with the 3172 // right stack below. 3173 currentStack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING); 3174 } 3175 3176 stack.addTask(task, onTop, "restoreRecentTask"); 3177 // TODO: move call for creation here and other place into Stack.addTask() 3178 task.createWindowContainer(onTop, true /* showForAllUsers */); 3179 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 3180 "Added restored task=" + task + " to stack=" + stack); 3181 final ArrayList<ActivityRecord> activities = task.mActivities; 3182 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 3183 activities.get(activityNdx).createWindowContainer(); 3184 } 3185 return true; 3186 } 3187 3188 @Override onRecentTaskAdded(TaskRecord task)3189 public void onRecentTaskAdded(TaskRecord task) { 3190 task.touchActiveTime(); 3191 } 3192 3193 @Override onRecentTaskRemoved(TaskRecord task, boolean wasTrimmed)3194 public void onRecentTaskRemoved(TaskRecord task, boolean wasTrimmed) { 3195 if (wasTrimmed) { 3196 // Task was trimmed from the recent tasks list -- remove the active task record as well 3197 // since the user won't really be able to go back to it 3198 removeTaskByIdLocked(task.taskId, false /* killProcess */, 3199 false /* removeFromRecents */, !PAUSE_IMMEDIATELY, "recent-task-trimmed"); 3200 } 3201 task.removedFromRecents(); 3202 } 3203 3204 /** 3205 * Move stack with all its existing content to specified display. 3206 * @param stackId Id of stack to move. 3207 * @param displayId Id of display to move stack to. 3208 * @param onTop Indicates whether container should be place on top or on bottom. 3209 */ moveStackToDisplayLocked(int stackId, int displayId, boolean onTop)3210 void moveStackToDisplayLocked(int stackId, int displayId, boolean onTop) { 3211 final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); 3212 if (activityDisplay == null) { 3213 throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId=" 3214 + displayId); 3215 } 3216 final ActivityStack stack = getStack(stackId); 3217 if (stack == null) { 3218 throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown stackId=" 3219 + stackId); 3220 } 3221 3222 final ActivityDisplay currentDisplay = stack.getDisplay(); 3223 if (currentDisplay == null) { 3224 throw new IllegalStateException("moveStackToDisplayLocked: Stack with stack=" + stack 3225 + " is not attached to any display."); 3226 } 3227 3228 if (currentDisplay.mDisplayId == displayId) { 3229 throw new IllegalArgumentException("Trying to move stack=" + stack 3230 + " to its current displayId=" + displayId); 3231 } 3232 3233 stack.reparent(activityDisplay, onTop); 3234 // TODO(multi-display): resize stacks properly if moved from split-screen. 3235 } 3236 3237 /** 3238 * Returns the reparent target stack, creating the stack if necessary. This call also enforces 3239 * the various checks on tasks that are going to be reparented from one stack to another. 3240 */ 3241 // TODO: Look into changing users to this method to ActivityDisplay.resolveWindowingMode() getReparentTargetStack(TaskRecord task, ActivityStack stack, boolean toTop)3242 ActivityStack getReparentTargetStack(TaskRecord task, ActivityStack stack, boolean toTop) { 3243 final ActivityStack prevStack = task.getStack(); 3244 final int stackId = stack.mStackId; 3245 final boolean inMultiWindowMode = stack.inMultiWindowMode(); 3246 3247 // Check that we aren't reparenting to the same stack that the task is already in 3248 if (prevStack != null && prevStack.mStackId == stackId) { 3249 Slog.w(TAG, "Can not reparent to same stack, task=" + task 3250 + " already in stackId=" + stackId); 3251 return prevStack; 3252 } 3253 3254 // Ensure that we aren't trying to move into a multi-window stack without multi-window 3255 // support 3256 if (inMultiWindowMode && !mService.mSupportsMultiWindow) { 3257 throw new IllegalArgumentException("Device doesn't support multi-window, can not" 3258 + " reparent task=" + task + " to stack=" + stack); 3259 } 3260 3261 // Ensure that we're not moving a task to a dynamic stack if device doesn't support 3262 // multi-display. 3263 if (stack.mDisplayId != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) { 3264 throw new IllegalArgumentException("Device doesn't support multi-display, can not" 3265 + " reparent task=" + task + " to stackId=" + stackId); 3266 } 3267 3268 // Ensure that we aren't trying to move into a freeform stack without freeform support 3269 if (stack.getWindowingMode() == WINDOWING_MODE_FREEFORM 3270 && !mService.mSupportsFreeformWindowManagement) { 3271 throw new IllegalArgumentException("Device doesn't support freeform, can not reparent" 3272 + " task=" + task); 3273 } 3274 3275 // Leave the task in its current stack or a fullscreen stack if it isn't resizeable and the 3276 // preferred stack is in multi-window mode. 3277 if (inMultiWindowMode && !task.isResizeable()) { 3278 Slog.w(TAG, "Can not move unresizeable task=" + task + " to multi-window stack=" + stack 3279 + " Moving to a fullscreen stack instead."); 3280 if (prevStack != null) { 3281 return prevStack; 3282 } 3283 stack = stack.getDisplay().createStack( 3284 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), toTop); 3285 } 3286 return stack; 3287 } 3288 moveTopStackActivityToPinnedStackLocked(int stackId, Rect destBounds)3289 boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect destBounds) { 3290 final ActivityStack stack = getStack(stackId); 3291 if (stack == null) { 3292 throw new IllegalArgumentException( 3293 "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId); 3294 } 3295 3296 final ActivityRecord r = stack.topRunningActivityLocked(); 3297 if (r == null) { 3298 Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity" 3299 + " in stack=" + stack); 3300 return false; 3301 } 3302 3303 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { 3304 Slog.w(TAG, 3305 "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for " 3306 + " r=" + r); 3307 return false; 3308 } 3309 3310 moveActivityToPinnedStackLocked(r, null /* sourceBounds */, 0f /* aspectRatio */, 3311 "moveTopActivityToPinnedStack"); 3312 return true; 3313 } 3314 moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceHintBounds, float aspectRatio, String reason)3315 void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceHintBounds, float aspectRatio, 3316 String reason) { 3317 3318 mWindowManager.deferSurfaceLayout(); 3319 3320 final ActivityDisplay display = r.getStack().getDisplay(); 3321 PinnedActivityStack stack = display.getPinnedStack(); 3322 3323 // This will clear the pinned stack by moving an existing task to the full screen stack, 3324 // ensuring only one task is present. 3325 if (stack != null) { 3326 moveTasksToFullscreenStackLocked(stack, !ON_TOP); 3327 } 3328 3329 // Need to make sure the pinned stack exist so we can resize it below... 3330 stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP); 3331 3332 // Calculate the target bounds here before the task is reparented back into pinned windowing 3333 // mode (which will reset the saved bounds) 3334 final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio); 3335 3336 try { 3337 final TaskRecord task = r.getTask(); 3338 // Resize the pinned stack to match the current size of the task the activity we are 3339 // going to be moving is currently contained in. We do this to have the right starting 3340 // animation bounds for the pinned stack to the desired bounds the caller wants. 3341 resizeStackLocked(stack, task.getOverrideBounds(), null /* tempTaskBounds */, 3342 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, 3343 true /* allowResizeInDockedMode */, !DEFER_RESUME); 3344 3345 if (task.mActivities.size() == 1) { 3346 // Defer resume until below, and do not schedule PiP changes until we animate below 3347 task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME, 3348 false /* schedulePictureInPictureModeChange */, reason); 3349 } else { 3350 // There are multiple activities in the task and moving the top activity should 3351 // reveal/leave the other activities in their original task. 3352 3353 // Currently, we don't support reparenting activities across tasks in two different 3354 // stacks, so instead, just create a new task in the same stack, reparent the 3355 // activity into that task, and then reparent the whole task to the new stack. This 3356 // ensures that all the necessary work to migrate states in the old and new stacks 3357 // is also done. 3358 final TaskRecord newTask = task.getStack().createTaskRecord( 3359 getNextTaskIdForUserLocked(r.userId), r.info, r.intent, null, null, true); 3360 r.reparent(newTask, MAX_VALUE, "moveActivityToStack"); 3361 3362 // Defer resume until below, and do not schedule PiP changes until we animate below 3363 newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, 3364 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason); 3365 } 3366 3367 // Reset the state that indicates it can enter PiP while pausing after we've moved it 3368 // to the pinned stack 3369 r.supportsEnterPipOnTaskSwitch = false; 3370 } finally { 3371 mWindowManager.continueSurfaceLayout(); 3372 } 3373 3374 stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */, 3375 true /* fromFullscreen */); 3376 3377 // Update the visibility of all activities after the they have been reparented to the new 3378 // stack. This MUST run after the animation above is scheduled to ensure that the windows 3379 // drawn signal is scheduled after the bounds animation start call on the bounds animator 3380 // thread. 3381 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 3382 resumeFocusedStackTopActivityLocked(); 3383 3384 mService.mTaskChangeNotificationController.notifyActivityPinned(r); 3385 } 3386 3387 /** Move activity with its stack to front and make the stack focused. */ moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason)3388 boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) { 3389 if (r == null || !r.isFocusable()) { 3390 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, 3391 "moveActivityStackToFront: unfocusable r=" + r); 3392 return false; 3393 } 3394 3395 final TaskRecord task = r.getTask(); 3396 final ActivityStack stack = r.getStack(); 3397 if (stack == null) { 3398 Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: r=" 3399 + r + " task=" + task); 3400 return false; 3401 } 3402 3403 if (stack == mFocusedStack && stack.topRunningActivityLocked() == r) { 3404 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, 3405 "moveActivityStackToFront: already on top, r=" + r); 3406 return false; 3407 } 3408 3409 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, 3410 "moveActivityStackToFront: r=" + r); 3411 3412 stack.moveToFront(reason, task); 3413 return true; 3414 } 3415 findTaskLocked(ActivityRecord r, int displayId)3416 ActivityRecord findTaskLocked(ActivityRecord r, int displayId) { 3417 mTmpFindTaskResult.r = null; 3418 mTmpFindTaskResult.matchedByRootAffinity = false; 3419 ActivityRecord affinityMatch = null; 3420 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 3421 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3422 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3423 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3424 final ActivityStack stack = display.getChildAt(stackNdx); 3425 if (!r.hasCompatibleActivityType(stack)) { 3426 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) " 3427 + stack); 3428 continue; 3429 } 3430 stack.findTaskLocked(r, mTmpFindTaskResult); 3431 // It is possible to have tasks in multiple stacks with the same root affinity, so 3432 // we should keep looking after finding an affinity match to see if there is a 3433 // better match in another stack. Also, task affinity isn't a good enough reason 3434 // to target a display which isn't the source of the intent, so skip any affinity 3435 // matches not on the specified display. 3436 if (mTmpFindTaskResult.r != null) { 3437 if (!mTmpFindTaskResult.matchedByRootAffinity) { 3438 return mTmpFindTaskResult.r; 3439 } else if (mTmpFindTaskResult.r.getDisplayId() == displayId) { 3440 // Note: since the traversing through the stacks is top down, the floating 3441 // tasks should always have lower priority than any affinity-matching tasks 3442 // in the fullscreen stacks 3443 affinityMatch = mTmpFindTaskResult.r; 3444 } else if (DEBUG_TASKS && mTmpFindTaskResult.matchedByRootAffinity) { 3445 Slog.d(TAG_TASKS, "Skipping match on different display " 3446 + mTmpFindTaskResult.r.getDisplayId() + " " + displayId); 3447 } 3448 } 3449 } 3450 } 3451 3452 if (DEBUG_TASKS && affinityMatch == null) Slog.d(TAG_TASKS, "No task found"); 3453 return affinityMatch; 3454 } 3455 findActivityLocked(Intent intent, ActivityInfo info, boolean compareIntentFilters)3456 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info, 3457 boolean compareIntentFilters) { 3458 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3459 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3460 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3461 final ActivityStack stack = display.getChildAt(stackNdx); 3462 final ActivityRecord ar = stack.findActivityLocked( 3463 intent, info, compareIntentFilters); 3464 if (ar != null) { 3465 return ar; 3466 } 3467 } 3468 } 3469 return null; 3470 } 3471 hasAwakeDisplay()3472 boolean hasAwakeDisplay() { 3473 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3474 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3475 if (!display.shouldSleep()) { 3476 return true; 3477 } 3478 } 3479 return false; 3480 } 3481 goingToSleepLocked()3482 void goingToSleepLocked() { 3483 scheduleSleepTimeout(); 3484 if (!mGoingToSleep.isHeld()) { 3485 mGoingToSleep.acquire(); 3486 if (mLaunchingActivity.isHeld()) { 3487 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 3488 throw new IllegalStateException("Calling must be system uid"); 3489 } 3490 mLaunchingActivity.release(); 3491 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 3492 } 3493 } 3494 3495 applySleepTokensLocked(false /* applyToStacks */); 3496 3497 checkReadyForSleepLocked(true /* allowDelay */); 3498 } 3499 prepareForShutdownLocked()3500 void prepareForShutdownLocked() { 3501 for (int i = 0; i < mActivityDisplays.size(); i++) { 3502 createSleepTokenLocked("shutdown", mActivityDisplays.keyAt(i)); 3503 } 3504 } 3505 shutdownLocked(int timeout)3506 boolean shutdownLocked(int timeout) { 3507 goingToSleepLocked(); 3508 3509 boolean timedout = false; 3510 final long endTime = System.currentTimeMillis() + timeout; 3511 while (true) { 3512 if (!putStacksToSleepLocked(true /* allowDelay */, true /* shuttingDown */)) { 3513 long timeRemaining = endTime - System.currentTimeMillis(); 3514 if (timeRemaining > 0) { 3515 try { 3516 mService.wait(timeRemaining); 3517 } catch (InterruptedException e) { 3518 } 3519 } else { 3520 Slog.w(TAG, "Activity manager shutdown timed out"); 3521 timedout = true; 3522 break; 3523 } 3524 } else { 3525 break; 3526 } 3527 } 3528 3529 // Force checkReadyForSleep to complete. 3530 checkReadyForSleepLocked(false /* allowDelay */); 3531 3532 return timedout; 3533 } 3534 comeOutOfSleepIfNeededLocked()3535 void comeOutOfSleepIfNeededLocked() { 3536 removeSleepTimeouts(); 3537 if (mGoingToSleep.isHeld()) { 3538 mGoingToSleep.release(); 3539 } 3540 } 3541 applySleepTokensLocked(boolean applyToStacks)3542 void applySleepTokensLocked(boolean applyToStacks) { 3543 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3544 // Set the sleeping state of the display. 3545 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3546 final boolean displayShouldSleep = display.shouldSleep(); 3547 if (displayShouldSleep == display.isSleeping()) { 3548 continue; 3549 } 3550 display.setIsSleeping(displayShouldSleep); 3551 3552 if (!applyToStacks) { 3553 continue; 3554 } 3555 3556 // Set the sleeping state of the stacks on the display. 3557 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3558 final ActivityStack stack = display.getChildAt(stackNdx); 3559 if (displayShouldSleep) { 3560 stack.goToSleepIfPossible(false /* shuttingDown */); 3561 } else { 3562 stack.awakeFromSleepingLocked(); 3563 if (isFocusedStack(stack) && !getKeyguardController().isKeyguardOrAodShowing( 3564 display.mDisplayId)) { 3565 // If the keyguard is unlocked - resume immediately. 3566 // It is possible that the display will not be awake at the time we 3567 // process the keyguard going away, which can happen before the sleep token 3568 // is released. As a result, it is important we resume the activity here. 3569 resumeFocusedStackTopActivityLocked(); 3570 } 3571 } 3572 } 3573 3574 if (displayShouldSleep || mGoingToSleepActivities.isEmpty()) { 3575 continue; 3576 } 3577 // The display is awake now, so clean up the going to sleep list. 3578 for (Iterator<ActivityRecord> it = mGoingToSleepActivities.iterator(); it.hasNext(); ) { 3579 final ActivityRecord r = it.next(); 3580 if (r.getDisplayId() == display.mDisplayId) { 3581 it.remove(); 3582 } 3583 } 3584 } 3585 } 3586 activitySleptLocked(ActivityRecord r)3587 void activitySleptLocked(ActivityRecord r) { 3588 mGoingToSleepActivities.remove(r); 3589 final ActivityStack s = r.getStack(); 3590 if (s != null) { 3591 s.checkReadyForSleep(); 3592 } else { 3593 checkReadyForSleepLocked(true); 3594 } 3595 } 3596 checkReadyForSleepLocked(boolean allowDelay)3597 void checkReadyForSleepLocked(boolean allowDelay) { 3598 if (!mService.isSleepingOrShuttingDownLocked()) { 3599 // Do not care. 3600 return; 3601 } 3602 3603 if (!putStacksToSleepLocked(allowDelay, false /* shuttingDown */)) { 3604 return; 3605 } 3606 3607 // Send launch end powerhint before going sleep 3608 sendPowerHintForLaunchEndIfNeeded(); 3609 3610 removeSleepTimeouts(); 3611 3612 if (mGoingToSleep.isHeld()) { 3613 mGoingToSleep.release(); 3614 } 3615 if (mService.mShuttingDown) { 3616 mService.notifyAll(); 3617 } 3618 } 3619 3620 // Tries to put all activity stacks to sleep. Returns true if all stacks were 3621 // successfully put to sleep. putStacksToSleepLocked(boolean allowDelay, boolean shuttingDown)3622 private boolean putStacksToSleepLocked(boolean allowDelay, boolean shuttingDown) { 3623 boolean allSleep = true; 3624 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3625 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3626 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3627 final ActivityStack stack = display.getChildAt(stackNdx); 3628 if (allowDelay) { 3629 allSleep &= stack.goToSleepIfPossible(shuttingDown); 3630 } else { 3631 stack.goToSleep(); 3632 } 3633 } 3634 } 3635 return allSleep; 3636 } 3637 reportResumedActivityLocked(ActivityRecord r)3638 boolean reportResumedActivityLocked(ActivityRecord r) { 3639 // A resumed activity cannot be stopping. remove from list 3640 mStoppingActivities.remove(r); 3641 3642 final ActivityStack stack = r.getStack(); 3643 if (isFocusedStack(stack)) { 3644 mService.updateUsageStats(r, true); 3645 } 3646 if (allResumedActivitiesComplete()) { 3647 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 3648 mWindowManager.executeAppTransition(); 3649 return true; 3650 } 3651 return false; 3652 } 3653 handleAppCrashLocked(ProcessRecord app)3654 void handleAppCrashLocked(ProcessRecord app) { 3655 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3656 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3657 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3658 final ActivityStack stack = display.getChildAt(stackNdx); 3659 stack.handleAppCrashLocked(app); 3660 } 3661 } 3662 } 3663 3664 // Called when WindowManager has finished animating the launchingBehind activity to the back. handleLaunchTaskBehindCompleteLocked(ActivityRecord r)3665 private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 3666 final TaskRecord task = r.getTask(); 3667 final ActivityStack stack = task.getStack(); 3668 3669 r.mLaunchTaskBehind = false; 3670 mRecentTasks.add(task); 3671 mService.mTaskChangeNotificationController.notifyTaskStackChanged(); 3672 r.setVisibility(false); 3673 3674 // When launching tasks behind, update the last active time of the top task after the new 3675 // task has been shown briefly 3676 final ActivityRecord top = stack.getTopActivity(); 3677 if (top != null) { 3678 top.getTask().touchActiveTime(); 3679 } 3680 } 3681 scheduleLaunchTaskBehindComplete(IBinder token)3682 void scheduleLaunchTaskBehindComplete(IBinder token) { 3683 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 3684 } 3685 3686 /** 3687 * Make sure that all activities that need to be visible in the system actually are and update 3688 * their configuration. 3689 */ ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, boolean preserveWindows)3690 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, 3691 boolean preserveWindows) { 3692 ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows, 3693 true /* notifyClients */); 3694 } 3695 3696 /** 3697 * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean) 3698 */ ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients)3699 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, 3700 boolean preserveWindows, boolean notifyClients) { 3701 getKeyguardController().beginActivityVisibilityUpdate(); 3702 try { 3703 // First the front stacks. In case any are not fullscreen and are in front of home. 3704 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3705 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3706 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3707 final ActivityStack stack = display.getChildAt(stackNdx); 3708 stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows, 3709 notifyClients); 3710 } 3711 } 3712 } finally { 3713 getKeyguardController().endActivityVisibilityUpdate(); 3714 } 3715 } 3716 addStartingWindowsForVisibleActivities(boolean taskSwitch)3717 void addStartingWindowsForVisibleActivities(boolean taskSwitch) { 3718 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3719 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3720 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3721 final ActivityStack stack = display.getChildAt(stackNdx); 3722 stack.addStartingWindowsForVisibleActivities(taskSwitch); 3723 } 3724 } 3725 } 3726 invalidateTaskLayers()3727 void invalidateTaskLayers() { 3728 mTaskLayersChanged = true; 3729 } 3730 rankTaskLayersIfNeeded()3731 void rankTaskLayersIfNeeded() { 3732 if (!mTaskLayersChanged) { 3733 return; 3734 } 3735 mTaskLayersChanged = false; 3736 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) { 3737 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3738 int baseLayer = 0; 3739 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3740 final ActivityStack stack = display.getChildAt(stackNdx); 3741 baseLayer += stack.rankTaskLayers(baseLayer); 3742 } 3743 } 3744 } 3745 clearOtherAppTimeTrackers(AppTimeTracker except)3746 void clearOtherAppTimeTrackers(AppTimeTracker except) { 3747 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3748 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3749 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3750 final ActivityStack stack = display.getChildAt(stackNdx); 3751 stack.clearOtherAppTimeTrackers(except); 3752 } 3753 } 3754 } 3755 scheduleDestroyAllActivities(ProcessRecord app, String reason)3756 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 3757 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3758 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3759 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3760 final ActivityStack stack = display.getChildAt(stackNdx); 3761 stack.scheduleDestroyActivities(app, reason); 3762 } 3763 } 3764 } 3765 releaseSomeActivitiesLocked(ProcessRecord app, String reason)3766 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 3767 // Examine all activities currently running in the process. 3768 TaskRecord firstTask = null; 3769 // Tasks is non-null only if two or more tasks are found. 3770 ArraySet<TaskRecord> tasks = null; 3771 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); 3772 for (int i = 0; i < app.activities.size(); i++) { 3773 ActivityRecord r = app.activities.get(i); 3774 // First, if we find an activity that is in the process of being destroyed, 3775 // then we just aren't going to do anything for now; we want things to settle 3776 // down before we try to prune more activities. 3777 if (r.finishing || r.isState(DESTROYING, DESTROYED)) { 3778 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 3779 return; 3780 } 3781 // Don't consider any activies that are currently not in a state where they 3782 // can be destroyed. 3783 if (r.visible || !r.stopped || !r.haveState 3784 || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) { 3785 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 3786 continue; 3787 } 3788 3789 final TaskRecord task = r.getTask(); 3790 if (task != null) { 3791 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task 3792 + " from " + r); 3793 if (firstTask == null) { 3794 firstTask = task; 3795 } else if (firstTask != task) { 3796 if (tasks == null) { 3797 tasks = new ArraySet<>(); 3798 tasks.add(firstTask); 3799 } 3800 tasks.add(task); 3801 } 3802 } 3803 } 3804 if (tasks == null) { 3805 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); 3806 return; 3807 } 3808 // If we have activities in multiple tasks that are in a position to be destroyed, 3809 // let's iterate through the tasks and release the oldest one. 3810 final int numDisplays = mActivityDisplays.size(); 3811 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 3812 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3813 final int stackCount = display.getChildCount(); 3814 // Step through all stacks starting from behind, to hit the oldest things first. 3815 for (int stackNdx = 0; stackNdx < stackCount; stackNdx++) { 3816 final ActivityStack stack = display.getChildAt(stackNdx); 3817 // Try to release activities in this stack; if we manage to, we are done. 3818 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 3819 return; 3820 } 3821 } 3822 } 3823 } 3824 switchUserLocked(int userId, UserState uss)3825 boolean switchUserLocked(int userId, UserState uss) { 3826 final int focusStackId = mFocusedStack.getStackId(); 3827 // We dismiss the docked stack whenever we switch users. 3828 final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack(); 3829 if (dockedStack != null) { 3830 moveTasksToFullscreenStackLocked(dockedStack, mFocusedStack == dockedStack); 3831 } 3832 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will 3833 // also cause all tasks to be moved to the fullscreen stack at a position that is 3834 // appropriate. 3835 removeStacksInWindowingModes(WINDOWING_MODE_PINNED); 3836 3837 mUserStackInFront.put(mCurrentUser, focusStackId); 3838 final int restoreStackId = mUserStackInFront.get(userId, mHomeStack.mStackId); 3839 mCurrentUser = userId; 3840 3841 mStartingUsers.add(uss); 3842 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3843 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3844 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3845 final ActivityStack stack = display.getChildAt(stackNdx); 3846 stack.switchUserLocked(userId); 3847 TaskRecord task = stack.topTask(); 3848 if (task != null) { 3849 stack.positionChildWindowContainerAtTop(task); 3850 } 3851 } 3852 } 3853 3854 ActivityStack stack = getStack(restoreStackId); 3855 if (stack == null) { 3856 stack = mHomeStack; 3857 } 3858 final boolean homeInFront = stack.isActivityTypeHome(); 3859 if (stack.isOnHomeDisplay()) { 3860 stack.moveToFront("switchUserOnHomeDisplay"); 3861 } else { 3862 // Stack was moved to another display while user was swapped out. 3863 resumeHomeStackTask(null, "switchUserOnOtherDisplay"); 3864 } 3865 return homeInFront; 3866 } 3867 3868 /** Checks whether the userid is a profile of the current user. */ isCurrentProfileLocked(int userId)3869 boolean isCurrentProfileLocked(int userId) { 3870 if (userId == mCurrentUser) return true; 3871 return mService.mUserController.isCurrentProfile(userId); 3872 } 3873 3874 /** 3875 * Returns whether a stopping activity is present that should be stopped after visible, rather 3876 * than idle. 3877 * @return {@code true} if such activity is present. {@code false} otherwise. 3878 */ isStoppingNoHistoryActivity()3879 boolean isStoppingNoHistoryActivity() { 3880 // Activities that are marked as nohistory should be stopped immediately after the resumed 3881 // activity has become visible. 3882 for (ActivityRecord record : mStoppingActivities) { 3883 if (record.isNoHistory()) { 3884 return true; 3885 } 3886 } 3887 3888 return false; 3889 } 3890 processStoppingActivitiesLocked(ActivityRecord idleActivity, boolean remove, boolean processPausingActivities)3891 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity, 3892 boolean remove, boolean processPausingActivities) { 3893 ArrayList<ActivityRecord> stops = null; 3894 3895 final boolean nowVisible = allResumedActivitiesVisible(); 3896 for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3897 ActivityRecord s = mStoppingActivities.get(activityNdx); 3898 boolean waitingVisible = mActivitiesWaitingForVisibleActivity.contains(s); 3899 if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3900 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3901 if (waitingVisible && nowVisible) { 3902 mActivitiesWaitingForVisibleActivity.remove(s); 3903 waitingVisible = false; 3904 if (s.finishing) { 3905 // If this activity is finishing, it is sitting on top of 3906 // everyone else but we now know it is no longer needed... 3907 // so get rid of it. Otherwise, we need to go through the 3908 // normal flow and hide it once we determine that it is 3909 // hidden by the activities in front of it. 3910 if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); 3911 s.setVisibility(false); 3912 } 3913 } 3914 if (remove) { 3915 final ActivityStack stack = s.getStack(); 3916 final boolean shouldSleepOrShutDown = stack != null 3917 ? stack.shouldSleepOrShutDownActivities() 3918 : mService.isSleepingOrShuttingDownLocked(); 3919 if (!waitingVisible || shouldSleepOrShutDown) { 3920 if (!processPausingActivities && s.isState(PAUSING)) { 3921 // Defer processing pausing activities in this iteration and reschedule 3922 // a delayed idle to reprocess it again 3923 removeTimeoutsForActivityLocked(idleActivity); 3924 scheduleIdleTimeoutLocked(idleActivity); 3925 continue; 3926 } 3927 3928 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); 3929 if (stops == null) { 3930 stops = new ArrayList<>(); 3931 } 3932 stops.add(s); 3933 mStoppingActivities.remove(activityNdx); 3934 } 3935 } 3936 } 3937 3938 return stops; 3939 } 3940 validateTopActivitiesLocked()3941 void validateTopActivitiesLocked() { 3942 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3943 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 3944 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 3945 final ActivityStack stack = display.getChildAt(stackNdx); 3946 final ActivityRecord r = stack.topRunningActivityLocked(); 3947 final ActivityState state = r == null ? DESTROYED : r.getState(); 3948 if (isFocusedStack(stack)) { 3949 if (r == null) Slog.e(TAG, 3950 "validateTop...: null top activity, stack=" + stack); 3951 else { 3952 final ActivityRecord pausing = stack.mPausingActivity; 3953 if (pausing != null && pausing == r) Slog.e(TAG, 3954 "validateTop...: top stack has pausing activity r=" + r 3955 + " state=" + state); 3956 if (state != INITIALIZING && state != RESUMED) Slog.e(TAG, 3957 "validateTop...: activity in front not resumed r=" + r 3958 + " state=" + state); 3959 } 3960 } else { 3961 final ActivityRecord resumed = stack.getResumedActivity(); 3962 if (resumed != null && resumed == r) Slog.e(TAG, 3963 "validateTop...: back stack has resumed activity r=" + r 3964 + " state=" + state); 3965 if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG, 3966 "validateTop...: activity in back resumed r=" + r + " state=" + state); 3967 } 3968 } 3969 } 3970 } 3971 dumpDisplays(PrintWriter pw)3972 public void dumpDisplays(PrintWriter pw) { 3973 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 3974 final ActivityDisplay display = mActivityDisplays.valueAt(i); 3975 pw.print("[id:" + display.mDisplayId + " stacks:"); 3976 display.dumpStacks(pw); 3977 pw.print("]"); 3978 } 3979 } 3980 dump(PrintWriter pw, String prefix)3981 public void dump(PrintWriter pw, String prefix) { 3982 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3983 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3984 pw.print(prefix); 3985 pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); 3986 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3987 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 3988 final ActivityDisplay display = mActivityDisplays.valueAt(i); 3989 display.dump(pw, prefix); 3990 } 3991 if (!mWaitingForActivityVisible.isEmpty()) { 3992 pw.print(prefix); pw.println("mWaitingForActivityVisible="); 3993 for (int i = 0; i < mWaitingForActivityVisible.size(); ++i) { 3994 pw.print(prefix); pw.print(prefix); mWaitingForActivityVisible.get(i).dump(pw, prefix); 3995 } 3996 } 3997 pw.print(prefix); pw.print("isHomeRecentsComponent="); 3998 pw.print(mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser)); 3999 4000 getKeyguardController().dump(pw, prefix); 4001 mService.getLockTaskController().dump(pw, prefix); 4002 } 4003 writeToProto(ProtoOutputStream proto, long fieldId)4004 public void writeToProto(ProtoOutputStream proto, long fieldId) { 4005 final long token = proto.start(fieldId); 4006 super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); 4007 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 4008 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 4009 activityDisplay.writeToProto(proto, DISPLAYS); 4010 } 4011 getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER); 4012 if (mFocusedStack != null) { 4013 proto.write(FOCUSED_STACK_ID, mFocusedStack.mStackId); 4014 ActivityRecord focusedActivity = getResumedActivityLocked(); 4015 if (focusedActivity != null) { 4016 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY); 4017 } 4018 } else { 4019 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID); 4020 } 4021 proto.write(IS_HOME_RECENTS_COMPONENT, 4022 mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser)); 4023 proto.end(token); 4024 } 4025 4026 /** 4027 * Dump all connected displays' configurations. 4028 * @param prefix Prefix to apply to each line of the dump. 4029 */ dumpDisplayConfigs(PrintWriter pw, String prefix)4030 void dumpDisplayConfigs(PrintWriter pw, String prefix) { 4031 pw.print(prefix); pw.println("Display override configurations:"); 4032 final int displayCount = mActivityDisplays.size(); 4033 for (int i = 0; i < displayCount; i++) { 4034 final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(i); 4035 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": "); 4036 pw.println(activityDisplay.getOverrideConfiguration()); 4037 } 4038 } 4039 4040 /** 4041 * Dumps the activities matching the given {@param name} in the either the focused stack 4042 * or all visible stacks if {@param dumpVisibleStacks} is true. 4043 */ getDumpActivitiesLocked(String name, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly)4044 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name, boolean dumpVisibleStacksOnly, 4045 boolean dumpFocusedStackOnly) { 4046 if (dumpFocusedStackOnly) { 4047 return mFocusedStack.getDumpActivitiesLocked(name); 4048 } else { 4049 ArrayList<ActivityRecord> activities = new ArrayList<>(); 4050 int numDisplays = mActivityDisplays.size(); 4051 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 4052 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 4053 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 4054 final ActivityStack stack = display.getChildAt(stackNdx); 4055 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) { 4056 activities.addAll(stack.getDumpActivitiesLocked(name)); 4057 } 4058 } 4059 } 4060 return activities; 4061 } 4062 } 4063 printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, boolean needSep, String prefix)4064 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 4065 boolean needSep, String prefix) { 4066 if (activity != null) { 4067 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 4068 if (needSep) { 4069 pw.println(); 4070 } 4071 pw.print(prefix); 4072 pw.println(activity); 4073 return true; 4074 } 4075 } 4076 return false; 4077 } 4078 dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage)4079 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 4080 boolean dumpClient, String dumpPackage) { 4081 boolean printed = false; 4082 boolean needSep = false; 4083 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 4084 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 4085 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 4086 pw.println(" (activities from top to bottom):"); 4087 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 4088 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 4089 final ActivityStack stack = display.getChildAt(stackNdx); 4090 pw.println(); 4091 pw.println(" Stack #" + stack.mStackId 4092 + ": type=" + activityTypeToString(stack.getActivityType()) 4093 + " mode=" + windowingModeToString(stack.getWindowingMode())); 4094 pw.println(" isSleeping=" + stack.shouldSleepActivities()); 4095 pw.println(" mBounds=" + stack.getOverrideBounds()); 4096 4097 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 4098 needSep); 4099 4100 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 4101 !dumpAll, false, dumpPackage, true, 4102 " Running activities (most recent first):", null); 4103 4104 needSep = printed; 4105 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 4106 " mPausingActivity: "); 4107 if (pr) { 4108 printed = true; 4109 needSep = false; 4110 } 4111 pr = printThisActivity(pw, stack.getResumedActivity(), dumpPackage, needSep, 4112 " mResumedActivity: "); 4113 if (pr) { 4114 printed = true; 4115 needSep = false; 4116 } 4117 if (dumpAll) { 4118 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 4119 " mLastPausedActivity: "); 4120 if (pr) { 4121 printed = true; 4122 needSep = true; 4123 } 4124 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 4125 needSep, " mLastNoHistoryActivity: "); 4126 } 4127 needSep = printed; 4128 } 4129 } 4130 4131 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 4132 false, dumpPackage, true, " Activities waiting to finish:", null); 4133 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 4134 false, dumpPackage, true, " Activities waiting to stop:", null); 4135 printed |= dumpHistoryList(fd, pw, mActivitiesWaitingForVisibleActivity, " ", "Wait", 4136 false, !dumpAll, false, dumpPackage, true, 4137 " Activities waiting for another to become visible:", null); 4138 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 4139 false, dumpPackage, true, " Activities waiting to sleep:", null); 4140 4141 return printed; 4142 } 4143 dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage, boolean needNL, String header, TaskRecord lastTask)4144 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 4145 String prefix, String label, boolean complete, boolean brief, boolean client, 4146 String dumpPackage, boolean needNL, String header, TaskRecord lastTask) { 4147 String innerPrefix = null; 4148 String[] args = null; 4149 boolean printed = false; 4150 for (int i=list.size()-1; i>=0; i--) { 4151 final ActivityRecord r = list.get(i); 4152 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 4153 continue; 4154 } 4155 if (innerPrefix == null) { 4156 innerPrefix = prefix + " "; 4157 args = new String[0]; 4158 } 4159 printed = true; 4160 final boolean full = !brief && (complete || !r.isInHistory()); 4161 if (needNL) { 4162 pw.println(""); 4163 needNL = false; 4164 } 4165 if (header != null) { 4166 pw.println(header); 4167 header = null; 4168 } 4169 if (lastTask != r.getTask()) { 4170 lastTask = r.getTask(); 4171 pw.print(prefix); 4172 pw.print(full ? "* " : " "); 4173 pw.println(lastTask); 4174 if (full) { 4175 lastTask.dump(pw, prefix + " "); 4176 } else if (complete) { 4177 // Complete + brief == give a summary. Isn't that obvious?!? 4178 if (lastTask.intent != null) { 4179 pw.print(prefix); pw.print(" "); 4180 pw.println(lastTask.intent.toInsecureStringWithClip()); 4181 } 4182 } 4183 } 4184 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 4185 pw.print(" #"); pw.print(i); pw.print(": "); 4186 pw.println(r); 4187 if (full) { 4188 r.dump(pw, innerPrefix); 4189 } else if (complete) { 4190 // Complete + brief == give a summary. Isn't that obvious?!? 4191 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 4192 if (r.app != null) { 4193 pw.print(innerPrefix); pw.println(r.app); 4194 } 4195 } 4196 if (client && r.app != null && r.app.thread != null) { 4197 // flush anything that is already in the PrintWriter since the thread is going 4198 // to write to the file descriptor directly 4199 pw.flush(); 4200 try { 4201 TransferPipe tp = new TransferPipe(); 4202 try { 4203 r.app.thread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args); 4204 // Short timeout, since blocking here can 4205 // deadlock with the application. 4206 tp.go(fd, 2000); 4207 } finally { 4208 tp.kill(); 4209 } 4210 } catch (IOException e) { 4211 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 4212 } catch (RemoteException e) { 4213 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 4214 } 4215 needNL = true; 4216 } 4217 } 4218 return printed; 4219 } 4220 scheduleIdleTimeoutLocked(ActivityRecord next)4221 void scheduleIdleTimeoutLocked(ActivityRecord next) { 4222 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 4223 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 4224 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 4225 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 4226 } 4227 scheduleIdleLocked()4228 final void scheduleIdleLocked() { 4229 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 4230 } 4231 removeTimeoutsForActivityLocked(ActivityRecord r)4232 void removeTimeoutsForActivityLocked(ActivityRecord r) { 4233 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 4234 + Debug.getCallers(4)); 4235 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 4236 } 4237 scheduleResumeTopActivities()4238 final void scheduleResumeTopActivities() { 4239 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 4240 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 4241 } 4242 } 4243 removeSleepTimeouts()4244 void removeSleepTimeouts() { 4245 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 4246 } 4247 scheduleSleepTimeout()4248 final void scheduleSleepTimeout() { 4249 removeSleepTimeouts(); 4250 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 4251 } 4252 4253 @Override onDisplayAdded(int displayId)4254 public void onDisplayAdded(int displayId) { 4255 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 4256 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 4257 } 4258 4259 @Override onDisplayRemoved(int displayId)4260 public void onDisplayRemoved(int displayId) { 4261 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 4262 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 4263 } 4264 4265 @Override onDisplayChanged(int displayId)4266 public void onDisplayChanged(int displayId) { 4267 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 4268 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 4269 } 4270 handleDisplayAdded(int displayId)4271 private void handleDisplayAdded(int displayId) { 4272 synchronized (mService) { 4273 getActivityDisplayOrCreateLocked(displayId); 4274 } 4275 } 4276 4277 /** Check if display with specified id is added to the list. */ isDisplayAdded(int displayId)4278 boolean isDisplayAdded(int displayId) { 4279 return getActivityDisplayOrCreateLocked(displayId) != null; 4280 } 4281 4282 // TODO: Look into consolidating with getActivityDisplayOrCreateLocked() getActivityDisplay(int displayId)4283 ActivityDisplay getActivityDisplay(int displayId) { 4284 return mActivityDisplays.get(displayId); 4285 } 4286 4287 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display. getDefaultDisplay()4288 ActivityDisplay getDefaultDisplay() { 4289 return mActivityDisplays.get(DEFAULT_DISPLAY); 4290 } 4291 4292 /** 4293 * Get an existing instance of {@link ActivityDisplay} or create new if there is a 4294 * corresponding record in display manager. 4295 */ 4296 // TODO: Look into consolidating with getActivityDisplay() getActivityDisplayOrCreateLocked(int displayId)4297 ActivityDisplay getActivityDisplayOrCreateLocked(int displayId) { 4298 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 4299 if (activityDisplay != null) { 4300 return activityDisplay; 4301 } 4302 if (mDisplayManager == null) { 4303 // The system isn't fully initialized yet. 4304 return null; 4305 } 4306 final Display display = mDisplayManager.getDisplay(displayId); 4307 if (display == null) { 4308 // The display is not registered in DisplayManager. 4309 return null; 4310 } 4311 // The display hasn't been added to ActivityManager yet, create a new record now. 4312 activityDisplay = new ActivityDisplay(this, display); 4313 attachDisplay(activityDisplay); 4314 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 4315 mWindowManager.onDisplayAdded(displayId); 4316 return activityDisplay; 4317 } 4318 4319 @VisibleForTesting attachDisplay(ActivityDisplay display)4320 void attachDisplay(ActivityDisplay display) { 4321 mActivityDisplays.put(display.mDisplayId, display); 4322 } 4323 calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display)4324 private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) { 4325 mDefaultMinSizeOfResizeableTask = 4326 mService.mContext.getResources().getDimensionPixelSize( 4327 com.android.internal.R.dimen.default_minimal_size_resizable_task); 4328 } 4329 handleDisplayRemoved(int displayId)4330 private void handleDisplayRemoved(int displayId) { 4331 if (displayId == DEFAULT_DISPLAY) { 4332 throw new IllegalArgumentException("Can't remove the primary display."); 4333 } 4334 4335 synchronized (mService) { 4336 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 4337 if (activityDisplay == null) { 4338 return; 4339 } 4340 4341 activityDisplay.remove(); 4342 4343 releaseSleepTokens(activityDisplay); 4344 4345 mActivityDisplays.remove(displayId); 4346 } 4347 } 4348 handleDisplayChanged(int displayId)4349 private void handleDisplayChanged(int displayId) { 4350 synchronized (mService) { 4351 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 4352 // TODO: The following code block should be moved into {@link ActivityDisplay}. 4353 if (activityDisplay != null) { 4354 // The window policy is responsible for stopping activities on the default display 4355 if (displayId != Display.DEFAULT_DISPLAY) { 4356 int displayState = activityDisplay.mDisplay.getState(); 4357 if (displayState == Display.STATE_OFF && activityDisplay.mOffToken == null) { 4358 activityDisplay.mOffToken = 4359 mService.acquireSleepToken("Display-off", displayId); 4360 } else if (displayState == Display.STATE_ON 4361 && activityDisplay.mOffToken != null) { 4362 activityDisplay.mOffToken.release(); 4363 activityDisplay.mOffToken = null; 4364 } 4365 } 4366 4367 activityDisplay.updateBounds(); 4368 } 4369 mWindowManager.onDisplayChanged(displayId); 4370 } 4371 } 4372 createSleepTokenLocked(String tag, int displayId)4373 SleepToken createSleepTokenLocked(String tag, int displayId) { 4374 ActivityDisplay display = mActivityDisplays.get(displayId); 4375 if (display == null) { 4376 throw new IllegalArgumentException("Invalid display: " + displayId); 4377 } 4378 4379 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId); 4380 mSleepTokens.add(token); 4381 display.mAllSleepTokens.add(token); 4382 return token; 4383 } 4384 removeSleepTokenLocked(SleepTokenImpl token)4385 private void removeSleepTokenLocked(SleepTokenImpl token) { 4386 mSleepTokens.remove(token); 4387 4388 ActivityDisplay display = mActivityDisplays.get(token.mDisplayId); 4389 if (display != null) { 4390 display.mAllSleepTokens.remove(token); 4391 if (display.mAllSleepTokens.isEmpty()) { 4392 mService.updateSleepIfNeededLocked(); 4393 } 4394 } 4395 } 4396 releaseSleepTokens(ActivityDisplay display)4397 private void releaseSleepTokens(ActivityDisplay display) { 4398 if (display.mAllSleepTokens.isEmpty()) { 4399 return; 4400 } 4401 for (SleepToken token : display.mAllSleepTokens) { 4402 mSleepTokens.remove(token); 4403 } 4404 display.mAllSleepTokens.clear(); 4405 4406 mService.updateSleepIfNeededLocked(); 4407 } 4408 getStackInfo(ActivityStack stack)4409 private StackInfo getStackInfo(ActivityStack stack) { 4410 final int displayId = stack.mDisplayId; 4411 final ActivityDisplay display = mActivityDisplays.get(displayId); 4412 StackInfo info = new StackInfo(); 4413 stack.getWindowContainerBounds(info.bounds); 4414 info.displayId = displayId; 4415 info.stackId = stack.mStackId; 4416 info.userId = stack.mCurrentUser; 4417 info.visible = stack.shouldBeVisible(null); 4418 // A stack might be not attached to a display. 4419 info.position = display != null ? display.getIndexOf(stack) : 0; 4420 info.configuration.setTo(stack.getConfiguration()); 4421 4422 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 4423 final int numTasks = tasks.size(); 4424 int[] taskIds = new int[numTasks]; 4425 String[] taskNames = new String[numTasks]; 4426 Rect[] taskBounds = new Rect[numTasks]; 4427 int[] taskUserIds = new int[numTasks]; 4428 for (int i = 0; i < numTasks; ++i) { 4429 final TaskRecord task = tasks.get(i); 4430 taskIds[i] = task.taskId; 4431 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 4432 : task.realActivity != null ? task.realActivity.flattenToString() 4433 : task.getTopActivity() != null ? task.getTopActivity().packageName 4434 : "unknown"; 4435 taskBounds[i] = new Rect(); 4436 task.getWindowContainerBounds(taskBounds[i]); 4437 taskUserIds[i] = task.userId; 4438 } 4439 info.taskIds = taskIds; 4440 info.taskNames = taskNames; 4441 info.taskBounds = taskBounds; 4442 info.taskUserIds = taskUserIds; 4443 4444 final ActivityRecord top = stack.topRunningActivityLocked(); 4445 info.topActivity = top != null ? top.intent.getComponent() : null; 4446 return info; 4447 } 4448 getStackInfo(int stackId)4449 StackInfo getStackInfo(int stackId) { 4450 ActivityStack stack = getStack(stackId); 4451 if (stack != null) { 4452 return getStackInfo(stack); 4453 } 4454 return null; 4455 } 4456 getStackInfo(int windowingMode, int activityType)4457 StackInfo getStackInfo(int windowingMode, int activityType) { 4458 final ActivityStack stack = getStack(windowingMode, activityType); 4459 return (stack != null) ? getStackInfo(stack) : null; 4460 } 4461 getAllStackInfosLocked()4462 ArrayList<StackInfo> getAllStackInfosLocked() { 4463 ArrayList<StackInfo> list = new ArrayList<>(); 4464 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 4465 final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); 4466 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 4467 final ActivityStack stack = display.getChildAt(stackNdx); 4468 list.add(getStackInfo(stack)); 4469 } 4470 } 4471 return list; 4472 } 4473 handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode, int preferredDisplayId, ActivityStack actualStack)4474 void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode, 4475 int preferredDisplayId, ActivityStack actualStack) { 4476 handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredDisplayId, 4477 actualStack, false /* forceNonResizable */); 4478 } 4479 handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode, int preferredDisplayId, ActivityStack actualStack, boolean forceNonResizable)4480 void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode, 4481 int preferredDisplayId, ActivityStack actualStack, boolean forceNonResizable) { 4482 final boolean isSecondaryDisplayPreferred = 4483 (preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY); 4484 final boolean inSplitScreenMode = actualStack != null 4485 && actualStack.getDisplay().hasSplitScreenPrimaryStack(); 4486 if (((!inSplitScreenMode && preferredWindowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) 4487 && !isSecondaryDisplayPreferred) || !task.isActivityTypeStandardOrUndefined()) { 4488 return; 4489 } 4490 4491 // Handle incorrect launch/move to secondary display if needed. 4492 if (isSecondaryDisplayPreferred) { 4493 final int actualDisplayId = task.getStack().mDisplayId; 4494 if (!task.canBeLaunchedOnDisplay(actualDisplayId)) { 4495 throw new IllegalStateException("Task resolved to incompatible display"); 4496 } 4497 // The task might have landed on a display different from requested. 4498 // TODO(multi-display): Find proper stack for the task on the default display. 4499 mService.setTaskWindowingMode(task.taskId, 4500 WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */); 4501 if (preferredDisplayId != actualDisplayId) { 4502 // Display a warning toast that we tried to put a non-resizeable task on a secondary 4503 // display with config different from global config. 4504 mService.mTaskChangeNotificationController 4505 .notifyActivityLaunchOnSecondaryDisplayFailed(); 4506 return; 4507 } 4508 } 4509 4510 if (!task.supportsSplitScreenWindowingMode() || forceNonResizable) { 4511 // Display a warning toast that we tried to put an app that doesn't support split-screen 4512 // in split-screen. 4513 mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack(); 4514 4515 // Dismiss docked stack. If task appeared to be in docked stack but is not resizable - 4516 // we need to move it to top of fullscreen stack, otherwise it will be covered. 4517 4518 final ActivityStack dockedStack = 4519 task.getStack().getDisplay().getSplitScreenPrimaryStack(); 4520 if (dockedStack != null) { 4521 moveTasksToFullscreenStackLocked(dockedStack, actualStack == dockedStack); 4522 } 4523 return; 4524 } 4525 4526 final ActivityRecord topActivity = task.getTopActivity(); 4527 if (topActivity != null && topActivity.isNonResizableOrForcedResizable() 4528 && !topActivity.noDisplay) { 4529 final String packageName = topActivity.appInfo.packageName; 4530 final int reason = isSecondaryDisplayPreferred 4531 ? FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY 4532 : FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; 4533 mService.mTaskChangeNotificationController.notifyActivityForcedResizable( 4534 task.taskId, reason, packageName); 4535 } 4536 } 4537 activityRelaunchedLocked(IBinder token)4538 void activityRelaunchedLocked(IBinder token) { 4539 mWindowManager.notifyAppRelaunchingFinished(token); 4540 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 4541 if (r != null) { 4542 if (r.getStack().shouldSleepOrShutDownActivities()) { 4543 r.setSleeping(true, true); 4544 } 4545 } 4546 } 4547 activityRelaunchingLocked(ActivityRecord r)4548 void activityRelaunchingLocked(ActivityRecord r) { 4549 mWindowManager.notifyAppRelaunching(r.appToken); 4550 } 4551 logStackState()4552 void logStackState() { 4553 mActivityMetricsLogger.logWindowState(); 4554 } 4555 scheduleUpdateMultiWindowMode(TaskRecord task)4556 void scheduleUpdateMultiWindowMode(TaskRecord task) { 4557 // If the stack is animating in a way where we will be forcing a multi-mode change at the 4558 // end, then ensure that we defer all in between multi-window mode changes 4559 if (task.getStack().deferScheduleMultiWindowModeChanged()) { 4560 return; 4561 } 4562 4563 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 4564 final ActivityRecord r = task.mActivities.get(i); 4565 if (r.app != null && r.app.thread != null) { 4566 mMultiWindowModeChangedActivities.add(r); 4567 } 4568 } 4569 4570 if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) { 4571 mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG); 4572 } 4573 } 4574 scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, ActivityStack prevStack)4575 void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, ActivityStack prevStack) { 4576 final ActivityStack stack = task.getStack(); 4577 if (prevStack == null || prevStack == stack 4578 || (!prevStack.inPinnedWindowingMode() && !stack.inPinnedWindowingMode())) { 4579 return; 4580 } 4581 4582 scheduleUpdatePictureInPictureModeIfNeeded(task, stack.getOverrideBounds()); 4583 } 4584 scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, Rect targetStackBounds)4585 void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, Rect targetStackBounds) { 4586 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 4587 final ActivityRecord r = task.mActivities.get(i); 4588 if (r.app != null && r.app.thread != null) { 4589 mPipModeChangedActivities.add(r); 4590 // If we are scheduling pip change, then remove this activity from multi-window 4591 // change list as the processing of pip change will make sure multi-window changed 4592 // message is processed in the right order relative to pip changed. 4593 mMultiWindowModeChangedActivities.remove(r); 4594 } 4595 } 4596 mPipModeChangedTargetStackBounds = targetStackBounds; 4597 4598 if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { 4599 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); 4600 } 4601 } 4602 updatePictureInPictureMode(TaskRecord task, Rect targetStackBounds, boolean forceUpdate)4603 void updatePictureInPictureMode(TaskRecord task, Rect targetStackBounds, boolean forceUpdate) { 4604 mHandler.removeMessages(REPORT_PIP_MODE_CHANGED_MSG); 4605 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 4606 final ActivityRecord r = task.mActivities.get(i); 4607 if (r.app != null && r.app.thread != null) { 4608 r.updatePictureInPictureMode(targetStackBounds, forceUpdate); 4609 } 4610 } 4611 } 4612 setDockedStackMinimized(boolean minimized)4613 void setDockedStackMinimized(boolean minimized) { 4614 mIsDockMinimized = minimized; 4615 if (mIsDockMinimized) { 4616 final ActivityStack current = getFocusedStack(); 4617 if (current.inSplitScreenPrimaryWindowingMode()) { 4618 // The primary split-screen stack can't be focused while it is minimize, so move 4619 // focus to something else. 4620 current.adjustFocusToNextFocusableStack("setDockedStackMinimized"); 4621 } 4622 } 4623 } 4624 wakeUp(String reason)4625 void wakeUp(String reason) { 4626 mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.am:TURN_ON:" + reason); 4627 } 4628 4629 /** 4630 * Begin deferring resume to avoid duplicate resumes in one pass. 4631 */ beginDeferResume()4632 private void beginDeferResume() { 4633 mDeferResumeCount++; 4634 } 4635 4636 /** 4637 * End deferring resume and determine if resume can be called. 4638 */ endDeferResume()4639 private void endDeferResume() { 4640 mDeferResumeCount--; 4641 } 4642 4643 /** 4644 * @return True if resume can be called. 4645 */ readyToResume()4646 private boolean readyToResume() { 4647 return mDeferResumeCount == 0; 4648 } 4649 4650 private final class ActivityStackSupervisorHandler extends Handler { 4651 ActivityStackSupervisorHandler(Looper looper)4652 public ActivityStackSupervisorHandler(Looper looper) { 4653 super(looper); 4654 } 4655 activityIdleInternal(ActivityRecord r, boolean processPausingActivities)4656 void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) { 4657 synchronized (mService) { 4658 activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */, 4659 processPausingActivities, null); 4660 } 4661 } 4662 4663 @Override handleMessage(Message msg)4664 public void handleMessage(Message msg) { 4665 switch (msg.what) { 4666 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: { 4667 synchronized (mService) { 4668 for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) { 4669 final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i); 4670 r.updateMultiWindowMode(); 4671 } 4672 } 4673 } break; 4674 case REPORT_PIP_MODE_CHANGED_MSG: { 4675 synchronized (mService) { 4676 for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) { 4677 final ActivityRecord r = mPipModeChangedActivities.remove(i); 4678 r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds, 4679 false /* forceUpdate */); 4680 } 4681 } 4682 } break; 4683 case IDLE_TIMEOUT_MSG: { 4684 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 4685 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 4686 // We don't at this point know if the activity is fullscreen, 4687 // so we need to be conservative and assume it isn't. 4688 activityIdleInternal((ActivityRecord) msg.obj, 4689 true /* processPausingActivities */); 4690 } break; 4691 case IDLE_NOW_MSG: { 4692 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 4693 activityIdleInternal((ActivityRecord) msg.obj, 4694 false /* processPausingActivities */); 4695 } break; 4696 case RESUME_TOP_ACTIVITY_MSG: { 4697 synchronized (mService) { 4698 resumeFocusedStackTopActivityLocked(); 4699 } 4700 } break; 4701 case SLEEP_TIMEOUT_MSG: { 4702 synchronized (mService) { 4703 if (mService.isSleepingOrShuttingDownLocked()) { 4704 Slog.w(TAG, "Sleep timeout! Sleeping now."); 4705 checkReadyForSleepLocked(false /* allowDelay */); 4706 } 4707 } 4708 } break; 4709 case LAUNCH_TIMEOUT_MSG: { 4710 synchronized (mService) { 4711 if (mLaunchingActivity.isHeld()) { 4712 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 4713 if (VALIDATE_WAKE_LOCK_CALLER 4714 && Binder.getCallingUid() != Process.myUid()) { 4715 throw new IllegalStateException("Calling must be system uid"); 4716 } 4717 mLaunchingActivity.release(); 4718 } 4719 } 4720 } break; 4721 case HANDLE_DISPLAY_ADDED: { 4722 handleDisplayAdded(msg.arg1); 4723 } break; 4724 case HANDLE_DISPLAY_CHANGED: { 4725 handleDisplayChanged(msg.arg1); 4726 } break; 4727 case HANDLE_DISPLAY_REMOVED: { 4728 handleDisplayRemoved(msg.arg1); 4729 } break; 4730 case LAUNCH_TASK_BEHIND_COMPLETE: { 4731 synchronized (mService) { 4732 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 4733 if (r != null) { 4734 handleLaunchTaskBehindCompleteLocked(r); 4735 } 4736 } 4737 } break; 4738 4739 } 4740 } 4741 } 4742 findStackBehind(ActivityStack stack)4743 ActivityStack findStackBehind(ActivityStack stack) { 4744 // TODO(multi-display): We are only looking for stacks on the default display. 4745 final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY); 4746 if (display == null) { 4747 return null; 4748 } 4749 for (int i = display.getChildCount() - 1; i >= 0; i--) { 4750 if (display.getChildAt(i) == stack && i > 0) { 4751 return display.getChildAt(i - 1); 4752 } 4753 } 4754 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 4755 + " in=" + display); 4756 } 4757 4758 /** 4759 * Puts a task into resizing mode during the next app transition. 4760 * 4761 * @param task The task to put into resizing mode 4762 */ setResizingDuringAnimation(TaskRecord task)4763 void setResizingDuringAnimation(TaskRecord task) { 4764 mResizingTasksDuringAnimation.add(task.taskId); 4765 task.setTaskDockedResizing(true); 4766 } 4767 startActivityFromRecents(int callingPid, int callingUid, int taskId, SafeActivityOptions options)4768 int startActivityFromRecents(int callingPid, int callingUid, int taskId, 4769 SafeActivityOptions options) { 4770 TaskRecord task = null; 4771 final String callingPackage; 4772 final Intent intent; 4773 final int userId; 4774 int activityType = ACTIVITY_TYPE_UNDEFINED; 4775 int windowingMode = WINDOWING_MODE_UNDEFINED; 4776 final ActivityOptions activityOptions = options != null 4777 ? options.getOptions(this) 4778 : null; 4779 if (activityOptions != null) { 4780 activityType = activityOptions.getLaunchActivityType(); 4781 windowingMode = activityOptions.getLaunchWindowingMode(); 4782 } 4783 if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) { 4784 throw new IllegalArgumentException("startActivityFromRecents: Task " 4785 + taskId + " can't be launch in the home/recents stack."); 4786 } 4787 4788 mWindowManager.deferSurfaceLayout(); 4789 try { 4790 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { 4791 mWindowManager.setDockedStackCreateState( 4792 activityOptions.getSplitScreenCreateMode(), null /* initialBounds */); 4793 4794 // Defer updating the stack in which recents is until the app transition is done, to 4795 // not run into issues where we still need to draw the task in recents but the 4796 // docked stack is already created. 4797 deferUpdateRecentsHomeStackBounds(); 4798 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false); 4799 } 4800 4801 task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, 4802 activityOptions, ON_TOP); 4803 if (task == null) { 4804 continueUpdateRecentsHomeStackBounds(); 4805 mWindowManager.executeAppTransition(); 4806 throw new IllegalArgumentException( 4807 "startActivityFromRecents: Task " + taskId + " not found."); 4808 } 4809 4810 if (windowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { 4811 // We always want to return to the home activity instead of the recents activity 4812 // from whatever is started from the recents activity, so move the home stack 4813 // forward. 4814 moveHomeStackToFront("startActivityFromRecents"); 4815 } 4816 4817 // If the user must confirm credentials (e.g. when first launching a work app and the 4818 // Work Challenge is present) let startActivityInPackage handle the intercepting. 4819 if (!mService.mUserController.shouldConfirmCredentials(task.userId) 4820 && task.getRootActivity() != null) { 4821 final ActivityRecord targetActivity = task.getTopActivity(); 4822 4823 sendPowerHintForLaunchStartIfNeeded(true /* forceSend */, targetActivity); 4824 mActivityMetricsLogger.notifyActivityLaunching(); 4825 try { 4826 mService.moveTaskToFrontLocked(task.taskId, 0, options, 4827 true /* fromRecents */); 4828 } finally { 4829 mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT, 4830 targetActivity); 4831 } 4832 4833 mService.getActivityStartController().postStartActivityProcessingForLastStarter( 4834 task.getTopActivity(), ActivityManager.START_TASK_TO_FRONT, 4835 task.getStack()); 4836 return ActivityManager.START_TASK_TO_FRONT; 4837 } 4838 callingPackage = task.mCallingPackage; 4839 intent = task.intent; 4840 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 4841 userId = task.userId; 4842 return mService.getActivityStartController().startActivityInPackage( 4843 task.mCallingUid, callingPid, callingUid, callingPackage, intent, null, null, 4844 null, 0, 0, options, userId, task, "startActivityFromRecents", 4845 false /* validateIncomingUser */); 4846 } finally { 4847 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && task != null) { 4848 // If we are launching the task in the docked stack, put it into resizing mode so 4849 // the window renders full-screen with the background filling the void. Also only 4850 // call this at the end to make sure that tasks exists on the window manager side. 4851 setResizingDuringAnimation(task); 4852 4853 final ActivityDisplay display = task.getStack().getDisplay(); 4854 final ActivityStack topSecondaryStack = 4855 display.getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); 4856 if (topSecondaryStack.isActivityTypeHome()) { 4857 // If the home activity if the top split-screen secondary stack, then the 4858 // primary split-screen stack is in the minimized mode which means it can't 4859 // receive input keys, so we should move the focused app to the home app so that 4860 // window manager can correctly calculate the focus window that can receive 4861 // input keys. 4862 moveHomeStackToFront("startActivityFromRecents: homeVisibleInSplitScreen"); 4863 4864 // Immediately update the minimized docked stack mode, the upcoming animation 4865 // for the docked activity (WMS.overridePendingAppTransitionMultiThumbFuture) 4866 // will do the animation to the target bounds 4867 mWindowManager.checkSplitScreenMinimizedChanged(false /* animate */); 4868 } 4869 } 4870 mWindowManager.continueSurfaceLayout(); 4871 } 4872 } 4873 4874 /** 4875 * @return a list of activities which are the top ones in each visible stack. The first 4876 * entry will be the focused activity. 4877 */ getTopVisibleActivities()4878 List<IBinder> getTopVisibleActivities() { 4879 final ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 4880 // Traverse all displays. 4881 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) { 4882 final ActivityDisplay display = mActivityDisplays.valueAt(i); 4883 // Traverse all stacks on a display. 4884 for (int j = display.getChildCount() - 1; j >= 0; --j) { 4885 final ActivityStack stack = display.getChildAt(j); 4886 // Get top activity from a visible stack and add it to the list. 4887 if (stack.shouldBeVisible(null /* starting */)) { 4888 final ActivityRecord top = stack.getTopActivity(); 4889 if (top != null) { 4890 if (stack == mFocusedStack) { 4891 topActivityTokens.add(0, top.appToken); 4892 } else { 4893 topActivityTokens.add(top.appToken); 4894 } 4895 } 4896 } 4897 } 4898 } 4899 return topActivityTokens; 4900 } 4901 4902 /** 4903 * Internal container to store a match qualifier alongside a WaitResult. 4904 */ 4905 static class WaitInfo { 4906 private final ComponentName mTargetComponent; 4907 private final WaitResult mResult; 4908 WaitInfo(ComponentName targetComponent, WaitResult result)4909 public WaitInfo(ComponentName targetComponent, WaitResult result) { 4910 this.mTargetComponent = targetComponent; 4911 this.mResult = result; 4912 } 4913 matches(ComponentName targetComponent)4914 public boolean matches(ComponentName targetComponent) { 4915 return mTargetComponent == null || mTargetComponent.equals(targetComponent); 4916 } 4917 getResult()4918 public WaitResult getResult() { 4919 return mResult; 4920 } 4921 getComponent()4922 public ComponentName getComponent() { 4923 return mTargetComponent; 4924 } 4925 dump(PrintWriter pw, String prefix)4926 public void dump(PrintWriter pw, String prefix) { 4927 pw.println(prefix + "WaitInfo:"); 4928 pw.println(prefix + " mTargetComponent=" + mTargetComponent); 4929 pw.println(prefix + " mResult="); 4930 mResult.dump(pw, prefix); 4931 } 4932 } 4933 4934 private final class SleepTokenImpl extends SleepToken { 4935 private final String mTag; 4936 private final long mAcquireTime; 4937 private final int mDisplayId; 4938 SleepTokenImpl(String tag, int displayId)4939 public SleepTokenImpl(String tag, int displayId) { 4940 mTag = tag; 4941 mDisplayId = displayId; 4942 mAcquireTime = SystemClock.uptimeMillis(); 4943 } 4944 4945 @Override release()4946 public void release() { 4947 synchronized (mService) { 4948 removeSleepTokenLocked(this); 4949 } 4950 } 4951 4952 @Override toString()4953 public String toString() { 4954 return "{\"" + mTag + "\", display " + mDisplayId 4955 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}"; 4956 } 4957 } 4958 4959 } 4960