ActivityStackSupervisor.java revision 9a98c526dd532ee3be29f6ba6640829c75f9cf1e
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.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; 127import static android.content.pm.PackageManager.PERMISSION_GRANTED; 128import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS; 131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE; 132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN; 133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; 134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE; 135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; 137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; 139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND; 142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS; 143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE; 144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; 145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE; 146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; 148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES; 150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; 152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; 153import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 154import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 155import static com.android.server.am.ActivityManagerService.ANIMATE; 156import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 157import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG; 158import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG; 159import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; 160import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; 161import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; 162import static com.android.server.am.ActivityStack.ActivityState.DESTROYED; 163import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; 164import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING; 165import static com.android.server.am.ActivityStack.ActivityState.PAUSED; 166import static com.android.server.am.ActivityStack.ActivityState.PAUSING; 167import static com.android.server.am.ActivityStack.ActivityState.RESUMED; 168import static com.android.server.am.ActivityStack.ActivityState.STOPPED; 169import static com.android.server.am.ActivityStack.ActivityState.STOPPING; 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 mDefaultMinimalSizeOfResizeableTask = -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 mService.mServices.updateServiceConnectionActivitiesLocked(r.app); 1342 1343 return true; 1344 } 1345 1346 void startSpecificActivityLocked(ActivityRecord r, 1347 boolean andResume, boolean checkConfig) { 1348 // Is this activity's application already running? 1349 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1350 r.info.applicationInfo.uid, true); 1351 1352 r.task.stack.setLaunchTime(r); 1353 1354 if (app != null && app.thread != null) { 1355 try { 1356 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1357 || !"android".equals(r.info.packageName)) { 1358 // Don't add this if it is a platform component that is marked 1359 // to run in multiple processes, because this is actually 1360 // part of the framework so doesn't make sense to track as a 1361 // separate apk in the process. 1362 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, 1363 mService.mProcessStats); 1364 } 1365 realStartActivityLocked(r, app, andResume, checkConfig); 1366 return; 1367 } catch (RemoteException e) { 1368 Slog.w(TAG, "Exception when starting activity " 1369 + r.intent.getComponent().flattenToShortString(), e); 1370 } 1371 1372 // If a dead object exception was thrown -- fall through to 1373 // restart the application. 1374 } 1375 1376 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1377 "activity", r.intent.getComponent(), false, false, true); 1378 } 1379 1380 boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, 1381 String resultWho, int requestCode, int callingPid, int callingUid, 1382 String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp, 1383 ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options) { 1384 final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, 1385 callingUid); 1386 if (startAnyPerm == PERMISSION_GRANTED) { 1387 return true; 1388 } 1389 final int componentRestriction = getComponentRestrictionForCallingPackage( 1390 aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity); 1391 final int actionRestriction = getActionRestrictionForCallingPackage( 1392 intent.getAction(), callingPackage, callingPid, callingUid); 1393 if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION 1394 || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1395 if (resultRecord != null) { 1396 resultStack.sendActivityResultLocked(-1, 1397 resultRecord, resultWho, requestCode, 1398 Activity.RESULT_CANCELED, null); 1399 } 1400 final String msg; 1401 if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { 1402 msg = "Permission Denial: starting " + intent.toString() 1403 + " from " + callerApp + " (pid=" + callingPid 1404 + ", uid=" + callingUid + ")" + " with revoked permission " 1405 + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); 1406 } else if (!aInfo.exported) { 1407 msg = "Permission Denial: starting " + intent.toString() 1408 + " from " + callerApp + " (pid=" + callingPid 1409 + ", uid=" + callingUid + ")" 1410 + " not exported from uid " + aInfo.applicationInfo.uid; 1411 } else { 1412 msg = "Permission Denial: starting " + intent.toString() 1413 + " from " + callerApp + " (pid=" + callingPid 1414 + ", uid=" + callingUid + ")" 1415 + " requires " + aInfo.permission; 1416 } 1417 Slog.w(TAG, msg); 1418 throw new SecurityException(msg); 1419 } 1420 1421 if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) { 1422 final String message = "Appop Denial: starting " + intent.toString() 1423 + " from " + callerApp + " (pid=" + callingPid 1424 + ", uid=" + callingUid + ")" 1425 + " requires " + AppOpsManager.permissionToOp( 1426 ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction())); 1427 Slog.w(TAG, message); 1428 return false; 1429 } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) { 1430 final String message = "Appop Denial: starting " + intent.toString() 1431 + " from " + callerApp + " (pid=" + callingPid 1432 + ", uid=" + callingUid + ")" 1433 + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission); 1434 Slog.w(TAG, message); 1435 return false; 1436 } 1437 if (options != null && options.getLaunchTaskId() != -1) { 1438 final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS, 1439 callingPid, callingUid); 1440 if (startInTaskPerm != PERMISSION_GRANTED) { 1441 final String msg = "Permission Denial: starting " + intent.toString() 1442 + " from " + callerApp + " (pid=" + callingPid 1443 + ", uid=" + callingUid + ") with launchTaskId=" 1444 + options.getLaunchTaskId(); 1445 Slog.w(TAG, msg); 1446 throw new SecurityException(msg); 1447 } 1448 } 1449 1450 return true; 1451 } 1452 1453 UserInfo getUserInfo(int userId) { 1454 final long identity = Binder.clearCallingIdentity(); 1455 try { 1456 return UserManager.get(mService.mContext).getUserInfo(userId); 1457 } finally { 1458 Binder.restoreCallingIdentity(identity); 1459 } 1460 } 1461 1462 private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, 1463 String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { 1464 if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, 1465 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) 1466 == PackageManager.PERMISSION_DENIED) { 1467 return ACTIVITY_RESTRICTION_PERMISSION; 1468 } 1469 1470 if (activityInfo.permission == null) { 1471 return ACTIVITY_RESTRICTION_NONE; 1472 } 1473 1474 final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); 1475 if (opCode == AppOpsManager.OP_NONE) { 1476 return ACTIVITY_RESTRICTION_NONE; 1477 } 1478 1479 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1480 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1481 if (!ignoreTargetSecurity) { 1482 return ACTIVITY_RESTRICTION_APPOP; 1483 } 1484 } 1485 1486 return ACTIVITY_RESTRICTION_NONE; 1487 } 1488 1489 private int getActionRestrictionForCallingPackage(String action, 1490 String callingPackage, int callingPid, int callingUid) { 1491 if (action == null) { 1492 return ACTIVITY_RESTRICTION_NONE; 1493 } 1494 1495 String permission = ACTION_TO_RUNTIME_PERMISSION.get(action); 1496 if (permission == null) { 1497 return ACTIVITY_RESTRICTION_NONE; 1498 } 1499 1500 final PackageInfo packageInfo; 1501 try { 1502 packageInfo = mService.mContext.getPackageManager() 1503 .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS); 1504 } catch (PackageManager.NameNotFoundException e) { 1505 Slog.i(TAG, "Cannot find package info for " + callingPackage); 1506 return ACTIVITY_RESTRICTION_NONE; 1507 } 1508 1509 if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) { 1510 return ACTIVITY_RESTRICTION_NONE; 1511 } 1512 1513 if (mService.checkPermission(permission, callingPid, callingUid) == 1514 PackageManager.PERMISSION_DENIED) { 1515 return ACTIVITY_RESTRICTION_PERMISSION; 1516 } 1517 1518 final int opCode = AppOpsManager.permissionToOpCode(permission); 1519 if (opCode == AppOpsManager.OP_NONE) { 1520 return ACTIVITY_RESTRICTION_NONE; 1521 } 1522 1523 if (mService.mAppOpsService.noteOperation(opCode, callingUid, 1524 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1525 return ACTIVITY_RESTRICTION_APPOP; 1526 } 1527 1528 return ACTIVITY_RESTRICTION_NONE; 1529 } 1530 1531 boolean moveActivityStackToFront(ActivityRecord r, String reason) { 1532 if (r == null) { 1533 // Not sure what you are trying to do, but it is not going to work... 1534 return false; 1535 } 1536 final TaskRecord task = r.task; 1537 if (task == null || task.stack == null) { 1538 Slog.w(TAG, "Can't move stack to front for r=" + r + " task=" + task); 1539 return false; 1540 } 1541 task.stack.moveToFront(reason, task); 1542 return true; 1543 } 1544 1545 void setLaunchSource(int uid) { 1546 mLaunchingActivity.setWorkSource(new WorkSource(uid)); 1547 } 1548 1549 void acquireLaunchWakelock() { 1550 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 1551 throw new IllegalStateException("Calling must be system uid"); 1552 } 1553 mLaunchingActivity.acquire(); 1554 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1555 // To be safe, don't allow the wake lock to be held for too long. 1556 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 1557 } 1558 } 1559 1560 /** 1561 * Called when the frontmost task is idle. 1562 * @return the state of mService.mBooting before this was called. 1563 */ 1564 private boolean checkFinishBootingLocked() { 1565 final boolean booting = mService.mBooting; 1566 boolean enableScreen = false; 1567 mService.mBooting = false; 1568 if (!mService.mBooted) { 1569 mService.mBooted = true; 1570 enableScreen = true; 1571 } 1572 if (booting || enableScreen) { 1573 mService.postFinishBooting(booting, enableScreen); 1574 } 1575 return booting; 1576 } 1577 1578 // Checked. 1579 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, 1580 Configuration config) { 1581 if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token); 1582 1583 ArrayList<ActivityRecord> finishes = null; 1584 ArrayList<UserState> startingUsers = null; 1585 int NS = 0; 1586 int NF = 0; 1587 boolean booting = false; 1588 boolean activityRemoved = false; 1589 1590 ActivityRecord r = ActivityRecord.forTokenLocked(token); 1591 if (r != null) { 1592 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers=" 1593 + Debug.getCallers(4)); 1594 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 1595 r.finishLaunchTickingLocked(); 1596 if (fromTimeout) { 1597 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 1598 } 1599 1600 // This is a hack to semi-deal with a race condition 1601 // in the client where it can be constructed with a 1602 // newer configuration from when we asked it to launch. 1603 // We'll update with whatever configuration it now says 1604 // it used to launch. 1605 if (config != null) { 1606 r.configuration = config; 1607 } 1608 1609 // We are now idle. If someone is waiting for a thumbnail from 1610 // us, we can now deliver. 1611 r.idle = true; 1612 1613 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 1614 if (isFocusedStack(r.task.stack) || fromTimeout) { 1615 booting = checkFinishBootingLocked(); 1616 } 1617 } 1618 1619 if (allResumedActivitiesIdle()) { 1620 if (r != null) { 1621 mService.scheduleAppGcsLocked(); 1622 } 1623 1624 if (mLaunchingActivity.isHeld()) { 1625 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 1626 if (VALIDATE_WAKE_LOCK_CALLER && 1627 Binder.getCallingUid() != Process.myUid()) { 1628 throw new IllegalStateException("Calling must be system uid"); 1629 } 1630 mLaunchingActivity.release(); 1631 } 1632 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1633 } 1634 1635 // Atomically retrieve all of the other things to do. 1636 final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true); 1637 NS = stops != null ? stops.size() : 0; 1638 if ((NF = mFinishingActivities.size()) > 0) { 1639 finishes = new ArrayList<>(mFinishingActivities); 1640 mFinishingActivities.clear(); 1641 } 1642 1643 if (mStartingUsers.size() > 0) { 1644 startingUsers = new ArrayList<>(mStartingUsers); 1645 mStartingUsers.clear(); 1646 } 1647 1648 // Stop any activities that are scheduled to do so but have been 1649 // waiting for the next one to start. 1650 for (int i = 0; i < NS; i++) { 1651 r = stops.get(i); 1652 final ActivityStack stack = r.task.stack; 1653 if (stack != null) { 1654 if (r.finishing) { 1655 stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false); 1656 } else { 1657 stack.stopActivityLocked(r); 1658 } 1659 } 1660 } 1661 1662 // Finish any activities that are scheduled to do so but have been 1663 // waiting for the next one to start. 1664 for (int i = 0; i < NF; i++) { 1665 r = finishes.get(i); 1666 final ActivityStack stack = r.task.stack; 1667 if (stack != null) { 1668 activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle"); 1669 } 1670 } 1671 1672 if (!booting) { 1673 // Complete user switch 1674 if (startingUsers != null) { 1675 for (int i = 0; i < startingUsers.size(); i++) { 1676 mService.mUserController.finishUserSwitch(startingUsers.get(i)); 1677 } 1678 } 1679 } 1680 1681 mService.trimApplications(); 1682 //dump(); 1683 //mWindowManager.dump(); 1684 1685 if (activityRemoved) { 1686 resumeFocusedStackTopActivityLocked(); 1687 } 1688 1689 return r; 1690 } 1691 1692 boolean handleAppDiedLocked(ProcessRecord app) { 1693 boolean hasVisibleActivities = false; 1694 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1695 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1696 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1697 hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); 1698 } 1699 } 1700 return hasVisibleActivities; 1701 } 1702 1703 void closeSystemDialogsLocked() { 1704 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1705 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1706 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1707 stacks.get(stackNdx).closeSystemDialogsLocked(); 1708 } 1709 } 1710 } 1711 1712 void removeUserLocked(int userId) { 1713 mUserStackInFront.delete(userId); 1714 } 1715 1716 /** 1717 * Update the last used stack id for non-current user (current user's last 1718 * used stack is the focused stack) 1719 */ 1720 void updateUserStackLocked(int userId, ActivityStack stack) { 1721 if (userId != mCurrentUser) { 1722 mUserStackInFront.put(userId, stack != null ? stack.getStackId() : HOME_STACK_ID); 1723 } 1724 } 1725 1726 /** 1727 * @return true if some activity was finished (or would have finished if doit were true). 1728 */ 1729 boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, 1730 boolean doit, boolean evenPersistent, int userId) { 1731 boolean didSomething = false; 1732 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1733 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1734 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1735 final ActivityStack stack = stacks.get(stackNdx); 1736 if (stack.finishDisabledPackageActivitiesLocked( 1737 packageName, filterByClasses, doit, evenPersistent, userId)) { 1738 didSomething = true; 1739 } 1740 } 1741 } 1742 return didSomething; 1743 } 1744 1745 void updatePreviousProcessLocked(ActivityRecord r) { 1746 // Now that this process has stopped, we may want to consider 1747 // it to be the previous app to try to keep around in case 1748 // the user wants to return to it. 1749 1750 // First, found out what is currently the foreground app, so that 1751 // we don't blow away the previous app if this activity is being 1752 // hosted by the process that is actually still the foreground. 1753 ProcessRecord fgApp = null; 1754 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1755 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1756 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1757 final ActivityStack stack = stacks.get(stackNdx); 1758 if (isFocusedStack(stack)) { 1759 if (stack.mResumedActivity != null) { 1760 fgApp = stack.mResumedActivity.app; 1761 } else if (stack.mPausingActivity != null) { 1762 fgApp = stack.mPausingActivity.app; 1763 } 1764 break; 1765 } 1766 } 1767 } 1768 1769 // Now set this one as the previous process, only if that really 1770 // makes sense to. 1771 if (r.app != null && fgApp != null && r.app != fgApp 1772 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 1773 && r.app != mService.mHomeProcess) { 1774 mService.mPreviousProcess = r.app; 1775 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 1776 } 1777 } 1778 1779 boolean resumeFocusedStackTopActivityLocked() { 1780 return resumeFocusedStackTopActivityLocked(null, null, null); 1781 } 1782 1783 boolean resumeFocusedStackTopActivityLocked( 1784 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 1785 if (targetStack != null && isFocusedStack(targetStack)) { 1786 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 1787 } 1788 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); 1789 return false; 1790 } 1791 1792 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) { 1793 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1794 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1795 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1796 stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo); 1797 } 1798 } 1799 } 1800 1801 TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) { 1802 TaskRecord finishedTask = null; 1803 ActivityStack focusedStack = getFocusedStack(); 1804 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1805 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1806 final int numStacks = stacks.size(); 1807 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1808 final ActivityStack stack = stacks.get(stackNdx); 1809 TaskRecord t = stack.finishTopRunningActivityLocked(app, reason); 1810 if (stack == focusedStack || finishedTask == null) { 1811 finishedTask = t; 1812 } 1813 } 1814 } 1815 return finishedTask; 1816 } 1817 1818 void finishVoiceTask(IVoiceInteractionSession session) { 1819 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1820 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1821 final int numStacks = stacks.size(); 1822 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1823 final ActivityStack stack = stacks.get(stackNdx); 1824 stack.finishVoiceTask(session); 1825 } 1826 } 1827 } 1828 1829 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options, 1830 String reason, boolean forceNonResizeable) { 1831 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 1832 mUserLeaving = true; 1833 } 1834 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 1835 // Caller wants the home activity moved with it. To accomplish this, 1836 // we'll just indicate that this task returns to the home task. 1837 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1838 } 1839 if (task.stack == null) { 1840 Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task=" 1841 + task + " to front. Stack is null"); 1842 return; 1843 } 1844 1845 if (task.isResizeable() && options != null) { 1846 int stackId = options.getLaunchStackId(); 1847 if (canUseActivityOptionsLaunchBounds(options, stackId)) { 1848 final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds()); 1849 task.updateOverrideConfiguration(bounds); 1850 if (stackId == INVALID_STACK_ID) { 1851 stackId = task.getLaunchStackId(); 1852 } 1853 if (stackId != task.stack.mStackId) { 1854 final ActivityStack stack = moveTaskToStackUncheckedLocked( 1855 task, stackId, ON_TOP, !FORCE_FOCUS, reason); 1856 stackId = stack.mStackId; 1857 // moveTaskToStackUncheckedLocked() should already placed the task on top, 1858 // still need moveTaskToFrontLocked() below for any transition settings. 1859 } 1860 if (StackId.resizeStackWithLaunchBounds(stackId)) { 1861 resizeStackLocked(stackId, bounds, 1862 null /* tempTaskBounds */, null /* tempTaskInsetBounds */, 1863 !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME); 1864 } else { 1865 // WM resizeTask must be done after the task is moved to the correct stack, 1866 // because Task's setBounds() also updates dim layer's bounds, but that has 1867 // dependency on the stack. 1868 mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, 1869 false /* relayout */, false /* forced */); 1870 } 1871 } 1872 } 1873 1874 final ActivityRecord r = task.getTopActivity(); 1875 task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options, 1876 r == null ? null : r.appTimeTracker, reason); 1877 1878 if (DEBUG_STACK) Slog.d(TAG_STACK, 1879 "findTaskToMoveToFront: moved to front of stack=" + task.stack); 1880 1881 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId, 1882 forceNonResizeable); 1883 } 1884 1885 boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) { 1886 // We use the launch bounds in the activity options is the device supports freeform 1887 // window management or is launching into the pinned stack. 1888 if (options.getLaunchBounds() == null) { 1889 return false; 1890 } 1891 return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID) 1892 || mService.mSupportsFreeformWindowManagement; 1893 } 1894 1895 ActivityStack getStack(int stackId) { 1896 return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 1897 } 1898 1899 ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) { 1900 ActivityContainer activityContainer = mActivityContainers.get(stackId); 1901 if (activityContainer != null) { 1902 return activityContainer.mStack; 1903 } 1904 if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) { 1905 return null; 1906 } 1907 return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop); 1908 } 1909 1910 ArrayList<ActivityStack> getStacks() { 1911 ArrayList<ActivityStack> allStacks = new ArrayList<>(); 1912 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1913 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 1914 } 1915 return allStacks; 1916 } 1917 1918 IBinder getHomeActivityToken() { 1919 ActivityRecord homeActivity = getHomeActivity(); 1920 if (homeActivity != null) { 1921 return homeActivity.appToken; 1922 } 1923 return null; 1924 } 1925 1926 ActivityRecord getHomeActivity() { 1927 return getHomeActivityForUser(mCurrentUser); 1928 } 1929 1930 ActivityRecord getHomeActivityForUser(int userId) { 1931 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 1932 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 1933 final TaskRecord task = tasks.get(taskNdx); 1934 if (task.isHomeTask()) { 1935 final ArrayList<ActivityRecord> activities = task.mActivities; 1936 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 1937 final ActivityRecord r = activities.get(activityNdx); 1938 if (r.isHomeActivity() 1939 && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) { 1940 return r; 1941 } 1942 } 1943 } 1944 } 1945 return null; 1946 } 1947 1948 /** 1949 * Returns if a stack should be treated as if it's docked. Returns true if the stack is 1950 * the docked stack itself, or if it's side-by-side to the docked stack. 1951 */ 1952 boolean isStackDockedInEffect(int stackId) { 1953 return stackId == DOCKED_STACK_ID || 1954 (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null); 1955 } 1956 1957 ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity, 1958 IActivityContainerCallback callback) { 1959 ActivityContainer activityContainer = 1960 new VirtualActivityContainer(parentActivity, callback); 1961 mActivityContainers.put(activityContainer.mStackId, activityContainer); 1962 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 1963 "createActivityContainer: " + activityContainer); 1964 parentActivity.mChildContainers.add(activityContainer); 1965 return activityContainer; 1966 } 1967 1968 void removeChildActivityContainers(ActivityRecord parentActivity) { 1969 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 1970 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 1971 ActivityContainer container = childStacks.remove(containerNdx); 1972 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing " 1973 + container); 1974 container.release(); 1975 } 1976 } 1977 1978 void deleteActivityContainer(IActivityContainer container) { 1979 ActivityContainer activityContainer = (ActivityContainer)container; 1980 if (activityContainer != null) { 1981 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 1982 "deleteActivityContainer: callers=" + Debug.getCallers(4)); 1983 final int stackId = activityContainer.mStackId; 1984 mActivityContainers.remove(stackId); 1985 mWindowManager.removeStack(stackId); 1986 } 1987 } 1988 1989 void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, 1990 boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) { 1991 if (stackId == DOCKED_STACK_ID) { 1992 resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null, 1993 preserveWindows); 1994 return; 1995 } 1996 final ActivityStack stack = getStack(stackId); 1997 if (stack == null) { 1998 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); 1999 return; 2000 } 2001 2002 if (!allowResizeInDockedMode && getStack(DOCKED_STACK_ID) != null) { 2003 // If the docked stack exist we don't allow resizes of stacks not caused by the docked 2004 // stack size changing so things don't get out of sync. 2005 return; 2006 } 2007 2008 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId); 2009 mWindowManager.deferSurfaceLayout(); 2010 try { 2011 resizeStackUncheckedLocked(stack, bounds, tempTaskBounds, tempTaskInsetBounds); 2012 if (!deferResume) { 2013 ensureConfigurationAndResume( 2014 stack, stack.topRunningActivityLocked(), preserveWindows); 2015 } 2016 } finally { 2017 mWindowManager.continueSurfaceLayout(); 2018 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2019 } 2020 } 2021 2022 void deferUpdateBounds(int stackId) { 2023 final ActivityStack stack = getStack(stackId); 2024 if (stack != null) { 2025 stack.deferUpdateBounds(); 2026 } 2027 } 2028 2029 void continueUpdateBounds(int stackId) { 2030 final ActivityStack stack = getStack(stackId); 2031 if (stack != null) { 2032 stack.continueUpdateBounds(); 2033 } 2034 } 2035 2036 void notifyAppTransitionDone() { 2037 continueUpdateBounds(HOME_STACK_ID); 2038 for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) { 2039 final int taskId = mResizingTasksDuringAnimation.valueAt(i); 2040 if (anyTaskForIdLocked(taskId) != null) { 2041 mWindowManager.setTaskDockedResizing(taskId, false); 2042 } 2043 } 2044 mResizingTasksDuringAnimation.clear(); 2045 } 2046 2047 void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds, 2048 Rect tempTaskInsetBounds) { 2049 bounds = TaskRecord.validateBounds(bounds); 2050 2051 if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) { 2052 return; 2053 } 2054 2055 mTmpBounds.clear(); 2056 mTmpConfigs.clear(); 2057 mTmpInsetBounds.clear(); 2058 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2059 final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds; 2060 final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds; 2061 for (int i = tasks.size() - 1; i >= 0; i--) { 2062 final TaskRecord task = tasks.get(i); 2063 if (task.isResizeable()) { 2064 if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) { 2065 // For freeform stack we don't adjust the size of the tasks to match that 2066 // of the stack, but we do try to make sure the tasks are still contained 2067 // with the bounds of the stack. 2068 tempRect2.set(task.mBounds); 2069 fitWithinBounds(tempRect2, bounds); 2070 task.updateOverrideConfiguration(tempRect2); 2071 } else { 2072 task.updateOverrideConfiguration(taskBounds, insetBounds); 2073 } 2074 } 2075 2076 mTmpConfigs.put(task.taskId, task.mOverrideConfig); 2077 mTmpBounds.put(task.taskId, task.mBounds); 2078 if (tempTaskInsetBounds != null) { 2079 mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds); 2080 } 2081 } 2082 2083 // We might trigger a configuration change. Save the current task bounds for freezing. 2084 mWindowManager.prepareFreezingTaskBounds(stack.mStackId); 2085 stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs, 2086 mTmpBounds, mTmpInsetBounds); 2087 stack.setBounds(bounds); 2088 } 2089 2090 private void ensureConfigurationAndResume(ActivityStack stack, ActivityRecord r, 2091 boolean preserveWindows) { 2092 if (r == null || !r.visible) { 2093 return; 2094 } 2095 final boolean updated = stack.ensureActivityConfigurationLocked(r, 0, 2096 preserveWindows); 2097 if (!updated) { 2098 resumeFocusedStackTopActivityLocked(); 2099 } 2100 } 2101 2102 void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) { 2103 final ActivityStack stack = getStack(fromStackId); 2104 if (stack == null) { 2105 return; 2106 } 2107 2108 mWindowManager.deferSurfaceLayout(); 2109 try { 2110 if (fromStackId == DOCKED_STACK_ID) { 2111 2112 // We are moving all tasks from the docked stack to the fullscreen stack, 2113 // which is dismissing the docked stack, so resize all other stacks to 2114 // fullscreen here already so we don't end up with resize trashing. 2115 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2116 if (StackId.isResizeableByDockedStack(i)) { 2117 ActivityStack otherStack = getStack(i); 2118 if (otherStack != null) { 2119 resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS, 2120 true /* allowResizeInDockedMode */, DEFER_RESUME); 2121 } 2122 } 2123 } 2124 2125 // Also disable docked stack resizing since we have manually adjusted the 2126 // size of other stacks above and we don't want to trigger a docked stack 2127 // resize when we remove task from it below and it is detached from the 2128 // display because it no longer contains any tasks. 2129 mAllowDockedStackResize = false; 2130 } 2131 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2132 final int size = tasks.size(); 2133 if (onTop) { 2134 for (int i = 0; i < size; i++) { 2135 moveTaskToStackLocked(tasks.get(i).taskId, 2136 FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/, 2137 "moveTasksToFullscreenStack", ANIMATE); 2138 } 2139 } else { 2140 for (int i = size - 1; i >= 0; i--) { 2141 positionTaskInStackLocked(tasks.get(i).taskId, 2142 FULLSCREEN_WORKSPACE_STACK_ID, 0); 2143 } 2144 } 2145 } finally { 2146 mAllowDockedStackResize = true; 2147 mWindowManager.continueSurfaceLayout(); 2148 } 2149 } 2150 2151 void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, 2152 Rect tempDockedTaskInsetBounds, 2153 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows) { 2154 2155 if (!mAllowDockedStackResize) { 2156 // Docked stack resize currently disabled. 2157 return; 2158 } 2159 2160 final ActivityStack stack = getStack(DOCKED_STACK_ID); 2161 if (stack == null) { 2162 Slog.w(TAG, "resizeDockedStackLocked: docked stack not found"); 2163 return; 2164 } 2165 2166 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack"); 2167 mWindowManager.deferSurfaceLayout(); 2168 try { 2169 // Don't allow re-entry while resizing. E.g. due to docked stack detaching. 2170 mAllowDockedStackResize = false; 2171 ActivityRecord r = stack.topRunningActivityLocked(); 2172 resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds, 2173 tempDockedTaskInsetBounds); 2174 2175 // TODO: Checking for isAttached might not be needed as if the user passes in null 2176 // dockedBounds then they want the docked stack to be dismissed. 2177 if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) { 2178 // The dock stack either was dismissed or went fullscreen, which is kinda the same. 2179 // In this case we make all other static stacks fullscreen and move all 2180 // docked stack tasks to the fullscreen stack. 2181 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP); 2182 2183 // stack shouldn't contain anymore activities, so nothing to resume. 2184 r = null; 2185 } else { 2186 // Docked stacks occupy a dedicated region on screen so the size of all other 2187 // static stacks need to be adjusted so they don't overlap with the docked stack. 2188 // We get the bounds to use from window manager which has been adjusted for any 2189 // screen controls and is also the same for all stacks. 2190 mWindowManager.getStackDockedModeBounds( 2191 HOME_STACK_ID, tempRect, true /* ignoreVisibility */); 2192 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2193 if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) { 2194 resizeStackLocked(i, tempRect, tempOtherTaskBounds, 2195 tempOtherTaskInsetBounds, preserveWindows, 2196 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2197 } 2198 } 2199 } 2200 ensureConfigurationAndResume(stack, r, preserveWindows); 2201 } finally { 2202 mAllowDockedStackResize = true; 2203 mWindowManager.continueSurfaceLayout(); 2204 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2205 } 2206 2207 mResizeDockedStackTimeout.notifyResizing(dockedBounds, 2208 tempDockedTaskBounds != null 2209 || tempDockedTaskInsetBounds != null 2210 || tempOtherTaskBounds != null 2211 || tempOtherTaskInsetBounds != null); 2212 } 2213 2214 void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 2215 final ActivityStack stack = getStack(PINNED_STACK_ID); 2216 if (stack == null) { 2217 Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found"); 2218 return; 2219 } 2220 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack"); 2221 mWindowManager.deferSurfaceLayout(); 2222 try { 2223 ActivityRecord r = stack.topRunningActivityLocked(); 2224 resizeStackUncheckedLocked(stack, pinnedBounds, tempPinnedTaskBounds, 2225 null); 2226 ensureConfigurationAndResume(stack, r, false); 2227 } finally { 2228 mWindowManager.continueSurfaceLayout(); 2229 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2230 } 2231 } 2232 2233 boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow, 2234 boolean deferResume) { 2235 if (!task.isResizeable()) { 2236 Slog.w(TAG, "resizeTask: task " + task + " not resizeable."); 2237 return true; 2238 } 2239 2240 // If this is a forced resize, let it go through even if the bounds is not changing, 2241 // as we might need a relayout due to surface size change (to/from fullscreen). 2242 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0; 2243 if (Objects.equals(task.mBounds, bounds) && !forced) { 2244 // Nothing to do here... 2245 return true; 2246 } 2247 bounds = TaskRecord.validateBounds(bounds); 2248 2249 if (!mWindowManager.isValidTaskId(task.taskId)) { 2250 // Task doesn't exist in window manager yet (e.g. was restored from recents). 2251 // All we can do for now is update the bounds so it can be used when the task is 2252 // added to window manager. 2253 task.updateOverrideConfiguration(bounds); 2254 if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) { 2255 // re-restore the task so it can have the proper stack association. 2256 restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID); 2257 } 2258 return true; 2259 } 2260 2261 // Do not move the task to another stack here. 2262 // This method assumes that the task is already placed in the right stack. 2263 // we do not mess with that decision and we only do the resize! 2264 2265 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId); 2266 2267 final Configuration overrideConfig = task.updateOverrideConfiguration(bounds); 2268 // This variable holds information whether the configuration didn't change in a significant 2269 // way and the activity was kept the way it was. If it's false, it means the activity had 2270 // to be relaunched due to configuration change. 2271 boolean kept = true; 2272 if (overrideConfig != null) { 2273 final ActivityRecord r = task.topRunningActivityLocked(); 2274 if (r != null) { 2275 final ActivityStack stack = task.stack; 2276 kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow); 2277 2278 if (!deferResume) { 2279 2280 // All other activities must be made visible with their correct configuration. 2281 ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); 2282 if (!kept) { 2283 resumeFocusedStackTopActivityLocked(); 2284 } 2285 } 2286 } 2287 } 2288 mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced); 2289 2290 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2291 return kept; 2292 } 2293 2294 ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) { 2295 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2296 if (activityDisplay == null) { 2297 return null; 2298 } 2299 2300 ActivityContainer activityContainer = new ActivityContainer(stackId); 2301 mActivityContainers.put(stackId, activityContainer); 2302 activityContainer.attachToDisplayLocked(activityDisplay, onTop); 2303 return activityContainer.mStack; 2304 } 2305 2306 int getNextStackId() { 2307 while (true) { 2308 if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID 2309 && getStack(mNextFreeStackId) == null) { 2310 break; 2311 } 2312 mNextFreeStackId++; 2313 } 2314 return mNextFreeStackId; 2315 } 2316 2317 /** 2318 * Restores a recent task to a stack 2319 * @param task The recent task to be restored. 2320 * @param stackId The stack to restore the task to (default launch stack will be used 2321 * if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}). 2322 * @return true if the task has been restored successfully. 2323 */ 2324 private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) { 2325 if (stackId == INVALID_STACK_ID) { 2326 stackId = task.getLaunchStackId(); 2327 } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) { 2328 // Preferred stack is the docked stack, but the task can't go in the docked stack. 2329 // Put it in the fullscreen stack. 2330 stackId = FULLSCREEN_WORKSPACE_STACK_ID; 2331 } 2332 2333 if (task.stack != null) { 2334 // Task has already been restored once. See if we need to do anything more 2335 if (task.stack.mStackId == stackId) { 2336 // Nothing else to do since it is already restored in the right stack. 2337 return true; 2338 } 2339 // Remove current stack association, so we can re-associate the task with the 2340 // right stack below. 2341 task.stack.removeTask(task, "restoreRecentTaskLocked", MOVING); 2342 } 2343 2344 final ActivityStack stack = 2345 getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); 2346 2347 if (stack == null) { 2348 // What does this mean??? Not sure how we would get here... 2349 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2350 "Unable to find/create stack to restore recent task=" + task); 2351 return false; 2352 } 2353 2354 stack.addTask(task, false, "restoreRecentTask"); 2355 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2356 "Added restored task=" + task + " to stack=" + stack); 2357 final ArrayList<ActivityRecord> activities = task.mActivities; 2358 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2359 stack.addConfigOverride(activities.get(activityNdx), task); 2360 } 2361 return true; 2362 } 2363 2364 /** 2365 * Moves the specified task record to the input stack id. 2366 * WARNING: This method performs an unchecked/raw move of the task and 2367 * can leave the system in an unstable state if used incorrectly. 2368 * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack. 2369 * @param task Task to move. 2370 * @param stackId Id of stack to move task to. 2371 * @param toTop True if the task should be placed at the top of the stack. 2372 * @param forceFocus if focus should be moved to the new stack 2373 * @param reason Reason the task is been moved. 2374 * @return The stack the task was moved to. 2375 */ 2376 ActivityStack moveTaskToStackUncheckedLocked( 2377 TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) { 2378 2379 if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) { 2380 throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't " 2381 + "support multi-window task=" + task + " to stackId=" + stackId); 2382 } 2383 2384 final ActivityRecord r = task.getTopActivity(); 2385 final ActivityStack prevStack = task.stack; 2386 final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r); 2387 final boolean wasResumed = prevStack.mResumedActivity == r; 2388 // In some cases the focused stack isn't the front stack. E.g. pinned stack. 2389 // Whenever we are moving the top activity from the front stack we want to make sure to move 2390 // the stack to the front. 2391 final boolean wasFront = isFrontStack(prevStack) 2392 && (prevStack.topRunningActivityLocked() == r); 2393 2394 if (stackId == DOCKED_STACK_ID && !task.isResizeable()) { 2395 // We don't allow moving a unresizeable task to the docked stack since the docked 2396 // stack is used for split-screen mode and will cause things like the docked divider to 2397 // show up. We instead leave the task in its current stack or move it to the fullscreen 2398 // stack if it isn't currently in a stack. 2399 stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID; 2400 Slog.w(TAG, "Can not move unresizeable task=" + task 2401 + " to docked stack. Moving to stackId=" + stackId + " instead."); 2402 } 2403 2404 // Temporarily disable resizeablility of task we are moving. We don't want it to be resized 2405 // if a docked stack is created below which will lead to the stack we are moving from and 2406 // its resizeable tasks being resized. 2407 task.mTemporarilyUnresizable = true; 2408 final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop); 2409 task.mTemporarilyUnresizable = false; 2410 mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop); 2411 stack.addTask(task, toTop, reason); 2412 2413 // If the task had focus before (or we're requested to move focus), 2414 // move focus to the new stack by moving the stack to the front. 2415 stack.moveToFrontAndResumeStateIfNeeded( 2416 r, forceFocus || wasFocused || wasFront, wasResumed, reason); 2417 2418 return stack; 2419 } 2420 2421 boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, 2422 String reason, boolean animate) { 2423 return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate, 2424 false /* deferResume */); 2425 } 2426 2427 boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, 2428 String reason, boolean animate, boolean deferResume) { 2429 final TaskRecord task = anyTaskForIdLocked(taskId); 2430 if (task == null) { 2431 Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId); 2432 return false; 2433 } 2434 2435 if (task.stack != null && task.stack.mStackId == stackId) { 2436 // You are already in the right stack silly... 2437 Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId); 2438 return true; 2439 } 2440 2441 if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) { 2442 throw new IllegalArgumentException("moveTaskToStack:" 2443 + "Attempt to move task " + taskId + " to unsupported freeform stack"); 2444 } 2445 2446 final ActivityRecord topActivity = task.getTopActivity(); 2447 final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID; 2448 final boolean mightReplaceWindow = 2449 StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) && topActivity != null; 2450 if (mightReplaceWindow) { 2451 // We are about to relaunch the activity because its configuration changed due to 2452 // being maximized, i.e. size change. The activity will first remove the old window 2453 // and then add a new one. This call will tell window manager about this, so it can 2454 // preserve the old window until the new one is drawn. This prevents having a gap 2455 // between the removal and addition, in which no window is visible. We also want the 2456 // entrance of the new window to be properly animated. 2457 // Note here we always set the replacing window first, as the flags might be needed 2458 // during the relaunch. If we end up not doing any relaunch, we clear the flags later. 2459 mWindowManager.setReplacingWindow(topActivity.appToken, animate); 2460 } 2461 2462 mWindowManager.deferSurfaceLayout(); 2463 final int preferredLaunchStackId = stackId; 2464 boolean kept = true; 2465 try { 2466 final ActivityStack stack = moveTaskToStackUncheckedLocked( 2467 task, stackId, toTop, forceFocus, reason + " moveTaskToStack"); 2468 stackId = stack.mStackId; 2469 2470 if (!animate) { 2471 stack.mNoAnimActivities.add(topActivity); 2472 } 2473 2474 // We might trigger a configuration change. Save the current task bounds for freezing. 2475 mWindowManager.prepareFreezingTaskBounds(stack.mStackId); 2476 2477 // Make sure the task has the appropriate bounds/size for the stack it is in. 2478 if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) { 2479 kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, 2480 !mightReplaceWindow, deferResume); 2481 } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) { 2482 Rect bounds = task.getLaunchBounds(); 2483 if (bounds == null) { 2484 stack.layoutTaskInStack(task, null); 2485 bounds = task.mBounds; 2486 } 2487 kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, 2488 deferResume); 2489 } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) { 2490 kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, 2491 !mightReplaceWindow, deferResume); 2492 } 2493 } finally { 2494 mWindowManager.continueSurfaceLayout(); 2495 } 2496 2497 if (mightReplaceWindow) { 2498 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old 2499 // window), we need to clear the replace window settings. Otherwise, we schedule a 2500 // timeout to remove the old window if the replacing window is not coming in time. 2501 mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept); 2502 } 2503 2504 if (!deferResume) { 2505 2506 // The task might have already been running and its visibility needs to be synchronized with 2507 // the visibility of the stack / windows. 2508 ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow); 2509 resumeFocusedStackTopActivityLocked(); 2510 } 2511 2512 handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId); 2513 2514 return (preferredLaunchStackId == stackId); 2515 } 2516 2517 boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) { 2518 final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 2519 if (stack == null) { 2520 throw new IllegalArgumentException( 2521 "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId); 2522 } 2523 2524 final ActivityRecord r = stack.topRunningActivityLocked(); 2525 if (r == null) { 2526 Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity" 2527 + " in stack=" + stack); 2528 return false; 2529 } 2530 2531 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { 2532 Slog.w(TAG, 2533 "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for " 2534 + " r=" + r); 2535 return false; 2536 } 2537 2538 moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds); 2539 return true; 2540 } 2541 2542 void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) { 2543 mWindowManager.deferSurfaceLayout(); 2544 try { 2545 final TaskRecord task = r.task; 2546 2547 if (r == task.stack.getVisibleBehindActivity()) { 2548 // An activity can't be pinned and visible behind at the same time. Go ahead and 2549 // release it from been visible behind before pinning. 2550 requestVisibleBehindLocked(r, false); 2551 } 2552 2553 // Need to make sure the pinned stack exist so we can resize it below... 2554 final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP); 2555 2556 // Resize the pinned stack to match the current size of the task the activity we are 2557 // going to be moving is currently contained in. We do this to have the right starting 2558 // animation bounds for the pinned stack to the desired bounds the caller wants. 2559 resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */, 2560 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, 2561 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2562 2563 if (task.mActivities.size() == 1) { 2564 // There is only one activity in the task. So, we can just move the task over to 2565 // the stack without re-parenting the activity in a different task. 2566 if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) { 2567 // Move the home stack forward if the task we just moved to the pinned stack 2568 // was launched from home so home should be visible behind it. 2569 moveHomeStackToFront(reason); 2570 } 2571 moveTaskToStackLocked( 2572 task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE); 2573 } else { 2574 stack.moveActivityToStack(r); 2575 } 2576 } finally { 2577 mWindowManager.continueSurfaceLayout(); 2578 } 2579 2580 // The task might have already been running and its visibility needs to be synchronized 2581 // with the visibility of the stack / windows. 2582 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2583 resumeFocusedStackTopActivityLocked(); 2584 2585 mWindowManager.animateResizePinnedStack(bounds, -1); 2586 mService.notifyActivityPinnedLocked(); 2587 } 2588 2589 void positionTaskInStackLocked(int taskId, int stackId, int position) { 2590 final TaskRecord task = anyTaskForIdLocked(taskId); 2591 if (task == null) { 2592 Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId); 2593 return; 2594 } 2595 final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); 2596 2597 task.updateOverrideConfigurationForStack(stack); 2598 2599 mWindowManager.positionTaskInStack( 2600 taskId, stackId, position, task.mBounds, task.mOverrideConfig); 2601 stack.positionTask(task, position); 2602 // The task might have already been running and its visibility needs to be synchronized with 2603 // the visibility of the stack / windows. 2604 stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2605 resumeFocusedStackTopActivityLocked(); 2606 } 2607 2608 ActivityRecord findTaskLocked(ActivityRecord r) { 2609 mTmpFindTaskResult.r = null; 2610 mTmpFindTaskResult.matchedByRootAffinity = false; 2611 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 2612 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2613 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2614 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2615 final ActivityStack stack = stacks.get(stackNdx); 2616 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2617 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack); 2618 continue; 2619 } 2620 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2621 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 2622 "Skipping stack: (new task not allowed) " + stack); 2623 continue; 2624 } 2625 stack.findTaskLocked(r, mTmpFindTaskResult); 2626 // It is possible to have task in multiple stacks with the same root affinity. 2627 // If the match we found was based on root affinity we keep on looking to see if 2628 // there is a better match in another stack. We eventually return the match based 2629 // on root affinity if we don't find a better match. 2630 if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) { 2631 return mTmpFindTaskResult.r; 2632 } 2633 } 2634 } 2635 if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found"); 2636 return mTmpFindTaskResult.r; 2637 } 2638 2639 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2640 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2641 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2642 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2643 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2644 if (ar != null) { 2645 return ar; 2646 } 2647 } 2648 } 2649 return null; 2650 } 2651 2652 void goingToSleepLocked() { 2653 scheduleSleepTimeout(); 2654 if (!mGoingToSleep.isHeld()) { 2655 mGoingToSleep.acquire(); 2656 if (mLaunchingActivity.isHeld()) { 2657 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2658 throw new IllegalStateException("Calling must be system uid"); 2659 } 2660 mLaunchingActivity.release(); 2661 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2662 } 2663 } 2664 checkReadyForSleepLocked(); 2665 } 2666 2667 boolean shutdownLocked(int timeout) { 2668 goingToSleepLocked(); 2669 2670 boolean timedout = false; 2671 final long endTime = System.currentTimeMillis() + timeout; 2672 while (true) { 2673 boolean cantShutdown = false; 2674 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2675 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2676 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2677 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2678 } 2679 } 2680 if (cantShutdown) { 2681 long timeRemaining = endTime - System.currentTimeMillis(); 2682 if (timeRemaining > 0) { 2683 try { 2684 mService.wait(timeRemaining); 2685 } catch (InterruptedException e) { 2686 } 2687 } else { 2688 Slog.w(TAG, "Activity manager shutdown timed out"); 2689 timedout = true; 2690 break; 2691 } 2692 } else { 2693 break; 2694 } 2695 } 2696 2697 // Force checkReadyForSleep to complete. 2698 mSleepTimeout = true; 2699 checkReadyForSleepLocked(); 2700 2701 return timedout; 2702 } 2703 2704 void comeOutOfSleepIfNeededLocked() { 2705 removeSleepTimeouts(); 2706 if (mGoingToSleep.isHeld()) { 2707 mGoingToSleep.release(); 2708 } 2709 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2710 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2711 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2712 final ActivityStack stack = stacks.get(stackNdx); 2713 stack.awakeFromSleepingLocked(); 2714 if (isFocusedStack(stack)) { 2715 resumeFocusedStackTopActivityLocked(); 2716 } 2717 } 2718 } 2719 mGoingToSleepActivities.clear(); 2720 } 2721 2722 void activitySleptLocked(ActivityRecord r) { 2723 mGoingToSleepActivities.remove(r); 2724 checkReadyForSleepLocked(); 2725 } 2726 2727 void checkReadyForSleepLocked() { 2728 if (!mService.isSleepingOrShuttingDown()) { 2729 // Do not care. 2730 return; 2731 } 2732 2733 if (!mSleepTimeout) { 2734 boolean dontSleep = false; 2735 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2736 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2737 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2738 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2739 } 2740 } 2741 2742 if (mStoppingActivities.size() > 0) { 2743 // Still need to tell some activities to stop; can't sleep yet. 2744 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop " 2745 + mStoppingActivities.size() + " activities"); 2746 scheduleIdleLocked(); 2747 dontSleep = true; 2748 } 2749 2750 if (mGoingToSleepActivities.size() > 0) { 2751 // Still need to tell some activities to sleep; can't sleep yet. 2752 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep " 2753 + mGoingToSleepActivities.size() + " activities"); 2754 dontSleep = true; 2755 } 2756 2757 if (dontSleep) { 2758 return; 2759 } 2760 } 2761 2762 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2763 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2764 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2765 stacks.get(stackNdx).goToSleep(); 2766 } 2767 } 2768 2769 removeSleepTimeouts(); 2770 2771 if (mGoingToSleep.isHeld()) { 2772 mGoingToSleep.release(); 2773 } 2774 if (mService.mShuttingDown) { 2775 mService.notifyAll(); 2776 } 2777 } 2778 2779 boolean reportResumedActivityLocked(ActivityRecord r) { 2780 final ActivityStack stack = r.task.stack; 2781 if (isFocusedStack(stack)) { 2782 mService.updateUsageStats(r, true); 2783 } 2784 if (allResumedActivitiesComplete()) { 2785 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2786 mWindowManager.executeAppTransition(); 2787 return true; 2788 } 2789 return false; 2790 } 2791 2792 void handleAppCrashLocked(ProcessRecord app) { 2793 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2794 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2795 int stackNdx = stacks.size() - 1; 2796 while (stackNdx >= 0) { 2797 stacks.get(stackNdx).handleAppCrashLocked(app); 2798 stackNdx--; 2799 } 2800 } 2801 } 2802 2803 boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) { 2804 final ActivityStack stack = r.task.stack; 2805 if (stack == null) { 2806 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2807 "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null"); 2808 return false; 2809 } 2810 2811 if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) { 2812 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r 2813 + " visible=" + visible + " stackId=" + stack.mStackId 2814 + " can't contain visible behind activities"); 2815 return false; 2816 } 2817 2818 final boolean isVisible = stack.hasVisibleBehindActivity(); 2819 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2820 "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible); 2821 2822 final ActivityRecord top = topRunningActivityLocked(); 2823 if (top == null || top == r || (visible == isVisible)) { 2824 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return"); 2825 stack.setVisibleBehindActivity(visible ? r : null); 2826 return true; 2827 } 2828 2829 // A non-top activity is reporting a visibility change. 2830 if (visible && top.fullscreen) { 2831 // Let the caller know that it can't be seen. 2832 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2833 "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen 2834 + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread=" 2835 + top.app.thread); 2836 return false; 2837 } else if (!visible && stack.getVisibleBehindActivity() != r) { 2838 // Only the activity set as currently visible behind should actively reset its 2839 // visible behind state. 2840 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2841 "requestVisibleBehind: returning visible=" + visible 2842 + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity() 2843 + " r=" + r); 2844 return false; 2845 } 2846 2847 stack.setVisibleBehindActivity(visible ? r : null); 2848 if (!visible) { 2849 // If there is a translucent home activity, we need to force it stop being translucent, 2850 // because we can't depend on the application to necessarily perform that operation. 2851 // Check out b/14469711 for details. 2852 final ActivityRecord next = stack.findNextTranslucentActivity(r); 2853 if (next != null && next.isHomeActivity()) { 2854 mService.convertFromTranslucent(next.appToken); 2855 } 2856 } 2857 if (top.app != null && top.app.thread != null) { 2858 // Notify the top app of the change. 2859 try { 2860 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); 2861 } catch (RemoteException e) { 2862 } 2863 } 2864 return true; 2865 } 2866 2867 // Called when WindowManager has finished animating the launchingBehind activity to the back. 2868 void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 2869 final TaskRecord task = r.task; 2870 final ActivityStack stack = task.stack; 2871 2872 r.mLaunchTaskBehind = false; 2873 task.setLastThumbnailLocked(stack.screenshotActivitiesLocked(r)); 2874 mRecentTasks.addLocked(task); 2875 mService.notifyTaskStackChangedLocked(); 2876 mWindowManager.setAppVisibility(r.appToken, false); 2877 2878 // When launching tasks behind, update the last active time of the top task after the new 2879 // task has been shown briefly 2880 final ActivityRecord top = stack.topActivity(); 2881 if (top != null) { 2882 top.task.touchActiveTime(); 2883 } 2884 } 2885 2886 void scheduleLaunchTaskBehindComplete(IBinder token) { 2887 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 2888 } 2889 2890 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, 2891 boolean preserveWindows) { 2892 // First the front stacks. In case any are not fullscreen and are in front of home. 2893 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2894 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2895 final int topStackNdx = stacks.size() - 1; 2896 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2897 final ActivityStack stack = stacks.get(stackNdx); 2898 stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows); 2899 } 2900 } 2901 } 2902 2903 void invalidateTaskLayers() { 2904 mTaskLayersChanged = true; 2905 } 2906 2907 void rankTaskLayersIfNeeded() { 2908 if (!mTaskLayersChanged) { 2909 return; 2910 } 2911 mTaskLayersChanged = false; 2912 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) { 2913 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2914 int baseLayer = 0; 2915 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2916 baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer); 2917 } 2918 } 2919 } 2920 2921 void clearOtherAppTimeTrackers(AppTimeTracker except) { 2922 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2923 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2924 final int topStackNdx = stacks.size() - 1; 2925 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2926 final ActivityStack stack = stacks.get(stackNdx); 2927 stack.clearOtherAppTimeTrackers(except); 2928 } 2929 } 2930 } 2931 2932 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2933 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2934 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2935 final int numStacks = stacks.size(); 2936 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2937 final ActivityStack stack = stacks.get(stackNdx); 2938 stack.scheduleDestroyActivities(app, reason); 2939 } 2940 } 2941 } 2942 2943 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 2944 // Examine all activities currently running in the process. 2945 TaskRecord firstTask = null; 2946 // Tasks is non-null only if two or more tasks are found. 2947 ArraySet<TaskRecord> tasks = null; 2948 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); 2949 for (int i = 0; i < app.activities.size(); i++) { 2950 ActivityRecord r = app.activities.get(i); 2951 // First, if we find an activity that is in the process of being destroyed, 2952 // then we just aren't going to do anything for now; we want things to settle 2953 // down before we try to prune more activities. 2954 if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) { 2955 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 2956 return; 2957 } 2958 // Don't consider any activies that are currently not in a state where they 2959 // can be destroyed. 2960 if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING 2961 || r.state == PAUSED || r.state == STOPPING) { 2962 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 2963 continue; 2964 } 2965 if (r.task != null) { 2966 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task 2967 + " from " + r); 2968 if (firstTask == null) { 2969 firstTask = r.task; 2970 } else if (firstTask != r.task) { 2971 if (tasks == null) { 2972 tasks = new ArraySet<>(); 2973 tasks.add(firstTask); 2974 } 2975 tasks.add(r.task); 2976 } 2977 } 2978 } 2979 if (tasks == null) { 2980 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); 2981 return; 2982 } 2983 // If we have activities in multiple tasks that are in a position to be destroyed, 2984 // let's iterate through the tasks and release the oldest one. 2985 final int numDisplays = mActivityDisplays.size(); 2986 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2987 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2988 // Step through all stacks starting from behind, to hit the oldest things first. 2989 for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) { 2990 final ActivityStack stack = stacks.get(stackNdx); 2991 // Try to release activities in this stack; if we manage to, we are done. 2992 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 2993 return; 2994 } 2995 } 2996 } 2997 } 2998 2999 boolean switchUserLocked(int userId, UserState uss) { 3000 final int focusStackId = mFocusedStack.getStackId(); 3001 // We dismiss the docked stack whenever we switch users. 3002 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, focusStackId == DOCKED_STACK_ID); 3003 3004 mUserStackInFront.put(mCurrentUser, focusStackId); 3005 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 3006 mCurrentUser = userId; 3007 3008 mStartingUsers.add(uss); 3009 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3010 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3011 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3012 final ActivityStack stack = stacks.get(stackNdx); 3013 stack.switchUserLocked(userId); 3014 TaskRecord task = stack.topTask(); 3015 if (task != null) { 3016 mWindowManager.moveTaskToTop(task.taskId); 3017 } 3018 } 3019 } 3020 3021 ActivityStack stack = getStack(restoreStackId); 3022 if (stack == null) { 3023 stack = mHomeStack; 3024 } 3025 final boolean homeInFront = stack.isHomeStack(); 3026 if (stack.isOnHomeDisplay()) { 3027 stack.moveToFront("switchUserOnHomeDisplay"); 3028 } else { 3029 // Stack was moved to another display while user was swapped out. 3030 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay"); 3031 } 3032 return homeInFront; 3033 } 3034 3035 /** Checks whether the userid is a profile of the current user. */ 3036 boolean isCurrentProfileLocked(int userId) { 3037 if (userId == mCurrentUser) return true; 3038 return mService.mUserController.isCurrentProfileLocked(userId); 3039 } 3040 3041 /** Checks whether the activity should be shown for current user. */ 3042 boolean okToShowLocked(ActivityRecord r) { 3043 return r != null && (isCurrentProfileLocked(r.userId) 3044 || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0); 3045 } 3046 3047 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 3048 ArrayList<ActivityRecord> stops = null; 3049 3050 final boolean nowVisible = allResumedActivitiesVisible(); 3051 for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3052 ActivityRecord s = mStoppingActivities.get(activityNdx); 3053 final boolean waitingVisible = mWaitingVisibleActivities.contains(s); 3054 if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3055 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3056 if (waitingVisible && nowVisible) { 3057 mWaitingVisibleActivities.remove(s); 3058 if (s.finishing) { 3059 // If this activity is finishing, it is sitting on top of 3060 // everyone else but we now know it is no longer needed... 3061 // so get rid of it. Otherwise, we need to go through the 3062 // normal flow and hide it once we determine that it is 3063 // hidden by the activities in front of it. 3064 if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); 3065 mWindowManager.setAppVisibility(s.appToken, false); 3066 } 3067 } 3068 if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 3069 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); 3070 if (stops == null) { 3071 stops = new ArrayList<>(); 3072 } 3073 stops.add(s); 3074 mStoppingActivities.remove(activityNdx); 3075 } 3076 } 3077 3078 return stops; 3079 } 3080 3081 void validateTopActivitiesLocked() { 3082 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3083 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3084 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3085 final ActivityStack stack = stacks.get(stackNdx); 3086 final ActivityRecord r = stack.topRunningActivityLocked(); 3087 final ActivityState state = r == null ? DESTROYED : r.state; 3088 if (isFocusedStack(stack)) { 3089 if (r == null) Slog.e(TAG, 3090 "validateTop...: null top activity, stack=" + stack); 3091 else { 3092 final ActivityRecord pausing = stack.mPausingActivity; 3093 if (pausing != null && pausing == r) Slog.e(TAG, 3094 "validateTop...: top stack has pausing activity r=" + r 3095 + " state=" + state); 3096 if (state != INITIALIZING && state != RESUMED) Slog.e(TAG, 3097 "validateTop...: activity in front not resumed r=" + r 3098 + " state=" + state); 3099 } 3100 } else { 3101 final ActivityRecord resumed = stack.mResumedActivity; 3102 if (resumed != null && resumed == r) Slog.e(TAG, 3103 "validateTop...: back stack has resumed activity r=" + r 3104 + " state=" + state); 3105 if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG, 3106 "validateTop...: activity in back resumed r=" + r + " state=" + state); 3107 } 3108 } 3109 } 3110 } 3111 3112 private String lockTaskModeToString() { 3113 switch (mLockTaskModeState) { 3114 case LOCK_TASK_MODE_LOCKED: 3115 return "LOCKED"; 3116 case LOCK_TASK_MODE_PINNED: 3117 return "PINNED"; 3118 case LOCK_TASK_MODE_NONE: 3119 return "NONE"; 3120 default: return "unknown=" + mLockTaskModeState; 3121 } 3122 } 3123 3124 public void dump(PrintWriter pw, String prefix) { 3125 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3126 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3127 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3128 pw.print(prefix); 3129 pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); 3130 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3131 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3132 pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); 3133 final SparseArray<String[]> packages = mService.mLockTaskPackages; 3134 if (packages.size() > 0) { 3135 pw.println(" mLockTaskPackages (userId:packages)="); 3136 for (int i = 0; i < packages.size(); ++i) { 3137 pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i)); 3138 pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i))); 3139 } 3140 } 3141 pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks); 3142 } 3143 3144 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3145 return mFocusedStack.getDumpActivitiesLocked(name); 3146 } 3147 3148 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3149 boolean needSep, String prefix) { 3150 if (activity != null) { 3151 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3152 if (needSep) { 3153 pw.println(); 3154 } 3155 pw.print(prefix); 3156 pw.println(activity); 3157 return true; 3158 } 3159 } 3160 return false; 3161 } 3162 3163 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3164 boolean dumpClient, String dumpPackage) { 3165 boolean printed = false; 3166 boolean needSep = false; 3167 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3168 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3169 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3170 pw.println(" (activities from top to bottom):"); 3171 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3172 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3173 final ActivityStack stack = stacks.get(stackNdx); 3174 StringBuilder stackHeader = new StringBuilder(128); 3175 stackHeader.append(" Stack #"); 3176 stackHeader.append(stack.mStackId); 3177 stackHeader.append(":"); 3178 stackHeader.append("\n"); 3179 stackHeader.append(" mFullscreen=" + stack.mFullscreen); 3180 stackHeader.append("\n"); 3181 stackHeader.append(" mBounds=" + stack.mBounds); 3182 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3183 needSep, stackHeader.toString()); 3184 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3185 !dumpAll, false, dumpPackage, true, 3186 " Running activities (most recent first):", null); 3187 3188 needSep = printed; 3189 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3190 " mPausingActivity: "); 3191 if (pr) { 3192 printed = true; 3193 needSep = false; 3194 } 3195 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3196 " mResumedActivity: "); 3197 if (pr) { 3198 printed = true; 3199 needSep = false; 3200 } 3201 if (dumpAll) { 3202 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3203 " mLastPausedActivity: "); 3204 if (pr) { 3205 printed = true; 3206 needSep = true; 3207 } 3208 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3209 needSep, " mLastNoHistoryActivity: "); 3210 } 3211 needSep = printed; 3212 } 3213 } 3214 3215 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3216 false, dumpPackage, true, " Activities waiting to finish:", null); 3217 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3218 false, dumpPackage, true, " Activities waiting to stop:", null); 3219 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3220 false, dumpPackage, true, " Activities waiting for another to become visible:", 3221 null); 3222 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3223 false, dumpPackage, true, " Activities waiting to sleep:", null); 3224 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3225 false, dumpPackage, true, " Activities waiting to sleep:", null); 3226 3227 return printed; 3228 } 3229 3230 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3231 String prefix, String label, boolean complete, boolean brief, boolean client, 3232 String dumpPackage, boolean needNL, String header1, String header2) { 3233 TaskRecord lastTask = null; 3234 String innerPrefix = null; 3235 String[] args = null; 3236 boolean printed = false; 3237 for (int i=list.size()-1; i>=0; i--) { 3238 final ActivityRecord r = list.get(i); 3239 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3240 continue; 3241 } 3242 if (innerPrefix == null) { 3243 innerPrefix = prefix + " "; 3244 args = new String[0]; 3245 } 3246 printed = true; 3247 final boolean full = !brief && (complete || !r.isInHistory()); 3248 if (needNL) { 3249 pw.println(""); 3250 needNL = false; 3251 } 3252 if (header1 != null) { 3253 pw.println(header1); 3254 header1 = null; 3255 } 3256 if (header2 != null) { 3257 pw.println(header2); 3258 header2 = null; 3259 } 3260 if (lastTask != r.task) { 3261 lastTask = r.task; 3262 pw.print(prefix); 3263 pw.print(full ? "* " : " "); 3264 pw.println(lastTask); 3265 if (full) { 3266 lastTask.dump(pw, prefix + " "); 3267 } else if (complete) { 3268 // Complete + brief == give a summary. Isn't that obvious?!? 3269 if (lastTask.intent != null) { 3270 pw.print(prefix); pw.print(" "); 3271 pw.println(lastTask.intent.toInsecureStringWithClip()); 3272 } 3273 } 3274 } 3275 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3276 pw.print(" #"); pw.print(i); pw.print(": "); 3277 pw.println(r); 3278 if (full) { 3279 r.dump(pw, innerPrefix); 3280 } else if (complete) { 3281 // Complete + brief == give a summary. Isn't that obvious?!? 3282 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3283 if (r.app != null) { 3284 pw.print(innerPrefix); pw.println(r.app); 3285 } 3286 } 3287 if (client && r.app != null && r.app.thread != null) { 3288 // flush anything that is already in the PrintWriter since the thread is going 3289 // to write to the file descriptor directly 3290 pw.flush(); 3291 try { 3292 TransferPipe tp = new TransferPipe(); 3293 try { 3294 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3295 r.appToken, innerPrefix, args); 3296 // Short timeout, since blocking here can 3297 // deadlock with the application. 3298 tp.go(fd, 2000); 3299 } finally { 3300 tp.kill(); 3301 } 3302 } catch (IOException e) { 3303 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3304 } catch (RemoteException e) { 3305 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3306 } 3307 needNL = true; 3308 } 3309 } 3310 return printed; 3311 } 3312 3313 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3314 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3315 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3316 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3317 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3318 } 3319 3320 final void scheduleIdleLocked() { 3321 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3322 } 3323 3324 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3325 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 3326 + Debug.getCallers(4)); 3327 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3328 } 3329 3330 final void scheduleResumeTopActivities() { 3331 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3332 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3333 } 3334 } 3335 3336 void removeSleepTimeouts() { 3337 mSleepTimeout = false; 3338 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3339 } 3340 3341 final void scheduleSleepTimeout() { 3342 removeSleepTimeouts(); 3343 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3344 } 3345 3346 @Override 3347 public void onDisplayAdded(int displayId) { 3348 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 3349 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3350 } 3351 3352 @Override 3353 public void onDisplayRemoved(int displayId) { 3354 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 3355 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3356 } 3357 3358 @Override 3359 public void onDisplayChanged(int displayId) { 3360 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 3361 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3362 } 3363 3364 private void handleDisplayAdded(int displayId) { 3365 boolean newDisplay; 3366 synchronized (mService) { 3367 newDisplay = mActivityDisplays.get(displayId) == null; 3368 if (newDisplay) { 3369 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3370 if (activityDisplay.mDisplay == null) { 3371 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3372 return; 3373 } 3374 mActivityDisplays.put(displayId, activityDisplay); 3375 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 3376 } 3377 } 3378 if (newDisplay) { 3379 mWindowManager.onDisplayAdded(displayId); 3380 } 3381 } 3382 3383 private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) { 3384 mDefaultMinimalSizeOfResizeableTask = 3385 mService.mContext.getResources().getDimensionPixelSize( 3386 com.android.internal.R.dimen.default_minimal_size_resizable_task); 3387 } 3388 3389 private void handleDisplayRemoved(int displayId) { 3390 synchronized (mService) { 3391 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3392 if (activityDisplay != null) { 3393 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3394 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3395 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3396 } 3397 mActivityDisplays.remove(displayId); 3398 } 3399 } 3400 mWindowManager.onDisplayRemoved(displayId); 3401 } 3402 3403 private void handleDisplayChanged(int displayId) { 3404 synchronized (mService) { 3405 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3406 if (activityDisplay != null) { 3407 // TODO: Update the bounds. 3408 } 3409 } 3410 mWindowManager.onDisplayChanged(displayId); 3411 } 3412 3413 private StackInfo getStackInfoLocked(ActivityStack stack) { 3414 StackInfo info = new StackInfo(); 3415 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3416 info.displayId = Display.DEFAULT_DISPLAY; 3417 info.stackId = stack.mStackId; 3418 info.userId = stack.mCurrentUser; 3419 info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE; 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 if (!task.canGoInDockedStack() || forceNonResizable) { 3512 // Display a warning toast that we tried to put a non-dockable task in the docked stack. 3513 mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG); 3514 3515 // Dismiss docked stack. If task appeared to be in docked stack but is not resizable - 3516 // we need to move it to top of fullscreen stack, otherwise it will be covered. 3517 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID); 3518 } else if (task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) { 3519 String packageName = task.getTopActivity() != null 3520 ? task.getTopActivity().appInfo.packageName : null; 3521 mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0, 3522 packageName).sendToTarget(); 3523 } 3524 } 3525 3526 void showLockTaskToast() { 3527 mLockTaskNotify.showToast(mLockTaskModeState); 3528 } 3529 3530 void showLockTaskEscapeMessageLocked(TaskRecord task) { 3531 if (mLockTaskModeTasks.contains(task)) { 3532 mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG); 3533 } 3534 } 3535 3536 void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason, 3537 boolean andResume) { 3538 if (task == null) { 3539 // Take out of lock task mode if necessary 3540 final TaskRecord lockedTask = getLockedTaskLocked(); 3541 if (lockedTask != null) { 3542 removeLockedTaskLocked(lockedTask); 3543 if (!mLockTaskModeTasks.isEmpty()) { 3544 // There are locked tasks remaining, can only finish this task, not unlock it. 3545 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3546 "setLockTaskModeLocked: Tasks remaining, can't unlock"); 3547 lockedTask.performClearTaskLocked(); 3548 resumeFocusedStackTopActivityLocked(); 3549 return; 3550 } 3551 } 3552 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3553 "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4)); 3554 return; 3555 } 3556 3557 // Should have already been checked, but do it again. 3558 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 3559 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3560 "setLockTaskModeLocked: Can't lock due to auth"); 3561 return; 3562 } 3563 if (isLockTaskModeViolation(task)) { 3564 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 3565 return; 3566 } 3567 3568 if (mLockTaskModeTasks.isEmpty()) { 3569 // First locktask. 3570 final Message lockTaskMsg = Message.obtain(); 3571 lockTaskMsg.obj = task.intent.getComponent().getPackageName(); 3572 lockTaskMsg.arg1 = task.userId; 3573 lockTaskMsg.what = LOCK_TASK_START_MSG; 3574 lockTaskMsg.arg2 = lockTaskModeState; 3575 mHandler.sendMessage(lockTaskMsg); 3576 } 3577 // Add it or move it to the top. 3578 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task + 3579 " Callers=" + Debug.getCallers(4)); 3580 mLockTaskModeTasks.remove(task); 3581 mLockTaskModeTasks.add(task); 3582 3583 if (task.mLockTaskUid == -1) { 3584 task.mLockTaskUid = task.effectiveUid; 3585 } 3586 3587 if (andResume) { 3588 findTaskToMoveToFrontLocked(task, 0, null, reason, 3589 lockTaskModeState != LOCK_TASK_MODE_NONE); 3590 resumeFocusedStackTopActivityLocked(); 3591 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { 3592 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId, 3593 true /* forceNonResizable */); 3594 } 3595 } 3596 3597 boolean isLockTaskModeViolation(TaskRecord task) { 3598 return isLockTaskModeViolation(task, false); 3599 } 3600 3601 boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) { 3602 if (getLockedTaskLocked() == task && !isNewClearTask) { 3603 return false; 3604 } 3605 final int lockTaskAuth = task.mLockTaskAuth; 3606 switch (lockTaskAuth) { 3607 case LOCK_TASK_AUTH_DONT_LOCK: 3608 return !mLockTaskModeTasks.isEmpty(); 3609 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 3610 case LOCK_TASK_AUTH_LAUNCHABLE: 3611 case LOCK_TASK_AUTH_WHITELISTED: 3612 return false; 3613 case LOCK_TASK_AUTH_PINNABLE: 3614 // Pinnable tasks can't be launched on top of locktask tasks. 3615 return !mLockTaskModeTasks.isEmpty(); 3616 default: 3617 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth); 3618 return true; 3619 } 3620 } 3621 3622 void onLockTaskPackagesUpdatedLocked() { 3623 boolean didSomething = false; 3624 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 3625 final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); 3626 final boolean wasWhitelisted = 3627 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3628 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3629 lockedTask.setLockTaskAuth(); 3630 final boolean isWhitelisted = 3631 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3632 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3633 if (wasWhitelisted && !isWhitelisted) { 3634 // Lost whitelisting authorization. End it now. 3635 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + 3636 lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); 3637 removeLockedTaskLocked(lockedTask); 3638 lockedTask.performClearTaskLocked(); 3639 didSomething = true; 3640 } 3641 } 3642 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3643 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3644 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3645 final ActivityStack stack = stacks.get(stackNdx); 3646 stack.onLockTaskPackagesUpdatedLocked(); 3647 } 3648 } 3649 final ActivityRecord r = topRunningActivityLocked(); 3650 final TaskRecord task = r != null ? r.task : null; 3651 if (mLockTaskModeTasks.isEmpty() && task != null 3652 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 3653 // This task must have just been authorized. 3654 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, 3655 "onLockTaskPackagesUpdated: starting new locktask task=" + task); 3656 setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated", 3657 false); 3658 didSomething = true; 3659 } 3660 if (didSomething) { 3661 resumeFocusedStackTopActivityLocked(); 3662 } 3663 } 3664 3665 int getLockTaskModeState() { 3666 return mLockTaskModeState; 3667 } 3668 3669 void activityRelaunchedLocked(IBinder token) { 3670 mWindowManager.notifyAppRelaunchingFinished(token); 3671 } 3672 3673 void activityRelaunchingLocked(ActivityRecord r) { 3674 mWindowManager.notifyAppRelaunching(r.appToken); 3675 } 3676 3677 void logStackState() { 3678 mActivityMetricsLogger.logWindowState(); 3679 } 3680 3681 void scheduleReportMultiWindowModeChanged(TaskRecord task) { 3682 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3683 final ActivityRecord r = task.mActivities.get(i); 3684 if (r.app != null && r.app.thread != null) { 3685 mMultiWindowModeChangedActivities.add(r); 3686 } 3687 } 3688 3689 if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) { 3690 mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG); 3691 } 3692 } 3693 3694 void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) { 3695 final ActivityStack stack = task.stack; 3696 if (prevStack == null || prevStack == stack 3697 || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) { 3698 return; 3699 } 3700 3701 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3702 final ActivityRecord r = task.mActivities.get(i); 3703 if (r.app != null && r.app.thread != null) { 3704 mPipModeChangedActivities.add(r); 3705 } 3706 } 3707 3708 if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { 3709 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); 3710 } 3711 } 3712 3713 void setDockedStackMinimized(boolean minimized) { 3714 mIsDockMinimized = minimized; 3715 if (minimized) { 3716 // Docked stack is not visible, no need to confirm credentials for its top activity. 3717 return; 3718 } 3719 final ActivityStack dockedStack = getStack(StackId.DOCKED_STACK_ID); 3720 if (dockedStack == null) { 3721 return; 3722 } 3723 final ActivityRecord top = dockedStack.topRunningActivityLocked(); 3724 if (top != null && mService.mUserController.shouldConfirmCredentials(top.userId)) { 3725 mService.mActivityStarter.showConfirmDeviceCredential(top.userId); 3726 } 3727 } 3728 3729 private final class ActivityStackSupervisorHandler extends Handler { 3730 3731 public ActivityStackSupervisorHandler(Looper looper) { 3732 super(looper); 3733 } 3734 3735 void activityIdleInternal(ActivityRecord r) { 3736 synchronized (mService) { 3737 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3738 } 3739 } 3740 3741 @Override 3742 public void handleMessage(Message msg) { 3743 switch (msg.what) { 3744 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: { 3745 synchronized (mService) { 3746 for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) { 3747 final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i); 3748 r.scheduleMultiWindowModeChanged(); 3749 } 3750 } 3751 } break; 3752 case REPORT_PIP_MODE_CHANGED_MSG: { 3753 synchronized (mService) { 3754 for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) { 3755 final ActivityRecord r = mPipModeChangedActivities.remove(i); 3756 r.schedulePictureInPictureModeChanged(); 3757 } 3758 } 3759 } break; 3760 case IDLE_TIMEOUT_MSG: { 3761 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3762 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3763 if (mService.mDidDexOpt) { 3764 mService.mDidDexOpt = false; 3765 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3766 nmsg.obj = msg.obj; 3767 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3768 return; 3769 } 3770 // We don't at this point know if the activity is fullscreen, 3771 // so we need to be conservative and assume it isn't. 3772 activityIdleInternal((ActivityRecord)msg.obj); 3773 } break; 3774 case IDLE_NOW_MSG: { 3775 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3776 activityIdleInternal((ActivityRecord)msg.obj); 3777 } break; 3778 case RESUME_TOP_ACTIVITY_MSG: { 3779 synchronized (mService) { 3780 resumeFocusedStackTopActivityLocked(); 3781 } 3782 } break; 3783 case SLEEP_TIMEOUT_MSG: { 3784 synchronized (mService) { 3785 if (mService.isSleepingOrShuttingDown()) { 3786 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3787 mSleepTimeout = true; 3788 checkReadyForSleepLocked(); 3789 } 3790 } 3791 } break; 3792 case LAUNCH_TIMEOUT_MSG: { 3793 if (mService.mDidDexOpt) { 3794 mService.mDidDexOpt = false; 3795 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3796 return; 3797 } 3798 synchronized (mService) { 3799 if (mLaunchingActivity.isHeld()) { 3800 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3801 if (VALIDATE_WAKE_LOCK_CALLER 3802 && Binder.getCallingUid() != Process.myUid()) { 3803 throw new IllegalStateException("Calling must be system uid"); 3804 } 3805 mLaunchingActivity.release(); 3806 } 3807 } 3808 } break; 3809 case HANDLE_DISPLAY_ADDED: { 3810 handleDisplayAdded(msg.arg1); 3811 } break; 3812 case HANDLE_DISPLAY_CHANGED: { 3813 handleDisplayChanged(msg.arg1); 3814 } break; 3815 case HANDLE_DISPLAY_REMOVED: { 3816 handleDisplayRemoved(msg.arg1); 3817 } break; 3818 case CONTAINER_CALLBACK_VISIBILITY: { 3819 final ActivityContainer container = (ActivityContainer) msg.obj; 3820 final IActivityContainerCallback callback = container.mCallback; 3821 if (callback != null) { 3822 try { 3823 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3824 } catch (RemoteException e) { 3825 } 3826 } 3827 } break; 3828 case LOCK_TASK_START_MSG: { 3829 // When lock task starts, we disable the status bars. 3830 try { 3831 if (mLockTaskNotify == null) { 3832 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3833 } 3834 mLockTaskNotify.show(true); 3835 mLockTaskModeState = msg.arg2; 3836 if (getStatusBarService() != null) { 3837 int flags = 0; 3838 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 3839 flags = StatusBarManager.DISABLE_MASK 3840 & (~StatusBarManager.DISABLE_BACK); 3841 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 3842 flags = StatusBarManager.DISABLE_MASK 3843 & (~StatusBarManager.DISABLE_BACK) 3844 & (~StatusBarManager.DISABLE_HOME) 3845 & (~StatusBarManager.DISABLE_RECENT); 3846 } 3847 getStatusBarService().disable(flags, mToken, 3848 mService.mContext.getPackageName()); 3849 } 3850 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3851 if (getDevicePolicyManager() != null) { 3852 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3853 (String)msg.obj, msg.arg1); 3854 } 3855 } catch (RemoteException ex) { 3856 throw new RuntimeException(ex); 3857 } 3858 } break; 3859 case LOCK_TASK_END_MSG: { 3860 // When lock task ends, we enable the status bars. 3861 try { 3862 if (getStatusBarService() != null) { 3863 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3864 mService.mContext.getPackageName()); 3865 } 3866 mWindowManager.reenableKeyguard(mToken); 3867 if (getDevicePolicyManager() != null) { 3868 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3869 msg.arg1); 3870 } 3871 if (mLockTaskNotify == null) { 3872 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3873 } 3874 mLockTaskNotify.show(false); 3875 try { 3876 boolean shouldLockKeyguard = Settings.Secure.getInt( 3877 mService.mContext.getContentResolver(), 3878 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; 3879 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) { 3880 mWindowManager.lockNow(null); 3881 mWindowManager.dismissKeyguard(); 3882 new LockPatternUtils(mService.mContext) 3883 .requireCredentialEntry(UserHandle.USER_ALL); 3884 } 3885 } catch (SettingNotFoundException e) { 3886 // No setting, don't lock. 3887 } 3888 } catch (RemoteException ex) { 3889 throw new RuntimeException(ex); 3890 } finally { 3891 mLockTaskModeState = LOCK_TASK_MODE_NONE; 3892 } 3893 } break; 3894 case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: { 3895 if (mLockTaskNotify == null) { 3896 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3897 } 3898 mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED); 3899 } break; 3900 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3901 final ActivityContainer container = (ActivityContainer) msg.obj; 3902 final IActivityContainerCallback callback = container.mCallback; 3903 if (callback != null) { 3904 try { 3905 callback.onAllActivitiesComplete(container.asBinder()); 3906 } catch (RemoteException e) { 3907 } 3908 } 3909 } break; 3910 case LAUNCH_TASK_BEHIND_COMPLETE: { 3911 synchronized (mService) { 3912 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 3913 if (r != null) { 3914 handleLaunchTaskBehindCompleteLocked(r); 3915 } 3916 } 3917 } break; 3918 3919 } 3920 } 3921 } 3922 3923 class ActivityContainer extends android.app.IActivityContainer.Stub { 3924 final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK | 3925 FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3926 final int mStackId; 3927 IActivityContainerCallback mCallback = null; 3928 final ActivityStack mStack; 3929 ActivityRecord mParentActivity = null; 3930 String mIdString; 3931 3932 boolean mVisible = true; 3933 3934 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3935 ActivityDisplay mActivityDisplay; 3936 3937 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3938 final static int CONTAINER_STATE_NO_SURFACE = 1; 3939 final static int CONTAINER_STATE_FINISHING = 2; 3940 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3941 3942 ActivityContainer(int stackId) { 3943 synchronized (mService) { 3944 mStackId = stackId; 3945 mStack = new ActivityStack(this, mRecentTasks); 3946 mIdString = "ActivtyContainer{" + mStackId + "}"; 3947 if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this); 3948 } 3949 } 3950 3951 void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) { 3952 if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this 3953 + " to display=" + activityDisplay + " onTop=" + onTop); 3954 mActivityDisplay = activityDisplay; 3955 mStack.attachDisplay(activityDisplay, onTop); 3956 activityDisplay.attachActivities(mStack, onTop); 3957 } 3958 3959 @Override 3960 public void attachToDisplay(int displayId) { 3961 synchronized (mService) { 3962 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3963 if (activityDisplay == null) { 3964 return; 3965 } 3966 attachToDisplayLocked(activityDisplay, true); 3967 } 3968 } 3969 3970 @Override 3971 public int getDisplayId() { 3972 synchronized (mService) { 3973 if (mActivityDisplay != null) { 3974 return mActivityDisplay.mDisplayId; 3975 } 3976 } 3977 return -1; 3978 } 3979 3980 @Override 3981 public int getStackId() { 3982 synchronized (mService) { 3983 return mStackId; 3984 } 3985 } 3986 3987 @Override 3988 public boolean injectEvent(InputEvent event) { 3989 final long origId = Binder.clearCallingIdentity(); 3990 try { 3991 synchronized (mService) { 3992 if (mActivityDisplay != null) { 3993 return mInputManagerInternal.injectInputEvent(event, 3994 mActivityDisplay.mDisplayId, 3995 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3996 } 3997 } 3998 return false; 3999 } finally { 4000 Binder.restoreCallingIdentity(origId); 4001 } 4002 } 4003 4004 @Override 4005 public void release() { 4006 synchronized (mService) { 4007 if (mContainerState == CONTAINER_STATE_FINISHING) { 4008 return; 4009 } 4010 mContainerState = CONTAINER_STATE_FINISHING; 4011 4012 long origId = Binder.clearCallingIdentity(); 4013 try { 4014 mStack.finishAllActivitiesLocked(false); 4015 mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack); 4016 } finally { 4017 Binder.restoreCallingIdentity(origId); 4018 } 4019 } 4020 } 4021 4022 protected void detachLocked() { 4023 if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display=" 4024 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 4025 if (mActivityDisplay != null) { 4026 mActivityDisplay.detachActivitiesLocked(mStack); 4027 mActivityDisplay = null; 4028 mStack.detachDisplay(); 4029 } 4030 } 4031 4032 @Override 4033 public final int startActivity(Intent intent) { 4034 return mService.startActivity(intent, this); 4035 } 4036 4037 @Override 4038 public final int startActivityIntentSender(IIntentSender intentSender) 4039 throws TransactionTooLargeException { 4040 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 4041 4042 if (!(intentSender instanceof PendingIntentRecord)) { 4043 throw new IllegalArgumentException("Bad PendingIntent object"); 4044 } 4045 4046 final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(), 4047 Binder.getCallingUid(), mCurrentUser, false, 4048 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 4049 4050 final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 4051 checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent, 4052 pendingIntent.key.requestResolvedType); 4053 4054 return pendingIntent.sendInner(0, null, null, null, null, null, null, 0, 4055 FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 4056 } 4057 4058 void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) { 4059 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 4060 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 4061 throw new SecurityException( 4062 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 4063 } 4064 } 4065 4066 @Override 4067 public IBinder asBinder() { 4068 return this; 4069 } 4070 4071 @Override 4072 public void setSurface(Surface surface, int width, int height, int density) { 4073 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 4074 } 4075 4076 ActivityStackSupervisor getOuter() { 4077 return ActivityStackSupervisor.this; 4078 } 4079 4080 boolean isAttachedLocked() { 4081 return mActivityDisplay != null; 4082 } 4083 4084 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 4085 void setVisible(boolean visible) { 4086 if (mVisible != visible) { 4087 mVisible = visible; 4088 if (mCallback != null) { 4089 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 4090 0 /* unused */, this).sendToTarget(); 4091 } 4092 } 4093 } 4094 4095 void setDrawn() { 4096 } 4097 4098 // You can always start a new task on a regular ActivityStack. 4099 boolean isEligibleForNewTasks() { 4100 return true; 4101 } 4102 4103 void onTaskListEmptyLocked() { 4104 detachLocked(); 4105 deleteActivityContainer(this); 4106 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 4107 } 4108 4109 @Override 4110 public String toString() { 4111 return mIdString + (mActivityDisplay == null ? "N" : "A"); 4112 } 4113 } 4114 4115 private class VirtualActivityContainer extends ActivityContainer { 4116 Surface mSurface; 4117 boolean mDrawn = false; 4118 4119 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 4120 super(getNextStackId()); 4121 mParentActivity = parent; 4122 mCallback = callback; 4123 mContainerState = CONTAINER_STATE_NO_SURFACE; 4124 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 4125 } 4126 4127 @Override 4128 public void setSurface(Surface surface, int width, int height, int density) { 4129 super.setSurface(surface, width, height, density); 4130 4131 synchronized (mService) { 4132 final long origId = Binder.clearCallingIdentity(); 4133 try { 4134 setSurfaceLocked(surface, width, height, density); 4135 } finally { 4136 Binder.restoreCallingIdentity(origId); 4137 } 4138 } 4139 } 4140 4141 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 4142 if (mContainerState == CONTAINER_STATE_FINISHING) { 4143 return; 4144 } 4145 VirtualActivityDisplay virtualActivityDisplay = 4146 (VirtualActivityDisplay) mActivityDisplay; 4147 if (virtualActivityDisplay == null) { 4148 virtualActivityDisplay = 4149 new VirtualActivityDisplay(width, height, density); 4150 mActivityDisplay = virtualActivityDisplay; 4151 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 4152 attachToDisplayLocked(virtualActivityDisplay, true); 4153 } 4154 4155 if (mSurface != null) { 4156 mSurface.release(); 4157 } 4158 4159 mSurface = surface; 4160 if (surface != null) { 4161 resumeFocusedStackTopActivityLocked(); 4162 } else { 4163 mContainerState = CONTAINER_STATE_NO_SURFACE; 4164 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 4165 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 4166 mStack.startPausingLocked(false, true, false, false); 4167 } 4168 } 4169 4170 setSurfaceIfReadyLocked(); 4171 4172 if (DEBUG_STACK) Slog.d(TAG_STACK, 4173 "setSurface: " + this + " to display=" + virtualActivityDisplay); 4174 } 4175 4176 @Override 4177 boolean isAttachedLocked() { 4178 return mSurface != null && super.isAttachedLocked(); 4179 } 4180 4181 @Override 4182 void setDrawn() { 4183 synchronized (mService) { 4184 mDrawn = true; 4185 setSurfaceIfReadyLocked(); 4186 } 4187 } 4188 4189 // Never start a new task on an ActivityView if it isn't explicitly specified. 4190 @Override 4191 boolean isEligibleForNewTasks() { 4192 return false; 4193 } 4194 4195 private void setSurfaceIfReadyLocked() { 4196 if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 4197 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 4198 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 4199 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 4200 mContainerState = CONTAINER_STATE_HAS_SURFACE; 4201 } 4202 } 4203 } 4204 4205 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 4206 * attached {@link ActivityStack}s */ 4207 class ActivityDisplay { 4208 /** Actual Display this object tracks. */ 4209 int mDisplayId; 4210 Display mDisplay; 4211 DisplayInfo mDisplayInfo = new DisplayInfo(); 4212 4213 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 4214 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 4215 final ArrayList<ActivityStack> mStacks = new ArrayList<>(); 4216 4217 ActivityRecord mVisibleBehindActivity; 4218 4219 ActivityDisplay() { 4220 } 4221 4222 // After instantiation, check that mDisplay is not null before using this. The alternative 4223 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. 4224 ActivityDisplay(int displayId) { 4225 final Display display = mDisplayManager.getDisplay(displayId); 4226 if (display == null) { 4227 return; 4228 } 4229 init(display); 4230 } 4231 4232 void init(Display display) { 4233 mDisplay = display; 4234 mDisplayId = display.getDisplayId(); 4235 mDisplay.getDisplayInfo(mDisplayInfo); 4236 } 4237 4238 void attachActivities(ActivityStack stack, boolean onTop) { 4239 if (DEBUG_STACK) Slog.v(TAG_STACK, 4240 "attachActivities: attaching " + stack + " to displayId=" + mDisplayId 4241 + " onTop=" + onTop); 4242 if (onTop) { 4243 mStacks.add(stack); 4244 } else { 4245 mStacks.add(0, stack); 4246 } 4247 } 4248 4249 void detachActivitiesLocked(ActivityStack stack) { 4250 if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack 4251 + " from displayId=" + mDisplayId); 4252 mStacks.remove(stack); 4253 } 4254 4255 void setVisibleBehindActivity(ActivityRecord r) { 4256 mVisibleBehindActivity = r; 4257 } 4258 4259 boolean hasVisibleBehindActivity() { 4260 return mVisibleBehindActivity != null; 4261 } 4262 4263 @Override 4264 public String toString() { 4265 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4266 } 4267 } 4268 4269 class VirtualActivityDisplay extends ActivityDisplay { 4270 VirtualDisplay mVirtualDisplay; 4271 4272 VirtualActivityDisplay(int width, int height, int density) { 4273 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 4274 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 4275 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 4276 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 4277 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 4278 4279 init(mVirtualDisplay.getDisplay()); 4280 4281 mWindowManager.handleDisplayAdded(mDisplayId); 4282 } 4283 4284 void setSurface(Surface surface) { 4285 if (mVirtualDisplay != null) { 4286 mVirtualDisplay.setSurface(surface); 4287 } 4288 } 4289 4290 @Override 4291 void detachActivitiesLocked(ActivityStack stack) { 4292 super.detachActivitiesLocked(stack); 4293 if (mVirtualDisplay != null) { 4294 mVirtualDisplay.release(); 4295 mVirtualDisplay = null; 4296 } 4297 } 4298 4299 @Override 4300 public String toString() { 4301 return "VirtualActivityDisplay={" + mDisplayId + "}"; 4302 } 4303 } 4304 4305 /** 4306 * Adjust bounds to stay within stack bounds. 4307 * 4308 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way 4309 * that keep them unchanged, but be contained within the stack bounds. 4310 * 4311 * @param bounds Bounds to be adjusted. 4312 * @param stackBounds Bounds within which the other bounds should remain. 4313 */ 4314 private static void fitWithinBounds(Rect bounds, Rect stackBounds) { 4315 if (stackBounds == null || stackBounds.contains(bounds)) { 4316 return; 4317 } 4318 4319 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) { 4320 final int maxRight = stackBounds.right 4321 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER); 4322 int horizontalDiff = stackBounds.left - bounds.left; 4323 if ((horizontalDiff < 0 && bounds.left >= maxRight) 4324 || (bounds.left + horizontalDiff >= maxRight)) { 4325 horizontalDiff = maxRight - bounds.left; 4326 } 4327 bounds.left += horizontalDiff; 4328 bounds.right += horizontalDiff; 4329 } 4330 4331 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) { 4332 final int maxBottom = stackBounds.bottom 4333 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER); 4334 int verticalDiff = stackBounds.top - bounds.top; 4335 if ((verticalDiff < 0 && bounds.top >= maxBottom) 4336 || (bounds.top + verticalDiff >= maxBottom)) { 4337 verticalDiff = maxBottom - bounds.top; 4338 } 4339 bounds.top += verticalDiff; 4340 bounds.bottom += verticalDiff; 4341 } 4342 } 4343 4344 ActivityStack findStackBehind(ActivityStack stack) { 4345 // TODO(multi-display): We are only looking for stacks on the default display. 4346 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4347 if (display == null) { 4348 return null; 4349 } 4350 final ArrayList<ActivityStack> stacks = display.mStacks; 4351 for (int i = stacks.size() - 1; i >= 0; i--) { 4352 if (stacks.get(i) == stack && i > 0) { 4353 return stacks.get(i - 1); 4354 } 4355 } 4356 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 4357 + " in=" + stacks); 4358 } 4359 4360 /** 4361 * Puts a task into resizing mode during the next app transition. 4362 * 4363 * @param taskId the id of the task to put into resizing mode 4364 */ 4365 private void setResizingDuringAnimation(int taskId) { 4366 mResizingTasksDuringAnimation.add(taskId); 4367 mWindowManager.setTaskDockedResizing(taskId, true); 4368 } 4369 4370 final int startActivityFromRecentsInner(int taskId, Bundle bOptions) { 4371 final TaskRecord task; 4372 final int callingUid; 4373 final String callingPackage; 4374 final Intent intent; 4375 final int userId; 4376 final ActivityOptions activityOptions = (bOptions != null) 4377 ? new ActivityOptions(bOptions) : null; 4378 final int launchStackId = (activityOptions != null) 4379 ? activityOptions.getLaunchStackId() : INVALID_STACK_ID; 4380 if (launchStackId == HOME_STACK_ID) { 4381 throw new IllegalArgumentException("startActivityFromRecentsInner: Task " 4382 + taskId + " can't be launch in the home stack."); 4383 } 4384 4385 if (launchStackId == DOCKED_STACK_ID) { 4386 mWindowManager.setDockedStackCreateState( 4387 activityOptions.getDockCreateMode(), null /* initialBounds */); 4388 4389 // Defer updating the stack in which recents is until the app transition is done, to 4390 // not run into issues where we still need to draw the task in recents but the 4391 // docked stack is already created. 4392 deferUpdateBounds(HOME_STACK_ID); 4393 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false); 4394 } 4395 4396 task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId); 4397 if (task == null) { 4398 continueUpdateBounds(HOME_STACK_ID); 4399 mWindowManager.executeAppTransition(); 4400 throw new IllegalArgumentException( 4401 "startActivityFromRecentsInner: Task " + taskId + " not found."); 4402 } 4403 4404 if (launchStackId != INVALID_STACK_ID) { 4405 if (task.stack.mStackId != launchStackId) { 4406 moveTaskToStackLocked( 4407 taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents", 4408 ANIMATE); 4409 } 4410 } 4411 4412 // If the user must confirm credentials (e.g. when first launching a work app and the 4413 // Work Challenge is present) let startActivityInPackage handle the intercepting. 4414 if (!mService.mUserController.shouldConfirmCredentials(task.userId) 4415 && task.getRootActivity() != null) { 4416 mActivityMetricsLogger.notifyActivityLaunching(); 4417 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions); 4418 4419 // If we are launching the task in the docked stack, put it into resizing mode so 4420 // the window renders full-screen with the background filling the void. Also only 4421 // call this at the end to make sure that tasks exists on the window manager side. 4422 if (launchStackId == DOCKED_STACK_ID) { 4423 setResizingDuringAnimation(taskId); 4424 } 4425 return ActivityManager.START_TASK_TO_FRONT; 4426 } 4427 callingUid = task.mCallingUid; 4428 callingPackage = task.mCallingPackage; 4429 intent = task.intent; 4430 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 4431 userId = task.userId; 4432 int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null, 4433 null, null, 0, 0, bOptions, userId, null, task); 4434 if (launchStackId == DOCKED_STACK_ID) { 4435 setResizingDuringAnimation(task.taskId); 4436 } 4437 return result; 4438 } 4439 4440 /** 4441 * @return a list of activities which are the top ones in each visible stack. The first 4442 * entry will be the focused activity. 4443 */ 4444 public List<IBinder> getTopVisibleActivities() { 4445 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4446 if (display == null) { 4447 return Collections.EMPTY_LIST; 4448 } 4449 ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 4450 final ArrayList<ActivityStack> stacks = display.mStacks; 4451 for (int i = stacks.size() - 1; i >= 0; i--) { 4452 ActivityStack stack = stacks.get(i); 4453 if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) { 4454 ActivityRecord top = stack.topActivity(); 4455 if (top != null) { 4456 if (stack == mFocusedStack) { 4457 topActivityTokens.add(0, top.appToken); 4458 } else { 4459 topActivityTokens.add(top.appToken); 4460 } 4461 } 4462 } 4463 } 4464 return topActivityTokens; 4465 } 4466} 4467