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 { 287 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, 288 Manifest.permission.CAMERA); 289 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, 290 Manifest.permission.CAMERA); 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 453 protected int getChildCount() { 454 return mActivityDisplays.size(); 455 } 456 457 @Override 458 protected ActivityDisplay getChildAt(int index) { 459 return mActivityDisplays.valueAt(index); 460 } 461 462 @Override 463 protected ConfigurationContainer getParent() { 464 return null; 465 } 466 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 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. */ 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 */ 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 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 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 607 public ActivityStackSupervisor(ActivityManagerService service, Looper looper) { 608 mService = service; 609 mLooper = looper; 610 mHandler = new ActivityStackSupervisorHandler(looper); 611 } 612 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 629 public ActivityMetricsLogger getActivityMetricsLogger() { 630 return mActivityMetricsLogger; 631 } 632 633 LaunchTimeTracker getLaunchTimeTracker() { 634 return mLaunchTimeTracker; 635 } 636 637 public KeyguardController getKeyguardController() { 638 return mKeyguardController; 639 } 640 641 void setRecentTasks(RecentTasks recentTasks) { 642 mRecentTasks = recentTasks; 643 mRecentTasks.registerCallback(this); 644 } 645 646 @VisibleForTesting 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 */ 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 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 686 ActivityStack getFocusedStack() { 687 return mFocusedStack; 688 } 689 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 698 ActivityStack getLastStack() { 699 return mLastFocusedStack; 700 } 701 702 boolean isFocusedStack(ActivityStack stack) { 703 return stack != null && stack == mFocusedStack; 704 } 705 706 /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */ 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 730 void moveHomeStackToFront(String reason) { 731 mHomeStack.moveToFront(reason); 732 } 733 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. */ 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 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 772 TaskRecord anyTaskForIdLocked(int id) { 773 return anyTaskForIdLocked(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE); 774 } 775 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 */ 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 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 */ 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 */ 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 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 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 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 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 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 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 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 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 */ 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 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 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 1124 void waitActivityVisible(ComponentName name, WaitResult result) { 1125 final WaitInfo waitInfo = new WaitInfo(name, result); 1126 mWaitingForActivityVisible.add(waitInfo); 1127 } 1128 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 1143 void reportActivityVisibleLocked(ActivityRecord r) { 1144 sendWaitingVisibleReportLocked(r); 1145 } 1146 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 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 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 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 */ 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 */ 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 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 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 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 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 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 */ 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 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 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 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 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 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. */ 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. */ 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 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 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 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 1969 void setLaunchSource(int uid) { 1970 mLaunchingActivity.setWorkSource(new WorkSource(uid)); 1971 } 1972 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") 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") 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 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 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 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 */ 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 */ 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 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 2210 boolean resumeFocusedStackTopActivityLocked() { 2211 return resumeFocusedStackTopActivityLocked(null, null, null); 2212 } 2213 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 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 */ 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 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 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 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 2350 LaunchParamsController getLaunchParamsController() { 2351 return mLaunchParamsController; 2352 } 2353 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) */ 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 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 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 */ 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. */ 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 */ 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()... 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 */ 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 */ 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 2648 ActivityRecord getHomeActivity() { 2649 return getHomeActivityForUser(mCurrentUser); 2650 } 2651 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 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 2712 void deferUpdateRecentsHomeStackBounds() { 2713 deferUpdateBounds(ACTIVITY_TYPE_RECENTS); 2714 deferUpdateBounds(ACTIVITY_TYPE_HOME); 2715 } 2716 2717 void deferUpdateBounds(int activityType) { 2718 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); 2719 if (stack != null) { 2720 stack.deferUpdateBounds(); 2721 } 2722 } 2723 2724 void continueUpdateRecentsHomeStackBounds() { 2725 continueUpdateBounds(ACTIVITY_TYPE_RECENTS); 2726 continueUpdateBounds(ACTIVITY_TYPE_HOME); 2727 } 2728 2729 void continueUpdateBounds(int activityType) { 2730 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); 2731 if (stack != null) { 2732 stack.continueUpdateBounds(); 2733 } 2734 } 2735 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 */ 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 2825 void moveTasksToFullscreenStackLocked(ActivityStack fromStack, boolean onTop) { 2826 moveTasksToFullscreenStackLocked(fromStack, DEFAULT_DISPLAY, onTop); 2827 } 2828 2829 void moveTasksToFullscreenStackLocked(ActivityStack fromStack, int toDisplayId, boolean onTop) { 2830 mWindowManager.inSurfaceTransaction(() -> 2831 moveTasksToFullscreenStackInSurfaceTransaction(fromStack, toDisplayId, onTop)); 2832 } 2833 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 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 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 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 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 */ 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 */ 3036 void removeStacksInWindowingModes(int... windowingModes) { 3037 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 3038 mActivityDisplays.valueAt(i).removeStacksInWindowingModes(windowingModes); 3039 } 3040 } 3041 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 */ 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 */ 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 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 */ 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 3189 public void onRecentTaskAdded(TaskRecord task) { 3190 task.touchActiveTime(); 3191 } 3192 3193 @Override 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 */ 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() 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 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 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. */ 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 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 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 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 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 3500 void prepareForShutdownLocked() { 3501 for (int i = 0; i < mActivityDisplays.size(); i++) { 3502 createSleepTokenLocked("shutdown", mActivityDisplays.keyAt(i)); 3503 } 3504 } 3505 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 3535 void comeOutOfSleepIfNeededLocked() { 3536 removeSleepTimeouts(); 3537 if (mGoingToSleep.isHeld()) { 3538 mGoingToSleep.release(); 3539 } 3540 } 3541 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 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 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. 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 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 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. 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 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 */ 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 */ 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 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 3727 void invalidateTaskLayers() { 3728 mTaskLayersChanged = true; 3729 } 3730 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 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 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 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 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. */ 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 */ 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 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 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 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 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 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 */ 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 */ 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 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 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 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 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 4228 final void scheduleIdleLocked() { 4229 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 4230 } 4231 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 4238 final void scheduleResumeTopActivities() { 4239 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 4240 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 4241 } 4242 } 4243 4244 void removeSleepTimeouts() { 4245 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 4246 } 4247 4248 final void scheduleSleepTimeout() { 4249 removeSleepTimeouts(); 4250 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 4251 } 4252 4253 @Override 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 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 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 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. */ 4278 boolean isDisplayAdded(int displayId) { 4279 return getActivityDisplayOrCreateLocked(displayId) != null; 4280 } 4281 4282 // TODO: Look into consolidating with getActivityDisplayOrCreateLocked() 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. 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() 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 4320 void attachDisplay(ActivityDisplay display) { 4321 mActivityDisplays.put(display.mDisplayId, display); 4322 } 4323 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 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 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 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 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 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 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 4449 StackInfo getStackInfo(int stackId) { 4450 ActivityStack stack = getStack(stackId); 4451 if (stack != null) { 4452 return getStackInfo(stack); 4453 } 4454 return null; 4455 } 4456 4457 StackInfo getStackInfo(int windowingMode, int activityType) { 4458 final ActivityStack stack = getStack(windowingMode, activityType); 4459 return (stack != null) ? getStackInfo(stack) : null; 4460 } 4461 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 4474 void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode, 4475 int preferredDisplayId, ActivityStack actualStack) { 4476 handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredDisplayId, 4477 actualStack, false /* forceNonResizable */); 4478 } 4479 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 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 4548 void activityRelaunchingLocked(ActivityRecord r) { 4549 mWindowManager.notifyAppRelaunching(r.appToken); 4550 } 4551 4552 void logStackState() { 4553 mActivityMetricsLogger.logWindowState(); 4554 } 4555 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 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 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 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 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 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 */ 4632 private void beginDeferResume() { 4633 mDeferResumeCount++; 4634 } 4635 4636 /** 4637 * End deferring resume and determine if resume can be called. 4638 */ 4639 private void endDeferResume() { 4640 mDeferResumeCount--; 4641 } 4642 4643 /** 4644 * @return True if resume can be called. 4645 */ 4646 private boolean readyToResume() { 4647 return mDeferResumeCount == 0; 4648 } 4649 4650 private final class ActivityStackSupervisorHandler extends Handler { 4651 4652 public ActivityStackSupervisorHandler(Looper looper) { 4653 super(looper); 4654 } 4655 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 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 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 */ 4763 void setResizingDuringAnimation(TaskRecord task) { 4764 mResizingTasksDuringAnimation.add(task.taskId); 4765 task.setTaskDockedResizing(true); 4766 } 4767 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 */ 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 4909 public WaitInfo(ComponentName targetComponent, WaitResult result) { 4910 this.mTargetComponent = targetComponent; 4911 this.mResult = result; 4912 } 4913 4914 public boolean matches(ComponentName targetComponent) { 4915 return mTargetComponent == null || mTargetComponent.equals(targetComponent); 4916 } 4917 4918 public WaitResult getResult() { 4919 return mResult; 4920 } 4921 4922 public ComponentName getComponent() { 4923 return mTargetComponent; 4924 } 4925 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 4939 public SleepTokenImpl(String tag, int displayId) { 4940 mTag = tag; 4941 mDisplayId = displayId; 4942 mAcquireTime = SystemClock.uptimeMillis(); 4943 } 4944 4945 @Override 4946 public void release() { 4947 synchronized (mService) { 4948 removeSleepTokenLocked(this); 4949 } 4950 } 4951 4952 @Override 4953 public String toString() { 4954 return "{\"" + mTag + "\", display " + mDisplayId 4955 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}"; 4956 } 4957 } 4958 4959 } 4960