ActivityStackSupervisor.java revision 45784f13ef6e159cbfb6e167aacb535732dcb803
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 17package com.android.server.am; 18 19import android.Manifest; 20import android.annotation.UserIdInt; 21import android.app.Activity; 22import android.app.ActivityManager; 23import android.app.ActivityManager.RunningTaskInfo; 24import android.app.ActivityManager.StackId; 25import android.app.ActivityManager.StackInfo; 26import android.app.ActivityOptions; 27import android.app.AppGlobals; 28import android.app.AppOpsManager; 29import android.app.IActivityContainer; 30import android.app.IActivityContainerCallback; 31import android.app.IActivityManager; 32import android.app.IActivityManager.WaitResult; 33import android.app.ProfilerInfo; 34import android.app.ResultInfo; 35import android.app.StatusBarManager; 36import android.app.admin.IDevicePolicyManager; 37import android.content.ComponentName; 38import android.content.Context; 39import android.content.IIntentSender; 40import android.content.Intent; 41import android.content.pm.ActivityInfo; 42import android.content.pm.ApplicationInfo; 43import android.content.pm.PackageInfo; 44import android.content.pm.PackageManager; 45import android.content.pm.ResolveInfo; 46import android.content.pm.UserInfo; 47import android.content.res.Configuration; 48import android.graphics.Rect; 49import android.hardware.display.DisplayManager; 50import android.hardware.display.DisplayManager.DisplayListener; 51import android.hardware.display.DisplayManagerGlobal; 52import android.hardware.display.VirtualDisplay; 53import android.hardware.input.InputManager; 54import android.hardware.input.InputManagerInternal; 55import android.os.Binder; 56import android.os.Bundle; 57import android.os.Debug; 58import android.os.Handler; 59import android.os.IBinder; 60import android.os.Looper; 61import android.os.Message; 62import android.os.ParcelFileDescriptor; 63import android.os.PowerManager; 64import android.os.Process; 65import android.os.RemoteException; 66import android.os.ServiceManager; 67import android.os.SystemClock; 68import android.os.Trace; 69import android.os.TransactionTooLargeException; 70import android.os.UserHandle; 71import android.os.UserManager; 72import android.os.WorkSource; 73import android.provider.MediaStore; 74import android.provider.Settings; 75import android.provider.Settings.SettingNotFoundException; 76import android.service.voice.IVoiceInteractionSession; 77import android.util.ArrayMap; 78import android.util.ArraySet; 79import android.util.EventLog; 80import android.util.Slog; 81import android.util.SparseArray; 82import android.util.SparseIntArray; 83import android.view.Display; 84import android.view.DisplayInfo; 85import android.view.InputEvent; 86import android.view.Surface; 87 88import com.android.internal.content.ReferrerIntent; 89import com.android.internal.os.TransferPipe; 90import com.android.internal.statusbar.IStatusBarService; 91import com.android.internal.util.ArrayUtils; 92import com.android.internal.widget.LockPatternUtils; 93import com.android.server.LocalServices; 94import com.android.server.am.ActivityStack.ActivityState; 95import com.android.server.wm.WindowManagerService; 96 97import java.io.FileDescriptor; 98import java.io.IOException; 99import java.io.PrintWriter; 100import java.util.ArrayList; 101import java.util.Arrays; 102import java.util.Collections; 103import java.util.List; 104import java.util.Objects; 105import java.util.Set; 106 107import static android.Manifest.permission.START_ANY_ACTIVITY; 108import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 109import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; 110import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; 111import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; 112import static android.app.ActivityManager.RESIZE_MODE_FORCED; 113import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; 114import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 115import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; 116import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID; 117import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 118import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 119import static android.app.ActivityManager.StackId.HOME_STACK_ID; 120import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 121import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID; 122import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 123import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 124import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 125import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; 126import static android.content.pm.PackageManager.PERMISSION_GRANTED; 127import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS; 130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE; 131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN; 132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; 133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE; 134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; 136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; 138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND; 141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS; 142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE; 143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; 144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE; 145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; 147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES; 149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; 151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; 152import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 153import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 154import static com.android.server.am.ActivityManagerService.ANIMATE; 155import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 156import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG; 157import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG; 158import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; 159import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; 160import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; 161import static com.android.server.am.ActivityStack.ActivityState.DESTROYED; 162import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; 163import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING; 164import static com.android.server.am.ActivityStack.ActivityState.PAUSED; 165import static com.android.server.am.ActivityStack.ActivityState.PAUSING; 166import static com.android.server.am.ActivityStack.ActivityState.RESUMED; 167import static com.android.server.am.ActivityStack.ActivityState.STOPPED; 168import static com.android.server.am.ActivityStack.ActivityState.STOPPING; 169import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING; 170import static com.android.server.am.ActivityStack.STACK_INVISIBLE; 171import static com.android.server.am.ActivityStack.STACK_VISIBLE; 172import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; 173import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; 174import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 175import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; 176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; 177import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS; 178 179public final class ActivityStackSupervisor implements DisplayListener { 180 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; 181 private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS; 182 private static final String TAG_IDLE = TAG + POSTFIX_IDLE; 183 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; 184 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; 185 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 186 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 187 private static final String TAG_STACK = TAG + POSTFIX_STACK; 188 private static final String TAG_STATES = TAG + POSTFIX_STATES; 189 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 190 static final String TAG_TASKS = TAG + POSTFIX_TASKS; 191 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND; 192 193 /** How long we wait until giving up on the last activity telling us it is idle. */ 194 static final int IDLE_TIMEOUT = 10 * 1000; 195 196 /** How long we can hold the sleep wake lock before giving up. */ 197 static final int SLEEP_TIMEOUT = 5 * 1000; 198 199 // How long we can hold the launch wake lock before giving up. 200 static final int LAUNCH_TIMEOUT = 10 * 1000; 201 202 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 203 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 204 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 205 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 206 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; 207 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; 208 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; 209 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; 210 static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8; 211 static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9; 212 static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10; 213 static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11; 214 static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12; 215 static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13; 216 static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14; 217 static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15; 218 219 private static final String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; 220 221 private static final String LOCK_TASK_TAG = "Lock-to-App"; 222 223 // Used to indicate if an object (e.g. stack) that we are trying to get 224 // should be created if it doesn't exist already. 225 static final boolean CREATE_IF_NEEDED = true; 226 227 // Used to indicate that windows of activities should be preserved during the resize. 228 static final boolean PRESERVE_WINDOWS = true; 229 230 // Used to indicate if an object (e.g. task) should be moved/created 231 // at the top of its container (e.g. stack). 232 static final boolean ON_TOP = true; 233 234 // Used to indicate that an objects (e.g. task) removal from its container 235 // (e.g. stack) is due to it moving to another container. 236 static final boolean MOVING = true; 237 238 // Force the focus to change to the stack we are moving a task to.. 239 static final boolean FORCE_FOCUS = true; 240 241 // Restore task from the saved recents if it can't be found in any live stack. 242 static final boolean RESTORE_FROM_RECENTS = true; 243 244 // Don't execute any calls to resume. 245 static final boolean DEFER_RESUME = true; 246 247 // Activity actions an app cannot start if it uses a permission which is not granted. 248 private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION = 249 new ArrayMap<>(); 250 251 static { 252 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, 253 Manifest.permission.CAMERA); 254 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, 255 Manifest.permission.CAMERA); 256 ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, 257 Manifest.permission.CALL_PHONE); 258 } 259 260 /** Action restriction: launching the activity is not restricted. */ 261 private static final int ACTIVITY_RESTRICTION_NONE = 0; 262 /** Action restriction: launching the activity is restricted by a permission. */ 263 private static final int ACTIVITY_RESTRICTION_PERMISSION = 1; 264 /** Action restriction: launching the activity is restricted by an app op. */ 265 private static final int ACTIVITY_RESTRICTION_APPOP = 2; 266 267 // The height/width divide used when fitting a task within a bounds with method 268 // {@link #fitWithinBounds}. 269 // We always want the task to to be visible in the bounds without affecting its size when 270 // fitting. To make sure this is the case, we don't adjust the task left or top side pass 271 // the input bounds right or bottom side minus the width or height divided by this value. 272 private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3; 273 274 /** Status Bar Service **/ 275 private IBinder mToken = new Binder(); 276 private IStatusBarService mStatusBarService; 277 private IDevicePolicyManager mDevicePolicyManager; 278 279 // For debugging to make sure the caller when acquiring/releasing our 280 // wake lock is the system process. 281 static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 282 /** The number of distinct task ids that can be assigned to the tasks of a single user */ 283 private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE; 284 285 final ActivityManagerService mService; 286 287 private RecentTasks mRecentTasks; 288 289 final ActivityStackSupervisorHandler mHandler; 290 291 /** Short cut */ 292 WindowManagerService mWindowManager; 293 DisplayManager mDisplayManager; 294 295 /** Counter for next free stack ID to use for dynamic activity stacks. */ 296 private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID; 297 298 /** 299 * Maps the task identifier that activities are currently being started in to the userId of the 300 * task. Each time a new task is created, the entry for the userId of the task is incremented 301 */ 302 private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20); 303 304 /** The current user */ 305 int mCurrentUser; 306 307 /** The stack containing the launcher app. Assumed to always be attached to 308 * Display.DEFAULT_DISPLAY. */ 309 ActivityStack mHomeStack; 310 311 /** The stack currently receiving input or launching the next activity. */ 312 ActivityStack mFocusedStack; 313 314 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 315 * been resumed. If stacks are changing position this will hold the old stack until the new 316 * stack becomes resumed after which it will be set to mFocusedStack. */ 317 private ActivityStack mLastFocusedStack; 318 319 /** List of activities that are waiting for a new activity to become visible before completing 320 * whatever operation they are supposed to do. */ 321 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>(); 322 323 /** List of processes waiting to find out about the next visible activity. */ 324 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>(); 325 326 /** List of processes waiting to find out about the next launched activity. */ 327 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>(); 328 329 /** List of activities that are ready to be stopped, but waiting for the next activity to 330 * settle down before doing so. */ 331 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>(); 332 333 /** List of activities that are ready to be finished, but waiting for the previous activity to 334 * settle down before doing so. It contains ActivityRecord objects. */ 335 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>(); 336 337 /** List of activities that are in the process of going to sleep. */ 338 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>(); 339 340 /** List of activities whose multi-window mode changed that we need to report to the 341 * application */ 342 final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>(); 343 344 /** List of activities whose picture-in-picture mode changed that we need to report to the 345 * application */ 346 final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>(); 347 348 /** Used on user changes */ 349 final ArrayList<UserState> mStartingUsers = new ArrayList<>(); 350 351 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 352 * is being brought in front of us. */ 353 boolean mUserLeaving = false; 354 355 /** Set when we have taken too long waiting to go to sleep. */ 356 boolean mSleepTimeout = false; 357 358 /** 359 * We don't want to allow the device to go to sleep while in the process 360 * of launching an activity. This is primarily to allow alarm intent 361 * receivers to launch an activity and get that to run before the device 362 * goes back to sleep. 363 */ 364 PowerManager.WakeLock mLaunchingActivity; 365 366 /** 367 * Set when the system is going to sleep, until we have 368 * successfully paused the current activity and released our wake lock. 369 * At that point the system is allowed to actually sleep. 370 */ 371 PowerManager.WakeLock mGoingToSleep; 372 373 /** Stack id of the front stack when user switched, indexed by userId. */ 374 SparseIntArray mUserStackInFront = new SparseIntArray(2); 375 376 // TODO: Add listener for removal of references. 377 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */ 378 private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>(); 379 380 /** Mapping from displayId to display current state */ 381 private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>(); 382 383 InputManagerInternal mInputManagerInternal; 384 385 /** The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks 386 * may be finished until there is only one entry left. If this is empty the system is not 387 * in lockTask mode. */ 388 ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>(); 389 /** Store the current lock task mode. Possible values: 390 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, 391 * {@link ActivityManager#LOCK_TASK_MODE_PINNED} 392 */ 393 private int mLockTaskModeState; 394 /** 395 * Notifies the user when entering/exiting lock-task. 396 */ 397 private LockTaskNotify mLockTaskNotify; 398 399 /** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */ 400 boolean inResumeTopActivity; 401 402 // temp. rects used during resize calculation so we don't need to create a new object each time. 403 private final Rect tempRect = new Rect(); 404 private final Rect tempRect2 = new Rect(); 405 406 private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>(); 407 private final SparseArray<Rect> mTmpBounds = new SparseArray<>(); 408 private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>(); 409 410 // The default minimal size that will be used if the activity doesn't specify its minimal size. 411 // It will be calculated when the default display gets added. 412 int mDefaultMinSizeOfResizeableTask = -1; 413 414 // Whether tasks have moved and we need to rank the tasks before next OOM scoring 415 private boolean mTaskLayersChanged = true; 416 417 final ActivityMetricsLogger mActivityMetricsLogger; 418 419 private final ResizeDockedStackTimeout mResizeDockedStackTimeout; 420 421 static class FindTaskResult { 422 ActivityRecord r; 423 boolean matchedByRootAffinity; 424 } 425 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); 426 427 /** 428 * Used to keep track whether app visibilities got changed since the last pause. Useful to 429 * determine whether to invoke the task stack change listener after pausing. 430 */ 431 boolean mAppVisibilitiesChangedSinceLastPause; 432 433 /** 434 * Set of tasks that are in resizing mode during an app transition to fill the "void". 435 */ 436 private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>(); 437 438 439 /** 440 * If set to {@code false} all calls to resize the docked stack {@link #resizeDockedStackLocked} 441 * will be ignored. Useful for the case where the caller is handling resizing of other stack and 442 * moving tasks around and doesn't want dock stack to be resized due to an automatic trigger 443 * like the docked stack going empty. 444 */ 445 private boolean mAllowDockedStackResize = true; 446 447 /** 448 * Is dock currently minimized. 449 */ 450 boolean mIsDockMinimized; 451 452 /** 453 * Description of a request to start a new activity, which has been held 454 * due to app switches being disabled. 455 */ 456 static class PendingActivityLaunch { 457 final ActivityRecord r; 458 final ActivityRecord sourceRecord; 459 final int startFlags; 460 final ActivityStack stack; 461 final ProcessRecord callerApp; 462 463 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 464 int _startFlags, ActivityStack _stack, ProcessRecord _callerApp) { 465 r = _r; 466 sourceRecord = _sourceRecord; 467 startFlags = _startFlags; 468 stack = _stack; 469 callerApp = _callerApp; 470 } 471 472 void sendErrorResult(String message) { 473 try { 474 if (callerApp.thread != null) { 475 callerApp.thread.scheduleCrash(message); 476 } 477 } catch (RemoteException e) { 478 Slog.e(TAG, "Exception scheduling crash of failed " 479 + "activity launcher sourceRecord=" + sourceRecord, e); 480 } 481 } 482 } 483 484 public ActivityStackSupervisor(ActivityManagerService service) { 485 mService = service; 486 mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper()); 487 mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext); 488 mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler); 489 } 490 491 void setRecentTasks(RecentTasks recentTasks) { 492 mRecentTasks = recentTasks; 493 } 494 495 /** 496 * At the time when the constructor runs, the power manager has not yet been 497 * initialized. So we initialize our wakelocks afterwards. 498 */ 499 void initPowerManagement() { 500 PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); 501 mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 502 mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*launch*"); 503 mLaunchingActivity.setReferenceCounted(false); 504 } 505 506 // This function returns a IStatusBarService. The value is from ServiceManager. 507 // getService and is cached. 508 private IStatusBarService getStatusBarService() { 509 synchronized (mService) { 510 if (mStatusBarService == null) { 511 mStatusBarService = IStatusBarService.Stub.asInterface( 512 ServiceManager.checkService(Context.STATUS_BAR_SERVICE)); 513 if (mStatusBarService == null) { 514 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE"); 515 } 516 } 517 return mStatusBarService; 518 } 519 } 520 521 private IDevicePolicyManager getDevicePolicyManager() { 522 synchronized (mService) { 523 if (mDevicePolicyManager == null) { 524 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 525 ServiceManager.checkService(Context.DEVICE_POLICY_SERVICE)); 526 if (mDevicePolicyManager == null) { 527 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE"); 528 } 529 } 530 return mDevicePolicyManager; 531 } 532 } 533 534 void setWindowManager(WindowManagerService wm) { 535 synchronized (mService) { 536 mWindowManager = wm; 537 538 mDisplayManager = 539 (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); 540 mDisplayManager.registerDisplayListener(this, null); 541 542 Display[] displays = mDisplayManager.getDisplays(); 543 for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { 544 final int displayId = displays[displayNdx].getDisplayId(); 545 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 546 if (activityDisplay.mDisplay == null) { 547 throw new IllegalStateException("Default Display does not exist"); 548 } 549 mActivityDisplays.put(displayId, activityDisplay); 550 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 551 } 552 553 mHomeStack = mFocusedStack = mLastFocusedStack = 554 getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP); 555 556 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 557 } 558 } 559 560 void notifyActivityDrawnForKeyguard() { 561 if (DEBUG_LOCKSCREEN) mService.logLockScreen(""); 562 mWindowManager.notifyActivityDrawnForKeyguard(); 563 } 564 565 ActivityStack getFocusedStack() { 566 return mFocusedStack; 567 } 568 569 ActivityStack getLastStack() { 570 return mLastFocusedStack; 571 } 572 573 boolean isFocusedStack(ActivityStack stack) { 574 if (stack == null) { 575 return false; 576 } 577 578 final ActivityRecord parent = stack.mActivityContainer.mParentActivity; 579 if (parent != null) { 580 stack = parent.task.stack; 581 } 582 return stack == mFocusedStack; 583 } 584 585 /** The top most stack. */ 586 boolean isFrontStack(ActivityStack stack) { 587 if (stack == null) { 588 return false; 589 } 590 591 final ActivityRecord parent = stack.mActivityContainer.mParentActivity; 592 if (parent != null) { 593 stack = parent.task.stack; 594 } 595 return stack == mHomeStack.mStacks.get((mHomeStack.mStacks.size() - 1)); 596 } 597 598 /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */ 599 void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) { 600 if (!focusCandidate.isFocusable()) { 601 // The focus candidate isn't focusable. Move focus to the top stack that is focusable. 602 focusCandidate = focusCandidate.getNextFocusableStackLocked(); 603 } 604 605 if (focusCandidate != mFocusedStack) { 606 mLastFocusedStack = mFocusedStack; 607 mFocusedStack = focusCandidate; 608 609 EventLogTags.writeAmFocusedStack( 610 mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(), 611 mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason); 612 } 613 614 final ActivityRecord r = topRunningActivityLocked(); 615 if (!mService.mDoingSetFocusedActivity && mService.mFocusedActivity != r) { 616 // The focus activity should always be the top activity in the focused stack. 617 // There will be chaos and anarchy if it isn't... 618 mService.setFocusedActivityLocked(r, reason + " setFocusStack"); 619 } 620 621 if (mService.mBooting || !mService.mBooted) { 622 if (r != null && r.idle) { 623 checkFinishBootingLocked(); 624 } 625 } 626 } 627 628 void moveHomeStackToFront(String reason) { 629 mHomeStack.moveToFront(reason); 630 } 631 632 /** Returns true if the focus activity was adjusted to the home stack top activity. */ 633 boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) { 634 if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { 635 mWindowManager.showRecentApps(false /* fromHome */); 636 return false; 637 } 638 639 mHomeStack.moveHomeStackTaskToTop(homeStackTaskType); 640 641 final ActivityRecord top = getHomeActivity(); 642 if (top == null) { 643 return false; 644 } 645 mService.setFocusedActivityLocked(top, reason); 646 return true; 647 } 648 649 boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) { 650 if (!mService.mBooting && !mService.mBooted) { 651 // Not ready yet! 652 return false; 653 } 654 655 if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) { 656 mWindowManager.showRecentApps(false /* fromHome */); 657 return false; 658 } 659 660 if (prev != null) { 661 prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); 662 } 663 664 mHomeStack.moveHomeStackTaskToTop(homeStackTaskType); 665 ActivityRecord r = getHomeActivity(); 666 final String myReason = reason + " resumeHomeStackTask"; 667 668 // Only resume home activity if isn't finishing. 669 if (r != null && !r.finishing) { 670 mService.setFocusedActivityLocked(r, myReason); 671 return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null); 672 } 673 return mService.startHomeActivityLocked(mCurrentUser, myReason); 674 } 675 676 TaskRecord anyTaskForIdLocked(int id) { 677 return anyTaskForIdLocked(id, RESTORE_FROM_RECENTS, INVALID_STACK_ID); 678 } 679 680 /** 681 * Returns a {@link TaskRecord} for the input id if available. Null otherwise. 682 * @param id Id of the task we would like returned. 683 * @param restoreFromRecents If the id was not in the active list, but was found in recents, 684 * restore the task from recents to the active list. 685 * @param stackId The stack to restore the task to (default launch stack will be used if 686 * stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}). 687 */ 688 TaskRecord anyTaskForIdLocked(int id, boolean restoreFromRecents, int stackId) { 689 int numDisplays = mActivityDisplays.size(); 690 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 691 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 692 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 693 ActivityStack stack = stacks.get(stackNdx); 694 TaskRecord task = stack.taskForIdLocked(id); 695 if (task != null) { 696 return task; 697 } 698 } 699 } 700 701 // Don't give up! Look in recents. 702 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents"); 703 TaskRecord task = mRecentTasks.taskForIdLocked(id); 704 if (task == null) { 705 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents"); 706 return null; 707 } 708 709 if (!restoreFromRecents) { 710 return task; 711 } 712 713 if (!restoreRecentTaskLocked(task, stackId)) { 714 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, 715 "Couldn't restore task id=" + id + " found in recents"); 716 return null; 717 } 718 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents"); 719 return task; 720 } 721 722 ActivityRecord isInAnyStackLocked(IBinder token) { 723 int numDisplays = mActivityDisplays.size(); 724 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 725 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 726 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 727 final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token); 728 if (r != null) { 729 return r; 730 } 731 } 732 } 733 return null; 734 } 735 736 /** 737 * TODO: Handle freefom mode. 738 * @return true when credential confirmation is needed for the user and there is any 739 * activity started by the user in any visible stack. 740 */ 741 boolean isUserLockedProfile(@UserIdInt int userId) { 742 if (!mService.mUserController.shouldConfirmCredentials(userId)) { 743 return false; 744 } 745 final ActivityStack fullScreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID); 746 final ActivityStack dockedStack = getStack(DOCKED_STACK_ID); 747 final ActivityStack[] activityStacks = new ActivityStack[] {fullScreenStack, dockedStack}; 748 for (final ActivityStack activityStack : activityStacks) { 749 if (activityStack == null) { 750 continue; 751 } 752 if (activityStack.topRunningActivityLocked() == null) { 753 continue; 754 } 755 if (activityStack.getStackVisibilityLocked(null) == STACK_INVISIBLE) { 756 continue; 757 } 758 if (activityStack.isDockedStack() && mIsDockMinimized) { 759 continue; 760 } 761 final TaskRecord topTask = activityStack.topTask(); 762 if (topTask == null) { 763 continue; 764 } 765 // To handle the case that work app is in the task but just is not the top one. 766 for (int i = topTask.mActivities.size() - 1; i >= 0; i--) { 767 final ActivityRecord activityRecord = topTask.mActivities.get(i); 768 if (activityRecord.userId == userId) { 769 return true; 770 } 771 } 772 } 773 return false; 774 } 775 776 void setNextTaskIdForUserLocked(int taskId, int userId) { 777 final int currentTaskId = mCurTaskIdForUser.get(userId, -1); 778 if (taskId > currentTaskId) { 779 mCurTaskIdForUser.put(userId, taskId); 780 } 781 } 782 783 int getNextTaskIdForUserLocked(int userId) { 784 final int currentTaskId = mCurTaskIdForUser.get(userId, userId * MAX_TASK_IDS_PER_USER); 785 // for a userId u, a taskId can only be in the range 786 // [u*MAX_TASK_IDS_PER_USER, (u+1)*MAX_TASK_IDS_PER_USER-1], so if MAX_TASK_IDS_PER_USER 787 // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on. 788 int candidateTaskId = currentTaskId; 789 while (mRecentTasks.taskIdTakenForUserLocked(candidateTaskId, userId) 790 || anyTaskForIdLocked(candidateTaskId, !RESTORE_FROM_RECENTS, 791 INVALID_STACK_ID) != null) { 792 candidateTaskId++; 793 if (candidateTaskId == (userId + 1) * MAX_TASK_IDS_PER_USER) { 794 // Wrap around as there will be smaller task ids that are available now. 795 candidateTaskId -= MAX_TASK_IDS_PER_USER; 796 } 797 if (candidateTaskId == currentTaskId) { 798 // Something wrong! 799 // All MAX_TASK_IDS_PER_USER task ids are taken up by running tasks for this user 800 throw new IllegalStateException("Cannot get an available task id." 801 + " Reached limit of " + MAX_TASK_IDS_PER_USER 802 + " running tasks per user."); 803 } 804 } 805 mCurTaskIdForUser.put(userId, candidateTaskId); 806 return candidateTaskId; 807 } 808 809 ActivityRecord resumedAppLocked() { 810 ActivityStack stack = mFocusedStack; 811 if (stack == null) { 812 return null; 813 } 814 ActivityRecord resumedActivity = stack.mResumedActivity; 815 if (resumedActivity == null || resumedActivity.app == null) { 816 resumedActivity = stack.mPausingActivity; 817 if (resumedActivity == null || resumedActivity.app == null) { 818 resumedActivity = stack.topRunningActivityLocked(); 819 } 820 } 821 return resumedActivity; 822 } 823 824 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { 825 final String processName = app.processName; 826 boolean didSomething = false; 827 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 828 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 829 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 830 final ActivityStack stack = stacks.get(stackNdx); 831 if (!isFocusedStack(stack)) { 832 continue; 833 } 834 ActivityRecord hr = stack.topRunningActivityLocked(); 835 if (hr != null) { 836 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 837 && processName.equals(hr.processName)) { 838 try { 839 if (realStartActivityLocked(hr, app, true, true)) { 840 didSomething = true; 841 } 842 } catch (RemoteException e) { 843 Slog.w(TAG, "Exception in new application when starting activity " 844 + hr.intent.getComponent().flattenToShortString(), e); 845 throw e; 846 } 847 } 848 } 849 } 850 } 851 if (!didSomething) { 852 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 853 } 854 return didSomething; 855 } 856 857 boolean allResumedActivitiesIdle() { 858 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 859 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 860 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 861 final ActivityStack stack = stacks.get(stackNdx); 862 if (!isFocusedStack(stack) || stack.numActivities() == 0) { 863 continue; 864 } 865 final ActivityRecord resumedActivity = stack.mResumedActivity; 866 if (resumedActivity == null || !resumedActivity.idle) { 867 if (DEBUG_STATES) Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack=" 868 + stack.mStackId + " " + resumedActivity + " not idle"); 869 return false; 870 } 871 } 872 } 873 return true; 874 } 875 876 boolean allResumedActivitiesComplete() { 877 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 878 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 879 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 880 final ActivityStack stack = stacks.get(stackNdx); 881 if (isFocusedStack(stack)) { 882 final ActivityRecord r = stack.mResumedActivity; 883 if (r != null && r.state != RESUMED) { 884 return false; 885 } 886 } 887 } 888 } 889 // TODO: Not sure if this should check if all Paused are complete too. 890 if (DEBUG_STACK) Slog.d(TAG_STACK, 891 "allResumedActivitiesComplete: mLastFocusedStack changing from=" + 892 mLastFocusedStack + " to=" + mFocusedStack); 893 mLastFocusedStack = mFocusedStack; 894 return true; 895 } 896 897 boolean allResumedActivitiesVisible() { 898 boolean foundResumed = false; 899 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 900 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 901 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 902 final ActivityStack stack = stacks.get(stackNdx); 903 final ActivityRecord r = stack.mResumedActivity; 904 if (r != null) { 905 if (!r.nowVisible || mWaitingVisibleActivities.contains(r)) { 906 return false; 907 } 908 foundResumed = true; 909 } 910 } 911 } 912 return foundResumed; 913 } 914 915 /** 916 * Pause all activities in either all of the stacks or just the back stacks. 917 * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). 918 * @return true if any activity was paused as a result of this call. 919 */ 920 boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) { 921 boolean someActivityPaused = false; 922 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 923 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 924 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 925 final ActivityStack stack = stacks.get(stackNdx); 926 if (!isFocusedStack(stack) && stack.mResumedActivity != null) { 927 if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack + 928 " mResumedActivity=" + stack.mResumedActivity); 929 someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, 930 dontWait); 931 } 932 } 933 } 934 return someActivityPaused; 935 } 936 937 boolean allPausedActivitiesComplete() { 938 boolean pausing = true; 939 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 940 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 941 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 942 final ActivityStack stack = stacks.get(stackNdx); 943 final ActivityRecord r = stack.mPausingActivity; 944 if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) { 945 if (DEBUG_STATES) { 946 Slog.d(TAG_STATES, 947 "allPausedActivitiesComplete: r=" + r + " state=" + r.state); 948 pausing = false; 949 } else { 950 return false; 951 } 952 } 953 } 954 } 955 return pausing; 956 } 957 958 void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping, 959 boolean resuming, boolean dontWait) { 960 // TODO: Put all stacks in supervisor and iterate through them instead. 961 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 962 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 963 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 964 final ActivityStack stack = stacks.get(stackNdx); 965 if (stack.mResumedActivity != null && 966 stack.mActivityContainer.mParentActivity == parent) { 967 stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait); 968 } 969 } 970 } 971 } 972 973 void cancelInitializingActivities() { 974 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 975 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 976 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 977 stacks.get(stackNdx).cancelInitializingActivities(); 978 } 979 } 980 } 981 982 void reportActivityVisibleLocked(ActivityRecord r) { 983 sendWaitingVisibleReportLocked(r); 984 } 985 986 void sendWaitingVisibleReportLocked(ActivityRecord r) { 987 boolean changed = false; 988 for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { 989 WaitResult w = mWaitingActivityVisible.get(i); 990 if (w.who == null) { 991 changed = true; 992 w.timeout = false; 993 if (r != null) { 994 w.who = new ComponentName(r.info.packageName, r.info.name); 995 } 996 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 997 w.thisTime = w.totalTime; 998 } 999 } 1000 if (changed) { 1001 mService.notifyAll(); 1002 } 1003 } 1004 1005 void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, 1006 long thisTime, long totalTime) { 1007 boolean changed = false; 1008 for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) { 1009 WaitResult w = mWaitingActivityLaunched.remove(i); 1010 if (w.who == null) { 1011 changed = true; 1012 w.timeout = timeout; 1013 if (r != null) { 1014 w.who = new ComponentName(r.info.packageName, r.info.name); 1015 } 1016 w.thisTime = thisTime; 1017 w.totalTime = totalTime; 1018 } 1019 } 1020 if (changed) { 1021 mService.notifyAll(); 1022 } 1023 } 1024 1025 ActivityRecord topRunningActivityLocked() { 1026 final ActivityStack focusedStack = mFocusedStack; 1027 ActivityRecord r = focusedStack.topRunningActivityLocked(); 1028 if (r != null) { 1029 return r; 1030 } 1031 1032 // Return to the home stack. 1033 final ArrayList<ActivityStack> stacks = mHomeStack.mStacks; 1034 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1035 final ActivityStack stack = stacks.get(stackNdx); 1036 if (stack != focusedStack && isFrontStack(stack) && stack.isFocusable()) { 1037 r = stack.topRunningActivityLocked(); 1038 if (r != null) { 1039 return r; 1040 } 1041 } 1042 } 1043 return null; 1044 } 1045 1046 void getTasksLocked(int maxNum, List<RunningTaskInfo> list, int callingUid, boolean allowed) { 1047 // Gather all of the running tasks for each stack into runningTaskLists. 1048 ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = 1049 new ArrayList<ArrayList<RunningTaskInfo>>(); 1050 final int numDisplays = mActivityDisplays.size(); 1051 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 1052 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1053 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1054 final ActivityStack stack = stacks.get(stackNdx); 1055 ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<>(); 1056 runningTaskLists.add(stackTaskList); 1057 stack.getTasksLocked(stackTaskList, callingUid, allowed); 1058 } 1059 } 1060 1061 // The lists are already sorted from most recent to oldest. Just pull the most recent off 1062 // each list and add it to list. Stop when all lists are empty or maxNum reached. 1063 while (maxNum > 0) { 1064 long mostRecentActiveTime = Long.MIN_VALUE; 1065 ArrayList<RunningTaskInfo> selectedStackList = null; 1066 final int numTaskLists = runningTaskLists.size(); 1067 for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) { 1068 ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx); 1069 if (!stackTaskList.isEmpty()) { 1070 final long lastActiveTime = stackTaskList.get(0).lastActiveTime; 1071 if (lastActiveTime > mostRecentActiveTime) { 1072 mostRecentActiveTime = lastActiveTime; 1073 selectedStackList = stackTaskList; 1074 } 1075 } 1076 } 1077 if (selectedStackList != null) { 1078 list.add(selectedStackList.remove(0)); 1079 --maxNum; 1080 } else { 1081 break; 1082 } 1083 } 1084 } 1085 1086 ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags, 1087 ProfilerInfo profilerInfo) { 1088 final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null; 1089 if (aInfo != null) { 1090 // Store the found target back into the intent, because now that 1091 // we have it we never want to do this again. For example, if the 1092 // user navigates back to this point in the history, we should 1093 // always restart the exact same activity. 1094 intent.setComponent(new ComponentName( 1095 aInfo.applicationInfo.packageName, aInfo.name)); 1096 1097 // Don't debug things in the system process 1098 if (!aInfo.processName.equals("system")) { 1099 if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) { 1100 final ProcessRecord app = mService.getProcessRecordLocked( 1101 aInfo.processName, aInfo.applicationInfo.uid, true); 1102 // If the process already started, we can't wait for debugger and shouldn't 1103 // modify the debug settings. 1104 // For non-persistent debug, normally we set the debug app here, and restores 1105 // to the original at attachApplication time. However, if the app process 1106 // already exists, we won't get another attachApplication, and the debug setting 1107 // never gets restored. Furthermore, if we get two such calls back-to-back, 1108 // both mOrigDebugApp and mDebugApp will become the same app, and it won't be 1109 // cleared even if we get attachApplication after the app process is killed. 1110 if (app == null || app.thread == null) { 1111 mService.setDebugApp(aInfo.processName, true, false); 1112 } else { 1113 Slog.w(TAG, "Ignoring waitForDebugger because process already exists"); 1114 } 1115 } 1116 1117 if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) { 1118 mService.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName); 1119 } 1120 1121 if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) { 1122 mService.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName); 1123 } 1124 1125 if (profilerInfo != null) { 1126 mService.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo); 1127 } 1128 } 1129 } 1130 return aInfo; 1131 } 1132 1133 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) { 1134 return resolveIntent(intent, resolvedType, userId, 0); 1135 } 1136 1137 ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) { 1138 try { 1139 return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType, 1140 PackageManager.MATCH_DEFAULT_ONLY | flags 1141 | ActivityManagerService.STOCK_PM_FLAGS, userId); 1142 } catch (RemoteException e) { 1143 } 1144 return null; 1145 } 1146 1147 ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, 1148 ProfilerInfo profilerInfo, int userId) { 1149 final ResolveInfo rInfo = resolveIntent(intent, resolvedType, userId); 1150 return resolveActivity(intent, rInfo, startFlags, profilerInfo); 1151 } 1152 1153 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, 1154 boolean andResume, boolean checkConfig) throws RemoteException { 1155 1156 if (!allPausedActivitiesComplete()) { 1157 // While there are activities pausing we skipping starting any new activities until 1158 // pauses are complete. NOTE: that we also do this for activities that are starting in 1159 // the paused state because they will first be resumed then paused on the client side. 1160 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, 1161 "realStartActivityLocked: Skipping start of r=" + r 1162 + " some activities pausing..."); 1163 return false; 1164 } 1165 1166 if (andResume) { 1167 r.startFreezingScreenLocked(app, 0); 1168 mWindowManager.setAppVisibility(r.appToken, true); 1169 1170 // schedule launch ticks to collect information about slow apps. 1171 r.startLaunchTickingLocked(); 1172 } 1173 1174 // Have the window manager re-evaluate the orientation of 1175 // the screen based on the new activity order. Note that 1176 // as a result of this, it can call back into the activity 1177 // manager with a new orientation. We don't care about that, 1178 // because the activity is not currently running so we are 1179 // just restarting it anyway. 1180 if (checkConfig) { 1181 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1182 mService.mConfiguration, 1183 r.mayFreezeScreenLocked(app) ? r.appToken : null); 1184 mService.updateConfigurationLocked(config, r, false); 1185 } 1186 1187 r.app = app; 1188 app.waitingToKill = null; 1189 r.launchCount++; 1190 r.lastLaunchTime = SystemClock.uptimeMillis(); 1191 1192 if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r); 1193 1194 int idx = app.activities.indexOf(r); 1195 if (idx < 0) { 1196 app.activities.add(r); 1197 } 1198 mService.updateLruProcessLocked(app, true, null); 1199 mService.updateOomAdjLocked(); 1200 1201 final TaskRecord task = r.task; 1202 if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || 1203 task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) { 1204 setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false); 1205 } 1206 1207 final ActivityStack stack = task.stack; 1208 try { 1209 if (app.thread == null) { 1210 throw new RemoteException(); 1211 } 1212 List<ResultInfo> results = null; 1213 List<ReferrerIntent> newIntents = null; 1214 if (andResume) { 1215 results = r.results; 1216 newIntents = r.newIntents; 1217 } 1218 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, 1219 "Launching: " + r + " icicle=" + r.icicle + " with results=" + results 1220 + " newIntents=" + newIntents + " andResume=" + andResume); 1221 if (andResume) { 1222 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 1223 r.userId, System.identityHashCode(r), 1224 task.taskId, r.shortComponentName); 1225 } 1226 if (r.isHomeActivity()) { 1227 // Home process is the root process of the task. 1228 mService.mHomeProcess = task.mActivities.get(0).app; 1229 } 1230 mService.notifyPackageUse(r.intent.getComponent().getPackageName(), 1231 PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY); 1232 r.sleeping = false; 1233 r.forceNewConfig = false; 1234 mService.showAskCompatModeDialogLocked(r); 1235 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo); 1236 ProfilerInfo profilerInfo = null; 1237 if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) { 1238 if (mService.mProfileProc == null || mService.mProfileProc == app) { 1239 mService.mProfileProc = app; 1240 final String profileFile = mService.mProfileFile; 1241 if (profileFile != null) { 1242 ParcelFileDescriptor profileFd = mService.mProfileFd; 1243 if (profileFd != null) { 1244 try { 1245 profileFd = profileFd.dup(); 1246 } catch (IOException e) { 1247 if (profileFd != null) { 1248 try { 1249 profileFd.close(); 1250 } catch (IOException o) { 1251 } 1252 profileFd = null; 1253 } 1254 } 1255 } 1256 1257 profilerInfo = new ProfilerInfo(profileFile, profileFd, 1258 mService.mSamplingInterval, mService.mAutoStopProfiler); 1259 } 1260 } 1261 } 1262 1263 if (andResume) { 1264 app.hasShownUi = true; 1265 app.pendingUiClean = true; 1266 } 1267 app.forceProcessStateUpTo(mService.mTopProcessState); 1268 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1269 System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), 1270 new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, 1271 task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, 1272 newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); 1273 1274 if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { 1275 // This may be a heavy-weight process! Note that the package 1276 // manager will ensure that only activity can run in the main 1277 // process of the .apk, which is the only thing that will be 1278 // considered heavy-weight. 1279 if (app.processName.equals(app.info.packageName)) { 1280 if (mService.mHeavyWeightProcess != null 1281 && mService.mHeavyWeightProcess != app) { 1282 Slog.w(TAG, "Starting new heavy weight process " + app 1283 + " when already running " 1284 + mService.mHeavyWeightProcess); 1285 } 1286 mService.mHeavyWeightProcess = app; 1287 Message msg = mService.mHandler.obtainMessage( 1288 ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG); 1289 msg.obj = r; 1290 mService.mHandler.sendMessage(msg); 1291 } 1292 } 1293 1294 } catch (RemoteException e) { 1295 if (r.launchFailed) { 1296 // This is the second time we failed -- finish activity 1297 // and give up. 1298 Slog.e(TAG, "Second failure launching " 1299 + r.intent.getComponent().flattenToShortString() 1300 + ", giving up", e); 1301 mService.appDiedLocked(app); 1302 stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, 1303 "2nd-crash", false); 1304 return false; 1305 } 1306 1307 // This is the first time we failed -- restart process and 1308 // retry. 1309 app.activities.remove(r); 1310 throw e; 1311 } 1312 1313 r.launchFailed = false; 1314 if (stack.updateLRUListLocked(r)) { 1315 Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list"); 1316 } 1317 1318 if (andResume) { 1319 // As part of the process of launching, ActivityThread also performs 1320 // a resume. 1321 stack.minimalResumeActivityLocked(r); 1322 } else { 1323 // This activity is not starting in the resumed state... which should look like we asked 1324 // it to pause+stop (but remain visible), and it has done so and reported back the 1325 // current icicle and other state. 1326 if (DEBUG_STATES) Slog.v(TAG_STATES, 1327 "Moving to PAUSED: " + r + " (starting in paused state)"); 1328 r.state = PAUSED; 1329 } 1330 1331 // Launch the new version setup screen if needed. We do this -after- 1332 // launching the initial activity (that is, home), so that it can have 1333 // a chance to initialize itself while in the background, making the 1334 // switch back to it faster and look better. 1335 if (isFocusedStack(stack)) { 1336 mService.startSetupActivityLocked(); 1337 } 1338 1339 // Update any services we are bound to that might care about whether 1340 // their client may have activities. 1341 if (r.app != null) { 1342 mService.mServices.updateServiceConnectionActivitiesLocked(r.app); 1343 } 1344 1345 return true; 1346 } 1347 1348 void startSpecificActivityLocked(ActivityRecord r, 1349 boolean andResume, boolean checkConfig) { 1350 // Is this activity's application already running? 1351 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1352 r.info.applicationInfo.uid, true); 1353 1354 r.task.stack.setLaunchTime(r); 1355 1356 if (app != null && app.thread != null) { 1357 try { 1358 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1359 || !"android".equals(r.info.packageName)) { 1360 // Don't add this if it is a platform component that is marked 1361 // to run in multiple processes, because this is actually 1362 // part of the framework so doesn't make sense to track as a 1363 // separate apk in the process. 1364 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, 1365 mService.mProcessStats); 1366 } 1367 realStartActivityLocked(r, app, andResume, checkConfig); 1368 return; 1369 } catch (RemoteException e) { 1370 Slog.w(TAG, "Exception when starting activity " 1371 + r.intent.getComponent().flattenToShortString(), e); 1372 } 1373 1374 // If a dead object exception was thrown -- fall through to 1375 // restart the application. 1376 } 1377 1378 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1379 "activity", r.intent.getComponent(), false, false, true); 1380 } 1381 1382 boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, 1383 String resultWho, int requestCode, int callingPid, int callingUid, 1384 String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp, 1385 ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options) { 1386 final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, 1387 callingUid); 1388 if (startAnyPerm == PERMISSION_GRANTED) { 1389 return true; 1390 } 1391 final int componentRestriction = getComponentRestrictionForCallingPackage( 1392 aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity); 1393 final int actionRestriction = getActionRestrictionForCallingPackage( 1394 intent.getAction(), callingPackage, callingPid, callingUid); 1395 if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION 1396 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1397 if (resultRecord != null) { 1398 resultStack.sendActivityResultLocked(-1, 1399 resultRecord, resultWho, requestCode, 1400 Activity.RESULT_CANCELED, null); 1401 } 1402 final String msg; 1403 if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1404 msg = "Permission Denial: starting " + intent.toString() 1405 + " from " + callerApp + " (pid=" + callingPid 1406 + ", uid=" + callingUid + ")" + " with revoked permission " 1407 + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); 1408 } else if (!aInfo.exported) { 1409 msg = "Permission Denial: starting " + intent.toString() 1410 + " from " + callerApp + " (pid=" + callingPid 1411 + ", uid=" + callingUid + ")" 1412 + " not exported from uid " + aInfo.applicationInfo.uid; 1413 } else { 1414 msg = "Permission Denial: starting " + intent.toString() 1415 + " from " + callerApp + " (pid=" + callingPid 1416 + ", uid=" + callingUid + ")" 1417 + " requires " + aInfo.permission; 1418 } 1419 Slog.w(TAG, msg); 1420 throw new SecurityException(msg); 1421 } 1422 1423 if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) { 1424 final String message = "Appop Denial: starting " + intent.toString() 1425 + " from " + callerApp + " (pid=" + callingPid 1426 + ", uid=" + callingUid + ")" 1427 + " requires " + AppOpsManager.permissionToOp( 1428 ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction())); 1429 Slog.w(TAG, message); 1430 return false; 1431 } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) { 1432 final String message = "Appop Denial: starting " + intent.toString() 1433 + " from " + callerApp + " (pid=" + callingPid 1434 + ", uid=" + callingUid + ")" 1435 + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission); 1436 Slog.w(TAG, message); 1437 return false; 1438 } 1439 if (options != null && options.getLaunchTaskId() != -1) { 1440 final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS, 1441 callingPid, callingUid); 1442 if (startInTaskPerm != PERMISSION_GRANTED) { 1443 final String msg = "Permission Denial: starting " + intent.toString() 1444 + " from " + callerApp + " (pid=" + callingPid 1445 + ", uid=" + callingUid + ") with launchTaskId=" 1446 + options.getLaunchTaskId(); 1447 Slog.w(TAG, msg); 1448 throw new SecurityException(msg); 1449 } 1450 } 1451 1452 return true; 1453 } 1454 1455 UserInfo getUserInfo(int userId) { 1456 final long identity = Binder.clearCallingIdentity(); 1457 try { 1458 return UserManager.get(mService.mContext).getUserInfo(userId); 1459 } finally { 1460 Binder.restoreCallingIdentity(identity); 1461 } 1462 } 1463 1464 private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, 1465 String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { 1466 if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, 1467 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) 1468 == PackageManager.PERMISSION_DENIED) { 1469 return ACTIVITY_RESTRICTION_PERMISSION; 1470 } 1471 1472 if (activityInfo.permission == null) { 1473 return ACTIVITY_RESTRICTION_NONE; 1474 } 1475 1476 final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); 1477 if (opCode == AppOpsManager.OP_NONE) { 1478 return ACTIVITY_RESTRICTION_NONE; 1479 } 1480 1481 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1482 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1483 if (!ignoreTargetSecurity) { 1484 return ACTIVITY_RESTRICTION_APPOP; 1485 } 1486 } 1487 1488 return ACTIVITY_RESTRICTION_NONE; 1489 } 1490 1491 private int getActionRestrictionForCallingPackage(String action, 1492 String callingPackage, int callingPid, int callingUid) { 1493 if (action == null) { 1494 return ACTIVITY_RESTRICTION_NONE; 1495 } 1496 1497 String permission = ACTION_TO_RUNTIME_PERMISSION.get(action); 1498 if (permission == null) { 1499 return ACTIVITY_RESTRICTION_NONE; 1500 } 1501 1502 final PackageInfo packageInfo; 1503 try { 1504 packageInfo = mService.mContext.getPackageManager() 1505 .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS); 1506 } catch (PackageManager.NameNotFoundException e) { 1507 Slog.i(TAG, "Cannot find package info for " + callingPackage); 1508 return ACTIVITY_RESTRICTION_NONE; 1509 } 1510 1511 if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) { 1512 return ACTIVITY_RESTRICTION_NONE; 1513 } 1514 1515 if (mService.checkPermission(permission, callingPid, callingUid) == 1516 PackageManager.PERMISSION_DENIED) { 1517 return ACTIVITY_RESTRICTION_PERMISSION; 1518 } 1519 1520 final int opCode = AppOpsManager.permissionToOpCode(permission); 1521 if (opCode == AppOpsManager.OP_NONE) { 1522 return ACTIVITY_RESTRICTION_NONE; 1523 } 1524 1525 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1526 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1527 return ACTIVITY_RESTRICTION_APPOP; 1528 } 1529 1530 return ACTIVITY_RESTRICTION_NONE; 1531 } 1532 1533 boolean moveActivityStackToFront(ActivityRecord r, String reason) { 1534 if (r == null) { 1535 // Not sure what you are trying to do, but it is not going to work... 1536 return false; 1537 } 1538 final TaskRecord task = r.task; 1539 if (task == null || task.stack == null) { 1540 Slog.w(TAG, "Can't move stack to front for r=" + r + " task=" + task); 1541 return false; 1542 } 1543 task.stack.moveToFront(reason, task); 1544 return true; 1545 } 1546 1547 void setLaunchSource(int uid) { 1548 mLaunchingActivity.setWorkSource(new WorkSource(uid)); 1549 } 1550 1551 void acquireLaunchWakelock() { 1552 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1553 throw new IllegalStateException("Calling must be system uid"); 1554 } 1555 mLaunchingActivity.acquire(); 1556 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1557 // To be safe, don't allow the wake lock to be held for too long. 1558 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1559 } 1560 } 1561 1562 /** 1563 * Called when the frontmost task is idle. 1564 * @return the state of mService.mBooting before this was called. 1565 */ 1566 private boolean checkFinishBootingLocked() { 1567 final boolean booting = mService.mBooting; 1568 boolean enableScreen = false; 1569 mService.mBooting = false; 1570 if (!mService.mBooted) { 1571 mService.mBooted = true; 1572 enableScreen = true; 1573 } 1574 if (booting || enableScreen) { 1575 mService.postFinishBooting(booting, enableScreen); 1576 } 1577 return booting; 1578 } 1579 1580 // Checked. 1581 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1582 Configuration config) { 1583 if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token); 1584 1585 ArrayList<ActivityRecord> finishes = null; 1586 ArrayList<UserState> startingUsers = null; 1587 int NS = 0; 1588 int NF = 0; 1589 boolean booting = false; 1590 boolean activityRemoved = false; 1591 1592 ActivityRecord r = ActivityRecord.forTokenLocked(token); 1593 if (r != null) { 1594 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers=" 1595 + Debug.getCallers(4)); 1596 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1597 r.finishLaunchTickingLocked(); 1598 if (fromTimeout) { 1599 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1600 } 1601 1602 // This is a hack to semi-deal with a race condition 1603 // in the client where it can be constructed with a 1604 // newer configuration from when we asked it to launch. 1605 // We'll update with whatever configuration it now says 1606 // it used to launch. 1607 if (config != null) { 1608 r.configuration = config; 1609 } 1610 1611 // We are now idle. If someone is waiting for a thumbnail from 1612 // us, we can now deliver. 1613 r.idle = true; 1614 1615 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1616 if (isFocusedStack(r.task.stack) || fromTimeout) { 1617 booting = checkFinishBootingLocked(); 1618 } 1619 } 1620 1621 if (allResumedActivitiesIdle()) { 1622 if (r != null) { 1623 mService.scheduleAppGcsLocked(); 1624 } 1625 1626 if (mLaunchingActivity.isHeld()) { 1627 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1628 if (VALIDATE_WAKE_LOCK_CALLER && 1629 Binder.getCallingUid() != Process.myUid()) { 1630 throw new IllegalStateException("Calling must be system uid"); 1631 } 1632 mLaunchingActivity.release(); 1633 } 1634 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1635 } 1636 1637 // Atomically retrieve all of the other things to do. 1638 final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true); 1639 NS = stops != null ? stops.size() : 0; 1640 if ((NF = mFinishingActivities.size()) > 0) { 1641 finishes = new ArrayList<>(mFinishingActivities); 1642 mFinishingActivities.clear(); 1643 } 1644 1645 if (mStartingUsers.size() > 0) { 1646 startingUsers = new ArrayList<>(mStartingUsers); 1647 mStartingUsers.clear(); 1648 } 1649 1650 // Stop any activities that are scheduled to do so but have been 1651 // waiting for the next one to start. 1652 for (int i = 0; i < NS; i++) { 1653 r = stops.get(i); 1654 final ActivityStack stack = r.task.stack; 1655 if (stack != null) { 1656 if (r.finishing) { 1657 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1658 } else { 1659 stack.stopActivityLocked(r); 1660 } 1661 } 1662 } 1663 1664 // Finish any activities that are scheduled to do so but have been 1665 // waiting for the next one to start. 1666 for (int i = 0; i < NF; i++) { 1667 r = finishes.get(i); 1668 final ActivityStack stack = r.task.stack; 1669 if (stack != null) { 1670 activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle"); 1671 } 1672 } 1673 1674 if (!booting) { 1675 // Complete user switch 1676 if (startingUsers != null) { 1677 for (int i = 0; i < startingUsers.size(); i++) { 1678 mService.mUserController.finishUserSwitch(startingUsers.get(i)); 1679 } 1680 } 1681 } 1682 1683 mService.trimApplications(); 1684 //dump(); 1685 //mWindowManager.dump(); 1686 1687 if (activityRemoved) { 1688 resumeFocusedStackTopActivityLocked(); 1689 } 1690 1691 return r; 1692 } 1693 1694 boolean handleAppDiedLocked(ProcessRecord app) { 1695 boolean hasVisibleActivities = false; 1696 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1697 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1698 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1699 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 1700 } 1701 } 1702 return hasVisibleActivities; 1703 } 1704 1705 void closeSystemDialogsLocked() { 1706 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1707 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1708 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1709 stacks.get(stackNdx).closeSystemDialogsLocked(); 1710 } 1711 } 1712 } 1713 1714 void removeUserLocked(int userId) { 1715 mUserStackInFront.delete(userId); 1716 } 1717 1718 /** 1719 * Update the last used stack id for non-current user (current user's last 1720 * used stack is the focused stack) 1721 */ 1722 void updateUserStackLocked(int userId, ActivityStack stack) { 1723 if (userId != mCurrentUser) { 1724 mUserStackInFront.put(userId, stack != null ? stack.getStackId() : HOME_STACK_ID); 1725 } 1726 } 1727 1728 /** 1729 * @return true if some activity was finished (or would have finished if doit were true). 1730 */ 1731 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, 1732 boolean doit, boolean evenPersistent, int userId) { 1733 boolean didSomething = false; 1734 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1735 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1736 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1737 final ActivityStack stack = stacks.get(stackNdx); 1738 if (stack.finishDisabledPackageActivitiesLocked( 1739 packageName, filterByClasses, doit, evenPersistent, userId)) { 1740 didSomething = true; 1741 } 1742 } 1743 } 1744 return didSomething; 1745 } 1746 1747 void updatePreviousProcessLocked(ActivityRecord r) { 1748 // Now that this process has stopped, we may want to consider 1749 // it to be the previous app to try to keep around in case 1750 // the user wants to return to it. 1751 1752 // First, found out what is currently the foreground app, so that 1753 // we don't blow away the previous app if this activity is being 1754 // hosted by the process that is actually still the foreground. 1755 ProcessRecord fgApp = null; 1756 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1757 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1758 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1759 final ActivityStack stack = stacks.get(stackNdx); 1760 if (isFocusedStack(stack)) { 1761 if (stack.mResumedActivity != null) { 1762 fgApp = stack.mResumedActivity.app; 1763 } else if (stack.mPausingActivity != null) { 1764 fgApp = stack.mPausingActivity.app; 1765 } 1766 break; 1767 } 1768 } 1769 } 1770 1771 // Now set this one as the previous process, only if that really 1772 // makes sense to. 1773 if (r.app != null && fgApp != null && r.app != fgApp 1774 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 1775 && r.app != mService.mHomeProcess) { 1776 mService.mPreviousProcess = r.app; 1777 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 1778 } 1779 } 1780 1781 boolean resumeFocusedStackTopActivityLocked() { 1782 return resumeFocusedStackTopActivityLocked(null, null, null); 1783 } 1784 1785 boolean resumeFocusedStackTopActivityLocked( 1786 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 1787 if (targetStack != null && isFocusedStack(targetStack)) { 1788 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 1789 } 1790 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); 1791 if (r == null || r.state != RESUMED) { 1792 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); 1793 } 1794 return false; 1795 } 1796 1797 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) { 1798 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1799 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1800 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1801 stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo); 1802 } 1803 } 1804 } 1805 1806 TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) { 1807 TaskRecord finishedTask = null; 1808 ActivityStack focusedStack = getFocusedStack(); 1809 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1810 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1811 final int numStacks = stacks.size(); 1812 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1813 final ActivityStack stack = stacks.get(stackNdx); 1814 TaskRecord t = stack.finishTopRunningActivityLocked(app, reason); 1815 if (stack == focusedStack || finishedTask == null) { 1816 finishedTask = t; 1817 } 1818 } 1819 } 1820 return finishedTask; 1821 } 1822 1823 void finishVoiceTask(IVoiceInteractionSession session) { 1824 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1825 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1826 final int numStacks = stacks.size(); 1827 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1828 final ActivityStack stack = stacks.get(stackNdx); 1829 stack.finishVoiceTask(session); 1830 } 1831 } 1832 } 1833 1834 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options, 1835 String reason, boolean forceNonResizeable) { 1836 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 1837 mUserLeaving = true; 1838 } 1839 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 1840 // Caller wants the home activity moved with it. To accomplish this, 1841 // we'll just indicate that this task returns to the home task. 1842 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1843 } 1844 if (task.stack == null) { 1845 Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task=" 1846 + task + " to front. Stack is null"); 1847 return; 1848 } 1849 1850 if (task.isResizeable() && options != null) { 1851 int stackId = options.getLaunchStackId(); 1852 if (canUseActivityOptionsLaunchBounds(options, stackId)) { 1853 final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds()); 1854 task.updateOverrideConfiguration(bounds); 1855 if (stackId == INVALID_STACK_ID) { 1856 stackId = task.getLaunchStackId(); 1857 } 1858 if (stackId != task.stack.mStackId) { 1859 final ActivityStack stack = moveTaskToStackUncheckedLocked( 1860 task, stackId, ON_TOP, !FORCE_FOCUS, reason); 1861 stackId = stack.mStackId; 1862 // moveTaskToStackUncheckedLocked() should already placed the task on top, 1863 // still need moveTaskToFrontLocked() below for any transition settings. 1864 } 1865 if (StackId.resizeStackWithLaunchBounds(stackId)) { 1866 resizeStackLocked(stackId, bounds, 1867 null /* tempTaskBounds */, null /* tempTaskInsetBounds */, 1868 !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME); 1869 } else { 1870 // WM resizeTask must be done after the task is moved to the correct stack, 1871 // because Task's setBounds() also updates dim layer's bounds, but that has 1872 // dependency on the stack. 1873 mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, 1874 false /* relayout */, false /* forced */); 1875 } 1876 } 1877 } 1878 1879 final ActivityRecord r = task.getTopActivity(); 1880 task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options, 1881 r == null ? null : r.appTimeTracker, reason); 1882 1883 if (DEBUG_STACK) Slog.d(TAG_STACK, 1884 "findTaskToMoveToFront: moved to front of stack=" + task.stack); 1885 1886 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId, 1887 forceNonResizeable); 1888 } 1889 1890 boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) { 1891 // We use the launch bounds in the activity options is the device supports freeform 1892 // window management or is launching into the pinned stack. 1893 if (options.getLaunchBounds() == null) { 1894 return false; 1895 } 1896 return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID) 1897 || mService.mSupportsFreeformWindowManagement; 1898 } 1899 1900 ActivityStack getStack(int stackId) { 1901 return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 1902 } 1903 1904 ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) { 1905 ActivityContainer activityContainer = mActivityContainers.get(stackId); 1906 if (activityContainer != null) { 1907 return activityContainer.mStack; 1908 } 1909 if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) { 1910 return null; 1911 } 1912 return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop); 1913 } 1914 1915 ArrayList<ActivityStack> getStacks() { 1916 ArrayList<ActivityStack> allStacks = new ArrayList<>(); 1917 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1918 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 1919 } 1920 return allStacks; 1921 } 1922 1923 IBinder getHomeActivityToken() { 1924 ActivityRecord homeActivity = getHomeActivity(); 1925 if (homeActivity != null) { 1926 return homeActivity.appToken; 1927 } 1928 return null; 1929 } 1930 1931 ActivityRecord getHomeActivity() { 1932 return getHomeActivityForUser(mCurrentUser); 1933 } 1934 1935 ActivityRecord getHomeActivityForUser(int userId) { 1936 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 1937 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 1938 final TaskRecord task = tasks.get(taskNdx); 1939 if (task.isHomeTask()) { 1940 final ArrayList<ActivityRecord> activities = task.mActivities; 1941 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 1942 final ActivityRecord r = activities.get(activityNdx); 1943 if (r.isHomeActivity() 1944 && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) { 1945 return r; 1946 } 1947 } 1948 } 1949 } 1950 return null; 1951 } 1952 1953 /** 1954 * Returns if a stack should be treated as if it's docked. Returns true if the stack is 1955 * the docked stack itself, or if it's side-by-side to the docked stack. 1956 */ 1957 boolean isStackDockedInEffect(int stackId) { 1958 return stackId == DOCKED_STACK_ID || 1959 (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null); 1960 } 1961 1962 ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity, 1963 IActivityContainerCallback callback) { 1964 ActivityContainer activityContainer = 1965 new VirtualActivityContainer(parentActivity, callback); 1966 mActivityContainers.put(activityContainer.mStackId, activityContainer); 1967 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 1968 "createActivityContainer: " + activityContainer); 1969 parentActivity.mChildContainers.add(activityContainer); 1970 return activityContainer; 1971 } 1972 1973 void removeChildActivityContainers(ActivityRecord parentActivity) { 1974 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 1975 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 1976 ActivityContainer container = childStacks.remove(containerNdx); 1977 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing " 1978 + container); 1979 container.release(); 1980 } 1981 } 1982 1983 void deleteActivityContainer(IActivityContainer container) { 1984 ActivityContainer activityContainer = (ActivityContainer)container; 1985 if (activityContainer != null) { 1986 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 1987 "deleteActivityContainer: callers=" + Debug.getCallers(4)); 1988 final int stackId = activityContainer.mStackId; 1989 mActivityContainers.remove(stackId); 1990 mWindowManager.removeStack(stackId); 1991 } 1992 } 1993 1994 void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, 1995 boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) { 1996 if (stackId == DOCKED_STACK_ID) { 1997 resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null, 1998 preserveWindows); 1999 return; 2000 } 2001 final ActivityStack stack = getStack(stackId); 2002 if (stack == null) { 2003 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); 2004 return; 2005 } 2006 2007 if (!allowResizeInDockedMode && getStack(DOCKED_STACK_ID) != null) { 2008 // If the docked stack exist we don't allow resizes of stacks not caused by the docked 2009 // stack size changing so things don't get out of sync. 2010 return; 2011 } 2012 2013 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId); 2014 mWindowManager.deferSurfaceLayout(); 2015 try { 2016 resizeStackUncheckedLocked(stack, bounds, tempTaskBounds, tempTaskInsetBounds); 2017 if (!deferResume) { 2018 stack.ensureVisibleActivitiesConfigurationLocked( 2019 stack.topRunningActivityLocked(), preserveWindows); 2020 } 2021 } finally { 2022 mWindowManager.continueSurfaceLayout(); 2023 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2024 } 2025 } 2026 2027 void deferUpdateBounds(int stackId) { 2028 final ActivityStack stack = getStack(stackId); 2029 if (stack != null) { 2030 stack.deferUpdateBounds(); 2031 } 2032 } 2033 2034 void continueUpdateBounds(int stackId) { 2035 final ActivityStack stack = getStack(stackId); 2036 if (stack != null) { 2037 stack.continueUpdateBounds(); 2038 } 2039 } 2040 2041 void notifyAppTransitionDone() { 2042 continueUpdateBounds(HOME_STACK_ID); 2043 for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) { 2044 final int taskId = mResizingTasksDuringAnimation.valueAt(i); 2045 if (anyTaskForIdLocked(taskId) != null) { 2046 mWindowManager.setTaskDockedResizing(taskId, false); 2047 } 2048 } 2049 mResizingTasksDuringAnimation.clear(); 2050 } 2051 2052 void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds, 2053 Rect tempTaskInsetBounds) { 2054 bounds = TaskRecord.validateBounds(bounds); 2055 2056 if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) { 2057 return; 2058 } 2059 2060 mTmpBounds.clear(); 2061 mTmpConfigs.clear(); 2062 mTmpInsetBounds.clear(); 2063 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2064 final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds; 2065 final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds; 2066 for (int i = tasks.size() - 1; i >= 0; i--) { 2067 final TaskRecord task = tasks.get(i); 2068 if (task.isResizeable()) { 2069 if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) { 2070 // For freeform stack we don't adjust the size of the tasks to match that 2071 // of the stack, but we do try to make sure the tasks are still contained 2072 // with the bounds of the stack. 2073 tempRect2.set(task.mBounds); 2074 fitWithinBounds(tempRect2, bounds); 2075 task.updateOverrideConfiguration(tempRect2); 2076 } else { 2077 task.updateOverrideConfiguration(taskBounds, insetBounds); 2078 } 2079 } 2080 2081 mTmpConfigs.put(task.taskId, task.mOverrideConfig); 2082 mTmpBounds.put(task.taskId, task.mBounds); 2083 if (tempTaskInsetBounds != null) { 2084 mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds); 2085 } 2086 } 2087 2088 // We might trigger a configuration change. Save the current task bounds for freezing. 2089 mWindowManager.prepareFreezingTaskBounds(stack.mStackId); 2090 stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs, 2091 mTmpBounds, mTmpInsetBounds); 2092 stack.setBounds(bounds); 2093 } 2094 2095 void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) { 2096 final ActivityStack stack = getStack(fromStackId); 2097 if (stack == null) { 2098 return; 2099 } 2100 2101 mWindowManager.deferSurfaceLayout(); 2102 try { 2103 if (fromStackId == DOCKED_STACK_ID) { 2104 2105 // We are moving all tasks from the docked stack to the fullscreen stack, 2106 // which is dismissing the docked stack, so resize all other stacks to 2107 // fullscreen here already so we don't end up with resize trashing. 2108 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2109 if (StackId.isResizeableByDockedStack(i)) { 2110 ActivityStack otherStack = getStack(i); 2111 if (otherStack != null) { 2112 resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS, 2113 true /* allowResizeInDockedMode */, DEFER_RESUME); 2114 } 2115 } 2116 } 2117 2118 // Also disable docked stack resizing since we have manually adjusted the 2119 // size of other stacks above and we don't want to trigger a docked stack 2120 // resize when we remove task from it below and it is detached from the 2121 // display because it no longer contains any tasks. 2122 mAllowDockedStackResize = false; 2123 } 2124 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2125 final int size = tasks.size(); 2126 if (onTop) { 2127 for (int i = 0; i < size; i++) { 2128 moveTaskToStackLocked(tasks.get(i).taskId, 2129 FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/, 2130 "moveTasksToFullscreenStack", ANIMATE, DEFER_RESUME); 2131 } 2132 2133 ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); 2134 resumeFocusedStackTopActivityLocked(); 2135 } else { 2136 for (int i = size - 1; i >= 0; i--) { 2137 positionTaskInStackLocked(tasks.get(i).taskId, 2138 FULLSCREEN_WORKSPACE_STACK_ID, 0); 2139 } 2140 } 2141 } finally { 2142 mAllowDockedStackResize = true; 2143 mWindowManager.continueSurfaceLayout(); 2144 } 2145 } 2146 2147 void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, 2148 Rect tempDockedTaskInsetBounds, 2149 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows) { 2150 2151 if (!mAllowDockedStackResize) { 2152 // Docked stack resize currently disabled. 2153 return; 2154 } 2155 2156 final ActivityStack stack = getStack(DOCKED_STACK_ID); 2157 if (stack == null) { 2158 Slog.w(TAG, "resizeDockedStackLocked: docked stack not found"); 2159 return; 2160 } 2161 2162 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack"); 2163 mWindowManager.deferSurfaceLayout(); 2164 try { 2165 // Don't allow re-entry while resizing. E.g. due to docked stack detaching. 2166 mAllowDockedStackResize = false; 2167 ActivityRecord r = stack.topRunningActivityLocked(); 2168 resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds, 2169 tempDockedTaskInsetBounds); 2170 2171 // TODO: Checking for isAttached might not be needed as if the user passes in null 2172 // dockedBounds then they want the docked stack to be dismissed. 2173 if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) { 2174 // The dock stack either was dismissed or went fullscreen, which is kinda the same. 2175 // In this case we make all other static stacks fullscreen and move all 2176 // docked stack tasks to the fullscreen stack. 2177 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP); 2178 2179 // stack shouldn't contain anymore activities, so nothing to resume. 2180 r = null; 2181 } else { 2182 // Docked stacks occupy a dedicated region on screen so the size of all other 2183 // static stacks need to be adjusted so they don't overlap with the docked stack. 2184 // We get the bounds to use from window manager which has been adjusted for any 2185 // screen controls and is also the same for all stacks. 2186 mWindowManager.getStackDockedModeBounds( 2187 HOME_STACK_ID, tempRect, true /* ignoreVisibility */); 2188 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2189 if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) { 2190 resizeStackLocked(i, tempRect, tempOtherTaskBounds, 2191 tempOtherTaskInsetBounds, preserveWindows, 2192 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2193 } 2194 } 2195 } 2196 stack.ensureVisibleActivitiesConfigurationLocked(r, preserveWindows); 2197 } finally { 2198 mAllowDockedStackResize = true; 2199 mWindowManager.continueSurfaceLayout(); 2200 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2201 } 2202 2203 mResizeDockedStackTimeout.notifyResizing(dockedBounds, 2204 tempDockedTaskBounds != null 2205 || tempDockedTaskInsetBounds != null 2206 || tempOtherTaskBounds != null 2207 || tempOtherTaskInsetBounds != null); 2208 } 2209 2210 void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 2211 final ActivityStack stack = getStack(PINNED_STACK_ID); 2212 if (stack == null) { 2213 Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found"); 2214 return; 2215 } 2216 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack"); 2217 mWindowManager.deferSurfaceLayout(); 2218 try { 2219 ActivityRecord r = stack.topRunningActivityLocked(); 2220 resizeStackUncheckedLocked(stack, pinnedBounds, tempPinnedTaskBounds, 2221 null); 2222 stack.ensureVisibleActivitiesConfigurationLocked(r, false); 2223 } finally { 2224 mWindowManager.continueSurfaceLayout(); 2225 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2226 } 2227 } 2228 2229 boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow, 2230 boolean deferResume) { 2231 if (!task.isResizeable()) { 2232 Slog.w(TAG, "resizeTask: task " + task + " not resizeable."); 2233 return true; 2234 } 2235 2236 // If this is a forced resize, let it go through even if the bounds is not changing, 2237 // as we might need a relayout due to surface size change (to/from fullscreen). 2238 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0; 2239 if (Objects.equals(task.mBounds, bounds) && !forced) { 2240 // Nothing to do here... 2241 return true; 2242 } 2243 bounds = TaskRecord.validateBounds(bounds); 2244 2245 if (!mWindowManager.isValidTaskId(task.taskId)) { 2246 // Task doesn't exist in window manager yet (e.g. was restored from recents). 2247 // All we can do for now is update the bounds so it can be used when the task is 2248 // added to window manager. 2249 task.updateOverrideConfiguration(bounds); 2250 if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) { 2251 // re-restore the task so it can have the proper stack association. 2252 restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID); 2253 } 2254 return true; 2255 } 2256 2257 // Do not move the task to another stack here. 2258 // This method assumes that the task is already placed in the right stack. 2259 // we do not mess with that decision and we only do the resize! 2260 2261 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId); 2262 2263 final Configuration overrideConfig = task.updateOverrideConfiguration(bounds); 2264 // This variable holds information whether the configuration didn't change in a significant 2265 // way and the activity was kept the way it was. If it's false, it means the activity had 2266 // to be relaunched due to configuration change. 2267 boolean kept = true; 2268 if (overrideConfig != null) { 2269 final ActivityRecord r = task.topRunningActivityLocked(); 2270 if (r != null) { 2271 final ActivityStack stack = task.stack; 2272 kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow); 2273 2274 if (!deferResume) { 2275 2276 // All other activities must be made visible with their correct configuration. 2277 ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); 2278 if (!kept) { 2279 resumeFocusedStackTopActivityLocked(); 2280 } 2281 } 2282 } 2283 } 2284 mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced); 2285 2286 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2287 return kept; 2288 } 2289 2290 ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) { 2291 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2292 if (activityDisplay == null) { 2293 return null; 2294 } 2295 2296 ActivityContainer activityContainer = new ActivityContainer(stackId); 2297 mActivityContainers.put(stackId, activityContainer); 2298 activityContainer.attachToDisplayLocked(activityDisplay, onTop); 2299 return activityContainer.mStack; 2300 } 2301 2302 int getNextStackId() { 2303 while (true) { 2304 if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID 2305 && getStack(mNextFreeStackId) == null) { 2306 break; 2307 } 2308 mNextFreeStackId++; 2309 } 2310 return mNextFreeStackId; 2311 } 2312 2313 /** 2314 * Restores a recent task to a stack 2315 * @param task The recent task to be restored. 2316 * @param stackId The stack to restore the task to (default launch stack will be used 2317 * if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}). 2318 * @return true if the task has been restored successfully. 2319 */ 2320 private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) { 2321 if (stackId == INVALID_STACK_ID) { 2322 stackId = task.getLaunchStackId(); 2323 } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) { 2324 // Preferred stack is the docked stack, but the task can't go in the docked stack. 2325 // Put it in the fullscreen stack. 2326 stackId = FULLSCREEN_WORKSPACE_STACK_ID; 2327 } 2328 2329 if (task.stack != null) { 2330 // Task has already been restored once. See if we need to do anything more 2331 if (task.stack.mStackId == stackId) { 2332 // Nothing else to do since it is already restored in the right stack. 2333 return true; 2334 } 2335 // Remove current stack association, so we can re-associate the task with the 2336 // right stack below. 2337 task.stack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING); 2338 } 2339 2340 final ActivityStack stack = 2341 getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); 2342 2343 if (stack == null) { 2344 // What does this mean??? Not sure how we would get here... 2345 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2346 "Unable to find/create stack to restore recent task=" + task); 2347 return false; 2348 } 2349 2350 stack.addTask(task, false, "restoreRecentTask"); 2351 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2352 "Added restored task=" + task + " to stack=" + stack); 2353 final ArrayList<ActivityRecord> activities = task.mActivities; 2354 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2355 stack.addConfigOverride(activities.get(activityNdx), task); 2356 } 2357 return true; 2358 } 2359 2360 /** 2361 * Moves the specified task record to the input stack id. 2362 * WARNING: This method performs an unchecked/raw move of the task and 2363 * can leave the system in an unstable state if used incorrectly. 2364 * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack. 2365 * @param task Task to move. 2366 * @param stackId Id of stack to move task to. 2367 * @param toTop True if the task should be placed at the top of the stack. 2368 * @param forceFocus if focus should be moved to the new stack 2369 * @param reason Reason the task is been moved. 2370 * @return The stack the task was moved to. 2371 */ 2372 ActivityStack moveTaskToStackUncheckedLocked( 2373 TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) { 2374 2375 if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) { 2376 throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't " 2377 + "support multi-window task=" + task + " to stackId=" + stackId); 2378 } 2379 2380 final ActivityRecord r = task.topRunningActivityLocked(); 2381 final ActivityStack prevStack = task.stack; 2382 final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r); 2383 final boolean wasResumed = prevStack.mResumedActivity == r; 2384 // In some cases the focused stack isn't the front stack. E.g. pinned stack. 2385 // Whenever we are moving the top activity from the front stack we want to make sure to move 2386 // the stack to the front. 2387 final boolean wasFront = isFrontStack(prevStack) 2388 && (prevStack.topRunningActivityLocked() == r); 2389 2390 if (stackId == DOCKED_STACK_ID && !task.isResizeable()) { 2391 // We don't allow moving a unresizeable task to the docked stack since the docked 2392 // stack is used for split-screen mode and will cause things like the docked divider to 2393 // show up. We instead leave the task in its current stack or move it to the fullscreen 2394 // stack if it isn't currently in a stack. 2395 stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID; 2396 Slog.w(TAG, "Can not move unresizeable task=" + task 2397 + " to docked stack. Moving to stackId=" + stackId + " instead."); 2398 } 2399 2400 // Temporarily disable resizeablility of task we are moving. We don't want it to be resized 2401 // if a docked stack is created below which will lead to the stack we are moving from and 2402 // its resizeable tasks being resized. 2403 task.mTemporarilyUnresizable = true; 2404 final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop); 2405 task.mTemporarilyUnresizable = false; 2406 mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop); 2407 stack.addTask(task, toTop, reason); 2408 2409 // If the task had focus before (or we're requested to move focus), 2410 // move focus to the new stack by moving the stack to the front. 2411 stack.moveToFrontAndResumeStateIfNeeded( 2412 r, forceFocus || wasFocused || wasFront, wasResumed, reason); 2413 2414 return stack; 2415 } 2416 2417 boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, 2418 String reason, boolean animate) { 2419 return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate, 2420 false /* deferResume */); 2421 } 2422 2423 boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, 2424 String reason, boolean animate, boolean deferResume) { 2425 final TaskRecord task = anyTaskForIdLocked(taskId); 2426 if (task == null) { 2427 Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId); 2428 return false; 2429 } 2430 2431 if (task.stack != null && task.stack.mStackId == stackId) { 2432 // You are already in the right stack silly... 2433 Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId); 2434 return true; 2435 } 2436 2437 if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) { 2438 throw new IllegalArgumentException("moveTaskToStack:" 2439 + "Attempt to move task " + taskId + " to unsupported freeform stack"); 2440 } 2441 2442 final ActivityRecord topActivity = task.getTopActivity(); 2443 final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID; 2444 final boolean mightReplaceWindow = 2445 StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) && topActivity != null; 2446 if (mightReplaceWindow) { 2447 // We are about to relaunch the activity because its configuration changed due to 2448 // being maximized, i.e. size change. The activity will first remove the old window 2449 // and then add a new one. This call will tell window manager about this, so it can 2450 // preserve the old window until the new one is drawn. This prevents having a gap 2451 // between the removal and addition, in which no window is visible. We also want the 2452 // entrance of the new window to be properly animated. 2453 // Note here we always set the replacing window first, as the flags might be needed 2454 // during the relaunch. If we end up not doing any relaunch, we clear the flags later. 2455 mWindowManager.setReplacingWindow(topActivity.appToken, animate); 2456 } 2457 2458 mWindowManager.deferSurfaceLayout(); 2459 final int preferredLaunchStackId = stackId; 2460 boolean kept = true; 2461 try { 2462 final ActivityStack stack = moveTaskToStackUncheckedLocked( 2463 task, stackId, toTop, forceFocus, reason + " moveTaskToStack"); 2464 stackId = stack.mStackId; 2465 2466 if (!animate) { 2467 stack.mNoAnimActivities.add(topActivity); 2468 } 2469 2470 // We might trigger a configuration change. Save the current task bounds for freezing. 2471 mWindowManager.prepareFreezingTaskBounds(stack.mStackId); 2472 2473 // Make sure the task has the appropriate bounds/size for the stack it is in. 2474 if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) { 2475 kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, 2476 !mightReplaceWindow, deferResume); 2477 } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) { 2478 Rect bounds = task.getLaunchBounds(); 2479 if (bounds == null) { 2480 stack.layoutTaskInStack(task, null); 2481 bounds = task.mBounds; 2482 } 2483 kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, 2484 deferResume); 2485 } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) { 2486 kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, 2487 !mightReplaceWindow, deferResume); 2488 } 2489 } finally { 2490 mWindowManager.continueSurfaceLayout(); 2491 } 2492 2493 if (mightReplaceWindow) { 2494 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old 2495 // window), we need to clear the replace window settings. Otherwise, we schedule a 2496 // timeout to remove the old window if the replacing window is not coming in time. 2497 mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept); 2498 } 2499 2500 if (!deferResume) { 2501 2502 // The task might have already been running and its visibility needs to be synchronized with 2503 // the visibility of the stack / windows. 2504 ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow); 2505 resumeFocusedStackTopActivityLocked(); 2506 } 2507 2508 handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId); 2509 2510 return (preferredLaunchStackId == stackId); 2511 } 2512 2513 boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) { 2514 final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 2515 if (stack == null) { 2516 throw new IllegalArgumentException( 2517 "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId); 2518 } 2519 2520 final ActivityRecord r = stack.topRunningActivityLocked(); 2521 if (r == null) { 2522 Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity" 2523 + " in stack=" + stack); 2524 return false; 2525 } 2526 2527 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { 2528 Slog.w(TAG, 2529 "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for " 2530 + " r=" + r); 2531 return false; 2532 } 2533 2534 moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds); 2535 return true; 2536 } 2537 2538 void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) { 2539 mWindowManager.deferSurfaceLayout(); 2540 try { 2541 final TaskRecord task = r.task; 2542 2543 if (r == task.stack.getVisibleBehindActivity()) { 2544 // An activity can't be pinned and visible behind at the same time. Go ahead and 2545 // release it from been visible behind before pinning. 2546 requestVisibleBehindLocked(r, false); 2547 } 2548 2549 // Need to make sure the pinned stack exist so we can resize it below... 2550 final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP); 2551 2552 // Resize the pinned stack to match the current size of the task the activity we are 2553 // going to be moving is currently contained in. We do this to have the right starting 2554 // animation bounds for the pinned stack to the desired bounds the caller wants. 2555 resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */, 2556 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, 2557 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2558 2559 if (task.mActivities.size() == 1) { 2560 // There is only one activity in the task. So, we can just move the task over to 2561 // the stack without re-parenting the activity in a different task. 2562 if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) { 2563 // Move the home stack forward if the task we just moved to the pinned stack 2564 // was launched from home so home should be visible behind it. 2565 moveHomeStackToFront(reason); 2566 } 2567 moveTaskToStackLocked( 2568 task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE); 2569 } else { 2570 stack.moveActivityToStack(r); 2571 } 2572 } finally { 2573 mWindowManager.continueSurfaceLayout(); 2574 } 2575 2576 // The task might have already been running and its visibility needs to be synchronized 2577 // with the visibility of the stack / windows. 2578 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2579 resumeFocusedStackTopActivityLocked(); 2580 2581 mWindowManager.animateResizePinnedStack(bounds, -1); 2582 mService.notifyActivityPinnedLocked(); 2583 } 2584 2585 void positionTaskInStackLocked(int taskId, int stackId, int position) { 2586 final TaskRecord task = anyTaskForIdLocked(taskId); 2587 if (task == null) { 2588 Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId); 2589 return; 2590 } 2591 final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); 2592 2593 task.updateOverrideConfigurationForStack(stack); 2594 2595 mWindowManager.positionTaskInStack( 2596 taskId, stackId, position, task.mBounds, task.mOverrideConfig); 2597 stack.positionTask(task, position); 2598 // The task might have already been running and its visibility needs to be synchronized with 2599 // the visibility of the stack / windows. 2600 stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2601 resumeFocusedStackTopActivityLocked(); 2602 } 2603 2604 ActivityRecord findTaskLocked(ActivityRecord r) { 2605 mTmpFindTaskResult.r = null; 2606 mTmpFindTaskResult.matchedByRootAffinity = false; 2607 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 2608 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2609 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2610 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2611 final ActivityStack stack = stacks.get(stackNdx); 2612 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2613 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack); 2614 continue; 2615 } 2616 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2617 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 2618 "Skipping stack: (new task not allowed) " + stack); 2619 continue; 2620 } 2621 stack.findTaskLocked(r, mTmpFindTaskResult); 2622 // It is possible to have task in multiple stacks with the same root affinity. 2623 // If the match we found was based on root affinity we keep on looking to see if 2624 // there is a better match in another stack. We eventually return the match based 2625 // on root affinity if we don't find a better match. 2626 if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) { 2627 return mTmpFindTaskResult.r; 2628 } 2629 } 2630 } 2631 if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found"); 2632 return mTmpFindTaskResult.r; 2633 } 2634 2635 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2636 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2637 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2638 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2639 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2640 if (ar != null) { 2641 return ar; 2642 } 2643 } 2644 } 2645 return null; 2646 } 2647 2648 void goingToSleepLocked() { 2649 scheduleSleepTimeout(); 2650 if (!mGoingToSleep.isHeld()) { 2651 mGoingToSleep.acquire(); 2652 if (mLaunchingActivity.isHeld()) { 2653 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2654 throw new IllegalStateException("Calling must be system uid"); 2655 } 2656 mLaunchingActivity.release(); 2657 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2658 } 2659 } 2660 checkReadyForSleepLocked(); 2661 } 2662 2663 boolean shutdownLocked(int timeout) { 2664 goingToSleepLocked(); 2665 2666 boolean timedout = false; 2667 final long endTime = System.currentTimeMillis() + timeout; 2668 while (true) { 2669 boolean cantShutdown = false; 2670 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2671 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2672 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2673 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2674 } 2675 } 2676 if (cantShutdown) { 2677 long timeRemaining = endTime - System.currentTimeMillis(); 2678 if (timeRemaining > 0) { 2679 try { 2680 mService.wait(timeRemaining); 2681 } catch (InterruptedException e) { 2682 } 2683 } else { 2684 Slog.w(TAG, "Activity manager shutdown timed out"); 2685 timedout = true; 2686 break; 2687 } 2688 } else { 2689 break; 2690 } 2691 } 2692 2693 // Force checkReadyForSleep to complete. 2694 mSleepTimeout = true; 2695 checkReadyForSleepLocked(); 2696 2697 return timedout; 2698 } 2699 2700 void comeOutOfSleepIfNeededLocked() { 2701 removeSleepTimeouts(); 2702 if (mGoingToSleep.isHeld()) { 2703 mGoingToSleep.release(); 2704 } 2705 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2706 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2707 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2708 final ActivityStack stack = stacks.get(stackNdx); 2709 stack.awakeFromSleepingLocked(); 2710 if (isFocusedStack(stack)) { 2711 resumeFocusedStackTopActivityLocked(); 2712 } 2713 } 2714 } 2715 mGoingToSleepActivities.clear(); 2716 } 2717 2718 void activitySleptLocked(ActivityRecord r) { 2719 mGoingToSleepActivities.remove(r); 2720 checkReadyForSleepLocked(); 2721 } 2722 2723 void checkReadyForSleepLocked() { 2724 if (!mService.isSleepingOrShuttingDown()) { 2725 // Do not care. 2726 return; 2727 } 2728 2729 if (!mSleepTimeout) { 2730 boolean dontSleep = false; 2731 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2732 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2733 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2734 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2735 } 2736 } 2737 2738 if (mStoppingActivities.size() > 0) { 2739 // Still need to tell some activities to stop; can't sleep yet. 2740 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop " 2741 + mStoppingActivities.size() + " activities"); 2742 scheduleIdleLocked(); 2743 dontSleep = true; 2744 } 2745 2746 if (mGoingToSleepActivities.size() > 0) { 2747 // Still need to tell some activities to sleep; can't sleep yet. 2748 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep " 2749 + mGoingToSleepActivities.size() + " activities"); 2750 dontSleep = true; 2751 } 2752 2753 if (dontSleep) { 2754 return; 2755 } 2756 } 2757 2758 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2759 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2760 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2761 stacks.get(stackNdx).goToSleep(); 2762 } 2763 } 2764 2765 removeSleepTimeouts(); 2766 2767 if (mGoingToSleep.isHeld()) { 2768 mGoingToSleep.release(); 2769 } 2770 if (mService.mShuttingDown) { 2771 mService.notifyAll(); 2772 } 2773 } 2774 2775 boolean reportResumedActivityLocked(ActivityRecord r) { 2776 final ActivityStack stack = r.task.stack; 2777 if (isFocusedStack(stack)) { 2778 mService.updateUsageStats(r, true); 2779 } 2780 if (allResumedActivitiesComplete()) { 2781 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2782 mWindowManager.executeAppTransition(); 2783 return true; 2784 } 2785 return false; 2786 } 2787 2788 void handleAppCrashLocked(ProcessRecord app) { 2789 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2790 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2791 int stackNdx = stacks.size() - 1; 2792 while (stackNdx >= 0) { 2793 stacks.get(stackNdx).handleAppCrashLocked(app); 2794 stackNdx--; 2795 } 2796 } 2797 } 2798 2799 boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) { 2800 final ActivityStack stack = r.task.stack; 2801 if (stack == null) { 2802 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2803 "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null"); 2804 return false; 2805 } 2806 2807 if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) { 2808 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r 2809 + " visible=" + visible + " stackId=" + stack.mStackId 2810 + " can't contain visible behind activities"); 2811 return false; 2812 } 2813 2814 final boolean isVisible = stack.hasVisibleBehindActivity(); 2815 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2816 "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible); 2817 2818 final ActivityRecord top = topRunningActivityLocked(); 2819 if (top == null || top == r || (visible == isVisible)) { 2820 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return"); 2821 stack.setVisibleBehindActivity(visible ? r : null); 2822 return true; 2823 } 2824 2825 // A non-top activity is reporting a visibility change. 2826 if (visible && top.fullscreen) { 2827 // Let the caller know that it can't be seen. 2828 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2829 "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen 2830 + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread=" 2831 + top.app.thread); 2832 return false; 2833 } else if (!visible && stack.getVisibleBehindActivity() != r) { 2834 // Only the activity set as currently visible behind should actively reset its 2835 // visible behind state. 2836 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2837 "requestVisibleBehind: returning visible=" + visible 2838 + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity() 2839 + " r=" + r); 2840 return false; 2841 } 2842 2843 stack.setVisibleBehindActivity(visible ? r : null); 2844 if (!visible) { 2845 // If there is a translucent home activity, we need to force it stop being translucent, 2846 // because we can't depend on the application to necessarily perform that operation. 2847 // Check out b/14469711 for details. 2848 final ActivityRecord next = stack.findNextTranslucentActivity(r); 2849 if (next != null && next.isHomeActivity()) { 2850 mService.convertFromTranslucent(next.appToken); 2851 } 2852 } 2853 if (top.app != null && top.app.thread != null) { 2854 // Notify the top app of the change. 2855 try { 2856 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); 2857 } catch (RemoteException e) { 2858 } 2859 } 2860 return true; 2861 } 2862 2863 // Called when WindowManager has finished animating the launchingBehind activity to the back. 2864 void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 2865 final TaskRecord task = r.task; 2866 final ActivityStack stack = task.stack; 2867 2868 r.mLaunchTaskBehind = false; 2869 task.setLastThumbnailLocked(stack.screenshotActivitiesLocked(r)); 2870 mRecentTasks.addLocked(task); 2871 mService.notifyTaskStackChangedLocked(); 2872 mWindowManager.setAppVisibility(r.appToken, false); 2873 2874 // When launching tasks behind, update the last active time of the top task after the new 2875 // task has been shown briefly 2876 final ActivityRecord top = stack.topActivity(); 2877 if (top != null) { 2878 top.task.touchActiveTime(); 2879 } 2880 } 2881 2882 void scheduleLaunchTaskBehindComplete(IBinder token) { 2883 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 2884 } 2885 2886 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, 2887 boolean preserveWindows) { 2888 // First the front stacks. In case any are not fullscreen and are in front of home. 2889 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2890 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2891 final int topStackNdx = stacks.size() - 1; 2892 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2893 final ActivityStack stack = stacks.get(stackNdx); 2894 stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows); 2895 } 2896 } 2897 } 2898 2899 void invalidateTaskLayers() { 2900 mTaskLayersChanged = true; 2901 } 2902 2903 void rankTaskLayersIfNeeded() { 2904 if (!mTaskLayersChanged) { 2905 return; 2906 } 2907 mTaskLayersChanged = false; 2908 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) { 2909 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2910 int baseLayer = 0; 2911 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2912 baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer); 2913 } 2914 } 2915 } 2916 2917 void clearOtherAppTimeTrackers(AppTimeTracker except) { 2918 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2919 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2920 final int topStackNdx = stacks.size() - 1; 2921 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2922 final ActivityStack stack = stacks.get(stackNdx); 2923 stack.clearOtherAppTimeTrackers(except); 2924 } 2925 } 2926 } 2927 2928 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2929 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2930 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2931 final int numStacks = stacks.size(); 2932 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2933 final ActivityStack stack = stacks.get(stackNdx); 2934 stack.scheduleDestroyActivities(app, reason); 2935 } 2936 } 2937 } 2938 2939 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 2940 // Examine all activities currently running in the process. 2941 TaskRecord firstTask = null; 2942 // Tasks is non-null only if two or more tasks are found. 2943 ArraySet<TaskRecord> tasks = null; 2944 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); 2945 for (int i = 0; i < app.activities.size(); i++) { 2946 ActivityRecord r = app.activities.get(i); 2947 // First, if we find an activity that is in the process of being destroyed, 2948 // then we just aren't going to do anything for now; we want things to settle 2949 // down before we try to prune more activities. 2950 if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) { 2951 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 2952 return; 2953 } 2954 // Don't consider any activies that are currently not in a state where they 2955 // can be destroyed. 2956 if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING 2957 || r.state == PAUSED || r.state == STOPPING) { 2958 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 2959 continue; 2960 } 2961 if (r.task != null) { 2962 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task 2963 + " from " + r); 2964 if (firstTask == null) { 2965 firstTask = r.task; 2966 } else if (firstTask != r.task) { 2967 if (tasks == null) { 2968 tasks = new ArraySet<>(); 2969 tasks.add(firstTask); 2970 } 2971 tasks.add(r.task); 2972 } 2973 } 2974 } 2975 if (tasks == null) { 2976 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); 2977 return; 2978 } 2979 // If we have activities in multiple tasks that are in a position to be destroyed, 2980 // let's iterate through the tasks and release the oldest one. 2981 final int numDisplays = mActivityDisplays.size(); 2982 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2983 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2984 // Step through all stacks starting from behind, to hit the oldest things first. 2985 for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) { 2986 final ActivityStack stack = stacks.get(stackNdx); 2987 // Try to release activities in this stack; if we manage to, we are done. 2988 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 2989 return; 2990 } 2991 } 2992 } 2993 } 2994 2995 boolean switchUserLocked(int userId, UserState uss) { 2996 final int focusStackId = mFocusedStack.getStackId(); 2997 // We dismiss the docked stack whenever we switch users. 2998 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, focusStackId == DOCKED_STACK_ID); 2999 3000 mUserStackInFront.put(mCurrentUser, focusStackId); 3001 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 3002 mCurrentUser = userId; 3003 3004 mStartingUsers.add(uss); 3005 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3006 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3007 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3008 final ActivityStack stack = stacks.get(stackNdx); 3009 stack.switchUserLocked(userId); 3010 TaskRecord task = stack.topTask(); 3011 if (task != null) { 3012 mWindowManager.moveTaskToTop(task.taskId); 3013 } 3014 } 3015 } 3016 3017 ActivityStack stack = getStack(restoreStackId); 3018 if (stack == null) { 3019 stack = mHomeStack; 3020 } 3021 final boolean homeInFront = stack.isHomeStack(); 3022 if (stack.isOnHomeDisplay()) { 3023 stack.moveToFront("switchUserOnHomeDisplay"); 3024 } else { 3025 // Stack was moved to another display while user was swapped out. 3026 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay"); 3027 } 3028 return homeInFront; 3029 } 3030 3031 /** Checks whether the userid is a profile of the current user. */ 3032 boolean isCurrentProfileLocked(int userId) { 3033 if (userId == mCurrentUser) return true; 3034 return mService.mUserController.isCurrentProfileLocked(userId); 3035 } 3036 3037 /** Checks whether the activity should be shown for current user. */ 3038 boolean okToShowLocked(ActivityRecord r) { 3039 return r != null && (isCurrentProfileLocked(r.userId) 3040 || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0); 3041 } 3042 3043 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 3044 ArrayList<ActivityRecord> stops = null; 3045 3046 final boolean nowVisible = allResumedActivitiesVisible(); 3047 for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3048 ActivityRecord s = mStoppingActivities.get(activityNdx); 3049 final boolean waitingVisible = mWaitingVisibleActivities.contains(s); 3050 if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3051 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3052 if (waitingVisible && nowVisible) { 3053 mWaitingVisibleActivities.remove(s); 3054 if (s.finishing) { 3055 // If this activity is finishing, it is sitting on top of 3056 // everyone else but we now know it is no longer needed... 3057 // so get rid of it. Otherwise, we need to go through the 3058 // normal flow and hide it once we determine that it is 3059 // hidden by the activities in front of it. 3060 if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); 3061 mWindowManager.setAppVisibility(s.appToken, false); 3062 } 3063 } 3064 if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 3065 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); 3066 if (stops == null) { 3067 stops = new ArrayList<>(); 3068 } 3069 stops.add(s); 3070 mStoppingActivities.remove(activityNdx); 3071 } 3072 } 3073 3074 return stops; 3075 } 3076 3077 void validateTopActivitiesLocked() { 3078 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3079 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3080 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3081 final ActivityStack stack = stacks.get(stackNdx); 3082 final ActivityRecord r = stack.topRunningActivityLocked(); 3083 final ActivityState state = r == null ? DESTROYED : r.state; 3084 if (isFocusedStack(stack)) { 3085 if (r == null) Slog.e(TAG, 3086 "validateTop...: null top activity, stack=" + stack); 3087 else { 3088 final ActivityRecord pausing = stack.mPausingActivity; 3089 if (pausing != null && pausing == r) Slog.e(TAG, 3090 "validateTop...: top stack has pausing activity r=" + r 3091 + " state=" + state); 3092 if (state != INITIALIZING && state != RESUMED) Slog.e(TAG, 3093 "validateTop...: activity in front not resumed r=" + r 3094 + " state=" + state); 3095 } 3096 } else { 3097 final ActivityRecord resumed = stack.mResumedActivity; 3098 if (resumed != null && resumed == r) Slog.e(TAG, 3099 "validateTop...: back stack has resumed activity r=" + r 3100 + " state=" + state); 3101 if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG, 3102 "validateTop...: activity in back resumed r=" + r + " state=" + state); 3103 } 3104 } 3105 } 3106 } 3107 3108 private String lockTaskModeToString() { 3109 switch (mLockTaskModeState) { 3110 case LOCK_TASK_MODE_LOCKED: 3111 return "LOCKED"; 3112 case LOCK_TASK_MODE_PINNED: 3113 return "PINNED"; 3114 case LOCK_TASK_MODE_NONE: 3115 return "NONE"; 3116 default: return "unknown=" + mLockTaskModeState; 3117 } 3118 } 3119 3120 public void dump(PrintWriter pw, String prefix) { 3121 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3122 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3123 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3124 pw.print(prefix); 3125 pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); 3126 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3127 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3128 pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); 3129 final SparseArray<String[]> packages = mService.mLockTaskPackages; 3130 if (packages.size() > 0) { 3131 pw.println(" mLockTaskPackages (userId:packages)="); 3132 for (int i = 0; i < packages.size(); ++i) { 3133 pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i)); 3134 pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i))); 3135 } 3136 } 3137 pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks); 3138 } 3139 3140 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3141 return mFocusedStack.getDumpActivitiesLocked(name); 3142 } 3143 3144 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3145 boolean needSep, String prefix) { 3146 if (activity != null) { 3147 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3148 if (needSep) { 3149 pw.println(); 3150 } 3151 pw.print(prefix); 3152 pw.println(activity); 3153 return true; 3154 } 3155 } 3156 return false; 3157 } 3158 3159 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3160 boolean dumpClient, String dumpPackage) { 3161 boolean printed = false; 3162 boolean needSep = false; 3163 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3164 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3165 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3166 pw.println(" (activities from top to bottom):"); 3167 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3168 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3169 final ActivityStack stack = stacks.get(stackNdx); 3170 StringBuilder stackHeader = new StringBuilder(128); 3171 stackHeader.append(" Stack #"); 3172 stackHeader.append(stack.mStackId); 3173 stackHeader.append(":"); 3174 stackHeader.append("\n"); 3175 stackHeader.append(" mFullscreen=" + stack.mFullscreen); 3176 stackHeader.append("\n"); 3177 stackHeader.append(" mBounds=" + stack.mBounds); 3178 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3179 needSep, stackHeader.toString()); 3180 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3181 !dumpAll, false, dumpPackage, true, 3182 " Running activities (most recent first):", null); 3183 3184 needSep = printed; 3185 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3186 " mPausingActivity: "); 3187 if (pr) { 3188 printed = true; 3189 needSep = false; 3190 } 3191 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3192 " mResumedActivity: "); 3193 if (pr) { 3194 printed = true; 3195 needSep = false; 3196 } 3197 if (dumpAll) { 3198 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3199 " mLastPausedActivity: "); 3200 if (pr) { 3201 printed = true; 3202 needSep = true; 3203 } 3204 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3205 needSep, " mLastNoHistoryActivity: "); 3206 } 3207 needSep = printed; 3208 } 3209 } 3210 3211 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3212 false, dumpPackage, true, " Activities waiting to finish:", null); 3213 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3214 false, dumpPackage, true, " Activities waiting to stop:", null); 3215 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3216 false, dumpPackage, true, " Activities waiting for another to become visible:", 3217 null); 3218 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3219 false, dumpPackage, true, " Activities waiting to sleep:", null); 3220 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3221 false, dumpPackage, true, " Activities waiting to sleep:", null); 3222 3223 return printed; 3224 } 3225 3226 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3227 String prefix, String label, boolean complete, boolean brief, boolean client, 3228 String dumpPackage, boolean needNL, String header1, String header2) { 3229 TaskRecord lastTask = null; 3230 String innerPrefix = null; 3231 String[] args = null; 3232 boolean printed = false; 3233 for (int i=list.size()-1; i>=0; i--) { 3234 final ActivityRecord r = list.get(i); 3235 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3236 continue; 3237 } 3238 if (innerPrefix == null) { 3239 innerPrefix = prefix + " "; 3240 args = new String[0]; 3241 } 3242 printed = true; 3243 final boolean full = !brief && (complete || !r.isInHistory()); 3244 if (needNL) { 3245 pw.println(""); 3246 needNL = false; 3247 } 3248 if (header1 != null) { 3249 pw.println(header1); 3250 header1 = null; 3251 } 3252 if (header2 != null) { 3253 pw.println(header2); 3254 header2 = null; 3255 } 3256 if (lastTask != r.task) { 3257 lastTask = r.task; 3258 pw.print(prefix); 3259 pw.print(full ? "* " : " "); 3260 pw.println(lastTask); 3261 if (full) { 3262 lastTask.dump(pw, prefix + " "); 3263 } else if (complete) { 3264 // Complete + brief == give a summary. Isn't that obvious?!? 3265 if (lastTask.intent != null) { 3266 pw.print(prefix); pw.print(" "); 3267 pw.println(lastTask.intent.toInsecureStringWithClip()); 3268 } 3269 } 3270 } 3271 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3272 pw.print(" #"); pw.print(i); pw.print(": "); 3273 pw.println(r); 3274 if (full) { 3275 r.dump(pw, innerPrefix); 3276 } else if (complete) { 3277 // Complete + brief == give a summary. Isn't that obvious?!? 3278 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3279 if (r.app != null) { 3280 pw.print(innerPrefix); pw.println(r.app); 3281 } 3282 } 3283 if (client && r.app != null && r.app.thread != null) { 3284 // flush anything that is already in the PrintWriter since the thread is going 3285 // to write to the file descriptor directly 3286 pw.flush(); 3287 try { 3288 TransferPipe tp = new TransferPipe(); 3289 try { 3290 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3291 r.appToken, innerPrefix, args); 3292 // Short timeout, since blocking here can 3293 // deadlock with the application. 3294 tp.go(fd, 2000); 3295 } finally { 3296 tp.kill(); 3297 } 3298 } catch (IOException e) { 3299 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3300 } catch (RemoteException e) { 3301 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3302 } 3303 needNL = true; 3304 } 3305 } 3306 return printed; 3307 } 3308 3309 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3310 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3311 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3312 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3313 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3314 } 3315 3316 final void scheduleIdleLocked() { 3317 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3318 } 3319 3320 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3321 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 3322 + Debug.getCallers(4)); 3323 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3324 } 3325 3326 final void scheduleResumeTopActivities() { 3327 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3328 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3329 } 3330 } 3331 3332 void removeSleepTimeouts() { 3333 mSleepTimeout = false; 3334 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3335 } 3336 3337 final void scheduleSleepTimeout() { 3338 removeSleepTimeouts(); 3339 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3340 } 3341 3342 @Override 3343 public void onDisplayAdded(int displayId) { 3344 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 3345 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3346 } 3347 3348 @Override 3349 public void onDisplayRemoved(int displayId) { 3350 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 3351 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3352 } 3353 3354 @Override 3355 public void onDisplayChanged(int displayId) { 3356 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 3357 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3358 } 3359 3360 private void handleDisplayAdded(int displayId) { 3361 boolean newDisplay; 3362 synchronized (mService) { 3363 newDisplay = mActivityDisplays.get(displayId) == null; 3364 if (newDisplay) { 3365 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3366 if (activityDisplay.mDisplay == null) { 3367 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3368 return; 3369 } 3370 mActivityDisplays.put(displayId, activityDisplay); 3371 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 3372 } 3373 } 3374 if (newDisplay) { 3375 mWindowManager.onDisplayAdded(displayId); 3376 } 3377 } 3378 3379 private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) { 3380 mDefaultMinSizeOfResizeableTask = 3381 mService.mContext.getResources().getDimensionPixelSize( 3382 com.android.internal.R.dimen.default_minimal_size_resizable_task); 3383 } 3384 3385 private void handleDisplayRemoved(int displayId) { 3386 synchronized (mService) { 3387 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3388 if (activityDisplay != null) { 3389 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3390 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3391 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3392 } 3393 mActivityDisplays.remove(displayId); 3394 } 3395 } 3396 mWindowManager.onDisplayRemoved(displayId); 3397 } 3398 3399 private void handleDisplayChanged(int displayId) { 3400 synchronized (mService) { 3401 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3402 if (activityDisplay != null) { 3403 // TODO: Update the bounds. 3404 } 3405 } 3406 mWindowManager.onDisplayChanged(displayId); 3407 } 3408 3409 private StackInfo getStackInfoLocked(ActivityStack stack) { 3410 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 3411 StackInfo info = new StackInfo(); 3412 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3413 info.displayId = Display.DEFAULT_DISPLAY; 3414 info.stackId = stack.mStackId; 3415 info.userId = stack.mCurrentUser; 3416 info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE; 3417 info.position = display != null 3418 ? display.mStacks.indexOf(stack) 3419 : 0; 3420 3421 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3422 final int numTasks = tasks.size(); 3423 int[] taskIds = new int[numTasks]; 3424 String[] taskNames = new String[numTasks]; 3425 Rect[] taskBounds = new Rect[numTasks]; 3426 int[] taskUserIds = new int[numTasks]; 3427 for (int i = 0; i < numTasks; ++i) { 3428 final TaskRecord task = tasks.get(i); 3429 taskIds[i] = task.taskId; 3430 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3431 : task.realActivity != null ? task.realActivity.flattenToString() 3432 : task.getTopActivity() != null ? task.getTopActivity().packageName 3433 : "unknown"; 3434 taskBounds[i] = new Rect(); 3435 mWindowManager.getTaskBounds(task.taskId, taskBounds[i]); 3436 taskUserIds[i] = task.userId; 3437 } 3438 info.taskIds = taskIds; 3439 info.taskNames = taskNames; 3440 info.taskBounds = taskBounds; 3441 info.taskUserIds = taskUserIds; 3442 3443 final ActivityRecord top = stack.topRunningActivityLocked(); 3444 info.topActivity = top != null ? top.intent.getComponent() : null; 3445 return info; 3446 } 3447 3448 StackInfo getStackInfoLocked(int stackId) { 3449 ActivityStack stack = getStack(stackId); 3450 if (stack != null) { 3451 return getStackInfoLocked(stack); 3452 } 3453 return null; 3454 } 3455 3456 ArrayList<StackInfo> getAllStackInfosLocked() { 3457 ArrayList<StackInfo> list = new ArrayList<>(); 3458 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3459 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3460 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3461 list.add(getStackInfoLocked(stacks.get(ndx))); 3462 } 3463 } 3464 return list; 3465 } 3466 3467 TaskRecord getLockedTaskLocked() { 3468 final int top = mLockTaskModeTasks.size() - 1; 3469 if (top >= 0) { 3470 return mLockTaskModeTasks.get(top); 3471 } 3472 return null; 3473 } 3474 3475 boolean isLockedTask(TaskRecord task) { 3476 return mLockTaskModeTasks.contains(task); 3477 } 3478 3479 boolean isLastLockedTask(TaskRecord task) { 3480 return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task); 3481 } 3482 3483 void removeLockedTaskLocked(final TaskRecord task) { 3484 if (!mLockTaskModeTasks.remove(task)) { 3485 return; 3486 } 3487 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task); 3488 if (mLockTaskModeTasks.isEmpty()) { 3489 // Last one. 3490 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task + 3491 " last task, reverting locktask mode. Callers=" + Debug.getCallers(3)); 3492 final Message lockTaskMsg = Message.obtain(); 3493 lockTaskMsg.arg1 = task.userId; 3494 lockTaskMsg.what = LOCK_TASK_END_MSG; 3495 mHandler.sendMessage(lockTaskMsg); 3496 } 3497 } 3498 3499 void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) { 3500 handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId, 3501 false /* forceNonResizable */); 3502 } 3503 3504 void handleNonResizableTaskIfNeeded( 3505 TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) { 3506 if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID) 3507 || task.isHomeTask()) { 3508 return; 3509 } 3510 3511 final ActivityRecord topActivity = task.getTopActivity(); 3512 if (!task.canGoInDockedStack() || forceNonResizable) { 3513 // Display a warning toast that we tried to put a non-dockable task in the docked stack. 3514 mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG); 3515 3516 // Dismiss docked stack. If task appeared to be in docked stack but is not resizable - 3517 // we need to move it to top of fullscreen stack, otherwise it will be covered. 3518 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID); 3519 } else if (topActivity != null && topActivity.isNonResizableOrForced() 3520 && !topActivity.noDisplay) { 3521 String packageName = topActivity.appInfo.packageName; 3522 mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0, 3523 packageName).sendToTarget(); 3524 } 3525 } 3526 3527 void showLockTaskToast() { 3528 if (mLockTaskNotify != null) { 3529 mLockTaskNotify.showToast(mLockTaskModeState); 3530 } 3531 } 3532 3533 void showLockTaskEscapeMessageLocked(TaskRecord task) { 3534 if (mLockTaskModeTasks.contains(task)) { 3535 mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG); 3536 } 3537 } 3538 3539 void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason, 3540 boolean andResume) { 3541 if (task == null) { 3542 // Take out of lock task mode if necessary 3543 final TaskRecord lockedTask = getLockedTaskLocked(); 3544 if (lockedTask != null) { 3545 removeLockedTaskLocked(lockedTask); 3546 if (!mLockTaskModeTasks.isEmpty()) { 3547 // There are locked tasks remaining, can only finish this task, not unlock it. 3548 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3549 "setLockTaskModeLocked: Tasks remaining, can't unlock"); 3550 lockedTask.performClearTaskLocked(); 3551 resumeFocusedStackTopActivityLocked(); 3552 return; 3553 } 3554 } 3555 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3556 "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4)); 3557 return; 3558 } 3559 3560 // Should have already been checked, but do it again. 3561 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 3562 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3563 "setLockTaskModeLocked: Can't lock due to auth"); 3564 return; 3565 } 3566 if (isLockTaskModeViolation(task)) { 3567 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 3568 return; 3569 } 3570 3571 if (mLockTaskModeTasks.isEmpty()) { 3572 // First locktask. 3573 final Message lockTaskMsg = Message.obtain(); 3574 lockTaskMsg.obj = task.intent.getComponent().getPackageName(); 3575 lockTaskMsg.arg1 = task.userId; 3576 lockTaskMsg.what = LOCK_TASK_START_MSG; 3577 lockTaskMsg.arg2 = lockTaskModeState; 3578 mHandler.sendMessage(lockTaskMsg); 3579 } 3580 // Add it or move it to the top. 3581 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task + 3582 " Callers=" + Debug.getCallers(4)); 3583 mLockTaskModeTasks.remove(task); 3584 mLockTaskModeTasks.add(task); 3585 3586 if (task.mLockTaskUid == -1) { 3587 task.mLockTaskUid = task.effectiveUid; 3588 } 3589 3590 if (andResume) { 3591 findTaskToMoveToFrontLocked(task, 0, null, reason, 3592 lockTaskModeState != LOCK_TASK_MODE_NONE); 3593 resumeFocusedStackTopActivityLocked(); 3594 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { 3595 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId, 3596 true /* forceNonResizable */); 3597 } 3598 } 3599 3600 boolean isLockTaskModeViolation(TaskRecord task) { 3601 return isLockTaskModeViolation(task, false); 3602 } 3603 3604 boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) { 3605 if (getLockedTaskLocked() == task && !isNewClearTask) { 3606 return false; 3607 } 3608 final int lockTaskAuth = task.mLockTaskAuth; 3609 switch (lockTaskAuth) { 3610 case LOCK_TASK_AUTH_DONT_LOCK: 3611 return !mLockTaskModeTasks.isEmpty(); 3612 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 3613 case LOCK_TASK_AUTH_LAUNCHABLE: 3614 case LOCK_TASK_AUTH_WHITELISTED: 3615 return false; 3616 case LOCK_TASK_AUTH_PINNABLE: 3617 // Pinnable tasks can't be launched on top of locktask tasks. 3618 return !mLockTaskModeTasks.isEmpty(); 3619 default: 3620 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth); 3621 return true; 3622 } 3623 } 3624 3625 void onLockTaskPackagesUpdatedLocked() { 3626 boolean didSomething = false; 3627 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 3628 final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); 3629 final boolean wasWhitelisted = 3630 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3631 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3632 lockedTask.setLockTaskAuth(); 3633 final boolean isWhitelisted = 3634 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3635 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3636 if (wasWhitelisted && !isWhitelisted) { 3637 // Lost whitelisting authorization. End it now. 3638 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + 3639 lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); 3640 removeLockedTaskLocked(lockedTask); 3641 lockedTask.performClearTaskLocked(); 3642 didSomething = true; 3643 } 3644 } 3645 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3646 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3647 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3648 final ActivityStack stack = stacks.get(stackNdx); 3649 stack.onLockTaskPackagesUpdatedLocked(); 3650 } 3651 } 3652 final ActivityRecord r = topRunningActivityLocked(); 3653 final TaskRecord task = r != null ? r.task : null; 3654 if (mLockTaskModeTasks.isEmpty() && task != null 3655 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 3656 // This task must have just been authorized. 3657 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, 3658 "onLockTaskPackagesUpdated: starting new locktask task=" + task); 3659 setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated", 3660 false); 3661 didSomething = true; 3662 } 3663 if (didSomething) { 3664 resumeFocusedStackTopActivityLocked(); 3665 } 3666 } 3667 3668 int getLockTaskModeState() { 3669 return mLockTaskModeState; 3670 } 3671 3672 void activityRelaunchedLocked(IBinder token) { 3673 mWindowManager.notifyAppRelaunchingFinished(token); 3674 } 3675 3676 void activityRelaunchingLocked(ActivityRecord r) { 3677 mWindowManager.notifyAppRelaunching(r.appToken); 3678 } 3679 3680 void logStackState() { 3681 mActivityMetricsLogger.logWindowState(); 3682 } 3683 3684 void scheduleReportMultiWindowModeChanged(TaskRecord task) { 3685 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3686 final ActivityRecord r = task.mActivities.get(i); 3687 if (r.app != null && r.app.thread != null) { 3688 mMultiWindowModeChangedActivities.add(r); 3689 } 3690 } 3691 3692 if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) { 3693 mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG); 3694 } 3695 } 3696 3697 void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) { 3698 final ActivityStack stack = task.stack; 3699 if (prevStack == null || prevStack == stack 3700 || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) { 3701 return; 3702 } 3703 3704 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3705 final ActivityRecord r = task.mActivities.get(i); 3706 if (r.app != null && r.app.thread != null) { 3707 mPipModeChangedActivities.add(r); 3708 } 3709 } 3710 3711 if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { 3712 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); 3713 } 3714 } 3715 3716 void setDockedStackMinimized(boolean minimized) { 3717 mIsDockMinimized = minimized; 3718 if (minimized) { 3719 // Docked stack is not visible, no need to confirm credentials for its top activity. 3720 return; 3721 } 3722 final ActivityStack dockedStack = getStack(StackId.DOCKED_STACK_ID); 3723 if (dockedStack == null) { 3724 return; 3725 } 3726 final ActivityRecord top = dockedStack.topRunningActivityLocked(); 3727 if (top != null && mService.mUserController.shouldConfirmCredentials(top.userId)) { 3728 mService.mActivityStarter.showConfirmDeviceCredential(top.userId); 3729 } 3730 } 3731 3732 private final class ActivityStackSupervisorHandler extends Handler { 3733 3734 public ActivityStackSupervisorHandler(Looper looper) { 3735 super(looper); 3736 } 3737 3738 void activityIdleInternal(ActivityRecord r) { 3739 synchronized (mService) { 3740 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3741 } 3742 } 3743 3744 @Override 3745 public void handleMessage(Message msg) { 3746 switch (msg.what) { 3747 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: { 3748 synchronized (mService) { 3749 for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) { 3750 final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i); 3751 r.scheduleMultiWindowModeChanged(); 3752 } 3753 } 3754 } break; 3755 case REPORT_PIP_MODE_CHANGED_MSG: { 3756 synchronized (mService) { 3757 for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) { 3758 final ActivityRecord r = mPipModeChangedActivities.remove(i); 3759 r.schedulePictureInPictureModeChanged(); 3760 } 3761 } 3762 } break; 3763 case IDLE_TIMEOUT_MSG: { 3764 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3765 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3766 if (mService.mDidDexOpt) { 3767 mService.mDidDexOpt = false; 3768 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3769 nmsg.obj = msg.obj; 3770 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3771 return; 3772 } 3773 // We don't at this point know if the activity is fullscreen, 3774 // so we need to be conservative and assume it isn't. 3775 activityIdleInternal((ActivityRecord)msg.obj); 3776 } break; 3777 case IDLE_NOW_MSG: { 3778 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3779 activityIdleInternal((ActivityRecord)msg.obj); 3780 } break; 3781 case RESUME_TOP_ACTIVITY_MSG: { 3782 synchronized (mService) { 3783 resumeFocusedStackTopActivityLocked(); 3784 } 3785 } break; 3786 case SLEEP_TIMEOUT_MSG: { 3787 synchronized (mService) { 3788 if (mService.isSleepingOrShuttingDown()) { 3789 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3790 mSleepTimeout = true; 3791 checkReadyForSleepLocked(); 3792 } 3793 } 3794 } break; 3795 case LAUNCH_TIMEOUT_MSG: { 3796 if (mService.mDidDexOpt) { 3797 mService.mDidDexOpt = false; 3798 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3799 return; 3800 } 3801 synchronized (mService) { 3802 if (mLaunchingActivity.isHeld()) { 3803 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3804 if (VALIDATE_WAKE_LOCK_CALLER 3805 && Binder.getCallingUid() != Process.myUid()) { 3806 throw new IllegalStateException("Calling must be system uid"); 3807 } 3808 mLaunchingActivity.release(); 3809 } 3810 } 3811 } break; 3812 case HANDLE_DISPLAY_ADDED: { 3813 handleDisplayAdded(msg.arg1); 3814 } break; 3815 case HANDLE_DISPLAY_CHANGED: { 3816 handleDisplayChanged(msg.arg1); 3817 } break; 3818 case HANDLE_DISPLAY_REMOVED: { 3819 handleDisplayRemoved(msg.arg1); 3820 } break; 3821 case CONTAINER_CALLBACK_VISIBILITY: { 3822 final ActivityContainer container = (ActivityContainer) msg.obj; 3823 final IActivityContainerCallback callback = container.mCallback; 3824 if (callback != null) { 3825 try { 3826 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3827 } catch (RemoteException e) { 3828 } 3829 } 3830 } break; 3831 case LOCK_TASK_START_MSG: { 3832 // When lock task starts, we disable the status bars. 3833 try { 3834 if (mLockTaskNotify == null) { 3835 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3836 } 3837 mLockTaskNotify.show(true); 3838 mLockTaskModeState = msg.arg2; 3839 if (getStatusBarService() != null) { 3840 int flags = 0; 3841 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 3842 flags = StatusBarManager.DISABLE_MASK 3843 & (~StatusBarManager.DISABLE_BACK); 3844 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 3845 flags = StatusBarManager.DISABLE_MASK 3846 & (~StatusBarManager.DISABLE_BACK) 3847 & (~StatusBarManager.DISABLE_HOME) 3848 & (~StatusBarManager.DISABLE_RECENT); 3849 } 3850 getStatusBarService().disable(flags, mToken, 3851 mService.mContext.getPackageName()); 3852 } 3853 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3854 if (getDevicePolicyManager() != null) { 3855 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3856 (String)msg.obj, msg.arg1); 3857 } 3858 } catch (RemoteException ex) { 3859 throw new RuntimeException(ex); 3860 } 3861 } break; 3862 case LOCK_TASK_END_MSG: { 3863 // When lock task ends, we enable the status bars. 3864 try { 3865 if (getStatusBarService() != null) { 3866 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3867 mService.mContext.getPackageName()); 3868 } 3869 mWindowManager.reenableKeyguard(mToken); 3870 if (getDevicePolicyManager() != null) { 3871 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3872 msg.arg1); 3873 } 3874 if (mLockTaskNotify == null) { 3875 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3876 } 3877 mLockTaskNotify.show(false); 3878 try { 3879 boolean shouldLockKeyguard = Settings.Secure.getInt( 3880 mService.mContext.getContentResolver(), 3881 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; 3882 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) { 3883 mWindowManager.lockNow(null); 3884 mWindowManager.dismissKeyguard(); 3885 new LockPatternUtils(mService.mContext) 3886 .requireCredentialEntry(UserHandle.USER_ALL); 3887 } 3888 } catch (SettingNotFoundException e) { 3889 // No setting, don't lock. 3890 } 3891 } catch (RemoteException ex) { 3892 throw new RuntimeException(ex); 3893 } finally { 3894 mLockTaskModeState = LOCK_TASK_MODE_NONE; 3895 } 3896 } break; 3897 case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: { 3898 if (mLockTaskNotify == null) { 3899 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3900 } 3901 mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED); 3902 } break; 3903 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3904 final ActivityContainer container = (ActivityContainer) msg.obj; 3905 final IActivityContainerCallback callback = container.mCallback; 3906 if (callback != null) { 3907 try { 3908 callback.onAllActivitiesComplete(container.asBinder()); 3909 } catch (RemoteException e) { 3910 } 3911 } 3912 } break; 3913 case LAUNCH_TASK_BEHIND_COMPLETE: { 3914 synchronized (mService) { 3915 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 3916 if (r != null) { 3917 handleLaunchTaskBehindCompleteLocked(r); 3918 } 3919 } 3920 } break; 3921 3922 } 3923 } 3924 } 3925 3926 class ActivityContainer extends android.app.IActivityContainer.Stub { 3927 final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK | 3928 FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3929 final int mStackId; 3930 IActivityContainerCallback mCallback = null; 3931 final ActivityStack mStack; 3932 ActivityRecord mParentActivity = null; 3933 String mIdString; 3934 3935 boolean mVisible = true; 3936 3937 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3938 ActivityDisplay mActivityDisplay; 3939 3940 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3941 final static int CONTAINER_STATE_NO_SURFACE = 1; 3942 final static int CONTAINER_STATE_FINISHING = 2; 3943 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3944 3945 ActivityContainer(int stackId) { 3946 synchronized (mService) { 3947 mStackId = stackId; 3948 mStack = new ActivityStack(this, mRecentTasks); 3949 mIdString = "ActivtyContainer{" + mStackId + "}"; 3950 if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this); 3951 } 3952 } 3953 3954 void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) { 3955 if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this 3956 + " to display=" + activityDisplay + " onTop=" + onTop); 3957 mActivityDisplay = activityDisplay; 3958 mStack.attachDisplay(activityDisplay, onTop); 3959 activityDisplay.attachActivities(mStack, onTop); 3960 } 3961 3962 @Override 3963 public void attachToDisplay(int displayId) { 3964 synchronized (mService) { 3965 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3966 if (activityDisplay == null) { 3967 return; 3968 } 3969 attachToDisplayLocked(activityDisplay, true); 3970 } 3971 } 3972 3973 @Override 3974 public int getDisplayId() { 3975 synchronized (mService) { 3976 if (mActivityDisplay != null) { 3977 return mActivityDisplay.mDisplayId; 3978 } 3979 } 3980 return -1; 3981 } 3982 3983 @Override 3984 public int getStackId() { 3985 synchronized (mService) { 3986 return mStackId; 3987 } 3988 } 3989 3990 @Override 3991 public boolean injectEvent(InputEvent event) { 3992 final long origId = Binder.clearCallingIdentity(); 3993 try { 3994 synchronized (mService) { 3995 if (mActivityDisplay != null) { 3996 return mInputManagerInternal.injectInputEvent(event, 3997 mActivityDisplay.mDisplayId, 3998 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3999 } 4000 } 4001 return false; 4002 } finally { 4003 Binder.restoreCallingIdentity(origId); 4004 } 4005 } 4006 4007 @Override 4008 public void release() { 4009 synchronized (mService) { 4010 if (mContainerState == CONTAINER_STATE_FINISHING) { 4011 return; 4012 } 4013 mContainerState = CONTAINER_STATE_FINISHING; 4014 4015 long origId = Binder.clearCallingIdentity(); 4016 try { 4017 mStack.finishAllActivitiesLocked(false); 4018 mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack); 4019 } finally { 4020 Binder.restoreCallingIdentity(origId); 4021 } 4022 } 4023 } 4024 4025 protected void detachLocked() { 4026 if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display=" 4027 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 4028 if (mActivityDisplay != null) { 4029 mActivityDisplay.detachActivitiesLocked(mStack); 4030 mActivityDisplay = null; 4031 mStack.detachDisplay(); 4032 } 4033 } 4034 4035 @Override 4036 public final int startActivity(Intent intent) { 4037 return mService.startActivity(intent, this); 4038 } 4039 4040 @Override 4041 public final int startActivityIntentSender(IIntentSender intentSender) 4042 throws TransactionTooLargeException { 4043 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 4044 4045 if (!(intentSender instanceof PendingIntentRecord)) { 4046 throw new IllegalArgumentException("Bad PendingIntent object"); 4047 } 4048 4049 final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(), 4050 Binder.getCallingUid(), mCurrentUser, false, 4051 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 4052 4053 final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 4054 checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent, 4055 pendingIntent.key.requestResolvedType); 4056 4057 return pendingIntent.sendInner(0, null, null, null, null, null, null, 0, 4058 FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 4059 } 4060 4061 void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) { 4062 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 4063 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 4064 throw new SecurityException( 4065 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 4066 } 4067 } 4068 4069 @Override 4070 public IBinder asBinder() { 4071 return this; 4072 } 4073 4074 @Override 4075 public void setSurface(Surface surface, int width, int height, int density) { 4076 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 4077 } 4078 4079 ActivityStackSupervisor getOuter() { 4080 return ActivityStackSupervisor.this; 4081 } 4082 4083 boolean isAttachedLocked() { 4084 return mActivityDisplay != null; 4085 } 4086 4087 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 4088 void setVisible(boolean visible) { 4089 if (mVisible != visible) { 4090 mVisible = visible; 4091 if (mCallback != null) { 4092 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 4093 0 /* unused */, this).sendToTarget(); 4094 } 4095 } 4096 } 4097 4098 void setDrawn() { 4099 } 4100 4101 // You can always start a new task on a regular ActivityStack. 4102 boolean isEligibleForNewTasks() { 4103 return true; 4104 } 4105 4106 void onTaskListEmptyLocked() { 4107 detachLocked(); 4108 deleteActivityContainer(this); 4109 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 4110 } 4111 4112 @Override 4113 public String toString() { 4114 return mIdString + (mActivityDisplay == null ? "N" : "A"); 4115 } 4116 } 4117 4118 private class VirtualActivityContainer extends ActivityContainer { 4119 Surface mSurface; 4120 boolean mDrawn = false; 4121 4122 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 4123 super(getNextStackId()); 4124 mParentActivity = parent; 4125 mCallback = callback; 4126 mContainerState = CONTAINER_STATE_NO_SURFACE; 4127 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 4128 } 4129 4130 @Override 4131 public void setSurface(Surface surface, int width, int height, int density) { 4132 super.setSurface(surface, width, height, density); 4133 4134 synchronized (mService) { 4135 final long origId = Binder.clearCallingIdentity(); 4136 try { 4137 setSurfaceLocked(surface, width, height, density); 4138 } finally { 4139 Binder.restoreCallingIdentity(origId); 4140 } 4141 } 4142 } 4143 4144 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 4145 if (mContainerState == CONTAINER_STATE_FINISHING) { 4146 return; 4147 } 4148 VirtualActivityDisplay virtualActivityDisplay = 4149 (VirtualActivityDisplay) mActivityDisplay; 4150 if (virtualActivityDisplay == null) { 4151 virtualActivityDisplay = 4152 new VirtualActivityDisplay(width, height, density); 4153 mActivityDisplay = virtualActivityDisplay; 4154 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 4155 attachToDisplayLocked(virtualActivityDisplay, true); 4156 } 4157 4158 if (mSurface != null) { 4159 mSurface.release(); 4160 } 4161 4162 mSurface = surface; 4163 if (surface != null) { 4164 resumeFocusedStackTopActivityLocked(); 4165 } else { 4166 mContainerState = CONTAINER_STATE_NO_SURFACE; 4167 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 4168 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 4169 mStack.startPausingLocked(false, true, false, false); 4170 } 4171 } 4172 4173 setSurfaceIfReadyLocked(); 4174 4175 if (DEBUG_STACK) Slog.d(TAG_STACK, 4176 "setSurface: " + this + " to display=" + virtualActivityDisplay); 4177 } 4178 4179 @Override 4180 boolean isAttachedLocked() { 4181 return mSurface != null && super.isAttachedLocked(); 4182 } 4183 4184 @Override 4185 void setDrawn() { 4186 synchronized (mService) { 4187 mDrawn = true; 4188 setSurfaceIfReadyLocked(); 4189 } 4190 } 4191 4192 // Never start a new task on an ActivityView if it isn't explicitly specified. 4193 @Override 4194 boolean isEligibleForNewTasks() { 4195 return false; 4196 } 4197 4198 private void setSurfaceIfReadyLocked() { 4199 if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 4200 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 4201 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 4202 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 4203 mContainerState = CONTAINER_STATE_HAS_SURFACE; 4204 } 4205 } 4206 } 4207 4208 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 4209 * attached {@link ActivityStack}s */ 4210 class ActivityDisplay { 4211 /** Actual Display this object tracks. */ 4212 int mDisplayId; 4213 Display mDisplay; 4214 DisplayInfo mDisplayInfo = new DisplayInfo(); 4215 4216 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 4217 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 4218 final ArrayList<ActivityStack> mStacks = new ArrayList<>(); 4219 4220 ActivityRecord mVisibleBehindActivity; 4221 4222 ActivityDisplay() { 4223 } 4224 4225 // After instantiation, check that mDisplay is not null before using this. The alternative 4226 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. 4227 ActivityDisplay(int displayId) { 4228 final Display display = mDisplayManager.getDisplay(displayId); 4229 if (display == null) { 4230 return; 4231 } 4232 init(display); 4233 } 4234 4235 void init(Display display) { 4236 mDisplay = display; 4237 mDisplayId = display.getDisplayId(); 4238 mDisplay.getDisplayInfo(mDisplayInfo); 4239 } 4240 4241 void attachActivities(ActivityStack stack, boolean onTop) { 4242 if (DEBUG_STACK) Slog.v(TAG_STACK, 4243 "attachActivities: attaching " + stack + " to displayId=" + mDisplayId 4244 + " onTop=" + onTop); 4245 if (onTop) { 4246 mStacks.add(stack); 4247 } else { 4248 mStacks.add(0, stack); 4249 } 4250 } 4251 4252 void detachActivitiesLocked(ActivityStack stack) { 4253 if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack 4254 + " from displayId=" + mDisplayId); 4255 mStacks.remove(stack); 4256 } 4257 4258 void setVisibleBehindActivity(ActivityRecord r) { 4259 mVisibleBehindActivity = r; 4260 } 4261 4262 boolean hasVisibleBehindActivity() { 4263 return mVisibleBehindActivity != null; 4264 } 4265 4266 @Override 4267 public String toString() { 4268 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4269 } 4270 } 4271 4272 class VirtualActivityDisplay extends ActivityDisplay { 4273 VirtualDisplay mVirtualDisplay; 4274 4275 VirtualActivityDisplay(int width, int height, int density) { 4276 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 4277 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 4278 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 4279 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 4280 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 4281 4282 init(mVirtualDisplay.getDisplay()); 4283 4284 mWindowManager.handleDisplayAdded(mDisplayId); 4285 } 4286 4287 void setSurface(Surface surface) { 4288 if (mVirtualDisplay != null) { 4289 mVirtualDisplay.setSurface(surface); 4290 } 4291 } 4292 4293 @Override 4294 void detachActivitiesLocked(ActivityStack stack) { 4295 super.detachActivitiesLocked(stack); 4296 if (mVirtualDisplay != null) { 4297 mVirtualDisplay.release(); 4298 mVirtualDisplay = null; 4299 } 4300 } 4301 4302 @Override 4303 public String toString() { 4304 return "VirtualActivityDisplay={" + mDisplayId + "}"; 4305 } 4306 } 4307 4308 /** 4309 * Adjust bounds to stay within stack bounds. 4310 * 4311 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way 4312 * that keep them unchanged, but be contained within the stack bounds. 4313 * 4314 * @param bounds Bounds to be adjusted. 4315 * @param stackBounds Bounds within which the other bounds should remain. 4316 */ 4317 private static void fitWithinBounds(Rect bounds, Rect stackBounds) { 4318 if (stackBounds == null || stackBounds.contains(bounds)) { 4319 return; 4320 } 4321 4322 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) { 4323 final int maxRight = stackBounds.right 4324 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER); 4325 int horizontalDiff = stackBounds.left - bounds.left; 4326 if ((horizontalDiff < 0 && bounds.left >= maxRight) 4327 || (bounds.left + horizontalDiff >= maxRight)) { 4328 horizontalDiff = maxRight - bounds.left; 4329 } 4330 bounds.left += horizontalDiff; 4331 bounds.right += horizontalDiff; 4332 } 4333 4334 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) { 4335 final int maxBottom = stackBounds.bottom 4336 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER); 4337 int verticalDiff = stackBounds.top - bounds.top; 4338 if ((verticalDiff < 0 && bounds.top >= maxBottom) 4339 || (bounds.top + verticalDiff >= maxBottom)) { 4340 verticalDiff = maxBottom - bounds.top; 4341 } 4342 bounds.top += verticalDiff; 4343 bounds.bottom += verticalDiff; 4344 } 4345 } 4346 4347 ActivityStack findStackBehind(ActivityStack stack) { 4348 // TODO(multi-display): We are only looking for stacks on the default display. 4349 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4350 if (display == null) { 4351 return null; 4352 } 4353 final ArrayList<ActivityStack> stacks = display.mStacks; 4354 for (int i = stacks.size() - 1; i >= 0; i--) { 4355 if (stacks.get(i) == stack && i > 0) { 4356 return stacks.get(i - 1); 4357 } 4358 } 4359 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 4360 + " in=" + stacks); 4361 } 4362 4363 /** 4364 * Puts a task into resizing mode during the next app transition. 4365 * 4366 * @param taskId the id of the task to put into resizing mode 4367 */ 4368 private void setResizingDuringAnimation(int taskId) { 4369 mResizingTasksDuringAnimation.add(taskId); 4370 mWindowManager.setTaskDockedResizing(taskId, true); 4371 } 4372 4373 final int startActivityFromRecentsInner(int taskId, Bundle bOptions) { 4374 final TaskRecord task; 4375 final int callingUid; 4376 final String callingPackage; 4377 final Intent intent; 4378 final int userId; 4379 final ActivityOptions activityOptions = (bOptions != null) 4380 ? new ActivityOptions(bOptions) : null; 4381 final int launchStackId = (activityOptions != null) 4382 ? activityOptions.getLaunchStackId() : INVALID_STACK_ID; 4383 if (launchStackId == HOME_STACK_ID) { 4384 throw new IllegalArgumentException("startActivityFromRecentsInner: Task " 4385 + taskId + " can't be launch in the home stack."); 4386 } 4387 4388 if (launchStackId == DOCKED_STACK_ID) { 4389 mWindowManager.setDockedStackCreateState( 4390 activityOptions.getDockCreateMode(), null /* initialBounds */); 4391 4392 // Defer updating the stack in which recents is until the app transition is done, to 4393 // not run into issues where we still need to draw the task in recents but the 4394 // docked stack is already created. 4395 deferUpdateBounds(HOME_STACK_ID); 4396 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false); 4397 } 4398 4399 task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId); 4400 if (task == null) { 4401 continueUpdateBounds(HOME_STACK_ID); 4402 mWindowManager.executeAppTransition(); 4403 throw new IllegalArgumentException( 4404 "startActivityFromRecentsInner: Task " + taskId + " not found."); 4405 } 4406 4407 if (launchStackId != INVALID_STACK_ID) { 4408 if (task.stack.mStackId != launchStackId) { 4409 moveTaskToStackLocked( 4410 taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents", 4411 ANIMATE); 4412 } 4413 } 4414 4415 // If the user must confirm credentials (e.g. when first launching a work app and the 4416 // Work Challenge is present) let startActivityInPackage handle the intercepting. 4417 if (!mService.mUserController.shouldConfirmCredentials(task.userId) 4418 && task.getRootActivity() != null) { 4419 mActivityMetricsLogger.notifyActivityLaunching(); 4420 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions); 4421 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT, 4422 task.getTopActivity()); 4423 4424 // If we are launching the task in the docked stack, put it into resizing mode so 4425 // the window renders full-screen with the background filling the void. Also only 4426 // call this at the end to make sure that tasks exists on the window manager side. 4427 if (launchStackId == DOCKED_STACK_ID) { 4428 setResizingDuringAnimation(taskId); 4429 } 4430 return ActivityManager.START_TASK_TO_FRONT; 4431 } 4432 callingUid = task.mCallingUid; 4433 callingPackage = task.mCallingPackage; 4434 intent = task.intent; 4435 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 4436 userId = task.userId; 4437 int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null, 4438 null, null, 0, 0, bOptions, userId, null, task); 4439 if (launchStackId == DOCKED_STACK_ID) { 4440 setResizingDuringAnimation(task.taskId); 4441 } 4442 return result; 4443 } 4444 4445 /** 4446 * @return a list of activities which are the top ones in each visible stack. The first 4447 * entry will be the focused activity. 4448 */ 4449 public List<IBinder> getTopVisibleActivities() { 4450 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4451 if (display == null) { 4452 return Collections.EMPTY_LIST; 4453 } 4454 ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 4455 final ArrayList<ActivityStack> stacks = display.mStacks; 4456 for (int i = stacks.size() - 1; i >= 0; i--) { 4457 ActivityStack stack = stacks.get(i); 4458 if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) { 4459 ActivityRecord top = stack.topActivity(); 4460 if (top != null) { 4461 if (stack == mFocusedStack) { 4462 topActivityTokens.add(0, top.appToken); 4463 } else { 4464 topActivityTokens.add(top.appToken); 4465 } 4466 } 4467 } 4468 } 4469 return topActivityTokens; 4470 } 4471} 4472