ActivityStackSupervisor.java revision 529c8e4cf24375ca21b5d61fb6b34e7010d6edad
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import android.Manifest; 20import android.annotation.UserIdInt; 21import android.app.Activity; 22import android.app.ActivityManager; 23import android.app.ActivityManager.RunningTaskInfo; 24import android.app.ActivityManager.StackId; 25import android.app.ActivityManager.StackInfo; 26import android.app.ActivityOptions; 27import android.app.AppGlobals; 28import android.app.AppOpsManager; 29import android.app.IActivityContainer; 30import android.app.IActivityContainerCallback; 31import android.app.IActivityManager; 32import android.app.IActivityManager.WaitResult; 33import android.app.ProfilerInfo; 34import android.app.ResultInfo; 35import android.app.StatusBarManager; 36import android.app.admin.IDevicePolicyManager; 37import android.content.ComponentName; 38import android.content.Context; 39import android.content.IIntentSender; 40import android.content.Intent; 41import android.content.pm.ActivityInfo; 42import android.content.pm.ApplicationInfo; 43import android.content.pm.PackageInfo; 44import android.content.pm.PackageManager; 45import android.content.pm.ResolveInfo; 46import android.content.pm.UserInfo; 47import android.content.res.Configuration; 48import android.graphics.Rect; 49import android.hardware.display.DisplayManager; 50import android.hardware.display.DisplayManager.DisplayListener; 51import android.hardware.display.DisplayManagerGlobal; 52import android.hardware.display.VirtualDisplay; 53import android.hardware.input.InputManager; 54import android.hardware.input.InputManagerInternal; 55import android.os.Binder; 56import android.os.Bundle; 57import android.os.Debug; 58import android.os.Handler; 59import android.os.IBinder; 60import android.os.Looper; 61import android.os.Message; 62import android.os.ParcelFileDescriptor; 63import android.os.PowerManager; 64import android.os.Process; 65import android.os.RemoteException; 66import android.os.ServiceManager; 67import android.os.SystemClock; 68import android.os.Trace; 69import android.os.TransactionTooLargeException; 70import android.os.UserHandle; 71import android.os.UserManager; 72import android.os.WorkSource; 73import android.provider.MediaStore; 74import android.provider.Settings; 75import android.provider.Settings.SettingNotFoundException; 76import android.service.voice.IVoiceInteractionSession; 77import android.util.ArrayMap; 78import android.util.ArraySet; 79import android.util.EventLog; 80import android.util.Slog; 81import android.util.SparseArray; 82import android.util.SparseIntArray; 83import android.view.Display; 84import android.view.DisplayInfo; 85import android.view.InputEvent; 86import android.view.Surface; 87 88import com.android.internal.content.ReferrerIntent; 89import com.android.internal.os.TransferPipe; 90import com.android.internal.statusbar.IStatusBarService; 91import com.android.internal.util.ArrayUtils; 92import com.android.internal.widget.LockPatternUtils; 93import com.android.server.LocalServices; 94import com.android.server.am.ActivityStack.ActivityState; 95import com.android.server.wm.WindowManagerService; 96 97import java.io.FileDescriptor; 98import java.io.IOException; 99import java.io.PrintWriter; 100import java.util.ArrayList; 101import java.util.Arrays; 102import java.util.Collections; 103import java.util.List; 104import java.util.Objects; 105import java.util.Set; 106 107import static android.Manifest.permission.START_ANY_ACTIVITY; 108import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 109import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; 110import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; 111import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; 112import static android.app.ActivityManager.RESIZE_MODE_FORCED; 113import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; 114import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 115import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; 116import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID; 117import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 118import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 119import static android.app.ActivityManager.StackId.HOME_STACK_ID; 120import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 121import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID; 122import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 123import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; 124import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 125import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; 126import static android.content.pm.PackageManager.PERMISSION_GRANTED; 127import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS; 130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE; 131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN; 132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; 133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE; 134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; 136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES; 138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND; 141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS; 142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE; 143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; 144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE; 145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; 147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES; 149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; 151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; 152import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 153import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 154import static com.android.server.am.ActivityManagerService.ANIMATE; 155import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; 156import static com.android.server.am.ActivityManagerService.NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG; 157import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG; 158import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; 159import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; 160import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE; 161import static com.android.server.am.ActivityStack.ActivityState.DESTROYED; 162import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; 163import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING; 164import static com.android.server.am.ActivityStack.ActivityState.PAUSED; 165import static com.android.server.am.ActivityStack.ActivityState.PAUSING; 166import static com.android.server.am.ActivityStack.ActivityState.RESUMED; 167import static com.android.server.am.ActivityStack.ActivityState.STOPPED; 168import static com.android.server.am.ActivityStack.ActivityState.STOPPING; 169import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING; 170import static com.android.server.am.ActivityStack.STACK_INVISIBLE; 171import static com.android.server.am.ActivityStack.STACK_VISIBLE; 172import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; 173import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; 174import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 175import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; 176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; 177import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS; 178 179public final class ActivityStackSupervisor implements DisplayListener { 180 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; 181 private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS; 182 private static final String TAG_IDLE = TAG + POSTFIX_IDLE; 183 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; 184 private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE; 185 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 186 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 187 private static final String TAG_STACK = TAG + POSTFIX_STACK; 188 private static final String TAG_STATES = TAG + POSTFIX_STATES; 189 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 190 static final String TAG_TASKS = TAG + POSTFIX_TASKS; 191 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND; 192 193 /** How long we wait until giving up on the last activity telling us it is idle. */ 194 static final int IDLE_TIMEOUT = 10 * 1000; 195 196 /** How long we can hold the sleep wake lock before giving up. */ 197 static final int SLEEP_TIMEOUT = 5 * 1000; 198 199 // How long we can hold the launch wake lock before giving up. 200 static final int LAUNCH_TIMEOUT = 10 * 1000; 201 202 static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG; 203 static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1; 204 static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; 205 static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; 206 static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; 207 static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; 208 static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; 209 static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; 210 static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8; 211 static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9; 212 static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10; 213 static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11; 214 static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12; 215 static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13; 216 static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14; 217 static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15; 218 219 private static final String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; 220 221 private static final String LOCK_TASK_TAG = "Lock-to-App"; 222 223 // Used to indicate if an object (e.g. stack) that we are trying to get 224 // should be created if it doesn't exist already. 225 static final boolean CREATE_IF_NEEDED = true; 226 227 // Used to indicate that windows of activities should be preserved during the resize. 228 static final boolean PRESERVE_WINDOWS = true; 229 230 // Used to indicate if an object (e.g. task) should be moved/created 231 // at the top of its container (e.g. stack). 232 static final boolean ON_TOP = true; 233 234 // Used to indicate that an objects (e.g. task) removal from its container 235 // (e.g. stack) is due to it moving to another container. 236 static final boolean MOVING = true; 237 238 // Force the focus to change to the stack we are moving a task to.. 239 static final boolean FORCE_FOCUS = true; 240 241 // Restore task from the saved recents if it can't be found in any live stack. 242 static final boolean RESTORE_FROM_RECENTS = true; 243 244 // Don't execute any calls to resume. 245 static final boolean DEFER_RESUME = true; 246 247 // Activity actions an app cannot start if it uses a permission which is not granted. 248 private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION = 249 new ArrayMap<>(); 250 251 static { 252 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_IMAGE_CAPTURE, 253 Manifest.permission.CAMERA); 254 ACTION_TO_RUNTIME_PERMISSION.put(MediaStore.ACTION_VIDEO_CAPTURE, 255 Manifest.permission.CAMERA); 256 ACTION_TO_RUNTIME_PERMISSION.put(Intent.ACTION_CALL, 257 Manifest.permission.CALL_PHONE); 258 } 259 260 /** Action restriction: launching the activity is not restricted. */ 261 private static final int ACTIVITY_RESTRICTION_NONE = 0; 262 /** Action restriction: launching the activity is restricted by a permission. */ 263 private static final int ACTIVITY_RESTRICTION_PERMISSION = 1; 264 /** Action restriction: launching the activity is restricted by an app op. */ 265 private static final int ACTIVITY_RESTRICTION_APPOP = 2; 266 267 // The height/width divide used when fitting a task within a bounds with method 268 // {@link #fitWithinBounds}. 269 // We always want the task to to be visible in the bounds without affecting its size when 270 // fitting. To make sure this is the case, we don't adjust the task left or top side pass 271 // the input bounds right or bottom side minus the width or height divided by this value. 272 private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3; 273 274 /** Status Bar Service **/ 275 private IBinder mToken = new Binder(); 276 private IStatusBarService mStatusBarService; 277 private IDevicePolicyManager mDevicePolicyManager; 278 279 // For debugging to make sure the caller when acquiring/releasing our 280 // wake lock is the system process. 281 static final boolean VALIDATE_WAKE_LOCK_CALLER = false; 282 /** The number of distinct task ids that can be assigned to the tasks of a single user */ 283 private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE; 284 285 final ActivityManagerService mService; 286 287 private RecentTasks mRecentTasks; 288 289 final ActivityStackSupervisorHandler mHandler; 290 291 /** Short cut */ 292 WindowManagerService mWindowManager; 293 DisplayManager mDisplayManager; 294 295 /** Counter for next free stack ID to use for dynamic activity stacks. */ 296 private int mNextFreeStackId = FIRST_DYNAMIC_STACK_ID; 297 298 /** 299 * Maps the task identifier that activities are currently being started in to the userId of the 300 * task. Each time a new task is created, the entry for the userId of the task is incremented 301 */ 302 private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20); 303 304 /** The current user */ 305 int mCurrentUser; 306 307 /** The stack containing the launcher app. Assumed to always be attached to 308 * Display.DEFAULT_DISPLAY. */ 309 ActivityStack mHomeStack; 310 311 /** The stack currently receiving input or launching the next activity. */ 312 ActivityStack mFocusedStack; 313 314 /** If this is the same as mFocusedStack then the activity on the top of the focused stack has 315 * been resumed. If stacks are changing position this will hold the old stack until the new 316 * stack becomes resumed after which it will be set to mFocusedStack. */ 317 private ActivityStack mLastFocusedStack; 318 319 /** List of activities that are waiting for a new activity to become visible before completing 320 * whatever operation they are supposed to do. */ 321 final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>(); 322 323 /** List of processes waiting to find out about the next visible activity. */ 324 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>(); 325 326 /** List of processes waiting to find out about the next launched activity. */ 327 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>(); 328 329 /** List of activities that are ready to be stopped, but waiting for the next activity to 330 * settle down before doing so. */ 331 final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>(); 332 333 /** List of activities that are ready to be finished, but waiting for the previous activity to 334 * settle down before doing so. It contains ActivityRecord objects. */ 335 final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>(); 336 337 /** List of activities that are in the process of going to sleep. */ 338 final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<>(); 339 340 /** List of activities whose multi-window mode changed that we need to report to the 341 * application */ 342 final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>(); 343 344 /** List of activities whose picture-in-picture mode changed that we need to report to the 345 * application */ 346 final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>(); 347 348 /** Used on user changes */ 349 final ArrayList<UserState> mStartingUsers = new ArrayList<>(); 350 351 /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity 352 * is being brought in front of us. */ 353 boolean mUserLeaving = false; 354 355 /** Set when we have taken too long waiting to go to sleep. */ 356 boolean mSleepTimeout = false; 357 358 /** 359 * We don't want to allow the device to go to sleep while in the process 360 * of launching an activity. This is primarily to allow alarm intent 361 * receivers to launch an activity and get that to run before the device 362 * goes back to sleep. 363 */ 364 PowerManager.WakeLock mLaunchingActivity; 365 366 /** 367 * Set when the system is going to sleep, until we have 368 * successfully paused the current activity and released our wake lock. 369 * At that point the system is allowed to actually sleep. 370 */ 371 PowerManager.WakeLock mGoingToSleep; 372 373 /** Stack id of the front stack when user switched, indexed by userId. */ 374 SparseIntArray mUserStackInFront = new SparseIntArray(2); 375 376 // TODO: Add listener for removal of references. 377 /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */ 378 private SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>(); 379 380 /** Mapping from displayId to display current state */ 381 private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>(); 382 383 InputManagerInternal mInputManagerInternal; 384 385 /** The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks 386 * may be finished until there is only one entry left. If this is empty the system is not 387 * in lockTask mode. */ 388 ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>(); 389 /** Store the current lock task mode. Possible values: 390 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, 391 * {@link ActivityManager#LOCK_TASK_MODE_PINNED} 392 */ 393 private int mLockTaskModeState; 394 /** 395 * Notifies the user when entering/exiting lock-task. 396 */ 397 private LockTaskNotify mLockTaskNotify; 398 399 /** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */ 400 boolean inResumeTopActivity; 401 402 // temp. rects used during resize calculation so we don't need to create a new object each time. 403 private final Rect tempRect = new Rect(); 404 private final Rect tempRect2 = new Rect(); 405 406 private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>(); 407 private final SparseArray<Rect> mTmpBounds = new SparseArray<>(); 408 private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>(); 409 410 // The default minimal size that will be used if the activity doesn't specify its minimal size. 411 // It will be calculated when the default display gets added. 412 int 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 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); 1789 if (r == null || r.state != RESUMED) { 1790 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); 1791 } 1792 return false; 1793 } 1794 1795 void updateActivityApplicationInfoLocked(ApplicationInfo aInfo) { 1796 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1797 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1798 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 1799 stacks.get(stackNdx).updateActivityApplicationInfoLocked(aInfo); 1800 } 1801 } 1802 } 1803 1804 TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) { 1805 TaskRecord finishedTask = null; 1806 ActivityStack focusedStack = getFocusedStack(); 1807 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1808 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1809 final int numStacks = stacks.size(); 1810 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1811 final ActivityStack stack = stacks.get(stackNdx); 1812 TaskRecord t = stack.finishTopRunningActivityLocked(app, reason); 1813 if (stack == focusedStack || finishedTask == null) { 1814 finishedTask = t; 1815 } 1816 } 1817 } 1818 return finishedTask; 1819 } 1820 1821 void finishVoiceTask(IVoiceInteractionSession session) { 1822 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1823 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 1824 final int numStacks = stacks.size(); 1825 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1826 final ActivityStack stack = stacks.get(stackNdx); 1827 stack.finishVoiceTask(session); 1828 } 1829 } 1830 } 1831 1832 void findTaskToMoveToFrontLocked(TaskRecord task, int flags, ActivityOptions options, 1833 String reason, boolean forceNonResizeable) { 1834 if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 1835 mUserLeaving = true; 1836 } 1837 if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 1838 // Caller wants the home activity moved with it. To accomplish this, 1839 // we'll just indicate that this task returns to the home task. 1840 task.setTaskToReturnTo(HOME_ACTIVITY_TYPE); 1841 } 1842 if (task.stack == null) { 1843 Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task=" 1844 + task + " to front. Stack is null"); 1845 return; 1846 } 1847 1848 if (task.isResizeable() && options != null) { 1849 int stackId = options.getLaunchStackId(); 1850 if (canUseActivityOptionsLaunchBounds(options, stackId)) { 1851 final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds()); 1852 task.updateOverrideConfiguration(bounds); 1853 if (stackId == INVALID_STACK_ID) { 1854 stackId = task.getLaunchStackId(); 1855 } 1856 if (stackId != task.stack.mStackId) { 1857 final ActivityStack stack = moveTaskToStackUncheckedLocked( 1858 task, stackId, ON_TOP, !FORCE_FOCUS, reason); 1859 stackId = stack.mStackId; 1860 // moveTaskToStackUncheckedLocked() should already placed the task on top, 1861 // still need moveTaskToFrontLocked() below for any transition settings. 1862 } 1863 if (StackId.resizeStackWithLaunchBounds(stackId)) { 1864 resizeStackLocked(stackId, bounds, 1865 null /* tempTaskBounds */, null /* tempTaskInsetBounds */, 1866 !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */, !DEFER_RESUME); 1867 } else { 1868 // WM resizeTask must be done after the task is moved to the correct stack, 1869 // because Task's setBounds() also updates dim layer's bounds, but that has 1870 // dependency on the stack. 1871 mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, 1872 false /* relayout */, false /* forced */); 1873 } 1874 } 1875 } 1876 1877 final ActivityRecord r = task.getTopActivity(); 1878 task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options, 1879 r == null ? null : r.appTimeTracker, reason); 1880 1881 if (DEBUG_STACK) Slog.d(TAG_STACK, 1882 "findTaskToMoveToFront: moved to front of stack=" + task.stack); 1883 1884 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId, 1885 forceNonResizeable); 1886 } 1887 1888 boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) { 1889 // We use the launch bounds in the activity options is the device supports freeform 1890 // window management or is launching into the pinned stack. 1891 if (options.getLaunchBounds() == null) { 1892 return false; 1893 } 1894 return (mService.mSupportsPictureInPicture && launchStackId == PINNED_STACK_ID) 1895 || mService.mSupportsFreeformWindowManagement; 1896 } 1897 1898 ActivityStack getStack(int stackId) { 1899 return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 1900 } 1901 1902 ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) { 1903 ActivityContainer activityContainer = mActivityContainers.get(stackId); 1904 if (activityContainer != null) { 1905 return activityContainer.mStack; 1906 } 1907 if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) { 1908 return null; 1909 } 1910 return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop); 1911 } 1912 1913 ArrayList<ActivityStack> getStacks() { 1914 ArrayList<ActivityStack> allStacks = new ArrayList<>(); 1915 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1916 allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); 1917 } 1918 return allStacks; 1919 } 1920 1921 IBinder getHomeActivityToken() { 1922 ActivityRecord homeActivity = getHomeActivity(); 1923 if (homeActivity != null) { 1924 return homeActivity.appToken; 1925 } 1926 return null; 1927 } 1928 1929 ActivityRecord getHomeActivity() { 1930 return getHomeActivityForUser(mCurrentUser); 1931 } 1932 1933 ActivityRecord getHomeActivityForUser(int userId) { 1934 final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); 1935 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 1936 final TaskRecord task = tasks.get(taskNdx); 1937 if (task.isHomeTask()) { 1938 final ArrayList<ActivityRecord> activities = task.mActivities; 1939 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 1940 final ActivityRecord r = activities.get(activityNdx); 1941 if (r.isHomeActivity() 1942 && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) { 1943 return r; 1944 } 1945 } 1946 } 1947 } 1948 return null; 1949 } 1950 1951 /** 1952 * Returns if a stack should be treated as if it's docked. Returns true if the stack is 1953 * the docked stack itself, or if it's side-by-side to the docked stack. 1954 */ 1955 boolean isStackDockedInEffect(int stackId) { 1956 return stackId == DOCKED_STACK_ID || 1957 (StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null); 1958 } 1959 1960 ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity, 1961 IActivityContainerCallback callback) { 1962 ActivityContainer activityContainer = 1963 new VirtualActivityContainer(parentActivity, callback); 1964 mActivityContainers.put(activityContainer.mStackId, activityContainer); 1965 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 1966 "createActivityContainer: " + activityContainer); 1967 parentActivity.mChildContainers.add(activityContainer); 1968 return activityContainer; 1969 } 1970 1971 void removeChildActivityContainers(ActivityRecord parentActivity) { 1972 final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers; 1973 for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) { 1974 ActivityContainer container = childStacks.remove(containerNdx); 1975 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing " 1976 + container); 1977 container.release(); 1978 } 1979 } 1980 1981 void deleteActivityContainer(IActivityContainer container) { 1982 ActivityContainer activityContainer = (ActivityContainer)container; 1983 if (activityContainer != null) { 1984 if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, 1985 "deleteActivityContainer: callers=" + Debug.getCallers(4)); 1986 final int stackId = activityContainer.mStackId; 1987 mActivityContainers.remove(stackId); 1988 mWindowManager.removeStack(stackId); 1989 } 1990 } 1991 1992 void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, 1993 boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) { 1994 if (stackId == DOCKED_STACK_ID) { 1995 resizeDockedStackLocked(bounds, tempTaskBounds, tempTaskInsetBounds, null, null, 1996 preserveWindows); 1997 return; 1998 } 1999 final ActivityStack stack = getStack(stackId); 2000 if (stack == null) { 2001 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); 2002 return; 2003 } 2004 2005 if (!allowResizeInDockedMode && getStack(DOCKED_STACK_ID) != null) { 2006 // If the docked stack exist we don't allow resizes of stacks not caused by the docked 2007 // stack size changing so things don't get out of sync. 2008 return; 2009 } 2010 2011 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId); 2012 mWindowManager.deferSurfaceLayout(); 2013 try { 2014 resizeStackUncheckedLocked(stack, bounds, tempTaskBounds, tempTaskInsetBounds); 2015 if (!deferResume) { 2016 stack.ensureVisibleActivitiesConfigurationLocked( 2017 stack.topRunningActivityLocked(), preserveWindows); 2018 } 2019 } finally { 2020 mWindowManager.continueSurfaceLayout(); 2021 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2022 } 2023 } 2024 2025 void deferUpdateBounds(int stackId) { 2026 final ActivityStack stack = getStack(stackId); 2027 if (stack != null) { 2028 stack.deferUpdateBounds(); 2029 } 2030 } 2031 2032 void continueUpdateBounds(int stackId) { 2033 final ActivityStack stack = getStack(stackId); 2034 if (stack != null) { 2035 stack.continueUpdateBounds(); 2036 } 2037 } 2038 2039 void notifyAppTransitionDone() { 2040 continueUpdateBounds(HOME_STACK_ID); 2041 for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) { 2042 final int taskId = mResizingTasksDuringAnimation.valueAt(i); 2043 if (anyTaskForIdLocked(taskId) != null) { 2044 mWindowManager.setTaskDockedResizing(taskId, false); 2045 } 2046 } 2047 mResizingTasksDuringAnimation.clear(); 2048 } 2049 2050 void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds, 2051 Rect tempTaskInsetBounds) { 2052 bounds = TaskRecord.validateBounds(bounds); 2053 2054 if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) { 2055 return; 2056 } 2057 2058 mTmpBounds.clear(); 2059 mTmpConfigs.clear(); 2060 mTmpInsetBounds.clear(); 2061 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2062 final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds; 2063 final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds; 2064 for (int i = tasks.size() - 1; i >= 0; i--) { 2065 final TaskRecord task = tasks.get(i); 2066 if (task.isResizeable()) { 2067 if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) { 2068 // For freeform stack we don't adjust the size of the tasks to match that 2069 // of the stack, but we do try to make sure the tasks are still contained 2070 // with the bounds of the stack. 2071 tempRect2.set(task.mBounds); 2072 fitWithinBounds(tempRect2, bounds); 2073 task.updateOverrideConfiguration(tempRect2); 2074 } else { 2075 task.updateOverrideConfiguration(taskBounds, insetBounds); 2076 } 2077 } 2078 2079 mTmpConfigs.put(task.taskId, task.mOverrideConfig); 2080 mTmpBounds.put(task.taskId, task.mBounds); 2081 if (tempTaskInsetBounds != null) { 2082 mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds); 2083 } 2084 } 2085 2086 // We might trigger a configuration change. Save the current task bounds for freezing. 2087 mWindowManager.prepareFreezingTaskBounds(stack.mStackId); 2088 stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs, 2089 mTmpBounds, mTmpInsetBounds); 2090 stack.setBounds(bounds); 2091 } 2092 2093 void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) { 2094 final ActivityStack stack = getStack(fromStackId); 2095 if (stack == null) { 2096 return; 2097 } 2098 2099 mWindowManager.deferSurfaceLayout(); 2100 try { 2101 if (fromStackId == DOCKED_STACK_ID) { 2102 2103 // We are moving all tasks from the docked stack to the fullscreen stack, 2104 // which is dismissing the docked stack, so resize all other stacks to 2105 // fullscreen here already so we don't end up with resize trashing. 2106 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2107 if (StackId.isResizeableByDockedStack(i)) { 2108 ActivityStack otherStack = getStack(i); 2109 if (otherStack != null) { 2110 resizeStackLocked(i, null, null, null, PRESERVE_WINDOWS, 2111 true /* allowResizeInDockedMode */, DEFER_RESUME); 2112 } 2113 } 2114 } 2115 2116 // Also disable docked stack resizing since we have manually adjusted the 2117 // size of other stacks above and we don't want to trigger a docked stack 2118 // resize when we remove task from it below and it is detached from the 2119 // display because it no longer contains any tasks. 2120 mAllowDockedStackResize = false; 2121 } 2122 final ArrayList<TaskRecord> tasks = stack.getAllTasks(); 2123 final int size = tasks.size(); 2124 if (onTop) { 2125 for (int i = 0; i < size; i++) { 2126 moveTaskToStackLocked(tasks.get(i).taskId, 2127 FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/, 2128 "moveTasksToFullscreenStack", ANIMATE, DEFER_RESUME); 2129 } 2130 2131 ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS); 2132 resumeFocusedStackTopActivityLocked(); 2133 } else { 2134 for (int i = size - 1; i >= 0; i--) { 2135 positionTaskInStackLocked(tasks.get(i).taskId, 2136 FULLSCREEN_WORKSPACE_STACK_ID, 0); 2137 } 2138 } 2139 } finally { 2140 mAllowDockedStackResize = true; 2141 mWindowManager.continueSurfaceLayout(); 2142 } 2143 } 2144 2145 void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds, 2146 Rect tempDockedTaskInsetBounds, 2147 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows) { 2148 2149 if (!mAllowDockedStackResize) { 2150 // Docked stack resize currently disabled. 2151 return; 2152 } 2153 2154 final ActivityStack stack = getStack(DOCKED_STACK_ID); 2155 if (stack == null) { 2156 Slog.w(TAG, "resizeDockedStackLocked: docked stack not found"); 2157 return; 2158 } 2159 2160 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack"); 2161 mWindowManager.deferSurfaceLayout(); 2162 try { 2163 // Don't allow re-entry while resizing. E.g. due to docked stack detaching. 2164 mAllowDockedStackResize = false; 2165 ActivityRecord r = stack.topRunningActivityLocked(); 2166 resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds, 2167 tempDockedTaskInsetBounds); 2168 2169 // TODO: Checking for isAttached might not be needed as if the user passes in null 2170 // dockedBounds then they want the docked stack to be dismissed. 2171 if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) { 2172 // The dock stack either was dismissed or went fullscreen, which is kinda the same. 2173 // In this case we make all other static stacks fullscreen and move all 2174 // docked stack tasks to the fullscreen stack. 2175 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, ON_TOP); 2176 2177 // stack shouldn't contain anymore activities, so nothing to resume. 2178 r = null; 2179 } else { 2180 // Docked stacks occupy a dedicated region on screen so the size of all other 2181 // static stacks need to be adjusted so they don't overlap with the docked stack. 2182 // We get the bounds to use from window manager which has been adjusted for any 2183 // screen controls and is also the same for all stacks. 2184 mWindowManager.getStackDockedModeBounds( 2185 HOME_STACK_ID, tempRect, true /* ignoreVisibility */); 2186 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { 2187 if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) { 2188 resizeStackLocked(i, tempRect, tempOtherTaskBounds, 2189 tempOtherTaskInsetBounds, preserveWindows, 2190 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2191 } 2192 } 2193 } 2194 stack.ensureVisibleActivitiesConfigurationLocked(r, preserveWindows); 2195 } finally { 2196 mAllowDockedStackResize = true; 2197 mWindowManager.continueSurfaceLayout(); 2198 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2199 } 2200 2201 mResizeDockedStackTimeout.notifyResizing(dockedBounds, 2202 tempDockedTaskBounds != null 2203 || tempDockedTaskInsetBounds != null 2204 || tempOtherTaskBounds != null 2205 || tempOtherTaskInsetBounds != null); 2206 } 2207 2208 void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 2209 final ActivityStack stack = getStack(PINNED_STACK_ID); 2210 if (stack == null) { 2211 Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found"); 2212 return; 2213 } 2214 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack"); 2215 mWindowManager.deferSurfaceLayout(); 2216 try { 2217 ActivityRecord r = stack.topRunningActivityLocked(); 2218 resizeStackUncheckedLocked(stack, pinnedBounds, tempPinnedTaskBounds, 2219 null); 2220 stack.ensureVisibleActivitiesConfigurationLocked(r, false); 2221 } finally { 2222 mWindowManager.continueSurfaceLayout(); 2223 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2224 } 2225 } 2226 2227 boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow, 2228 boolean deferResume) { 2229 if (!task.isResizeable()) { 2230 Slog.w(TAG, "resizeTask: task " + task + " not resizeable."); 2231 return true; 2232 } 2233 2234 // If this is a forced resize, let it go through even if the bounds is not changing, 2235 // as we might need a relayout due to surface size change (to/from fullscreen). 2236 final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0; 2237 if (Objects.equals(task.mBounds, bounds) && !forced) { 2238 // Nothing to do here... 2239 return true; 2240 } 2241 bounds = TaskRecord.validateBounds(bounds); 2242 2243 if (!mWindowManager.isValidTaskId(task.taskId)) { 2244 // Task doesn't exist in window manager yet (e.g. was restored from recents). 2245 // All we can do for now is update the bounds so it can be used when the task is 2246 // added to window manager. 2247 task.updateOverrideConfiguration(bounds); 2248 if (task.stack != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) { 2249 // re-restore the task so it can have the proper stack association. 2250 restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID); 2251 } 2252 return true; 2253 } 2254 2255 // Do not move the task to another stack here. 2256 // This method assumes that the task is already placed in the right stack. 2257 // we do not mess with that decision and we only do the resize! 2258 2259 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeTask_" + task.taskId); 2260 2261 final Configuration overrideConfig = task.updateOverrideConfiguration(bounds); 2262 // This variable holds information whether the configuration didn't change in a significant 2263 // way and the activity was kept the way it was. If it's false, it means the activity had 2264 // to be relaunched due to configuration change. 2265 boolean kept = true; 2266 if (overrideConfig != null) { 2267 final ActivityRecord r = task.topRunningActivityLocked(); 2268 if (r != null) { 2269 final ActivityStack stack = task.stack; 2270 kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow); 2271 2272 if (!deferResume) { 2273 2274 // All other activities must be made visible with their correct configuration. 2275 ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); 2276 if (!kept) { 2277 resumeFocusedStackTopActivityLocked(); 2278 } 2279 } 2280 } 2281 } 2282 mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig, kept, forced); 2283 2284 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 2285 return kept; 2286 } 2287 2288 ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) { 2289 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 2290 if (activityDisplay == null) { 2291 return null; 2292 } 2293 2294 ActivityContainer activityContainer = new ActivityContainer(stackId); 2295 mActivityContainers.put(stackId, activityContainer); 2296 activityContainer.attachToDisplayLocked(activityDisplay, onTop); 2297 return activityContainer.mStack; 2298 } 2299 2300 int getNextStackId() { 2301 while (true) { 2302 if (mNextFreeStackId >= FIRST_DYNAMIC_STACK_ID 2303 && getStack(mNextFreeStackId) == null) { 2304 break; 2305 } 2306 mNextFreeStackId++; 2307 } 2308 return mNextFreeStackId; 2309 } 2310 2311 /** 2312 * Restores a recent task to a stack 2313 * @param task The recent task to be restored. 2314 * @param stackId The stack to restore the task to (default launch stack will be used 2315 * if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}). 2316 * @return true if the task has been restored successfully. 2317 */ 2318 private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) { 2319 if (stackId == INVALID_STACK_ID) { 2320 stackId = task.getLaunchStackId(); 2321 } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) { 2322 // Preferred stack is the docked stack, but the task can't go in the docked stack. 2323 // Put it in the fullscreen stack. 2324 stackId = FULLSCREEN_WORKSPACE_STACK_ID; 2325 } 2326 2327 if (task.stack != null) { 2328 // Task has already been restored once. See if we need to do anything more 2329 if (task.stack.mStackId == stackId) { 2330 // Nothing else to do since it is already restored in the right stack. 2331 return true; 2332 } 2333 // Remove current stack association, so we can re-associate the task with the 2334 // right stack below. 2335 task.stack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING); 2336 } 2337 2338 final ActivityStack stack = 2339 getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); 2340 2341 if (stack == null) { 2342 // What does this mean??? Not sure how we would get here... 2343 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2344 "Unable to find/create stack to restore recent task=" + task); 2345 return false; 2346 } 2347 2348 stack.addTask(task, false, "restoreRecentTask"); 2349 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, 2350 "Added restored task=" + task + " to stack=" + stack); 2351 final ArrayList<ActivityRecord> activities = task.mActivities; 2352 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 2353 stack.addConfigOverride(activities.get(activityNdx), task); 2354 } 2355 return true; 2356 } 2357 2358 /** 2359 * Moves the specified task record to the input stack id. 2360 * WARNING: This method performs an unchecked/raw move of the task and 2361 * can leave the system in an unstable state if used incorrectly. 2362 * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack. 2363 * @param task Task to move. 2364 * @param stackId Id of stack to move task to. 2365 * @param toTop True if the task should be placed at the top of the stack. 2366 * @param forceFocus if focus should be moved to the new stack 2367 * @param reason Reason the task is been moved. 2368 * @return The stack the task was moved to. 2369 */ 2370 ActivityStack moveTaskToStackUncheckedLocked( 2371 TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) { 2372 2373 if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) { 2374 throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't " 2375 + "support multi-window task=" + task + " to stackId=" + stackId); 2376 } 2377 2378 final ActivityRecord r = task.topRunningActivityLocked(); 2379 final ActivityStack prevStack = task.stack; 2380 final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r); 2381 final boolean wasResumed = prevStack.mResumedActivity == r; 2382 // In some cases the focused stack isn't the front stack. E.g. pinned stack. 2383 // Whenever we are moving the top activity from the front stack we want to make sure to move 2384 // the stack to the front. 2385 final boolean wasFront = isFrontStack(prevStack) 2386 && (prevStack.topRunningActivityLocked() == r); 2387 2388 if (stackId == DOCKED_STACK_ID && !task.isResizeable()) { 2389 // We don't allow moving a unresizeable task to the docked stack since the docked 2390 // stack is used for split-screen mode and will cause things like the docked divider to 2391 // show up. We instead leave the task in its current stack or move it to the fullscreen 2392 // stack if it isn't currently in a stack. 2393 stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID; 2394 Slog.w(TAG, "Can not move unresizeable task=" + task 2395 + " to docked stack. Moving to stackId=" + stackId + " instead."); 2396 } 2397 2398 // Temporarily disable resizeablility of task we are moving. We don't want it to be resized 2399 // if a docked stack is created below which will lead to the stack we are moving from and 2400 // its resizeable tasks being resized. 2401 task.mTemporarilyUnresizable = true; 2402 final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop); 2403 task.mTemporarilyUnresizable = false; 2404 mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop); 2405 stack.addTask(task, toTop, reason); 2406 2407 // If the task had focus before (or we're requested to move focus), 2408 // move focus to the new stack by moving the stack to the front. 2409 stack.moveToFrontAndResumeStateIfNeeded( 2410 r, forceFocus || wasFocused || wasFront, wasResumed, reason); 2411 2412 return stack; 2413 } 2414 2415 boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, 2416 String reason, boolean animate) { 2417 return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate, 2418 false /* deferResume */); 2419 } 2420 2421 boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, 2422 String reason, boolean animate, boolean deferResume) { 2423 final TaskRecord task = anyTaskForIdLocked(taskId); 2424 if (task == null) { 2425 Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId); 2426 return false; 2427 } 2428 2429 if (task.stack != null && task.stack.mStackId == stackId) { 2430 // You are already in the right stack silly... 2431 Slog.i(TAG, "moveTaskToStack: taskId=" + taskId + " already in stackId=" + stackId); 2432 return true; 2433 } 2434 2435 if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) { 2436 throw new IllegalArgumentException("moveTaskToStack:" 2437 + "Attempt to move task " + taskId + " to unsupported freeform stack"); 2438 } 2439 2440 final ActivityRecord topActivity = task.getTopActivity(); 2441 final int sourceStackId = task.stack != null ? task.stack.mStackId : INVALID_STACK_ID; 2442 final boolean mightReplaceWindow = 2443 StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) && topActivity != null; 2444 if (mightReplaceWindow) { 2445 // We are about to relaunch the activity because its configuration changed due to 2446 // being maximized, i.e. size change. The activity will first remove the old window 2447 // and then add a new one. This call will tell window manager about this, so it can 2448 // preserve the old window until the new one is drawn. This prevents having a gap 2449 // between the removal and addition, in which no window is visible. We also want the 2450 // entrance of the new window to be properly animated. 2451 // Note here we always set the replacing window first, as the flags might be needed 2452 // during the relaunch. If we end up not doing any relaunch, we clear the flags later. 2453 mWindowManager.setReplacingWindow(topActivity.appToken, animate); 2454 } 2455 2456 mWindowManager.deferSurfaceLayout(); 2457 final int preferredLaunchStackId = stackId; 2458 boolean kept = true; 2459 try { 2460 final ActivityStack stack = moveTaskToStackUncheckedLocked( 2461 task, stackId, toTop, forceFocus, reason + " moveTaskToStack"); 2462 stackId = stack.mStackId; 2463 2464 if (!animate) { 2465 stack.mNoAnimActivities.add(topActivity); 2466 } 2467 2468 // We might trigger a configuration change. Save the current task bounds for freezing. 2469 mWindowManager.prepareFreezingTaskBounds(stack.mStackId); 2470 2471 // Make sure the task has the appropriate bounds/size for the stack it is in. 2472 if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) { 2473 kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, 2474 !mightReplaceWindow, deferResume); 2475 } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) { 2476 Rect bounds = task.getLaunchBounds(); 2477 if (bounds == null) { 2478 stack.layoutTaskInStack(task, null); 2479 bounds = task.mBounds; 2480 } 2481 kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, 2482 deferResume); 2483 } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) { 2484 kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, 2485 !mightReplaceWindow, deferResume); 2486 } 2487 } finally { 2488 mWindowManager.continueSurfaceLayout(); 2489 } 2490 2491 if (mightReplaceWindow) { 2492 // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old 2493 // window), we need to clear the replace window settings. Otherwise, we schedule a 2494 // timeout to remove the old window if the replacing window is not coming in time. 2495 mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept); 2496 } 2497 2498 if (!deferResume) { 2499 2500 // The task might have already been running and its visibility needs to be synchronized with 2501 // the visibility of the stack / windows. 2502 ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow); 2503 resumeFocusedStackTopActivityLocked(); 2504 } 2505 2506 handleNonResizableTaskIfNeeded(task, preferredLaunchStackId, stackId); 2507 2508 return (preferredLaunchStackId == stackId); 2509 } 2510 2511 boolean moveTopStackActivityToPinnedStackLocked(int stackId, Rect bounds) { 2512 final ActivityStack stack = getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP); 2513 if (stack == null) { 2514 throw new IllegalArgumentException( 2515 "moveTopStackActivityToPinnedStackLocked: Unknown stackId=" + stackId); 2516 } 2517 2518 final ActivityRecord r = stack.topRunningActivityLocked(); 2519 if (r == null) { 2520 Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: No top running activity" 2521 + " in stack=" + stack); 2522 return false; 2523 } 2524 2525 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { 2526 Slog.w(TAG, 2527 "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for " 2528 + " r=" + r); 2529 return false; 2530 } 2531 2532 moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds); 2533 return true; 2534 } 2535 2536 void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) { 2537 mWindowManager.deferSurfaceLayout(); 2538 try { 2539 final TaskRecord task = r.task; 2540 2541 if (r == task.stack.getVisibleBehindActivity()) { 2542 // An activity can't be pinned and visible behind at the same time. Go ahead and 2543 // release it from been visible behind before pinning. 2544 requestVisibleBehindLocked(r, false); 2545 } 2546 2547 // Need to make sure the pinned stack exist so we can resize it below... 2548 final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP); 2549 2550 // Resize the pinned stack to match the current size of the task the activity we are 2551 // going to be moving is currently contained in. We do this to have the right starting 2552 // animation bounds for the pinned stack to the desired bounds the caller wants. 2553 resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */, 2554 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, 2555 true /* allowResizeInDockedMode */, !DEFER_RESUME); 2556 2557 if (task.mActivities.size() == 1) { 2558 // There is only one activity in the task. So, we can just move the task over to 2559 // the stack without re-parenting the activity in a different task. 2560 if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) { 2561 // Move the home stack forward if the task we just moved to the pinned stack 2562 // was launched from home so home should be visible behind it. 2563 moveHomeStackToFront(reason); 2564 } 2565 moveTaskToStackLocked( 2566 task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE); 2567 } else { 2568 stack.moveActivityToStack(r); 2569 } 2570 } finally { 2571 mWindowManager.continueSurfaceLayout(); 2572 } 2573 2574 // The task might have already been running and its visibility needs to be synchronized 2575 // with the visibility of the stack / windows. 2576 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2577 resumeFocusedStackTopActivityLocked(); 2578 2579 mWindowManager.animateResizePinnedStack(bounds, -1); 2580 mService.notifyActivityPinnedLocked(); 2581 } 2582 2583 void positionTaskInStackLocked(int taskId, int stackId, int position) { 2584 final TaskRecord task = anyTaskForIdLocked(taskId); 2585 if (task == null) { 2586 Slog.w(TAG, "positionTaskInStackLocked: no task for id=" + taskId); 2587 return; 2588 } 2589 final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, !ON_TOP); 2590 2591 task.updateOverrideConfigurationForStack(stack); 2592 2593 mWindowManager.positionTaskInStack( 2594 taskId, stackId, position, task.mBounds, task.mOverrideConfig); 2595 stack.positionTask(task, position); 2596 // The task might have already been running and its visibility needs to be synchronized with 2597 // the visibility of the stack / windows. 2598 stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2599 resumeFocusedStackTopActivityLocked(); 2600 } 2601 2602 ActivityRecord findTaskLocked(ActivityRecord r) { 2603 mTmpFindTaskResult.r = null; 2604 mTmpFindTaskResult.matchedByRootAffinity = false; 2605 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 2606 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2607 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2608 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2609 final ActivityStack stack = stacks.get(stackNdx); 2610 if (!r.isApplicationActivity() && !stack.isHomeStack()) { 2611 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack); 2612 continue; 2613 } 2614 if (!stack.mActivityContainer.isEligibleForNewTasks()) { 2615 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 2616 "Skipping stack: (new task not allowed) " + stack); 2617 continue; 2618 } 2619 stack.findTaskLocked(r, mTmpFindTaskResult); 2620 // It is possible to have task in multiple stacks with the same root affinity. 2621 // If the match we found was based on root affinity we keep on looking to see if 2622 // there is a better match in another stack. We eventually return the match based 2623 // on root affinity if we don't find a better match. 2624 if (mTmpFindTaskResult.r != null && !mTmpFindTaskResult.matchedByRootAffinity) { 2625 return mTmpFindTaskResult.r; 2626 } 2627 } 2628 } 2629 if (DEBUG_TASKS && mTmpFindTaskResult.r == null) Slog.d(TAG_TASKS, "No task found"); 2630 return mTmpFindTaskResult.r; 2631 } 2632 2633 ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { 2634 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2635 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2636 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2637 final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); 2638 if (ar != null) { 2639 return ar; 2640 } 2641 } 2642 } 2643 return null; 2644 } 2645 2646 void goingToSleepLocked() { 2647 scheduleSleepTimeout(); 2648 if (!mGoingToSleep.isHeld()) { 2649 mGoingToSleep.acquire(); 2650 if (mLaunchingActivity.isHeld()) { 2651 if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { 2652 throw new IllegalStateException("Calling must be system uid"); 2653 } 2654 mLaunchingActivity.release(); 2655 mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 2656 } 2657 } 2658 checkReadyForSleepLocked(); 2659 } 2660 2661 boolean shutdownLocked(int timeout) { 2662 goingToSleepLocked(); 2663 2664 boolean timedout = false; 2665 final long endTime = System.currentTimeMillis() + timeout; 2666 while (true) { 2667 boolean cantShutdown = false; 2668 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2669 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2670 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2671 cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2672 } 2673 } 2674 if (cantShutdown) { 2675 long timeRemaining = endTime - System.currentTimeMillis(); 2676 if (timeRemaining > 0) { 2677 try { 2678 mService.wait(timeRemaining); 2679 } catch (InterruptedException e) { 2680 } 2681 } else { 2682 Slog.w(TAG, "Activity manager shutdown timed out"); 2683 timedout = true; 2684 break; 2685 } 2686 } else { 2687 break; 2688 } 2689 } 2690 2691 // Force checkReadyForSleep to complete. 2692 mSleepTimeout = true; 2693 checkReadyForSleepLocked(); 2694 2695 return timedout; 2696 } 2697 2698 void comeOutOfSleepIfNeededLocked() { 2699 removeSleepTimeouts(); 2700 if (mGoingToSleep.isHeld()) { 2701 mGoingToSleep.release(); 2702 } 2703 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2704 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2705 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2706 final ActivityStack stack = stacks.get(stackNdx); 2707 stack.awakeFromSleepingLocked(); 2708 if (isFocusedStack(stack)) { 2709 resumeFocusedStackTopActivityLocked(); 2710 } 2711 } 2712 } 2713 mGoingToSleepActivities.clear(); 2714 } 2715 2716 void activitySleptLocked(ActivityRecord r) { 2717 mGoingToSleepActivities.remove(r); 2718 checkReadyForSleepLocked(); 2719 } 2720 2721 void checkReadyForSleepLocked() { 2722 if (!mService.isSleepingOrShuttingDown()) { 2723 // Do not care. 2724 return; 2725 } 2726 2727 if (!mSleepTimeout) { 2728 boolean dontSleep = false; 2729 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2730 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2731 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2732 dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); 2733 } 2734 } 2735 2736 if (mStoppingActivities.size() > 0) { 2737 // Still need to tell some activities to stop; can't sleep yet. 2738 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop " 2739 + mStoppingActivities.size() + " activities"); 2740 scheduleIdleLocked(); 2741 dontSleep = true; 2742 } 2743 2744 if (mGoingToSleepActivities.size() > 0) { 2745 // Still need to tell some activities to sleep; can't sleep yet. 2746 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep " 2747 + mGoingToSleepActivities.size() + " activities"); 2748 dontSleep = true; 2749 } 2750 2751 if (dontSleep) { 2752 return; 2753 } 2754 } 2755 2756 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2757 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2758 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2759 stacks.get(stackNdx).goToSleep(); 2760 } 2761 } 2762 2763 removeSleepTimeouts(); 2764 2765 if (mGoingToSleep.isHeld()) { 2766 mGoingToSleep.release(); 2767 } 2768 if (mService.mShuttingDown) { 2769 mService.notifyAll(); 2770 } 2771 } 2772 2773 boolean reportResumedActivityLocked(ActivityRecord r) { 2774 final ActivityStack stack = r.task.stack; 2775 if (isFocusedStack(stack)) { 2776 mService.updateUsageStats(r, true); 2777 } 2778 if (allResumedActivitiesComplete()) { 2779 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 2780 mWindowManager.executeAppTransition(); 2781 return true; 2782 } 2783 return false; 2784 } 2785 2786 void handleAppCrashLocked(ProcessRecord app) { 2787 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2788 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2789 int stackNdx = stacks.size() - 1; 2790 while (stackNdx >= 0) { 2791 stacks.get(stackNdx).handleAppCrashLocked(app); 2792 stackNdx--; 2793 } 2794 } 2795 } 2796 2797 boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) { 2798 final ActivityStack stack = r.task.stack; 2799 if (stack == null) { 2800 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2801 "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null"); 2802 return false; 2803 } 2804 2805 if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) { 2806 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r 2807 + " visible=" + visible + " stackId=" + stack.mStackId 2808 + " can't contain visible behind activities"); 2809 return false; 2810 } 2811 2812 final boolean isVisible = stack.hasVisibleBehindActivity(); 2813 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2814 "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible); 2815 2816 final ActivityRecord top = topRunningActivityLocked(); 2817 if (top == null || top == r || (visible == isVisible)) { 2818 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return"); 2819 stack.setVisibleBehindActivity(visible ? r : null); 2820 return true; 2821 } 2822 2823 // A non-top activity is reporting a visibility change. 2824 if (visible && top.fullscreen) { 2825 // Let the caller know that it can't be seen. 2826 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2827 "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen 2828 + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread=" 2829 + top.app.thread); 2830 return false; 2831 } else if (!visible && stack.getVisibleBehindActivity() != r) { 2832 // Only the activity set as currently visible behind should actively reset its 2833 // visible behind state. 2834 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 2835 "requestVisibleBehind: returning visible=" + visible 2836 + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity() 2837 + " r=" + r); 2838 return false; 2839 } 2840 2841 stack.setVisibleBehindActivity(visible ? r : null); 2842 if (!visible) { 2843 // If there is a translucent home activity, we need to force it stop being translucent, 2844 // because we can't depend on the application to necessarily perform that operation. 2845 // Check out b/14469711 for details. 2846 final ActivityRecord next = stack.findNextTranslucentActivity(r); 2847 if (next != null && next.isHomeActivity()) { 2848 mService.convertFromTranslucent(next.appToken); 2849 } 2850 } 2851 if (top.app != null && top.app.thread != null) { 2852 // Notify the top app of the change. 2853 try { 2854 top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); 2855 } catch (RemoteException e) { 2856 } 2857 } 2858 return true; 2859 } 2860 2861 // Called when WindowManager has finished animating the launchingBehind activity to the back. 2862 void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) { 2863 final TaskRecord task = r.task; 2864 final ActivityStack stack = task.stack; 2865 2866 r.mLaunchTaskBehind = false; 2867 task.setLastThumbnailLocked(stack.screenshotActivitiesLocked(r)); 2868 mRecentTasks.addLocked(task); 2869 mService.notifyTaskStackChangedLocked(); 2870 mWindowManager.setAppVisibility(r.appToken, false); 2871 2872 // When launching tasks behind, update the last active time of the top task after the new 2873 // task has been shown briefly 2874 final ActivityRecord top = stack.topActivity(); 2875 if (top != null) { 2876 top.task.touchActiveTime(); 2877 } 2878 } 2879 2880 void scheduleLaunchTaskBehindComplete(IBinder token) { 2881 mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget(); 2882 } 2883 2884 void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges, 2885 boolean preserveWindows) { 2886 // First the front stacks. In case any are not fullscreen and are in front of home. 2887 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2888 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2889 final int topStackNdx = stacks.size() - 1; 2890 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2891 final ActivityStack stack = stacks.get(stackNdx); 2892 stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows); 2893 } 2894 } 2895 } 2896 2897 void invalidateTaskLayers() { 2898 mTaskLayersChanged = true; 2899 } 2900 2901 void rankTaskLayersIfNeeded() { 2902 if (!mTaskLayersChanged) { 2903 return; 2904 } 2905 mTaskLayersChanged = false; 2906 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) { 2907 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2908 int baseLayer = 0; 2909 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 2910 baseLayer += stacks.get(stackNdx).rankTaskLayers(baseLayer); 2911 } 2912 } 2913 } 2914 2915 void clearOtherAppTimeTrackers(AppTimeTracker except) { 2916 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2917 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2918 final int topStackNdx = stacks.size() - 1; 2919 for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { 2920 final ActivityStack stack = stacks.get(stackNdx); 2921 stack.clearOtherAppTimeTrackers(except); 2922 } 2923 } 2924 } 2925 2926 void scheduleDestroyAllActivities(ProcessRecord app, String reason) { 2927 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2928 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2929 final int numStacks = stacks.size(); 2930 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2931 final ActivityStack stack = stacks.get(stackNdx); 2932 stack.scheduleDestroyActivities(app, reason); 2933 } 2934 } 2935 } 2936 2937 void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { 2938 // Examine all activities currently running in the process. 2939 TaskRecord firstTask = null; 2940 // Tasks is non-null only if two or more tasks are found. 2941 ArraySet<TaskRecord> tasks = null; 2942 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); 2943 for (int i = 0; i < app.activities.size(); i++) { 2944 ActivityRecord r = app.activities.get(i); 2945 // First, if we find an activity that is in the process of being destroyed, 2946 // then we just aren't going to do anything for now; we want things to settle 2947 // down before we try to prune more activities. 2948 if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) { 2949 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); 2950 return; 2951 } 2952 // Don't consider any activies that are currently not in a state where they 2953 // can be destroyed. 2954 if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING 2955 || r.state == PAUSED || r.state == STOPPING) { 2956 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); 2957 continue; 2958 } 2959 if (r.task != null) { 2960 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + r.task 2961 + " from " + r); 2962 if (firstTask == null) { 2963 firstTask = r.task; 2964 } else if (firstTask != r.task) { 2965 if (tasks == null) { 2966 tasks = new ArraySet<>(); 2967 tasks.add(firstTask); 2968 } 2969 tasks.add(r.task); 2970 } 2971 } 2972 } 2973 if (tasks == null) { 2974 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); 2975 return; 2976 } 2977 // If we have activities in multiple tasks that are in a position to be destroyed, 2978 // let's iterate through the tasks and release the oldest one. 2979 final int numDisplays = mActivityDisplays.size(); 2980 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2981 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 2982 // Step through all stacks starting from behind, to hit the oldest things first. 2983 for (int stackNdx = 0; stackNdx < stacks.size(); stackNdx++) { 2984 final ActivityStack stack = stacks.get(stackNdx); 2985 // Try to release activities in this stack; if we manage to, we are done. 2986 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 2987 return; 2988 } 2989 } 2990 } 2991 } 2992 2993 boolean switchUserLocked(int userId, UserState uss) { 2994 final int focusStackId = mFocusedStack.getStackId(); 2995 // We dismiss the docked stack whenever we switch users. 2996 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, focusStackId == DOCKED_STACK_ID); 2997 2998 mUserStackInFront.put(mCurrentUser, focusStackId); 2999 final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); 3000 mCurrentUser = userId; 3001 3002 mStartingUsers.add(uss); 3003 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3004 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3005 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3006 final ActivityStack stack = stacks.get(stackNdx); 3007 stack.switchUserLocked(userId); 3008 TaskRecord task = stack.topTask(); 3009 if (task != null) { 3010 mWindowManager.moveTaskToTop(task.taskId); 3011 } 3012 } 3013 } 3014 3015 ActivityStack stack = getStack(restoreStackId); 3016 if (stack == null) { 3017 stack = mHomeStack; 3018 } 3019 final boolean homeInFront = stack.isHomeStack(); 3020 if (stack.isOnHomeDisplay()) { 3021 stack.moveToFront("switchUserOnHomeDisplay"); 3022 } else { 3023 // Stack was moved to another display while user was swapped out. 3024 resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay"); 3025 } 3026 return homeInFront; 3027 } 3028 3029 /** Checks whether the userid is a profile of the current user. */ 3030 boolean isCurrentProfileLocked(int userId) { 3031 if (userId == mCurrentUser) return true; 3032 return mService.mUserController.isCurrentProfileLocked(userId); 3033 } 3034 3035 /** Checks whether the activity should be shown for current user. */ 3036 boolean okToShowLocked(ActivityRecord r) { 3037 return r != null && (isCurrentProfileLocked(r.userId) 3038 || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0); 3039 } 3040 3041 final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { 3042 ArrayList<ActivityRecord> stops = null; 3043 3044 final boolean nowVisible = allResumedActivitiesVisible(); 3045 for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { 3046 ActivityRecord s = mStoppingActivities.get(activityNdx); 3047 final boolean waitingVisible = mWaitingVisibleActivities.contains(s); 3048 if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible 3049 + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); 3050 if (waitingVisible && nowVisible) { 3051 mWaitingVisibleActivities.remove(s); 3052 if (s.finishing) { 3053 // If this activity is finishing, it is sitting on top of 3054 // everyone else but we now know it is no longer needed... 3055 // so get rid of it. Otherwise, we need to go through the 3056 // normal flow and hide it once we determine that it is 3057 // hidden by the activities in front of it. 3058 if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); 3059 mWindowManager.setAppVisibility(s.appToken, false); 3060 } 3061 } 3062 if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { 3063 if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); 3064 if (stops == null) { 3065 stops = new ArrayList<>(); 3066 } 3067 stops.add(s); 3068 mStoppingActivities.remove(activityNdx); 3069 } 3070 } 3071 3072 return stops; 3073 } 3074 3075 void validateTopActivitiesLocked() { 3076 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3077 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3078 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3079 final ActivityStack stack = stacks.get(stackNdx); 3080 final ActivityRecord r = stack.topRunningActivityLocked(); 3081 final ActivityState state = r == null ? DESTROYED : r.state; 3082 if (isFocusedStack(stack)) { 3083 if (r == null) Slog.e(TAG, 3084 "validateTop...: null top activity, stack=" + stack); 3085 else { 3086 final ActivityRecord pausing = stack.mPausingActivity; 3087 if (pausing != null && pausing == r) Slog.e(TAG, 3088 "validateTop...: top stack has pausing activity r=" + r 3089 + " state=" + state); 3090 if (state != INITIALIZING && state != RESUMED) Slog.e(TAG, 3091 "validateTop...: activity in front not resumed r=" + r 3092 + " state=" + state); 3093 } 3094 } else { 3095 final ActivityRecord resumed = stack.mResumedActivity; 3096 if (resumed != null && resumed == r) Slog.e(TAG, 3097 "validateTop...: back stack has resumed activity r=" + r 3098 + " state=" + state); 3099 if (r != null && (state == INITIALIZING || state == RESUMED)) Slog.e(TAG, 3100 "validateTop...: activity in back resumed r=" + r + " state=" + state); 3101 } 3102 } 3103 } 3104 } 3105 3106 private String lockTaskModeToString() { 3107 switch (mLockTaskModeState) { 3108 case LOCK_TASK_MODE_LOCKED: 3109 return "LOCKED"; 3110 case LOCK_TASK_MODE_PINNED: 3111 return "PINNED"; 3112 case LOCK_TASK_MODE_NONE: 3113 return "NONE"; 3114 default: return "unknown=" + mLockTaskModeState; 3115 } 3116 } 3117 3118 public void dump(PrintWriter pw, String prefix) { 3119 pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); 3120 pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); 3121 pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); 3122 pw.print(prefix); 3123 pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser); 3124 pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); 3125 pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers); 3126 pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString()); 3127 final SparseArray<String[]> packages = mService.mLockTaskPackages; 3128 if (packages.size() > 0) { 3129 pw.println(" mLockTaskPackages (userId:packages)="); 3130 for (int i = 0; i < packages.size(); ++i) { 3131 pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i)); 3132 pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i))); 3133 } 3134 } 3135 pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks); 3136 } 3137 3138 ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { 3139 return mFocusedStack.getDumpActivitiesLocked(name); 3140 } 3141 3142 static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, 3143 boolean needSep, String prefix) { 3144 if (activity != null) { 3145 if (dumpPackage == null || dumpPackage.equals(activity.packageName)) { 3146 if (needSep) { 3147 pw.println(); 3148 } 3149 pw.print(prefix); 3150 pw.println(activity); 3151 return true; 3152 } 3153 } 3154 return false; 3155 } 3156 3157 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, 3158 boolean dumpClient, String dumpPackage) { 3159 boolean printed = false; 3160 boolean needSep = false; 3161 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3162 ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); 3163 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 3164 pw.println(" (activities from top to bottom):"); 3165 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3166 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3167 final ActivityStack stack = stacks.get(stackNdx); 3168 StringBuilder stackHeader = new StringBuilder(128); 3169 stackHeader.append(" Stack #"); 3170 stackHeader.append(stack.mStackId); 3171 stackHeader.append(":"); 3172 stackHeader.append("\n"); 3173 stackHeader.append(" mFullscreen=" + stack.mFullscreen); 3174 stackHeader.append("\n"); 3175 stackHeader.append(" mBounds=" + stack.mBounds); 3176 printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, 3177 needSep, stackHeader.toString()); 3178 printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, 3179 !dumpAll, false, dumpPackage, true, 3180 " Running activities (most recent first):", null); 3181 3182 needSep = printed; 3183 boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, 3184 " mPausingActivity: "); 3185 if (pr) { 3186 printed = true; 3187 needSep = false; 3188 } 3189 pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, 3190 " mResumedActivity: "); 3191 if (pr) { 3192 printed = true; 3193 needSep = false; 3194 } 3195 if (dumpAll) { 3196 pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, 3197 " mLastPausedActivity: "); 3198 if (pr) { 3199 printed = true; 3200 needSep = true; 3201 } 3202 printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, 3203 needSep, " mLastNoHistoryActivity: "); 3204 } 3205 needSep = printed; 3206 } 3207 } 3208 3209 printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, 3210 false, dumpPackage, true, " Activities waiting to finish:", null); 3211 printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, 3212 false, dumpPackage, true, " Activities waiting to stop:", null); 3213 printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll, 3214 false, dumpPackage, true, " Activities waiting for another to become visible:", 3215 null); 3216 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3217 false, dumpPackage, true, " Activities waiting to sleep:", null); 3218 printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, 3219 false, dumpPackage, true, " Activities waiting to sleep:", null); 3220 3221 return printed; 3222 } 3223 3224 static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list, 3225 String prefix, String label, boolean complete, boolean brief, boolean client, 3226 String dumpPackage, boolean needNL, String header1, String header2) { 3227 TaskRecord lastTask = null; 3228 String innerPrefix = null; 3229 String[] args = null; 3230 boolean printed = false; 3231 for (int i=list.size()-1; i>=0; i--) { 3232 final ActivityRecord r = list.get(i); 3233 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 3234 continue; 3235 } 3236 if (innerPrefix == null) { 3237 innerPrefix = prefix + " "; 3238 args = new String[0]; 3239 } 3240 printed = true; 3241 final boolean full = !brief && (complete || !r.isInHistory()); 3242 if (needNL) { 3243 pw.println(""); 3244 needNL = false; 3245 } 3246 if (header1 != null) { 3247 pw.println(header1); 3248 header1 = null; 3249 } 3250 if (header2 != null) { 3251 pw.println(header2); 3252 header2 = null; 3253 } 3254 if (lastTask != r.task) { 3255 lastTask = r.task; 3256 pw.print(prefix); 3257 pw.print(full ? "* " : " "); 3258 pw.println(lastTask); 3259 if (full) { 3260 lastTask.dump(pw, prefix + " "); 3261 } else if (complete) { 3262 // Complete + brief == give a summary. Isn't that obvious?!? 3263 if (lastTask.intent != null) { 3264 pw.print(prefix); pw.print(" "); 3265 pw.println(lastTask.intent.toInsecureStringWithClip()); 3266 } 3267 } 3268 } 3269 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 3270 pw.print(" #"); pw.print(i); pw.print(": "); 3271 pw.println(r); 3272 if (full) { 3273 r.dump(pw, innerPrefix); 3274 } else if (complete) { 3275 // Complete + brief == give a summary. Isn't that obvious?!? 3276 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 3277 if (r.app != null) { 3278 pw.print(innerPrefix); pw.println(r.app); 3279 } 3280 } 3281 if (client && r.app != null && r.app.thread != null) { 3282 // flush anything that is already in the PrintWriter since the thread is going 3283 // to write to the file descriptor directly 3284 pw.flush(); 3285 try { 3286 TransferPipe tp = new TransferPipe(); 3287 try { 3288 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 3289 r.appToken, innerPrefix, args); 3290 // Short timeout, since blocking here can 3291 // deadlock with the application. 3292 tp.go(fd, 2000); 3293 } finally { 3294 tp.kill(); 3295 } 3296 } catch (IOException e) { 3297 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 3298 } catch (RemoteException e) { 3299 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 3300 } 3301 needNL = true; 3302 } 3303 } 3304 return printed; 3305 } 3306 3307 void scheduleIdleTimeoutLocked(ActivityRecord next) { 3308 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3309 "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4)); 3310 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next); 3311 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 3312 } 3313 3314 final void scheduleIdleLocked() { 3315 mHandler.sendEmptyMessage(IDLE_NOW_MSG); 3316 } 3317 3318 void removeTimeoutsForActivityLocked(ActivityRecord r) { 3319 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "removeTimeoutsForActivity: Callers=" 3320 + Debug.getCallers(4)); 3321 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3322 } 3323 3324 final void scheduleResumeTopActivities() { 3325 if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { 3326 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 3327 } 3328 } 3329 3330 void removeSleepTimeouts() { 3331 mSleepTimeout = false; 3332 mHandler.removeMessages(SLEEP_TIMEOUT_MSG); 3333 } 3334 3335 final void scheduleSleepTimeout() { 3336 removeSleepTimeouts(); 3337 mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); 3338 } 3339 3340 @Override 3341 public void onDisplayAdded(int displayId) { 3342 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 3343 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); 3344 } 3345 3346 @Override 3347 public void onDisplayRemoved(int displayId) { 3348 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 3349 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); 3350 } 3351 3352 @Override 3353 public void onDisplayChanged(int displayId) { 3354 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 3355 mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); 3356 } 3357 3358 private void handleDisplayAdded(int displayId) { 3359 boolean newDisplay; 3360 synchronized (mService) { 3361 newDisplay = mActivityDisplays.get(displayId) == null; 3362 if (newDisplay) { 3363 ActivityDisplay activityDisplay = new ActivityDisplay(displayId); 3364 if (activityDisplay.mDisplay == null) { 3365 Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); 3366 return; 3367 } 3368 mActivityDisplays.put(displayId, activityDisplay); 3369 calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); 3370 } 3371 } 3372 if (newDisplay) { 3373 mWindowManager.onDisplayAdded(displayId); 3374 } 3375 } 3376 3377 private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) { 3378 mDefaultMinimalSizeOfResizeableTask = 3379 mService.mContext.getResources().getDimensionPixelSize( 3380 com.android.internal.R.dimen.default_minimal_size_resizable_task); 3381 } 3382 3383 private void handleDisplayRemoved(int displayId) { 3384 synchronized (mService) { 3385 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3386 if (activityDisplay != null) { 3387 ArrayList<ActivityStack> stacks = activityDisplay.mStacks; 3388 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3389 stacks.get(stackNdx).mActivityContainer.detachLocked(); 3390 } 3391 mActivityDisplays.remove(displayId); 3392 } 3393 } 3394 mWindowManager.onDisplayRemoved(displayId); 3395 } 3396 3397 private void handleDisplayChanged(int displayId) { 3398 synchronized (mService) { 3399 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3400 if (activityDisplay != null) { 3401 // TODO: Update the bounds. 3402 } 3403 } 3404 mWindowManager.onDisplayChanged(displayId); 3405 } 3406 3407 private StackInfo getStackInfoLocked(ActivityStack stack) { 3408 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 3409 StackInfo info = new StackInfo(); 3410 mWindowManager.getStackBounds(stack.mStackId, info.bounds); 3411 info.displayId = Display.DEFAULT_DISPLAY; 3412 info.stackId = stack.mStackId; 3413 info.userId = stack.mCurrentUser; 3414 info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE; 3415 info.position = display != null 3416 ? display.mStacks.indexOf(stack) 3417 : 0; 3418 3419 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 3420 final int numTasks = tasks.size(); 3421 int[] taskIds = new int[numTasks]; 3422 String[] taskNames = new String[numTasks]; 3423 Rect[] taskBounds = new Rect[numTasks]; 3424 int[] taskUserIds = new int[numTasks]; 3425 for (int i = 0; i < numTasks; ++i) { 3426 final TaskRecord task = tasks.get(i); 3427 taskIds[i] = task.taskId; 3428 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 3429 : task.realActivity != null ? task.realActivity.flattenToString() 3430 : task.getTopActivity() != null ? task.getTopActivity().packageName 3431 : "unknown"; 3432 taskBounds[i] = new Rect(); 3433 mWindowManager.getTaskBounds(task.taskId, taskBounds[i]); 3434 taskUserIds[i] = task.userId; 3435 } 3436 info.taskIds = taskIds; 3437 info.taskNames = taskNames; 3438 info.taskBounds = taskBounds; 3439 info.taskUserIds = taskUserIds; 3440 3441 final ActivityRecord top = stack.topRunningActivityLocked(); 3442 info.topActivity = top != null ? top.intent.getComponent() : null; 3443 return info; 3444 } 3445 3446 StackInfo getStackInfoLocked(int stackId) { 3447 ActivityStack stack = getStack(stackId); 3448 if (stack != null) { 3449 return getStackInfoLocked(stack); 3450 } 3451 return null; 3452 } 3453 3454 ArrayList<StackInfo> getAllStackInfosLocked() { 3455 ArrayList<StackInfo> list = new ArrayList<>(); 3456 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 3457 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3458 for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { 3459 list.add(getStackInfoLocked(stacks.get(ndx))); 3460 } 3461 } 3462 return list; 3463 } 3464 3465 TaskRecord getLockedTaskLocked() { 3466 final int top = mLockTaskModeTasks.size() - 1; 3467 if (top >= 0) { 3468 return mLockTaskModeTasks.get(top); 3469 } 3470 return null; 3471 } 3472 3473 boolean isLockedTask(TaskRecord task) { 3474 return mLockTaskModeTasks.contains(task); 3475 } 3476 3477 boolean isLastLockedTask(TaskRecord task) { 3478 return mLockTaskModeTasks.size() == 1 && mLockTaskModeTasks.contains(task); 3479 } 3480 3481 void removeLockedTaskLocked(final TaskRecord task) { 3482 if (!mLockTaskModeTasks.remove(task)) { 3483 return; 3484 } 3485 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTaskLocked: removed " + task); 3486 if (mLockTaskModeTasks.isEmpty()) { 3487 // Last one. 3488 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task + 3489 " last task, reverting locktask mode. Callers=" + Debug.getCallers(3)); 3490 final Message lockTaskMsg = Message.obtain(); 3491 lockTaskMsg.arg1 = task.userId; 3492 lockTaskMsg.what = LOCK_TASK_END_MSG; 3493 mHandler.sendMessage(lockTaskMsg); 3494 } 3495 } 3496 3497 void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) { 3498 handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId, 3499 false /* forceNonResizable */); 3500 } 3501 3502 void handleNonResizableTaskIfNeeded( 3503 TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) { 3504 if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID) 3505 || task.isHomeTask()) { 3506 return; 3507 } 3508 3509 final ActivityRecord topActivity = task.getTopActivity(); 3510 if (!task.canGoInDockedStack() || forceNonResizable) { 3511 // Display a warning toast that we tried to put a non-dockable task in the docked stack. 3512 mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG); 3513 3514 // Dismiss docked stack. If task appeared to be in docked stack but is not resizable - 3515 // we need to move it to top of fullscreen stack, otherwise it will be covered. 3516 moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID); 3517 } else if (topActivity != null && topActivity.isNonResizableOrForced() 3518 && !topActivity.noDisplay) { 3519 String packageName = topActivity.appInfo.packageName; 3520 mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0, 3521 packageName).sendToTarget(); 3522 } 3523 } 3524 3525 void showLockTaskToast() { 3526 mLockTaskNotify.showToast(mLockTaskModeState); 3527 } 3528 3529 void showLockTaskEscapeMessageLocked(TaskRecord task) { 3530 if (mLockTaskModeTasks.contains(task)) { 3531 mHandler.sendEmptyMessage(SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG); 3532 } 3533 } 3534 3535 void setLockTaskModeLocked(TaskRecord task, int lockTaskModeState, String reason, 3536 boolean andResume) { 3537 if (task == null) { 3538 // Take out of lock task mode if necessary 3539 final TaskRecord lockedTask = getLockedTaskLocked(); 3540 if (lockedTask != null) { 3541 removeLockedTaskLocked(lockedTask); 3542 if (!mLockTaskModeTasks.isEmpty()) { 3543 // There are locked tasks remaining, can only finish this task, not unlock it. 3544 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3545 "setLockTaskModeLocked: Tasks remaining, can't unlock"); 3546 lockedTask.performClearTaskLocked(); 3547 resumeFocusedStackTopActivityLocked(); 3548 return; 3549 } 3550 } 3551 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3552 "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4)); 3553 return; 3554 } 3555 3556 // Should have already been checked, but do it again. 3557 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 3558 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, 3559 "setLockTaskModeLocked: Can't lock due to auth"); 3560 return; 3561 } 3562 if (isLockTaskModeViolation(task)) { 3563 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 3564 return; 3565 } 3566 3567 if (mLockTaskModeTasks.isEmpty()) { 3568 // First locktask. 3569 final Message lockTaskMsg = Message.obtain(); 3570 lockTaskMsg.obj = task.intent.getComponent().getPackageName(); 3571 lockTaskMsg.arg1 = task.userId; 3572 lockTaskMsg.what = LOCK_TASK_START_MSG; 3573 lockTaskMsg.arg2 = lockTaskModeState; 3574 mHandler.sendMessage(lockTaskMsg); 3575 } 3576 // Add it or move it to the top. 3577 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task + 3578 " Callers=" + Debug.getCallers(4)); 3579 mLockTaskModeTasks.remove(task); 3580 mLockTaskModeTasks.add(task); 3581 3582 if (task.mLockTaskUid == -1) { 3583 task.mLockTaskUid = task.effectiveUid; 3584 } 3585 3586 if (andResume) { 3587 findTaskToMoveToFrontLocked(task, 0, null, reason, 3588 lockTaskModeState != LOCK_TASK_MODE_NONE); 3589 resumeFocusedStackTopActivityLocked(); 3590 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { 3591 handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId, 3592 true /* forceNonResizable */); 3593 } 3594 } 3595 3596 boolean isLockTaskModeViolation(TaskRecord task) { 3597 return isLockTaskModeViolation(task, false); 3598 } 3599 3600 boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) { 3601 if (getLockedTaskLocked() == task && !isNewClearTask) { 3602 return false; 3603 } 3604 final int lockTaskAuth = task.mLockTaskAuth; 3605 switch (lockTaskAuth) { 3606 case LOCK_TASK_AUTH_DONT_LOCK: 3607 return !mLockTaskModeTasks.isEmpty(); 3608 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 3609 case LOCK_TASK_AUTH_LAUNCHABLE: 3610 case LOCK_TASK_AUTH_WHITELISTED: 3611 return false; 3612 case LOCK_TASK_AUTH_PINNABLE: 3613 // Pinnable tasks can't be launched on top of locktask tasks. 3614 return !mLockTaskModeTasks.isEmpty(); 3615 default: 3616 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth); 3617 return true; 3618 } 3619 } 3620 3621 void onLockTaskPackagesUpdatedLocked() { 3622 boolean didSomething = false; 3623 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 3624 final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); 3625 final boolean wasWhitelisted = 3626 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3627 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3628 lockedTask.setLockTaskAuth(); 3629 final boolean isWhitelisted = 3630 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || 3631 (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); 3632 if (wasWhitelisted && !isWhitelisted) { 3633 // Lost whitelisting authorization. End it now. 3634 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + 3635 lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); 3636 removeLockedTaskLocked(lockedTask); 3637 lockedTask.performClearTaskLocked(); 3638 didSomething = true; 3639 } 3640 } 3641 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 3642 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; 3643 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 3644 final ActivityStack stack = stacks.get(stackNdx); 3645 stack.onLockTaskPackagesUpdatedLocked(); 3646 } 3647 } 3648 final ActivityRecord r = topRunningActivityLocked(); 3649 final TaskRecord task = r != null ? r.task : null; 3650 if (mLockTaskModeTasks.isEmpty() && task != null 3651 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 3652 // This task must have just been authorized. 3653 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, 3654 "onLockTaskPackagesUpdated: starting new locktask task=" + task); 3655 setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated", 3656 false); 3657 didSomething = true; 3658 } 3659 if (didSomething) { 3660 resumeFocusedStackTopActivityLocked(); 3661 } 3662 } 3663 3664 int getLockTaskModeState() { 3665 return mLockTaskModeState; 3666 } 3667 3668 void activityRelaunchedLocked(IBinder token) { 3669 mWindowManager.notifyAppRelaunchingFinished(token); 3670 } 3671 3672 void activityRelaunchingLocked(ActivityRecord r) { 3673 mWindowManager.notifyAppRelaunching(r.appToken); 3674 } 3675 3676 void logStackState() { 3677 mActivityMetricsLogger.logWindowState(); 3678 } 3679 3680 void scheduleReportMultiWindowModeChanged(TaskRecord task) { 3681 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3682 final ActivityRecord r = task.mActivities.get(i); 3683 if (r.app != null && r.app.thread != null) { 3684 mMultiWindowModeChangedActivities.add(r); 3685 } 3686 } 3687 3688 if (!mHandler.hasMessages(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG)) { 3689 mHandler.sendEmptyMessage(REPORT_MULTI_WINDOW_MODE_CHANGED_MSG); 3690 } 3691 } 3692 3693 void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) { 3694 final ActivityStack stack = task.stack; 3695 if (prevStack == null || prevStack == stack 3696 || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) { 3697 return; 3698 } 3699 3700 for (int i = task.mActivities.size() - 1; i >= 0; i--) { 3701 final ActivityRecord r = task.mActivities.get(i); 3702 if (r.app != null && r.app.thread != null) { 3703 mPipModeChangedActivities.add(r); 3704 } 3705 } 3706 3707 if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { 3708 mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); 3709 } 3710 } 3711 3712 void setDockedStackMinimized(boolean minimized) { 3713 mIsDockMinimized = minimized; 3714 if (minimized) { 3715 // Docked stack is not visible, no need to confirm credentials for its top activity. 3716 return; 3717 } 3718 final ActivityStack dockedStack = getStack(StackId.DOCKED_STACK_ID); 3719 if (dockedStack == null) { 3720 return; 3721 } 3722 final ActivityRecord top = dockedStack.topRunningActivityLocked(); 3723 if (top != null && mService.mUserController.shouldConfirmCredentials(top.userId)) { 3724 mService.mActivityStarter.showConfirmDeviceCredential(top.userId); 3725 } 3726 } 3727 3728 private final class ActivityStackSupervisorHandler extends Handler { 3729 3730 public ActivityStackSupervisorHandler(Looper looper) { 3731 super(looper); 3732 } 3733 3734 void activityIdleInternal(ActivityRecord r) { 3735 synchronized (mService) { 3736 activityIdleInternalLocked(r != null ? r.appToken : null, true, null); 3737 } 3738 } 3739 3740 @Override 3741 public void handleMessage(Message msg) { 3742 switch (msg.what) { 3743 case REPORT_MULTI_WINDOW_MODE_CHANGED_MSG: { 3744 synchronized (mService) { 3745 for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) { 3746 final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i); 3747 r.scheduleMultiWindowModeChanged(); 3748 } 3749 } 3750 } break; 3751 case REPORT_PIP_MODE_CHANGED_MSG: { 3752 synchronized (mService) { 3753 for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) { 3754 final ActivityRecord r = mPipModeChangedActivities.remove(i); 3755 r.schedulePictureInPictureModeChanged(); 3756 } 3757 } 3758 } break; 3759 case IDLE_TIMEOUT_MSG: { 3760 if (DEBUG_IDLE) Slog.d(TAG_IDLE, 3761 "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); 3762 if (mService.mDidDexOpt) { 3763 mService.mDidDexOpt = false; 3764 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 3765 nmsg.obj = msg.obj; 3766 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 3767 return; 3768 } 3769 // We don't at this point know if the activity is fullscreen, 3770 // so we need to be conservative and assume it isn't. 3771 activityIdleInternal((ActivityRecord)msg.obj); 3772 } break; 3773 case IDLE_NOW_MSG: { 3774 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); 3775 activityIdleInternal((ActivityRecord)msg.obj); 3776 } break; 3777 case RESUME_TOP_ACTIVITY_MSG: { 3778 synchronized (mService) { 3779 resumeFocusedStackTopActivityLocked(); 3780 } 3781 } break; 3782 case SLEEP_TIMEOUT_MSG: { 3783 synchronized (mService) { 3784 if (mService.isSleepingOrShuttingDown()) { 3785 Slog.w(TAG, "Sleep timeout! Sleeping now."); 3786 mSleepTimeout = true; 3787 checkReadyForSleepLocked(); 3788 } 3789 } 3790 } break; 3791 case LAUNCH_TIMEOUT_MSG: { 3792 if (mService.mDidDexOpt) { 3793 mService.mDidDexOpt = false; 3794 mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT); 3795 return; 3796 } 3797 synchronized (mService) { 3798 if (mLaunchingActivity.isHeld()) { 3799 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 3800 if (VALIDATE_WAKE_LOCK_CALLER 3801 && Binder.getCallingUid() != Process.myUid()) { 3802 throw new IllegalStateException("Calling must be system uid"); 3803 } 3804 mLaunchingActivity.release(); 3805 } 3806 } 3807 } break; 3808 case HANDLE_DISPLAY_ADDED: { 3809 handleDisplayAdded(msg.arg1); 3810 } break; 3811 case HANDLE_DISPLAY_CHANGED: { 3812 handleDisplayChanged(msg.arg1); 3813 } break; 3814 case HANDLE_DISPLAY_REMOVED: { 3815 handleDisplayRemoved(msg.arg1); 3816 } break; 3817 case CONTAINER_CALLBACK_VISIBILITY: { 3818 final ActivityContainer container = (ActivityContainer) msg.obj; 3819 final IActivityContainerCallback callback = container.mCallback; 3820 if (callback != null) { 3821 try { 3822 callback.setVisible(container.asBinder(), msg.arg1 == 1); 3823 } catch (RemoteException e) { 3824 } 3825 } 3826 } break; 3827 case LOCK_TASK_START_MSG: { 3828 // When lock task starts, we disable the status bars. 3829 try { 3830 if (mLockTaskNotify == null) { 3831 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3832 } 3833 mLockTaskNotify.show(true); 3834 mLockTaskModeState = msg.arg2; 3835 if (getStatusBarService() != null) { 3836 int flags = 0; 3837 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 3838 flags = StatusBarManager.DISABLE_MASK 3839 & (~StatusBarManager.DISABLE_BACK); 3840 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 3841 flags = StatusBarManager.DISABLE_MASK 3842 & (~StatusBarManager.DISABLE_BACK) 3843 & (~StatusBarManager.DISABLE_HOME) 3844 & (~StatusBarManager.DISABLE_RECENT); 3845 } 3846 getStatusBarService().disable(flags, mToken, 3847 mService.mContext.getPackageName()); 3848 } 3849 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG); 3850 if (getDevicePolicyManager() != null) { 3851 getDevicePolicyManager().notifyLockTaskModeChanged(true, 3852 (String)msg.obj, msg.arg1); 3853 } 3854 } catch (RemoteException ex) { 3855 throw new RuntimeException(ex); 3856 } 3857 } break; 3858 case LOCK_TASK_END_MSG: { 3859 // When lock task ends, we enable the status bars. 3860 try { 3861 if (getStatusBarService() != null) { 3862 getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken, 3863 mService.mContext.getPackageName()); 3864 } 3865 mWindowManager.reenableKeyguard(mToken); 3866 if (getDevicePolicyManager() != null) { 3867 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, 3868 msg.arg1); 3869 } 3870 if (mLockTaskNotify == null) { 3871 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3872 } 3873 mLockTaskNotify.show(false); 3874 try { 3875 boolean shouldLockKeyguard = Settings.Secure.getInt( 3876 mService.mContext.getContentResolver(), 3877 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED) != 0; 3878 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) { 3879 mWindowManager.lockNow(null); 3880 mWindowManager.dismissKeyguard(); 3881 new LockPatternUtils(mService.mContext) 3882 .requireCredentialEntry(UserHandle.USER_ALL); 3883 } 3884 } catch (SettingNotFoundException e) { 3885 // No setting, don't lock. 3886 } 3887 } catch (RemoteException ex) { 3888 throw new RuntimeException(ex); 3889 } finally { 3890 mLockTaskModeState = LOCK_TASK_MODE_NONE; 3891 } 3892 } break; 3893 case SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG: { 3894 if (mLockTaskNotify == null) { 3895 mLockTaskNotify = new LockTaskNotify(mService.mContext); 3896 } 3897 mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED); 3898 } break; 3899 case CONTAINER_CALLBACK_TASK_LIST_EMPTY: { 3900 final ActivityContainer container = (ActivityContainer) msg.obj; 3901 final IActivityContainerCallback callback = container.mCallback; 3902 if (callback != null) { 3903 try { 3904 callback.onAllActivitiesComplete(container.asBinder()); 3905 } catch (RemoteException e) { 3906 } 3907 } 3908 } break; 3909 case LAUNCH_TASK_BEHIND_COMPLETE: { 3910 synchronized (mService) { 3911 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 3912 if (r != null) { 3913 handleLaunchTaskBehindCompleteLocked(r); 3914 } 3915 } 3916 } break; 3917 3918 } 3919 } 3920 } 3921 3922 class ActivityContainer extends android.app.IActivityContainer.Stub { 3923 final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK | 3924 FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION; 3925 final int mStackId; 3926 IActivityContainerCallback mCallback = null; 3927 final ActivityStack mStack; 3928 ActivityRecord mParentActivity = null; 3929 String mIdString; 3930 3931 boolean mVisible = true; 3932 3933 /** Display this ActivityStack is currently on. Null if not attached to a Display. */ 3934 ActivityDisplay mActivityDisplay; 3935 3936 final static int CONTAINER_STATE_HAS_SURFACE = 0; 3937 final static int CONTAINER_STATE_NO_SURFACE = 1; 3938 final static int CONTAINER_STATE_FINISHING = 2; 3939 int mContainerState = CONTAINER_STATE_HAS_SURFACE; 3940 3941 ActivityContainer(int stackId) { 3942 synchronized (mService) { 3943 mStackId = stackId; 3944 mStack = new ActivityStack(this, mRecentTasks); 3945 mIdString = "ActivtyContainer{" + mStackId + "}"; 3946 if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this); 3947 } 3948 } 3949 3950 void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) { 3951 if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this 3952 + " to display=" + activityDisplay + " onTop=" + onTop); 3953 mActivityDisplay = activityDisplay; 3954 mStack.attachDisplay(activityDisplay, onTop); 3955 activityDisplay.attachActivities(mStack, onTop); 3956 } 3957 3958 @Override 3959 public void attachToDisplay(int displayId) { 3960 synchronized (mService) { 3961 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); 3962 if (activityDisplay == null) { 3963 return; 3964 } 3965 attachToDisplayLocked(activityDisplay, true); 3966 } 3967 } 3968 3969 @Override 3970 public int getDisplayId() { 3971 synchronized (mService) { 3972 if (mActivityDisplay != null) { 3973 return mActivityDisplay.mDisplayId; 3974 } 3975 } 3976 return -1; 3977 } 3978 3979 @Override 3980 public int getStackId() { 3981 synchronized (mService) { 3982 return mStackId; 3983 } 3984 } 3985 3986 @Override 3987 public boolean injectEvent(InputEvent event) { 3988 final long origId = Binder.clearCallingIdentity(); 3989 try { 3990 synchronized (mService) { 3991 if (mActivityDisplay != null) { 3992 return mInputManagerInternal.injectInputEvent(event, 3993 mActivityDisplay.mDisplayId, 3994 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 3995 } 3996 } 3997 return false; 3998 } finally { 3999 Binder.restoreCallingIdentity(origId); 4000 } 4001 } 4002 4003 @Override 4004 public void release() { 4005 synchronized (mService) { 4006 if (mContainerState == CONTAINER_STATE_FINISHING) { 4007 return; 4008 } 4009 mContainerState = CONTAINER_STATE_FINISHING; 4010 4011 long origId = Binder.clearCallingIdentity(); 4012 try { 4013 mStack.finishAllActivitiesLocked(false); 4014 mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack); 4015 } finally { 4016 Binder.restoreCallingIdentity(origId); 4017 } 4018 } 4019 } 4020 4021 protected void detachLocked() { 4022 if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display=" 4023 + mActivityDisplay + " Callers=" + Debug.getCallers(2)); 4024 if (mActivityDisplay != null) { 4025 mActivityDisplay.detachActivitiesLocked(mStack); 4026 mActivityDisplay = null; 4027 mStack.detachDisplay(); 4028 } 4029 } 4030 4031 @Override 4032 public final int startActivity(Intent intent) { 4033 return mService.startActivity(intent, this); 4034 } 4035 4036 @Override 4037 public final int startActivityIntentSender(IIntentSender intentSender) 4038 throws TransactionTooLargeException { 4039 mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); 4040 4041 if (!(intentSender instanceof PendingIntentRecord)) { 4042 throw new IllegalArgumentException("Bad PendingIntent object"); 4043 } 4044 4045 final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(), 4046 Binder.getCallingUid(), mCurrentUser, false, 4047 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 4048 4049 final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; 4050 checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent, 4051 pendingIntent.key.requestResolvedType); 4052 4053 return pendingIntent.sendInner(0, null, null, null, null, null, null, 0, 4054 FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); 4055 } 4056 4057 void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) { 4058 ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId); 4059 if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { 4060 throw new SecurityException( 4061 "Attempt to embed activity that has not set allowEmbedded=\"true\""); 4062 } 4063 } 4064 4065 @Override 4066 public IBinder asBinder() { 4067 return this; 4068 } 4069 4070 @Override 4071 public void setSurface(Surface surface, int width, int height, int density) { 4072 mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); 4073 } 4074 4075 ActivityStackSupervisor getOuter() { 4076 return ActivityStackSupervisor.this; 4077 } 4078 4079 boolean isAttachedLocked() { 4080 return mActivityDisplay != null; 4081 } 4082 4083 // TODO: Make sure every change to ActivityRecord.visible results in a call to this. 4084 void setVisible(boolean visible) { 4085 if (mVisible != visible) { 4086 mVisible = visible; 4087 if (mCallback != null) { 4088 mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0, 4089 0 /* unused */, this).sendToTarget(); 4090 } 4091 } 4092 } 4093 4094 void setDrawn() { 4095 } 4096 4097 // You can always start a new task on a regular ActivityStack. 4098 boolean isEligibleForNewTasks() { 4099 return true; 4100 } 4101 4102 void onTaskListEmptyLocked() { 4103 detachLocked(); 4104 deleteActivityContainer(this); 4105 mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget(); 4106 } 4107 4108 @Override 4109 public String toString() { 4110 return mIdString + (mActivityDisplay == null ? "N" : "A"); 4111 } 4112 } 4113 4114 private class VirtualActivityContainer extends ActivityContainer { 4115 Surface mSurface; 4116 boolean mDrawn = false; 4117 4118 VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) { 4119 super(getNextStackId()); 4120 mParentActivity = parent; 4121 mCallback = callback; 4122 mContainerState = CONTAINER_STATE_NO_SURFACE; 4123 mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}"; 4124 } 4125 4126 @Override 4127 public void setSurface(Surface surface, int width, int height, int density) { 4128 super.setSurface(surface, width, height, density); 4129 4130 synchronized (mService) { 4131 final long origId = Binder.clearCallingIdentity(); 4132 try { 4133 setSurfaceLocked(surface, width, height, density); 4134 } finally { 4135 Binder.restoreCallingIdentity(origId); 4136 } 4137 } 4138 } 4139 4140 private void setSurfaceLocked(Surface surface, int width, int height, int density) { 4141 if (mContainerState == CONTAINER_STATE_FINISHING) { 4142 return; 4143 } 4144 VirtualActivityDisplay virtualActivityDisplay = 4145 (VirtualActivityDisplay) mActivityDisplay; 4146 if (virtualActivityDisplay == null) { 4147 virtualActivityDisplay = 4148 new VirtualActivityDisplay(width, height, density); 4149 mActivityDisplay = virtualActivityDisplay; 4150 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay); 4151 attachToDisplayLocked(virtualActivityDisplay, true); 4152 } 4153 4154 if (mSurface != null) { 4155 mSurface.release(); 4156 } 4157 4158 mSurface = surface; 4159 if (surface != null) { 4160 resumeFocusedStackTopActivityLocked(); 4161 } else { 4162 mContainerState = CONTAINER_STATE_NO_SURFACE; 4163 ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); 4164 if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { 4165 mStack.startPausingLocked(false, true, false, false); 4166 } 4167 } 4168 4169 setSurfaceIfReadyLocked(); 4170 4171 if (DEBUG_STACK) Slog.d(TAG_STACK, 4172 "setSurface: " + this + " to display=" + virtualActivityDisplay); 4173 } 4174 4175 @Override 4176 boolean isAttachedLocked() { 4177 return mSurface != null && super.isAttachedLocked(); 4178 } 4179 4180 @Override 4181 void setDrawn() { 4182 synchronized (mService) { 4183 mDrawn = true; 4184 setSurfaceIfReadyLocked(); 4185 } 4186 } 4187 4188 // Never start a new task on an ActivityView if it isn't explicitly specified. 4189 @Override 4190 boolean isEligibleForNewTasks() { 4191 return false; 4192 } 4193 4194 private void setSurfaceIfReadyLocked() { 4195 if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn + 4196 " mContainerState=" + mContainerState + " mSurface=" + mSurface); 4197 if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) { 4198 ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface); 4199 mContainerState = CONTAINER_STATE_HAS_SURFACE; 4200 } 4201 } 4202 } 4203 4204 /** Exactly one of these classes per Display in the system. Capable of holding zero or more 4205 * attached {@link ActivityStack}s */ 4206 class ActivityDisplay { 4207 /** Actual Display this object tracks. */ 4208 int mDisplayId; 4209 Display mDisplay; 4210 DisplayInfo mDisplayInfo = new DisplayInfo(); 4211 4212 /** All of the stacks on this display. Order matters, topmost stack is in front of all other 4213 * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ 4214 final ArrayList<ActivityStack> mStacks = new ArrayList<>(); 4215 4216 ActivityRecord mVisibleBehindActivity; 4217 4218 ActivityDisplay() { 4219 } 4220 4221 // After instantiation, check that mDisplay is not null before using this. The alternative 4222 // is for this to throw an exception if mDisplayManager.getDisplay() returns null. 4223 ActivityDisplay(int displayId) { 4224 final Display display = mDisplayManager.getDisplay(displayId); 4225 if (display == null) { 4226 return; 4227 } 4228 init(display); 4229 } 4230 4231 void init(Display display) { 4232 mDisplay = display; 4233 mDisplayId = display.getDisplayId(); 4234 mDisplay.getDisplayInfo(mDisplayInfo); 4235 } 4236 4237 void attachActivities(ActivityStack stack, boolean onTop) { 4238 if (DEBUG_STACK) Slog.v(TAG_STACK, 4239 "attachActivities: attaching " + stack + " to displayId=" + mDisplayId 4240 + " onTop=" + onTop); 4241 if (onTop) { 4242 mStacks.add(stack); 4243 } else { 4244 mStacks.add(0, stack); 4245 } 4246 } 4247 4248 void detachActivitiesLocked(ActivityStack stack) { 4249 if (DEBUG_STACK) Slog.v(TAG_STACK, "detachActivitiesLocked: detaching " + stack 4250 + " from displayId=" + mDisplayId); 4251 mStacks.remove(stack); 4252 } 4253 4254 void setVisibleBehindActivity(ActivityRecord r) { 4255 mVisibleBehindActivity = r; 4256 } 4257 4258 boolean hasVisibleBehindActivity() { 4259 return mVisibleBehindActivity != null; 4260 } 4261 4262 @Override 4263 public String toString() { 4264 return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; 4265 } 4266 } 4267 4268 class VirtualActivityDisplay extends ActivityDisplay { 4269 VirtualDisplay mVirtualDisplay; 4270 4271 VirtualActivityDisplay(int width, int height, int density) { 4272 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 4273 mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null, 4274 VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null, 4275 DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | 4276 DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null, null); 4277 4278 init(mVirtualDisplay.getDisplay()); 4279 4280 mWindowManager.handleDisplayAdded(mDisplayId); 4281 } 4282 4283 void setSurface(Surface surface) { 4284 if (mVirtualDisplay != null) { 4285 mVirtualDisplay.setSurface(surface); 4286 } 4287 } 4288 4289 @Override 4290 void detachActivitiesLocked(ActivityStack stack) { 4291 super.detachActivitiesLocked(stack); 4292 if (mVirtualDisplay != null) { 4293 mVirtualDisplay.release(); 4294 mVirtualDisplay = null; 4295 } 4296 } 4297 4298 @Override 4299 public String toString() { 4300 return "VirtualActivityDisplay={" + mDisplayId + "}"; 4301 } 4302 } 4303 4304 /** 4305 * Adjust bounds to stay within stack bounds. 4306 * 4307 * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way 4308 * that keep them unchanged, but be contained within the stack bounds. 4309 * 4310 * @param bounds Bounds to be adjusted. 4311 * @param stackBounds Bounds within which the other bounds should remain. 4312 */ 4313 private static void fitWithinBounds(Rect bounds, Rect stackBounds) { 4314 if (stackBounds == null || stackBounds.contains(bounds)) { 4315 return; 4316 } 4317 4318 if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) { 4319 final int maxRight = stackBounds.right 4320 - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER); 4321 int horizontalDiff = stackBounds.left - bounds.left; 4322 if ((horizontalDiff < 0 && bounds.left >= maxRight) 4323 || (bounds.left + horizontalDiff >= maxRight)) { 4324 horizontalDiff = maxRight - bounds.left; 4325 } 4326 bounds.left += horizontalDiff; 4327 bounds.right += horizontalDiff; 4328 } 4329 4330 if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) { 4331 final int maxBottom = stackBounds.bottom 4332 - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER); 4333 int verticalDiff = stackBounds.top - bounds.top; 4334 if ((verticalDiff < 0 && bounds.top >= maxBottom) 4335 || (bounds.top + verticalDiff >= maxBottom)) { 4336 verticalDiff = maxBottom - bounds.top; 4337 } 4338 bounds.top += verticalDiff; 4339 bounds.bottom += verticalDiff; 4340 } 4341 } 4342 4343 ActivityStack findStackBehind(ActivityStack stack) { 4344 // TODO(multi-display): We are only looking for stacks on the default display. 4345 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4346 if (display == null) { 4347 return null; 4348 } 4349 final ArrayList<ActivityStack> stacks = display.mStacks; 4350 for (int i = stacks.size() - 1; i >= 0; i--) { 4351 if (stacks.get(i) == stack && i > 0) { 4352 return stacks.get(i - 1); 4353 } 4354 } 4355 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 4356 + " in=" + stacks); 4357 } 4358 4359 /** 4360 * Puts a task into resizing mode during the next app transition. 4361 * 4362 * @param taskId the id of the task to put into resizing mode 4363 */ 4364 private void setResizingDuringAnimation(int taskId) { 4365 mResizingTasksDuringAnimation.add(taskId); 4366 mWindowManager.setTaskDockedResizing(taskId, true); 4367 } 4368 4369 final int startActivityFromRecentsInner(int taskId, Bundle bOptions) { 4370 final TaskRecord task; 4371 final int callingUid; 4372 final String callingPackage; 4373 final Intent intent; 4374 final int userId; 4375 final ActivityOptions activityOptions = (bOptions != null) 4376 ? new ActivityOptions(bOptions) : null; 4377 final int launchStackId = (activityOptions != null) 4378 ? activityOptions.getLaunchStackId() : INVALID_STACK_ID; 4379 if (launchStackId == HOME_STACK_ID) { 4380 throw new IllegalArgumentException("startActivityFromRecentsInner: Task " 4381 + taskId + " can't be launch in the home stack."); 4382 } 4383 4384 if (launchStackId == DOCKED_STACK_ID) { 4385 mWindowManager.setDockedStackCreateState( 4386 activityOptions.getDockCreateMode(), null /* initialBounds */); 4387 4388 // Defer updating the stack in which recents is until the app transition is done, to 4389 // not run into issues where we still need to draw the task in recents but the 4390 // docked stack is already created. 4391 deferUpdateBounds(HOME_STACK_ID); 4392 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false); 4393 } 4394 4395 task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId); 4396 if (task == null) { 4397 continueUpdateBounds(HOME_STACK_ID); 4398 mWindowManager.executeAppTransition(); 4399 throw new IllegalArgumentException( 4400 "startActivityFromRecentsInner: Task " + taskId + " not found."); 4401 } 4402 4403 if (launchStackId != INVALID_STACK_ID) { 4404 if (task.stack.mStackId != launchStackId) { 4405 moveTaskToStackLocked( 4406 taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents", 4407 ANIMATE); 4408 } 4409 } 4410 4411 // If the user must confirm credentials (e.g. when first launching a work app and the 4412 // Work Challenge is present) let startActivityInPackage handle the intercepting. 4413 if (!mService.mUserController.shouldConfirmCredentials(task.userId) 4414 && task.getRootActivity() != null) { 4415 mActivityMetricsLogger.notifyActivityLaunching(); 4416 mService.moveTaskToFrontLocked(task.taskId, 0, bOptions); 4417 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT, 4418 task.getTopActivity()); 4419 4420 // If we are launching the task in the docked stack, put it into resizing mode so 4421 // the window renders full-screen with the background filling the void. Also only 4422 // call this at the end to make sure that tasks exists on the window manager side. 4423 if (launchStackId == DOCKED_STACK_ID) { 4424 setResizingDuringAnimation(taskId); 4425 } 4426 return ActivityManager.START_TASK_TO_FRONT; 4427 } 4428 callingUid = task.mCallingUid; 4429 callingPackage = task.mCallingPackage; 4430 intent = task.intent; 4431 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 4432 userId = task.userId; 4433 int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null, 4434 null, null, 0, 0, bOptions, userId, null, task); 4435 if (launchStackId == DOCKED_STACK_ID) { 4436 setResizingDuringAnimation(task.taskId); 4437 } 4438 return result; 4439 } 4440 4441 /** 4442 * @return a list of activities which are the top ones in each visible stack. The first 4443 * entry will be the focused activity. 4444 */ 4445 public List<IBinder> getTopVisibleActivities() { 4446 final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY); 4447 if (display == null) { 4448 return Collections.EMPTY_LIST; 4449 } 4450 ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 4451 final ArrayList<ActivityStack> stacks = display.mStacks; 4452 for (int i = stacks.size() - 1; i >= 0; i--) { 4453 ActivityStack stack = stacks.get(i); 4454 if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) { 4455 ActivityRecord top = stack.topActivity(); 4456 if (top != null) { 4457 if (stack == mFocusedStack) { 4458 topActivityTokens.add(0, top.appToken); 4459 } else { 4460 topActivityTokens.add(top.appToken); 4461 } 4462 } 4463 } 4464 } 4465 return topActivityTokens; 4466 } 4467} 4468