1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.wm; 18 19 import static android.app.ActivityTaskManager.INVALID_STACK_ID; 20 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; 22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 23 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; 24 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 25 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 26 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 27 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; 28 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 29 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; 30 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; 31 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 32 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 33 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; 34 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; 35 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 36 import static android.view.Display.DEFAULT_DISPLAY; 37 import static android.view.Display.INVALID_DISPLAY; 38 import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY; 39 40 import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER; 41 import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS; 42 import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID; 43 import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT; 44 import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER; 45 import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES; 46 import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY; 47 import static com.android.server.wm.ActivityStack.ActivityState.PAUSED; 48 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; 49 import static com.android.server.wm.ActivityStack.ActivityState.STOPPED; 50 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING; 51 import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME; 52 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP; 53 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; 54 import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; 55 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; 56 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; 57 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE; 58 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK; 59 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; 60 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; 61 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS; 62 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE; 63 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES; 64 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS; 65 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 66 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 67 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; 68 import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; 69 import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT; 70 71 import static java.lang.Integer.MAX_VALUE; 72 73 import android.annotation.IntDef; 74 import android.annotation.NonNull; 75 import android.annotation.Nullable; 76 import android.annotation.UserIdInt; 77 import android.app.ActivityManager; 78 import android.app.ActivityOptions; 79 import android.app.AppGlobals; 80 import android.app.WindowConfiguration; 81 import android.content.ComponentName; 82 import android.content.Intent; 83 import android.content.pm.ActivityInfo; 84 import android.content.pm.ApplicationInfo; 85 import android.content.pm.ResolveInfo; 86 import android.content.res.Configuration; 87 import android.content.res.Resources; 88 import android.graphics.Rect; 89 import android.hardware.display.DisplayManager; 90 import android.hardware.display.DisplayManagerInternal; 91 import android.hardware.power.V1_0.PowerHint; 92 import android.os.FactoryTest; 93 import android.os.IBinder; 94 import android.os.RemoteException; 95 import android.os.SystemClock; 96 import android.os.Trace; 97 import android.os.UserHandle; 98 import android.os.storage.StorageManager; 99 import android.provider.Settings; 100 import android.service.voice.IVoiceInteractionSession; 101 import android.util.ArraySet; 102 import android.util.DisplayMetrics; 103 import android.util.IntArray; 104 import android.util.Pair; 105 import android.util.Slog; 106 import android.util.SparseArray; 107 import android.util.SparseIntArray; 108 import android.util.TimeUtils; 109 import android.util.proto.ProtoOutputStream; 110 import android.view.Display; 111 import android.view.DisplayInfo; 112 113 import com.android.internal.annotations.VisibleForTesting; 114 import com.android.internal.app.ResolverActivity; 115 import com.android.server.LocalServices; 116 import com.android.server.am.ActivityManagerService; 117 import com.android.server.am.AppTimeTracker; 118 import com.android.server.am.UserState; 119 import com.android.server.policy.WindowManagerPolicy; 120 121 import java.io.FileDescriptor; 122 import java.io.PrintWriter; 123 import java.lang.annotation.Retention; 124 import java.lang.annotation.RetentionPolicy; 125 import java.util.ArrayList; 126 import java.util.Iterator; 127 import java.util.List; 128 import java.util.Set; 129 130 /** 131 * Root node for activity containers. 132 * TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The 133 * intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy. 134 */ 135 class RootActivityContainer extends ConfigurationContainer 136 implements DisplayManager.DisplayListener { 137 138 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootActivityContainer" : TAG_ATM; 139 static final String TAG_TASKS = TAG + POSTFIX_TASKS; 140 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 141 static final String TAG_STATES = TAG + POSTFIX_STATES; 142 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 143 144 /** 145 * The modes which affect which tasks are returned when calling 146 * {@link RootActivityContainer#anyTaskForId(int)}. 147 */ 148 @Retention(RetentionPolicy.SOURCE) 149 @IntDef({ 150 MATCH_TASK_IN_STACKS_ONLY, 151 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, 152 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 153 }) 154 public @interface AnyTaskForIdMatchTaskMode {} 155 // Match only tasks in the current stacks 156 static final int MATCH_TASK_IN_STACKS_ONLY = 0; 157 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks 158 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1; 159 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the 160 // provided stack id 161 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2; 162 163 ActivityTaskManagerService mService; 164 ActivityStackSupervisor mStackSupervisor; 165 WindowManagerService mWindowManager; 166 DisplayManager mDisplayManager; 167 private DisplayManagerInternal mDisplayManagerInternal; 168 // TODO: Remove after object merge with RootWindowContainer. 169 private RootWindowContainer mRootWindowContainer; 170 171 /** 172 * List of displays which contain activities, sorted by z-order. 173 * The last entry in the list is the topmost. 174 */ 175 private final ArrayList<ActivityDisplay> mActivityDisplays = new ArrayList<>(); 176 177 /** Reference to default display so we can quickly look it up. */ 178 private ActivityDisplay mDefaultDisplay; 179 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 180 181 /** The current user */ 182 int mCurrentUser; 183 /** Stack id of the front stack when user switched, indexed by userId. */ 184 SparseIntArray mUserStackInFront = new SparseIntArray(2); 185 186 /** 187 * A list of tokens that cause the top activity to be put to sleep. 188 * They are used by components that may hide and block interaction with underlying 189 * activities. 190 */ 191 final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>(); 192 193 /** Is dock currently minimized. */ 194 boolean mIsDockMinimized; 195 196 /** Set when a power hint has started, but not ended. */ 197 private boolean mPowerHintSent; 198 199 // The default minimal size that will be used if the activity doesn't specify its minimal size. 200 // It will be calculated when the default display gets added. 201 int mDefaultMinSizeOfResizeableTaskDp = -1; 202 203 // Whether tasks have moved and we need to rank the tasks before next OOM scoring 204 private boolean mTaskLayersChanged = true; 205 206 private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>(); 207 208 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); 209 static class FindTaskResult { 210 ActivityRecord mRecord; 211 boolean mIdealMatch; 212 clear()213 void clear() { 214 mRecord = null; 215 mIdealMatch = false; 216 } 217 setTo(FindTaskResult result)218 void setTo(FindTaskResult result) { 219 mRecord = result.mRecord; 220 mIdealMatch = result.mIdealMatch; 221 } 222 } 223 RootActivityContainer(ActivityTaskManagerService service)224 RootActivityContainer(ActivityTaskManagerService service) { 225 mService = service; 226 mStackSupervisor = service.mStackSupervisor; 227 mStackSupervisor.mRootActivityContainer = this; 228 } 229 230 @VisibleForTesting setWindowContainer(RootWindowContainer container)231 void setWindowContainer(RootWindowContainer container) { 232 mRootWindowContainer = container; 233 mRootWindowContainer.setRootActivityContainer(this); 234 } 235 setWindowManager(WindowManagerService wm)236 void setWindowManager(WindowManagerService wm) { 237 mWindowManager = wm; 238 setWindowContainer(mWindowManager.mRoot); 239 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class); 240 mDisplayManager.registerDisplayListener(this, mService.mUiHandler); 241 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 242 243 final Display[] displays = mDisplayManager.getDisplays(); 244 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) { 245 final Display display = displays[displayNdx]; 246 final ActivityDisplay activityDisplay = new ActivityDisplay(this, display); 247 if (activityDisplay.mDisplayId == DEFAULT_DISPLAY) { 248 mDefaultDisplay = activityDisplay; 249 } 250 addChild(activityDisplay, ActivityDisplay.POSITION_TOP); 251 } 252 calculateDefaultMinimalSizeOfResizeableTasks(); 253 254 final ActivityDisplay defaultDisplay = getDefaultDisplay(); 255 256 defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); 257 positionChildAt(defaultDisplay, ActivityDisplay.POSITION_TOP); 258 } 259 260 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display. getDefaultDisplay()261 ActivityDisplay getDefaultDisplay() { 262 return mDefaultDisplay; 263 } 264 265 /** 266 * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is 267 * defined in {@link DisplayInfo#uniqueId}. 268 * 269 * @param uniqueId the unique ID of the display 270 * @return the {@link ActivityDisplay} or {@code null} if nothing is found. 271 */ getActivityDisplay(String uniqueId)272 ActivityDisplay getActivityDisplay(String uniqueId) { 273 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 274 final ActivityDisplay display = mActivityDisplays.get(i); 275 final boolean isValid = display.mDisplay.isValid(); 276 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) { 277 return display; 278 } 279 } 280 281 return null; 282 } 283 284 // TODO: Look into consolidating with getActivityDisplayOrCreate() getActivityDisplay(int displayId)285 ActivityDisplay getActivityDisplay(int displayId) { 286 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 287 final ActivityDisplay activityDisplay = mActivityDisplays.get(i); 288 if (activityDisplay.mDisplayId == displayId) { 289 return activityDisplay; 290 } 291 } 292 return null; 293 } 294 295 /** 296 * Get an existing instance of {@link ActivityDisplay} or create new if there is a 297 * corresponding record in display manager. 298 */ 299 // TODO: Look into consolidating with getActivityDisplay() getActivityDisplayOrCreate(int displayId)300 @Nullable ActivityDisplay getActivityDisplayOrCreate(int displayId) { 301 ActivityDisplay activityDisplay = getActivityDisplay(displayId); 302 if (activityDisplay != null) { 303 return activityDisplay; 304 } 305 if (mDisplayManager == null) { 306 // The system isn't fully initialized yet. 307 return null; 308 } 309 final Display display = mDisplayManager.getDisplay(displayId); 310 if (display == null) { 311 // The display is not registered in DisplayManager. 312 return null; 313 } 314 // The display hasn't been added to ActivityManager yet, create a new record now. 315 activityDisplay = new ActivityDisplay(this, display); 316 addChild(activityDisplay, ActivityDisplay.POSITION_BOTTOM); 317 return activityDisplay; 318 } 319 320 /** Check if display with specified id is added to the list. */ isDisplayAdded(int displayId)321 boolean isDisplayAdded(int displayId) { 322 return getActivityDisplayOrCreate(displayId) != null; 323 } 324 getDefaultDisplayHomeActivity()325 ActivityRecord getDefaultDisplayHomeActivity() { 326 return getDefaultDisplayHomeActivityForUser(mCurrentUser); 327 } 328 getDefaultDisplayHomeActivityForUser(int userId)329 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) { 330 return getActivityDisplay(DEFAULT_DISPLAY).getHomeActivityForUser(userId); 331 } 332 startHomeOnAllDisplays(int userId, String reason)333 boolean startHomeOnAllDisplays(int userId, String reason) { 334 boolean homeStarted = false; 335 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) { 336 final int displayId = mActivityDisplays.get(i).mDisplayId; 337 homeStarted |= startHomeOnDisplay(userId, reason, displayId); 338 } 339 return homeStarted; 340 } 341 startHomeOnEmptyDisplays(String reason)342 void startHomeOnEmptyDisplays(String reason) { 343 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) { 344 final ActivityDisplay display = mActivityDisplays.get(i); 345 if (display.topRunningActivity() == null) { 346 startHomeOnDisplay(mCurrentUser, reason, display.mDisplayId); 347 } 348 } 349 } 350 startHomeOnDisplay(int userId, String reason, int displayId)351 boolean startHomeOnDisplay(int userId, String reason, int displayId) { 352 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */, 353 false /* fromHomeKey */); 354 } 355 356 /** 357 * This starts home activity on displays that can have system decorations based on displayId - 358 * Default display always use primary home component. 359 * For Secondary displays, the home activity must have category SECONDARY_HOME and then resolves 360 * according to the priorities listed below. 361 * - If default home is not set, always use the secondary home defined in the config. 362 * - Use currently selected primary home activity. 363 * - Use the activity in the same package as currently selected primary home activity. 364 * If there are multiple activities matched, use first one. 365 * - Use the secondary home defined in the config. 366 */ startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey)367 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, 368 boolean fromHomeKey) { 369 // Fallback to top focused display if the displayId is invalid. 370 if (displayId == INVALID_DISPLAY) { 371 displayId = getTopDisplayFocusedStack().mDisplayId; 372 } 373 374 Intent homeIntent = null; 375 ActivityInfo aInfo = null; 376 if (displayId == DEFAULT_DISPLAY) { 377 homeIntent = mService.getHomeIntent(); 378 aInfo = resolveHomeActivity(userId, homeIntent); 379 } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) { 380 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId); 381 aInfo = info.first; 382 homeIntent = info.second; 383 } 384 if (aInfo == null || homeIntent == null) { 385 return false; 386 } 387 388 if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) { 389 return false; 390 } 391 392 // Updates the home component of the intent. 393 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); 394 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK); 395 // Updates the extra information of the intent. 396 if (fromHomeKey) { 397 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true); 398 } 399 // Update the reason for ANR debugging to verify if the user activity is the one that 400 // actually launched. 401 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId( 402 aInfo.applicationInfo.uid) + ":" + displayId; 403 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason, 404 displayId); 405 return true; 406 } 407 408 /** 409 * This resolves the home activity info. 410 * @return the home activity info if any. 411 */ 412 @VisibleForTesting resolveHomeActivity(int userId, Intent homeIntent)413 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) { 414 final int flags = ActivityManagerService.STOCK_PM_FLAGS; 415 final ComponentName comp = homeIntent.getComponent(); 416 ActivityInfo aInfo = null; 417 try { 418 if (comp != null) { 419 // Factory test. 420 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 421 } else { 422 final String resolvedType = 423 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver()); 424 final ResolveInfo info = AppGlobals.getPackageManager() 425 .resolveIntent(homeIntent, resolvedType, flags, userId); 426 if (info != null) { 427 aInfo = info.activityInfo; 428 } 429 } 430 } catch (RemoteException e) { 431 // ignore 432 } 433 434 if (aInfo == null) { 435 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable()); 436 return null; 437 } 438 439 aInfo = new ActivityInfo(aInfo); 440 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId); 441 return aInfo; 442 } 443 444 @VisibleForTesting resolveSecondaryHomeActivity(int userId, int displayId)445 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, int displayId) { 446 if (displayId == DEFAULT_DISPLAY) { 447 throw new IllegalArgumentException( 448 "resolveSecondaryHomeActivity: Should not be DEFAULT_DISPLAY"); 449 } 450 // Resolve activities in the same package as currently selected primary home activity. 451 Intent homeIntent = mService.getHomeIntent(); 452 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent); 453 if (aInfo != null) { 454 if (ResolverActivity.class.getName().equals(aInfo.name)) { 455 // Always fallback to secondary home component if default home is not set. 456 aInfo = null; 457 } else { 458 // Look for secondary home activities in the currently selected default home 459 // package. 460 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName); 461 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent); 462 final int size = resolutions.size(); 463 final String targetName = aInfo.name; 464 aInfo = null; 465 for (int i = 0; i < size; i++) { 466 ResolveInfo resolveInfo = resolutions.get(i); 467 // We need to traverse all resolutions to check if the currently selected 468 // default home activity is present. 469 if (resolveInfo.activityInfo.name.equals(targetName)) { 470 aInfo = resolveInfo.activityInfo; 471 break; 472 } 473 } 474 if (aInfo == null && size > 0) { 475 // First one is the best. 476 aInfo = resolutions.get(0).activityInfo; 477 } 478 } 479 } 480 481 if (aInfo != null) { 482 if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) { 483 aInfo = null; 484 } 485 } 486 487 // Fallback to secondary home component. 488 if (aInfo == null) { 489 homeIntent = mService.getSecondaryHomeIntent(null); 490 aInfo = resolveHomeActivity(userId, homeIntent); 491 } 492 return Pair.create(aInfo, homeIntent); 493 } 494 495 /** 496 * Retrieve all activities that match the given intent. 497 * The list should already ordered from best to worst matched. 498 * {@link android.content.pm.PackageManager#queryIntentActivities} 499 */ 500 @VisibleForTesting resolveActivities(int userId, Intent homeIntent)501 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) { 502 List<ResolveInfo> resolutions; 503 try { 504 final String resolvedType = 505 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver()); 506 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent, 507 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList(); 508 509 } catch (RemoteException e) { 510 resolutions = new ArrayList<>(); 511 } 512 return resolutions; 513 } 514 resumeHomeActivity(ActivityRecord prev, String reason, int displayId)515 boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) { 516 if (!mService.isBooting() && !mService.isBooted()) { 517 // Not ready yet! 518 return false; 519 } 520 521 if (displayId == INVALID_DISPLAY) { 522 displayId = DEFAULT_DISPLAY; 523 } 524 525 final ActivityRecord r = getActivityDisplay(displayId).getHomeActivity(); 526 final String myReason = reason + " resumeHomeActivity"; 527 528 // Only resume home activity if isn't finishing. 529 if (r != null && !r.finishing) { 530 r.moveFocusableActivityToTop(myReason); 531 return resumeFocusedStacksTopActivities(r.getActivityStack(), prev, null); 532 } 533 return startHomeOnDisplay(mCurrentUser, myReason, displayId); 534 } 535 536 /** 537 * Check if the display is valid for secondary home activity. 538 * @param displayId The id of the target display. 539 * @return {@code true} if allow to launch, {@code false} otherwise. 540 */ shouldPlaceSecondaryHomeOnDisplay(int displayId)541 boolean shouldPlaceSecondaryHomeOnDisplay(int displayId) { 542 if (displayId == DEFAULT_DISPLAY) { 543 throw new IllegalArgumentException( 544 "shouldPlaceSecondaryHomeOnDisplay: Should not be DEFAULT_DISPLAY"); 545 } else if (displayId == INVALID_DISPLAY) { 546 return false; 547 } 548 549 if (!mService.mSupportsMultiDisplay) { 550 // Can't launch home on secondary display if device does not support multi-display. 551 return false; 552 } 553 554 final boolean deviceProvisioned = Settings.Global.getInt( 555 mService.mContext.getContentResolver(), 556 Settings.Global.DEVICE_PROVISIONED, 0) != 0; 557 if (!deviceProvisioned) { 558 // Can't launch home on secondary display before device is provisioned. 559 return false; 560 } 561 562 if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) { 563 // Can't launch home on secondary displays if device is still locked. 564 return false; 565 } 566 567 final ActivityDisplay display = getActivityDisplay(displayId); 568 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) { 569 // Can't launch home on display that doesn't support system decorations. 570 return false; 571 } 572 573 return true; 574 } 575 576 /** 577 * Check if home activity start should be allowed on a display. 578 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched. 579 * @param displayId The id of the target display. 580 * @param allowInstrumenting Whether launching home should be allowed if being instrumented. 581 * @return {@code true} if allow to launch, {@code false} otherwise. 582 */ canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId, boolean allowInstrumenting)583 boolean canStartHomeOnDisplay(ActivityInfo homeInfo, int displayId, 584 boolean allowInstrumenting) { 585 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 586 && mService.mTopAction == null) { 587 // We are running in factory test mode, but unable to find the factory test app, so 588 // just sit around displaying the error message and don't try to start anything. 589 return false; 590 } 591 592 final WindowProcessController app = 593 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid); 594 if (!allowInstrumenting && app != null && app.isInstrumenting()) { 595 // Don't do this if the home app is currently being instrumented. 596 return false; 597 } 598 599 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY 600 && displayId == mService.mVr2dDisplayId)) { 601 // No restrictions to default display or vr 2d display. 602 return true; 603 } 604 605 if (!shouldPlaceSecondaryHomeOnDisplay(displayId)) { 606 return false; 607 } 608 609 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK 610 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE; 611 if (!supportMultipleInstance) { 612 // Can't launch home on secondary displays if it requested to be single instance. 613 return false; 614 } 615 616 return true; 617 } 618 619 /** 620 * Ensure all activities visibility, update orientation and configuration. 621 * 622 * @param starting The currently starting activity or {@code null} if there is none. 623 * @param displayId The id of the display where operation is executed. 624 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to 625 * {@code true} if config changed. 626 * @param deferResume Whether to defer resume while updating config. 627 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched 628 * because of configuration update. 629 */ ensureVisibilityAndConfig(ActivityRecord starting, int displayId, boolean markFrozenIfConfigChanged, boolean deferResume)630 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId, 631 boolean markFrozenIfConfigChanged, boolean deferResume) { 632 // First ensure visibility without updating the config just yet. We need this to know what 633 // activities are affecting configuration now. 634 // Passing null here for 'starting' param value, so that visibility of actual starting 635 // activity will be properly updated. 636 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, 637 false /* preserveWindows */, false /* notifyClients */); 638 639 if (displayId == INVALID_DISPLAY) { 640 // The caller didn't provide a valid display id, skip updating config. 641 return true; 642 } 643 644 // Force-update the orientation from the WindowManager, since we need the true configuration 645 // to send to the client now. 646 final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId); 647 Configuration config = null; 648 if (displayContent != null) { 649 config = displayContent.updateOrientationFromAppTokens( 650 getDisplayOverrideConfiguration(displayId), 651 starting != null && starting.mayFreezeScreenLocked(starting.app) 652 ? starting.appToken : null, 653 true /* forceUpdate */); 654 } 655 if (starting != null && markFrozenIfConfigChanged && config != null) { 656 starting.frozenBeforeDestroy = true; 657 } 658 659 // Update the configuration of the activities on the display. 660 return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume, 661 displayId); 662 } 663 664 /** 665 * @return a list of activities which are the top ones in each visible stack. The first 666 * entry will be the focused activity. 667 */ getTopVisibleActivities()668 List<IBinder> getTopVisibleActivities() { 669 final ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 670 final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); 671 // Traverse all displays. 672 for (int i = mActivityDisplays.size() - 1; i >= 0; i--) { 673 final ActivityDisplay display = mActivityDisplays.get(i); 674 // Traverse all stacks on a display. 675 for (int j = display.getChildCount() - 1; j >= 0; --j) { 676 final ActivityStack stack = display.getChildAt(j); 677 // Get top activity from a visible stack and add it to the list. 678 if (stack.shouldBeVisible(null /* starting */)) { 679 final ActivityRecord top = stack.getTopActivity(); 680 if (top != null) { 681 if (stack == topFocusedStack) { 682 topActivityTokens.add(0, top.appToken); 683 } else { 684 topActivityTokens.add(top.appToken); 685 } 686 } 687 } 688 } 689 } 690 return topActivityTokens; 691 } 692 getTopDisplayFocusedStack()693 ActivityStack getTopDisplayFocusedStack() { 694 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 695 final ActivityStack focusedStack = mActivityDisplays.get(i).getFocusedStack(); 696 if (focusedStack != null) { 697 return focusedStack; 698 } 699 } 700 return null; 701 } 702 getTopResumedActivity()703 ActivityRecord getTopResumedActivity() { 704 final ActivityStack focusedStack = getTopDisplayFocusedStack(); 705 if (focusedStack == null) { 706 return null; 707 } 708 final ActivityRecord resumedActivity = focusedStack.getResumedActivity(); 709 if (resumedActivity != null && resumedActivity.app != null) { 710 return resumedActivity; 711 } 712 // The top focused stack might not have a resumed activity yet - look on all displays in 713 // focus order. 714 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 715 final ActivityDisplay display = mActivityDisplays.get(i); 716 final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity(); 717 if (resumedActivityOnDisplay != null) { 718 return resumedActivityOnDisplay; 719 } 720 } 721 return null; 722 } 723 isFocusable(ConfigurationContainer container, boolean alwaysFocusable)724 boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) { 725 if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) { 726 return false; 727 } 728 729 return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable; 730 } 731 isTopDisplayFocusedStack(ActivityStack stack)732 boolean isTopDisplayFocusedStack(ActivityStack stack) { 733 return stack != null && stack == getTopDisplayFocusedStack(); 734 } 735 updatePreviousProcess(ActivityRecord r)736 void updatePreviousProcess(ActivityRecord r) { 737 // Now that this process has stopped, we may want to consider it to be the previous app to 738 // try to keep around in case the user wants to return to it. 739 740 // First, found out what is currently the foreground app, so that we don't blow away the 741 // previous app if this activity is being hosted by the process that is actually still the 742 // foreground. 743 WindowProcessController fgApp = null; 744 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 745 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 746 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 747 final ActivityStack stack = display.getChildAt(stackNdx); 748 if (isTopDisplayFocusedStack(stack)) { 749 final ActivityRecord resumedActivity = stack.getResumedActivity(); 750 if (resumedActivity != null) { 751 fgApp = resumedActivity.app; 752 } else if (stack.mPausingActivity != null) { 753 fgApp = stack.mPausingActivity.app; 754 } 755 break; 756 } 757 } 758 } 759 760 // Now set this one as the previous process, only if that really makes sense to. 761 if (r.hasProcess() && fgApp != null && r.app != fgApp 762 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 763 && r.app != mService.mHomeProcess) { 764 mService.mPreviousProcess = r.app; 765 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 766 } 767 } 768 attachApplication(WindowProcessController app)769 boolean attachApplication(WindowProcessController app) throws RemoteException { 770 final String processName = app.mName; 771 boolean didSomething = false; 772 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 773 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 774 final ActivityStack stack = display.getFocusedStack(); 775 if (stack != null) { 776 stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); 777 final ActivityRecord top = stack.topRunningActivityLocked(); 778 final int size = mTmpActivityList.size(); 779 for (int i = 0; i < size; i++) { 780 final ActivityRecord activity = mTmpActivityList.get(i); 781 if (activity.app == null && app.mUid == activity.info.applicationInfo.uid 782 && processName.equals(activity.processName)) { 783 try { 784 if (mStackSupervisor.realStartActivityLocked(activity, app, 785 top == activity /* andResume */, true /* checkConfig */)) { 786 didSomething = true; 787 } 788 } catch (RemoteException e) { 789 Slog.w(TAG, "Exception in new application when starting activity " 790 + top.intent.getComponent().flattenToShortString(), e); 791 throw e; 792 } 793 } 794 } 795 } 796 } 797 if (!didSomething) { 798 ensureActivitiesVisible(null, 0, false /* preserve_windows */); 799 } 800 return didSomething; 801 } 802 803 /** 804 * Make sure that all activities that need to be visible in the system actually are and update 805 * their configuration. 806 */ ensureActivitiesVisible(ActivityRecord starting, int configChanges, boolean preserveWindows)807 void ensureActivitiesVisible(ActivityRecord starting, int configChanges, 808 boolean preserveWindows) { 809 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */); 810 } 811 812 /** 813 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean) 814 */ ensureActivitiesVisible(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients)815 void ensureActivitiesVisible(ActivityRecord starting, int configChanges, 816 boolean preserveWindows, boolean notifyClients) { 817 mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate(); 818 try { 819 // First the front stacks. In case any are not fullscreen and are in front of home. 820 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 821 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 822 display.ensureActivitiesVisible(starting, configChanges, preserveWindows, 823 notifyClients); 824 } 825 } finally { 826 mStackSupervisor.getKeyguardController().endActivityVisibilityUpdate(); 827 } 828 } 829 switchUser(int userId, UserState uss)830 boolean switchUser(int userId, UserState uss) { 831 final int focusStackId = getTopDisplayFocusedStack().getStackId(); 832 // We dismiss the docked stack whenever we switch users. 833 final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack(); 834 if (dockedStack != null) { 835 mStackSupervisor.moveTasksToFullscreenStackLocked( 836 dockedStack, dockedStack.isFocusedStackOnDisplay()); 837 } 838 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will 839 // also cause all tasks to be moved to the fullscreen stack at a position that is 840 // appropriate. 841 removeStacksInWindowingModes(WINDOWING_MODE_PINNED); 842 843 mUserStackInFront.put(mCurrentUser, focusStackId); 844 final int restoreStackId = 845 mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId); 846 mCurrentUser = userId; 847 848 mStackSupervisor.mStartingUsers.add(uss); 849 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 850 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 851 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 852 final ActivityStack stack = display.getChildAt(stackNdx); 853 stack.switchUserLocked(userId); 854 TaskRecord task = stack.topTask(); 855 if (task != null) { 856 stack.positionChildWindowContainerAtTop(task); 857 } 858 } 859 } 860 861 ActivityStack stack = getStack(restoreStackId); 862 if (stack == null) { 863 stack = getDefaultDisplay().getHomeStack(); 864 } 865 final boolean homeInFront = stack.isActivityTypeHome(); 866 if (stack.isOnHomeDisplay()) { 867 stack.moveToFront("switchUserOnHomeDisplay"); 868 } else { 869 // Stack was moved to another display while user was swapped out. 870 resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY); 871 } 872 return homeInFront; 873 } 874 removeUser(int userId)875 void removeUser(int userId) { 876 mUserStackInFront.delete(userId); 877 } 878 879 /** 880 * Update the last used stack id for non-current user (current user's last 881 * used stack is the focused stack) 882 */ updateUserStack(int userId, ActivityStack stack)883 void updateUserStack(int userId, ActivityStack stack) { 884 if (userId != mCurrentUser) { 885 mUserStackInFront.put(userId, stack != null ? stack.getStackId() 886 : getDefaultDisplay().getHomeStack().mStackId); 887 } 888 } 889 resizeStack(ActivityStack stack, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume)890 void resizeStack(ActivityStack stack, Rect bounds, Rect tempTaskBounds, 891 Rect tempTaskInsetBounds, boolean preserveWindows, boolean allowResizeInDockedMode, 892 boolean deferResume) { 893 894 if (stack.inSplitScreenPrimaryWindowingMode()) { 895 mStackSupervisor.resizeDockedStackLocked(bounds, tempTaskBounds, 896 tempTaskInsetBounds, null, null, preserveWindows, deferResume); 897 return; 898 } 899 900 final boolean splitScreenActive = getDefaultDisplay().hasSplitScreenPrimaryStack(); 901 if (!allowResizeInDockedMode 902 && !stack.getWindowConfiguration().tasksAreFloating() && splitScreenActive) { 903 // If the docked stack exists, don't resize non-floating stacks independently of the 904 // size computed from the docked stack size (otherwise they will be out of sync) 905 return; 906 } 907 908 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stack.mStackId); 909 mWindowManager.deferSurfaceLayout(); 910 try { 911 if (stack.affectedBySplitScreenResize()) { 912 if (bounds == null && stack.inSplitScreenWindowingMode()) { 913 // null bounds = fullscreen windowing mode...at least for now. 914 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); 915 } else if (splitScreenActive) { 916 // If we are in split-screen mode and this stack support split-screen, then 917 // it should be split-screen secondary mode. i.e. adjacent to the docked stack. 918 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); 919 } 920 } 921 stack.resize(bounds, tempTaskBounds, tempTaskInsetBounds); 922 if (!deferResume) { 923 stack.ensureVisibleActivitiesConfigurationLocked( 924 stack.topRunningActivityLocked(), preserveWindows); 925 } 926 } finally { 927 mWindowManager.continueSurfaceLayout(); 928 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 929 } 930 } 931 932 /** 933 * Move stack with all its existing content to specified display. 934 * @param stackId Id of stack to move. 935 * @param displayId Id of display to move stack to. 936 * @param onTop Indicates whether container should be place on top or on bottom. 937 */ moveStackToDisplay(int stackId, int displayId, boolean onTop)938 void moveStackToDisplay(int stackId, int displayId, boolean onTop) { 939 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId); 940 if (activityDisplay == null) { 941 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId=" 942 + displayId); 943 } 944 final ActivityStack stack = getStack(stackId); 945 if (stack == null) { 946 throw new IllegalArgumentException("moveStackToDisplay: Unknown stackId=" 947 + stackId); 948 } 949 950 final ActivityDisplay currentDisplay = stack.getDisplay(); 951 if (currentDisplay == null) { 952 throw new IllegalStateException("moveStackToDisplay: Stack with stack=" + stack 953 + " is not attached to any display."); 954 } 955 956 if (currentDisplay.mDisplayId == displayId) { 957 throw new IllegalArgumentException("Trying to move stack=" + stack 958 + " to its current displayId=" + displayId); 959 } 960 961 if (activityDisplay.isSingleTaskInstance() && activityDisplay.getChildCount() > 0) { 962 // We don't allow moving stacks to single instance display that already has a child. 963 Slog.e(TAG, "Can not move stack=" + stack 964 + " to single task instance display=" + activityDisplay); 965 return; 966 } 967 968 stack.reparent(activityDisplay, onTop, false /* displayRemoved */); 969 // TODO(multi-display): resize stacks properly if moved from split-screen. 970 } 971 moveTopStackActivityToPinnedStack(int stackId)972 boolean moveTopStackActivityToPinnedStack(int stackId) { 973 final ActivityStack stack = getStack(stackId); 974 if (stack == null) { 975 throw new IllegalArgumentException( 976 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId); 977 } 978 979 final ActivityRecord r = stack.topRunningActivityLocked(); 980 if (r == null) { 981 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity" 982 + " in stack=" + stack); 983 return false; 984 } 985 986 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { 987 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for " 988 + " r=" + r); 989 return false; 990 } 991 992 moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */, 993 "moveTopActivityToPinnedStack"); 994 return true; 995 } 996 moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio, String reason)997 void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio, 998 String reason) { 999 1000 mWindowManager.deferSurfaceLayout(); 1001 1002 final ActivityDisplay display = r.getActivityStack().getDisplay(); 1003 ActivityStack stack = display.getPinnedStack(); 1004 1005 // This will clear the pinned stack by moving an existing task to the full screen stack, 1006 // ensuring only one task is present. 1007 if (stack != null) { 1008 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, !ON_TOP); 1009 } 1010 1011 // Need to make sure the pinned stack exist so we can resize it below... 1012 stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP); 1013 1014 // Calculate the target bounds here before the task is reparented back into pinned windowing 1015 // mode (which will reset the saved bounds) 1016 final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio); 1017 1018 try { 1019 final TaskRecord task = r.getTaskRecord(); 1020 // Resize the pinned stack to match the current size of the task the activity we are 1021 // going to be moving is currently contained in. We do this to have the right starting 1022 // animation bounds for the pinned stack to the desired bounds the caller wants. 1023 resizeStack(stack, task.getRequestedOverrideBounds(), null /* tempTaskBounds */, 1024 null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, 1025 true /* allowResizeInDockedMode */, !DEFER_RESUME); 1026 1027 if (task.mActivities.size() == 1) { 1028 // Defer resume until below, and do not schedule PiP changes until we animate below 1029 task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME, 1030 false /* schedulePictureInPictureModeChange */, reason); 1031 } else { 1032 // There are multiple activities in the task and moving the top activity should 1033 // reveal/leave the other activities in their original task. 1034 1035 // Currently, we don't support reparenting activities across tasks in two different 1036 // stacks, so instead, just create a new task in the same stack, reparent the 1037 // activity into that task, and then reparent the whole task to the new stack. This 1038 // ensures that all the necessary work to migrate states in the old and new stacks 1039 // is also done. 1040 final TaskRecord newTask = task.getStack().createTaskRecord( 1041 mStackSupervisor.getNextTaskIdForUserLocked(r.mUserId), r.info, 1042 r.intent, null, null, true); 1043 r.reparent(newTask, MAX_VALUE, "moveActivityToStack"); 1044 1045 // Defer resume until below, and do not schedule PiP changes until we animate below 1046 newTask.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, 1047 DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason); 1048 } 1049 1050 // Reset the state that indicates it can enter PiP while pausing after we've moved it 1051 // to the pinned stack 1052 r.supportsEnterPipOnTaskSwitch = false; 1053 } finally { 1054 mWindowManager.continueSurfaceLayout(); 1055 } 1056 1057 stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */, 1058 true /* fromFullscreen */); 1059 1060 // Update the visibility of all activities after the they have been reparented to the new 1061 // stack. This MUST run after the animation above is scheduled to ensure that the windows 1062 // drawn signal is scheduled after the bounds animation start call on the bounds animator 1063 // thread. 1064 ensureActivitiesVisible(null, 0, false /* preserveWindows */); 1065 resumeFocusedStacksTopActivities(); 1066 1067 mService.getTaskChangeNotificationController().notifyActivityPinned(r); 1068 } 1069 executeAppTransitionForAllDisplay()1070 void executeAppTransitionForAllDisplay() { 1071 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1072 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1073 display.mDisplayContent.executeAppTransition(); 1074 } 1075 } 1076 setDockedStackMinimized(boolean minimized)1077 void setDockedStackMinimized(boolean minimized) { 1078 // Get currently focused stack before setting mIsDockMinimized. We do this because if 1079 // split-screen is active, primary stack will not be focusable (see #isFocusable) while 1080 // still occluding other stacks. This will cause getTopDisplayFocusedStack() to return null. 1081 final ActivityStack current = getTopDisplayFocusedStack(); 1082 mIsDockMinimized = minimized; 1083 if (mIsDockMinimized) { 1084 if (current.inSplitScreenPrimaryWindowingMode()) { 1085 // The primary split-screen stack can't be focused while it is minimize, so move 1086 // focus to something else. 1087 current.adjustFocusToNextFocusableStack("setDockedStackMinimized"); 1088 } 1089 } 1090 } 1091 findTask(ActivityRecord r, int preferredDisplayId)1092 ActivityRecord findTask(ActivityRecord r, int preferredDisplayId) { 1093 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 1094 mTmpFindTaskResult.clear(); 1095 1096 // Looking up task on preferred display first 1097 final ActivityDisplay preferredDisplay = getActivityDisplay(preferredDisplayId); 1098 if (preferredDisplay != null) { 1099 preferredDisplay.findTaskLocked(r, true /* isPreferredDisplay */, mTmpFindTaskResult); 1100 if (mTmpFindTaskResult.mIdealMatch) { 1101 return mTmpFindTaskResult.mRecord; 1102 } 1103 } 1104 1105 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1106 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1107 if (display.mDisplayId == preferredDisplayId) { 1108 continue; 1109 } 1110 1111 display.findTaskLocked(r, false /* isPreferredDisplay */, mTmpFindTaskResult); 1112 if (mTmpFindTaskResult.mIdealMatch) { 1113 return mTmpFindTaskResult.mRecord; 1114 } 1115 } 1116 1117 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found"); 1118 return mTmpFindTaskResult.mRecord; 1119 } 1120 1121 /** 1122 * Finish the topmost activities in all stacks that belong to the crashed app. 1123 * @param app The app that crashed. 1124 * @param reason Reason to perform this action. 1125 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished. 1126 */ finishTopCrashedActivities(WindowProcessController app, String reason)1127 int finishTopCrashedActivities(WindowProcessController app, String reason) { 1128 TaskRecord finishedTask = null; 1129 ActivityStack focusedStack = getTopDisplayFocusedStack(); 1130 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1131 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1132 // It is possible that request to finish activity might also remove its task and stack, 1133 // so we need to be careful with indexes in the loop and check child count every time. 1134 for (int stackNdx = 0; stackNdx < display.getChildCount(); ++stackNdx) { 1135 final ActivityStack stack = display.getChildAt(stackNdx); 1136 final TaskRecord t = stack.finishTopCrashedActivityLocked(app, reason); 1137 if (stack == focusedStack || finishedTask == null) { 1138 finishedTask = t; 1139 } 1140 } 1141 } 1142 return finishedTask != null ? finishedTask.taskId : INVALID_TASK_ID; 1143 } 1144 resumeFocusedStacksTopActivities()1145 boolean resumeFocusedStacksTopActivities() { 1146 return resumeFocusedStacksTopActivities(null, null, null); 1147 } 1148 resumeFocusedStacksTopActivities( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions)1149 boolean resumeFocusedStacksTopActivities( 1150 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 1151 1152 if (!mStackSupervisor.readyToResume()) { 1153 return false; 1154 } 1155 1156 boolean result = false; 1157 if (targetStack != null && (targetStack.isTopStackOnDisplay() 1158 || getTopDisplayFocusedStack() == targetStack)) { 1159 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 1160 } 1161 1162 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1163 boolean resumedOnDisplay = false; 1164 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1165 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1166 final ActivityStack stack = display.getChildAt(stackNdx); 1167 final ActivityRecord topRunningActivity = stack.topRunningActivityLocked(); 1168 if (!stack.isFocusableAndVisible() || topRunningActivity == null) { 1169 continue; 1170 } 1171 if (stack == targetStack) { 1172 // Simply update the result for targetStack because the targetStack had 1173 // already resumed in above. We don't want to resume it again, especially in 1174 // some cases, it would cause a second launch failure if app process was dead. 1175 resumedOnDisplay |= result; 1176 continue; 1177 } 1178 if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) { 1179 // Kick off any lingering app transitions form the MoveTaskToFront operation, 1180 // but only consider the top task and stack on that display. 1181 stack.executeAppTransition(targetOptions); 1182 } else { 1183 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target); 1184 } 1185 } 1186 if (!resumedOnDisplay) { 1187 // In cases when there are no valid activities (e.g. device just booted or launcher 1188 // crashed) it's possible that nothing was resumed on a display. Requesting resume 1189 // of top activity in focused stack explicitly will make sure that at least home 1190 // activity is started and resumed, and no recursion occurs. 1191 final ActivityStack focusedStack = display.getFocusedStack(); 1192 if (focusedStack != null) { 1193 focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); 1194 } 1195 } 1196 } 1197 1198 return result; 1199 } 1200 applySleepTokens(boolean applyToStacks)1201 void applySleepTokens(boolean applyToStacks) { 1202 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1203 // Set the sleeping state of the display. 1204 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1205 final boolean displayShouldSleep = display.shouldSleep(); 1206 if (displayShouldSleep == display.isSleeping()) { 1207 continue; 1208 } 1209 display.setIsSleeping(displayShouldSleep); 1210 1211 if (!applyToStacks) { 1212 continue; 1213 } 1214 1215 // Set the sleeping state of the stacks on the display. 1216 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1217 final ActivityStack stack = display.getChildAt(stackNdx); 1218 if (displayShouldSleep) { 1219 stack.goToSleepIfPossible(false /* shuttingDown */); 1220 } else { 1221 // When the display which can only contain one task turns on, start a special 1222 // transition. {@link AppTransitionController#handleAppTransitionReady} later 1223 // picks up the transition, and schedules 1224 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is 1225 // triggered after contents are drawn on the display. 1226 if (display.isSingleTaskInstance()) { 1227 display.mDisplayContent.prepareAppTransition( 1228 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false); 1229 } 1230 stack.awakeFromSleepingLocked(); 1231 if (stack.isFocusedStackOnDisplay() 1232 && !mStackSupervisor.getKeyguardController() 1233 .isKeyguardOrAodShowing(display.mDisplayId)) { 1234 // If the keyguard is unlocked - resume immediately. 1235 // It is possible that the display will not be awake at the time we 1236 // process the keyguard going away, which can happen before the sleep token 1237 // is released. As a result, it is important we resume the activity here. 1238 resumeFocusedStacksTopActivities(); 1239 } 1240 } 1241 } 1242 1243 if (displayShouldSleep || mStackSupervisor.mGoingToSleepActivities.isEmpty()) { 1244 continue; 1245 } 1246 // The display is awake now, so clean up the going to sleep list. 1247 for (Iterator<ActivityRecord> it = 1248 mStackSupervisor.mGoingToSleepActivities.iterator(); it.hasNext(); ) { 1249 final ActivityRecord r = it.next(); 1250 if (r.getDisplayId() == display.mDisplayId) { 1251 it.remove(); 1252 } 1253 } 1254 } 1255 } 1256 getStack(int stackId)1257 protected <T extends ActivityStack> T getStack(int stackId) { 1258 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 1259 final T stack = mActivityDisplays.get(i).getStack(stackId); 1260 if (stack != null) { 1261 return stack; 1262 } 1263 } 1264 return null; 1265 } 1266 1267 /** @see ActivityDisplay#getStack(int, int) */ getStack(int windowingMode, int activityType)1268 private <T extends ActivityStack> T getStack(int windowingMode, int activityType) { 1269 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 1270 final T stack = mActivityDisplays.get(i).getStack(windowingMode, activityType); 1271 if (stack != null) { 1272 return stack; 1273 } 1274 } 1275 return null; 1276 } 1277 getStackInfo(ActivityStack stack)1278 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) { 1279 final int displayId = stack.mDisplayId; 1280 final ActivityDisplay display = getActivityDisplay(displayId); 1281 ActivityManager.StackInfo info = new ActivityManager.StackInfo(); 1282 stack.getWindowContainerBounds(info.bounds); 1283 info.displayId = displayId; 1284 info.stackId = stack.mStackId; 1285 info.userId = stack.mCurrentUser; 1286 info.visible = stack.shouldBeVisible(null); 1287 // A stack might be not attached to a display. 1288 info.position = display != null ? display.getIndexOf(stack) : 0; 1289 info.configuration.setTo(stack.getConfiguration()); 1290 1291 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 1292 final int numTasks = tasks.size(); 1293 int[] taskIds = new int[numTasks]; 1294 String[] taskNames = new String[numTasks]; 1295 Rect[] taskBounds = new Rect[numTasks]; 1296 int[] taskUserIds = new int[numTasks]; 1297 for (int i = 0; i < numTasks; ++i) { 1298 final TaskRecord task = tasks.get(i); 1299 taskIds[i] = task.taskId; 1300 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 1301 : task.realActivity != null ? task.realActivity.flattenToString() 1302 : task.getTopActivity() != null ? task.getTopActivity().packageName 1303 : "unknown"; 1304 taskBounds[i] = new Rect(); 1305 task.getWindowContainerBounds(taskBounds[i]); 1306 taskUserIds[i] = task.userId; 1307 } 1308 info.taskIds = taskIds; 1309 info.taskNames = taskNames; 1310 info.taskBounds = taskBounds; 1311 info.taskUserIds = taskUserIds; 1312 1313 final ActivityRecord top = stack.topRunningActivityLocked(); 1314 info.topActivity = top != null ? top.intent.getComponent() : null; 1315 return info; 1316 } 1317 getStackInfo(int stackId)1318 ActivityManager.StackInfo getStackInfo(int stackId) { 1319 ActivityStack stack = getStack(stackId); 1320 if (stack != null) { 1321 return getStackInfo(stack); 1322 } 1323 return null; 1324 } 1325 getStackInfo(int windowingMode, int activityType)1326 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) { 1327 final ActivityStack stack = getStack(windowingMode, activityType); 1328 return (stack != null) ? getStackInfo(stack) : null; 1329 } 1330 getAllStackInfos()1331 ArrayList<ActivityManager.StackInfo> getAllStackInfos() { 1332 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>(); 1333 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 1334 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1335 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1336 final ActivityStack stack = display.getChildAt(stackNdx); 1337 list.add(getStackInfo(stack)); 1338 } 1339 } 1340 return list; 1341 } 1342 deferUpdateBounds(int activityType)1343 void deferUpdateBounds(int activityType) { 1344 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); 1345 if (stack != null) { 1346 stack.deferUpdateBounds(); 1347 } 1348 } 1349 continueUpdateBounds(int activityType)1350 void continueUpdateBounds(int activityType) { 1351 final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType); 1352 if (stack != null) { 1353 stack.continueUpdateBounds(); 1354 } 1355 } 1356 1357 @Override onDisplayAdded(int displayId)1358 public void onDisplayAdded(int displayId) { 1359 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 1360 synchronized (mService.mGlobalLock) { 1361 final ActivityDisplay display = getActivityDisplayOrCreate(displayId); 1362 if (display == null) { 1363 return; 1364 } 1365 // Do not start home before booting, or it may accidentally finish booting before it 1366 // starts. Instead, we expect home activities to be launched when the system is ready 1367 // (ActivityManagerService#systemReady). 1368 if (mService.isBooted() || mService.isBooting()) { 1369 startSystemDecorations(display.mDisplayContent); 1370 } 1371 } 1372 } 1373 startSystemDecorations(final DisplayContent displayContent)1374 private void startSystemDecorations(final DisplayContent displayContent) { 1375 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId()); 1376 displayContent.getDisplayPolicy().notifyDisplayReady(); 1377 } 1378 1379 @Override onDisplayRemoved(int displayId)1380 public void onDisplayRemoved(int displayId) { 1381 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 1382 if (displayId == DEFAULT_DISPLAY) { 1383 throw new IllegalArgumentException("Can't remove the primary display."); 1384 } 1385 1386 synchronized (mService.mGlobalLock) { 1387 final ActivityDisplay activityDisplay = getActivityDisplay(displayId); 1388 if (activityDisplay == null) { 1389 return; 1390 } 1391 1392 activityDisplay.remove(); 1393 } 1394 } 1395 1396 @Override onDisplayChanged(int displayId)1397 public void onDisplayChanged(int displayId) { 1398 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 1399 synchronized (mService.mGlobalLock) { 1400 final ActivityDisplay activityDisplay = getActivityDisplay(displayId); 1401 if (activityDisplay != null) { 1402 activityDisplay.onDisplayChanged(); 1403 } 1404 } 1405 } 1406 1407 /** Update lists of UIDs that are present on displays and have access to them. */ updateUIDsPresentOnDisplay()1408 void updateUIDsPresentOnDisplay() { 1409 mDisplayAccessUIDs.clear(); 1410 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1411 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx); 1412 // Only bother calculating the whitelist for private displays 1413 if (activityDisplay.isPrivate()) { 1414 mDisplayAccessUIDs.append( 1415 activityDisplay.mDisplayId, activityDisplay.getPresentUIDs()); 1416 } 1417 } 1418 // Store updated lists in DisplayManager. Callers from outside of AM should get them there. 1419 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs); 1420 } 1421 findStackBehind(ActivityStack stack)1422 ActivityStack findStackBehind(ActivityStack stack) { 1423 final ActivityDisplay display = getActivityDisplay(stack.mDisplayId); 1424 if (display != null) { 1425 for (int i = display.getChildCount() - 1; i >= 0; i--) { 1426 if (display.getChildAt(i) == stack && i > 0) { 1427 return display.getChildAt(i - 1); 1428 } 1429 } 1430 } 1431 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 1432 + " in=" + display); 1433 } 1434 1435 @Override getChildCount()1436 protected int getChildCount() { 1437 return mActivityDisplays.size(); 1438 } 1439 1440 @Override getChildAt(int index)1441 protected ActivityDisplay getChildAt(int index) { 1442 return mActivityDisplays.get(index); 1443 } 1444 1445 @Override getParent()1446 protected ConfigurationContainer getParent() { 1447 return null; 1448 } 1449 1450 // TODO: remove after object merge with RootWindowContainer onChildPositionChanged(ActivityDisplay display, int position)1451 void onChildPositionChanged(ActivityDisplay display, int position) { 1452 // Assume AM lock is held from positionChildAt of controller in each hierarchy. 1453 if (display != null) { 1454 positionChildAt(display, position); 1455 } 1456 } 1457 1458 /** Change the z-order of the given display. */ positionChildAt(ActivityDisplay display, int position)1459 private void positionChildAt(ActivityDisplay display, int position) { 1460 if (position >= mActivityDisplays.size()) { 1461 position = mActivityDisplays.size() - 1; 1462 } else if (position < 0) { 1463 position = 0; 1464 } 1465 1466 if (mActivityDisplays.isEmpty()) { 1467 mActivityDisplays.add(display); 1468 } else if (mActivityDisplays.get(position) != display) { 1469 mActivityDisplays.remove(display); 1470 mActivityDisplays.add(position, display); 1471 } 1472 mStackSupervisor.updateTopResumedActivityIfNeeded(); 1473 } 1474 1475 @VisibleForTesting addChild(ActivityDisplay activityDisplay, int position)1476 void addChild(ActivityDisplay activityDisplay, int position) { 1477 positionChildAt(activityDisplay, position); 1478 mRootWindowContainer.positionChildAt(position, activityDisplay.mDisplayContent); 1479 } 1480 removeChild(ActivityDisplay activityDisplay)1481 void removeChild(ActivityDisplay activityDisplay) { 1482 // The caller must tell the controller of {@link ActivityDisplay} to release its container 1483 // {@link DisplayContent}. That is done in {@link ActivityDisplay#releaseSelfIfNeeded}). 1484 mActivityDisplays.remove(activityDisplay); 1485 } 1486 getDisplayOverrideConfiguration(int displayId)1487 Configuration getDisplayOverrideConfiguration(int displayId) { 1488 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId); 1489 if (activityDisplay == null) { 1490 throw new IllegalArgumentException("No display found with id: " + displayId); 1491 } 1492 1493 return activityDisplay.getRequestedOverrideConfiguration(); 1494 } 1495 setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId)1496 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) { 1497 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId); 1498 if (activityDisplay == null) { 1499 throw new IllegalArgumentException("No display found with id: " + displayId); 1500 } 1501 1502 activityDisplay.onRequestedOverrideConfigurationChanged(overrideConfiguration); 1503 } 1504 prepareForShutdown()1505 void prepareForShutdown() { 1506 for (int i = 0; i < mActivityDisplays.size(); i++) { 1507 createSleepToken("shutdown", mActivityDisplays.get(i).mDisplayId); 1508 } 1509 } 1510 createSleepToken(String tag, int displayId)1511 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) { 1512 final ActivityDisplay display = getActivityDisplay(displayId); 1513 if (display == null) { 1514 throw new IllegalArgumentException("Invalid display: " + displayId); 1515 } 1516 1517 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId); 1518 mSleepTokens.add(token); 1519 display.mAllSleepTokens.add(token); 1520 return token; 1521 } 1522 removeSleepToken(SleepTokenImpl token)1523 private void removeSleepToken(SleepTokenImpl token) { 1524 mSleepTokens.remove(token); 1525 1526 final ActivityDisplay display = getActivityDisplay(token.mDisplayId); 1527 if (display != null) { 1528 display.mAllSleepTokens.remove(token); 1529 if (display.mAllSleepTokens.isEmpty()) { 1530 mService.updateSleepIfNeededLocked(); 1531 } 1532 } 1533 } 1534 addStartingWindowsForVisibleActivities(boolean taskSwitch)1535 void addStartingWindowsForVisibleActivities(boolean taskSwitch) { 1536 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1537 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1538 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1539 final ActivityStack stack = display.getChildAt(stackNdx); 1540 stack.addStartingWindowsForVisibleActivities(taskSwitch); 1541 } 1542 } 1543 } 1544 invalidateTaskLayers()1545 void invalidateTaskLayers() { 1546 mTaskLayersChanged = true; 1547 } 1548 rankTaskLayersIfNeeded()1549 void rankTaskLayersIfNeeded() { 1550 if (!mTaskLayersChanged) { 1551 return; 1552 } 1553 mTaskLayersChanged = false; 1554 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); displayNdx++) { 1555 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1556 int baseLayer = 0; 1557 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1558 final ActivityStack stack = display.getChildAt(stackNdx); 1559 baseLayer += stack.rankTaskLayers(baseLayer); 1560 } 1561 } 1562 } 1563 clearOtherAppTimeTrackers(AppTimeTracker except)1564 void clearOtherAppTimeTrackers(AppTimeTracker except) { 1565 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1566 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1567 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1568 final ActivityStack stack = display.getChildAt(stackNdx); 1569 stack.clearOtherAppTimeTrackers(except); 1570 } 1571 } 1572 } 1573 scheduleDestroyAllActivities(WindowProcessController app, String reason)1574 void scheduleDestroyAllActivities(WindowProcessController app, String reason) { 1575 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1576 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1577 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1578 final ActivityStack stack = display.getChildAt(stackNdx); 1579 stack.scheduleDestroyActivities(app, reason); 1580 } 1581 } 1582 } 1583 releaseSomeActivitiesLocked(WindowProcessController app, String reason)1584 void releaseSomeActivitiesLocked(WindowProcessController app, String reason) { 1585 // Tasks is non-null only if two or more tasks are found. 1586 ArraySet<TaskRecord> tasks = app.getReleaseSomeActivitiesTasks(); 1587 if (tasks == null) { 1588 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); 1589 return; 1590 } 1591 // If we have activities in multiple tasks that are in a position to be destroyed, 1592 // let's iterate through the tasks and release the oldest one. 1593 final int numDisplays = mActivityDisplays.size(); 1594 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 1595 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1596 final int stackCount = display.getChildCount(); 1597 // Step through all stacks starting from behind, to hit the oldest things first. 1598 for (int stackNdx = 0; stackNdx < stackCount; stackNdx++) { 1599 final ActivityStack stack = display.getChildAt(stackNdx); 1600 // Try to release activities in this stack; if we manage to, we are done. 1601 if (stack.releaseSomeActivitiesLocked(app, tasks, reason) > 0) { 1602 return; 1603 } 1604 } 1605 } 1606 } 1607 1608 // Tries to put all activity stacks to sleep. Returns true if all stacks were 1609 // successfully put to sleep. putStacksToSleep(boolean allowDelay, boolean shuttingDown)1610 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) { 1611 boolean allSleep = true; 1612 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1613 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1614 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1615 // Stacks and activities could be removed while putting activities to sleep if 1616 // the app process was gone. This prevents us getting exception by accessing an 1617 // invalid stack index. 1618 if (stackNdx >= display.getChildCount()) { 1619 continue; 1620 } 1621 1622 final ActivityStack stack = display.getChildAt(stackNdx); 1623 if (allowDelay) { 1624 allSleep &= stack.goToSleepIfPossible(shuttingDown); 1625 } else { 1626 stack.goToSleep(); 1627 } 1628 } 1629 } 1630 return allSleep; 1631 } 1632 handleAppCrash(WindowProcessController app)1633 void handleAppCrash(WindowProcessController app) { 1634 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1635 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1636 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1637 final ActivityStack stack = display.getChildAt(stackNdx); 1638 stack.handleAppCrash(app); 1639 } 1640 } 1641 } 1642 findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters)1643 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) { 1644 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1645 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1646 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1647 final ActivityStack stack = display.getChildAt(stackNdx); 1648 final ActivityRecord ar = stack.findActivityLocked( 1649 intent, info, compareIntentFilters); 1650 if (ar != null) { 1651 return ar; 1652 } 1653 } 1654 } 1655 return null; 1656 } 1657 hasAwakeDisplay()1658 boolean hasAwakeDisplay() { 1659 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1660 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1661 if (!display.shouldSleep()) { 1662 return true; 1663 } 1664 } 1665 return false; 1666 } 1667 getLaunchStack(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop)1668 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, 1669 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) { 1670 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */, 1671 -1 /* no realCallingPid */, -1 /* no realCallingUid */); 1672 } 1673 1674 /** 1675 * Returns the right stack to use for launching factoring in all the input parameters. 1676 * 1677 * @param r The activity we are trying to launch. Can be null. 1678 * @param options The activity options used to the launch. Can be null. 1679 * @param candidateTask The possible task the activity might be launched in. Can be null. 1680 * @param launchParams The resolved launch params to use. 1681 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} 1682 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} 1683 * 1684 * @return The stack to use for the launch or INVALID_STACK_ID. 1685 */ getLaunchStack(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop, @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, int realCallingUid)1686 <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, 1687 @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop, 1688 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, 1689 int realCallingUid) { 1690 int taskId = INVALID_TASK_ID; 1691 int displayId = INVALID_DISPLAY; 1692 //Rect bounds = null; 1693 1694 // We give preference to the launch preference in activity options. 1695 if (options != null) { 1696 taskId = options.getLaunchTaskId(); 1697 displayId = options.getLaunchDisplayId(); 1698 } 1699 1700 // First preference for stack goes to the task Id set in the activity options. Use the stack 1701 // associated with that if possible. 1702 if (taskId != INVALID_TASK_ID) { 1703 // Temporarily set the task id to invalid in case in re-entry. 1704 options.setLaunchTaskId(INVALID_TASK_ID); 1705 final TaskRecord task = anyTaskForId(taskId, 1706 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop); 1707 options.setLaunchTaskId(taskId); 1708 if (task != null) { 1709 return task.getStack(); 1710 } 1711 } 1712 1713 final int activityType = resolveActivityType(r, options, candidateTask); 1714 T stack; 1715 1716 // Next preference for stack goes to the display Id set the candidate display. 1717 if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) { 1718 displayId = launchParams.mPreferredDisplayId; 1719 } 1720 final boolean canLaunchOnDisplayFromStartRequest = 1721 realCallingPid != 0 && realCallingUid > 0 && r != null 1722 && mStackSupervisor.canPlaceEntityOnDisplay(displayId, realCallingPid, 1723 realCallingUid, r.info); 1724 // Checking if the activity's launch caller, or the realCallerId of the activity from 1725 // start request (i.e. PendingIntent caller) is allowed to launch on the display. 1726 if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId) 1727 || canLaunchOnDisplayFromStartRequest)) { 1728 if (r != null) { 1729 stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options, 1730 launchParams); 1731 if (stack != null) { 1732 return stack; 1733 } 1734 } 1735 final ActivityDisplay display = getActivityDisplayOrCreate(displayId); 1736 if (display != null) { 1737 stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop); 1738 if (stack != null) { 1739 return stack; 1740 } 1741 } 1742 } 1743 1744 // Give preference to the stack and display of the input task and activity if they match the 1745 // mode we want to launch into. 1746 stack = null; 1747 ActivityDisplay display = null; 1748 if (candidateTask != null) { 1749 stack = candidateTask.getStack(); 1750 } 1751 if (stack == null && r != null) { 1752 stack = r.getActivityStack(); 1753 } 1754 if (stack != null) { 1755 display = stack.getDisplay(); 1756 if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) { 1757 int windowingMode = launchParams != null ? launchParams.mWindowingMode 1758 : WindowConfiguration.WINDOWING_MODE_UNDEFINED; 1759 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) { 1760 windowingMode = display.resolveWindowingMode(r, options, candidateTask, 1761 activityType); 1762 } 1763 if (stack.isCompatible(windowingMode, activityType)) { 1764 return stack; 1765 } 1766 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY 1767 && display.getSplitScreenPrimaryStack() == stack 1768 && candidateTask == stack.topTask()) { 1769 // This is a special case when we try to launch an activity that is currently on 1770 // top of split-screen primary stack, but is targeting split-screen secondary. 1771 // In this case we don't want to move it to another stack. 1772 // TODO(b/78788972): Remove after differentiating between preferred and required 1773 // launch options. 1774 return stack; 1775 } 1776 } 1777 } 1778 1779 if (display == null || !canLaunchOnDisplay(r, display.mDisplayId)) { 1780 display = getDefaultDisplay(); 1781 } 1782 1783 return display.getOrCreateStack(r, options, candidateTask, activityType, onTop); 1784 } 1785 1786 /** @return true if activity record is null or can be launched on provided display. */ canLaunchOnDisplay(ActivityRecord r, int displayId)1787 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) { 1788 if (r == null) { 1789 return true; 1790 } 1791 return r.canBeLaunchedOnDisplay(displayId); 1792 } 1793 1794 /** 1795 * Get a topmost stack on the display, that is a valid launch stack for specified activity. 1796 * If there is no such stack, new dynamic stack can be created. 1797 * @param displayId Target display. 1798 * @param r Activity that should be launched there. 1799 * @param candidateTask The possible task the activity might be put in. 1800 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. 1801 */ getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r, @Nullable TaskRecord candidateTask, @Nullable ActivityOptions options, @Nullable LaunchParamsController.LaunchParams launchParams)1802 private ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r, 1803 @Nullable TaskRecord candidateTask, @Nullable ActivityOptions options, 1804 @Nullable LaunchParamsController.LaunchParams launchParams) { 1805 final ActivityDisplay activityDisplay = getActivityDisplayOrCreate(displayId); 1806 if (activityDisplay == null) { 1807 throw new IllegalArgumentException( 1808 "Display with displayId=" + displayId + " not found."); 1809 } 1810 1811 if (!r.canBeLaunchedOnDisplay(displayId)) { 1812 return null; 1813 } 1814 1815 // If {@code r} is already in target display and its task is the same as the candidate task, 1816 // the intention should be getting a launch stack for the reusable activity, so we can use 1817 // the existing stack. 1818 if (r.getDisplayId() == displayId && r.getTaskRecord() == candidateTask) { 1819 return candidateTask.getStack(); 1820 } 1821 1822 int windowingMode; 1823 if (launchParams != null) { 1824 // When launch params is not null, we always defer to its windowing mode. Sometimes 1825 // it could be unspecified, which indicates it should inherit windowing mode from 1826 // display. 1827 windowingMode = launchParams.mWindowingMode; 1828 } else { 1829 windowingMode = options != null ? options.getLaunchWindowingMode() 1830 : r.getWindowingMode(); 1831 } 1832 windowingMode = activityDisplay.validateWindowingMode(windowingMode, r, candidateTask, 1833 r.getActivityType()); 1834 1835 // Return the topmost valid stack on the display. 1836 for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) { 1837 final ActivityStack stack = activityDisplay.getChildAt(i); 1838 if (isValidLaunchStack(stack, r, windowingMode)) { 1839 return stack; 1840 } 1841 } 1842 1843 // If there is no valid stack on the external display - check if new dynamic stack will do. 1844 if (displayId != DEFAULT_DISPLAY) { 1845 final int activityType = 1846 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED 1847 ? options.getLaunchActivityType() : r.getActivityType(); 1848 return activityDisplay.createStack(windowingMode, activityType, true /*onTop*/); 1849 } 1850 1851 return null; 1852 } 1853 getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r, @Nullable ActivityOptions options, @Nullable LaunchParamsController.LaunchParams launchParams)1854 ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r, 1855 @Nullable ActivityOptions options, 1856 @Nullable LaunchParamsController.LaunchParams launchParams) { 1857 return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options, 1858 launchParams); 1859 } 1860 1861 // TODO: Can probably be consolidated into getLaunchStack()... isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode)1862 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) { 1863 switch (stack.getActivityType()) { 1864 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome(); 1865 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents(); 1866 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant(); 1867 } 1868 // There is a 1-to-1 relationship between stack and task when not in 1869 // primary split-windowing mode. 1870 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY 1871 && r.supportsSplitScreenWindowingMode() 1872 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY 1873 || windowingMode == WINDOWING_MODE_UNDEFINED)) { 1874 return true; 1875 } 1876 return false; 1877 } 1878 resolveActivityType(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable TaskRecord task)1879 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options, 1880 @Nullable TaskRecord task) { 1881 // Preference is given to the activity type for the activity then the task since the type 1882 // once set shouldn't change. 1883 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED; 1884 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) { 1885 activityType = task.getActivityType(); 1886 } 1887 if (activityType != ACTIVITY_TYPE_UNDEFINED) { 1888 return activityType; 1889 } 1890 if (options != null) { 1891 activityType = options.getLaunchActivityType(); 1892 } 1893 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD; 1894 } 1895 1896 /** 1897 * Get next focusable stack in the system. This will search through the stack on the same 1898 * display as the current focused stack, looking for a focusable and visible stack, different 1899 * from the target stack. If no valid candidates will be found, it will then go through all 1900 * displays and stacks in last-focused order. 1901 * 1902 * @param currentFocus The stack that previously had focus. 1903 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next 1904 * candidate. 1905 * @return Next focusable {@link ActivityStack}, {@code null} if not found. 1906 */ getNextFocusableStack(@onNull ActivityStack currentFocus, boolean ignoreCurrent)1907 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus, 1908 boolean ignoreCurrent) { 1909 // First look for next focusable stack on the same display 1910 final ActivityDisplay preferredDisplay = currentFocus.getDisplay(); 1911 final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack( 1912 currentFocus, ignoreCurrent); 1913 if (preferredFocusableStack != null) { 1914 return preferredFocusableStack; 1915 } 1916 if (preferredDisplay.supportsSystemDecorations()) { 1917 // Stop looking for focusable stack on other displays because the preferred display 1918 // supports system decorations. Home activity would be launched on the same display if 1919 // no focusable stack found. 1920 return null; 1921 } 1922 1923 // Now look through all displays 1924 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 1925 final ActivityDisplay display = mActivityDisplays.get(i); 1926 if (display == preferredDisplay) { 1927 // We've already checked this one 1928 continue; 1929 } 1930 final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus, 1931 ignoreCurrent); 1932 if (nextFocusableStack != null) { 1933 return nextFocusableStack; 1934 } 1935 } 1936 1937 return null; 1938 } 1939 1940 /** 1941 * Get next valid stack for launching provided activity in the system. This will search across 1942 * displays and stacks in last-focused order for a focusable and visible stack, except those 1943 * that are on a currently focused display. 1944 * 1945 * @param r The activity that is being launched. 1946 * @param currentFocus The display that previously had focus and thus needs to be ignored when 1947 * searching for the next candidate. 1948 * @return Next valid {@link ActivityStack}, null if not found. 1949 */ getNextValidLaunchStack(@onNull ActivityRecord r, int currentFocus)1950 ActivityStack getNextValidLaunchStack(@NonNull ActivityRecord r, int currentFocus) { 1951 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 1952 final ActivityDisplay display = mActivityDisplays.get(i); 1953 if (display.mDisplayId == currentFocus) { 1954 continue; 1955 } 1956 final ActivityStack stack = getValidLaunchStackOnDisplay(display.mDisplayId, r, 1957 null /* options */, null /* launchParams */); 1958 if (stack != null) { 1959 return stack; 1960 } 1961 } 1962 return null; 1963 } 1964 handleAppDied(WindowProcessController app)1965 boolean handleAppDied(WindowProcessController app) { 1966 boolean hasVisibleActivities = false; 1967 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1968 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1969 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1970 final ActivityStack stack = display.getChildAt(stackNdx); 1971 hasVisibleActivities |= stack.handleAppDiedLocked(app); 1972 } 1973 } 1974 return hasVisibleActivities; 1975 } 1976 closeSystemDialogs()1977 void closeSystemDialogs() { 1978 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1979 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1980 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1981 final ActivityStack stack = display.getChildAt(stackNdx); 1982 stack.closeSystemDialogsLocked(); 1983 } 1984 } 1985 } 1986 1987 /** @return true if some activity was finished (or would have finished if doit were true). */ finishDisabledPackageActivities(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId)1988 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses, 1989 boolean doit, boolean evenPersistent, int userId) { 1990 boolean didSomething = false; 1991 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 1992 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 1993 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 1994 final ActivityStack stack = display.getChildAt(stackNdx); 1995 if (stack.finishDisabledPackageActivitiesLocked( 1996 packageName, filterByClasses, doit, evenPersistent, userId)) { 1997 didSomething = true; 1998 } 1999 } 2000 } 2001 return didSomething; 2002 } 2003 updateActivityApplicationInfo(ApplicationInfo aInfo)2004 void updateActivityApplicationInfo(ApplicationInfo aInfo) { 2005 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2006 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2007 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2008 final ActivityStack stack = display.getChildAt(stackNdx); 2009 stack.updateActivityApplicationInfoLocked(aInfo); 2010 } 2011 } 2012 } 2013 finishVoiceTask(IVoiceInteractionSession session)2014 void finishVoiceTask(IVoiceInteractionSession session) { 2015 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2016 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2017 final int numStacks = display.getChildCount(); 2018 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 2019 final ActivityStack stack = display.getChildAt(stackNdx); 2020 stack.finishVoiceTask(session); 2021 } 2022 } 2023 } 2024 2025 /** 2026 * Removes stacks in the input windowing modes from the system if they are of activity type 2027 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED 2028 */ removeStacksInWindowingModes(int... windowingModes)2029 void removeStacksInWindowingModes(int... windowingModes) { 2030 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 2031 mActivityDisplays.get(i).removeStacksInWindowingModes(windowingModes); 2032 } 2033 } 2034 removeStacksWithActivityTypes(int... activityTypes)2035 void removeStacksWithActivityTypes(int... activityTypes) { 2036 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 2037 mActivityDisplays.get(i).removeStacksWithActivityTypes(activityTypes); 2038 } 2039 } 2040 topRunningActivity()2041 ActivityRecord topRunningActivity() { 2042 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 2043 final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity(); 2044 if (topActivity != null) { 2045 return topActivity; 2046 } 2047 } 2048 return null; 2049 } 2050 allResumedActivitiesIdle()2051 boolean allResumedActivitiesIdle() { 2052 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2053 // TODO(b/117135575): Check resumed activities on all visible stacks. 2054 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2055 if (display.isSleeping()) { 2056 // No resumed activities while display is sleeping. 2057 continue; 2058 } 2059 2060 // If the focused stack is not null or not empty, there should have some activities 2061 // resuming or resumed. Make sure these activities are idle. 2062 final ActivityStack stack = display.getFocusedStack(); 2063 if (stack == null || stack.numActivities() == 0) { 2064 continue; 2065 } 2066 final ActivityRecord resumedActivity = stack.getResumedActivity(); 2067 if (resumedActivity == null || !resumedActivity.idle) { 2068 if (DEBUG_STATES) { 2069 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack=" 2070 + stack.mStackId + " " + resumedActivity + " not idle"); 2071 } 2072 return false; 2073 } 2074 } 2075 // Send launch end powerhint when idle 2076 sendPowerHintForLaunchEndIfNeeded(); 2077 return true; 2078 } 2079 allResumedActivitiesVisible()2080 boolean allResumedActivitiesVisible() { 2081 boolean foundResumed = false; 2082 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2083 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2084 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2085 final ActivityStack stack = display.getChildAt(stackNdx); 2086 final ActivityRecord r = stack.getResumedActivity(); 2087 if (r != null) { 2088 if (!r.nowVisible) { 2089 return false; 2090 } 2091 foundResumed = true; 2092 } 2093 } 2094 } 2095 return foundResumed; 2096 } 2097 allPausedActivitiesComplete()2098 boolean allPausedActivitiesComplete() { 2099 boolean pausing = true; 2100 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2101 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2102 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2103 final ActivityStack stack = display.getChildAt(stackNdx); 2104 final ActivityRecord r = stack.mPausingActivity; 2105 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) { 2106 if (DEBUG_STATES) { 2107 Slog.d(TAG_STATES, 2108 "allPausedActivitiesComplete: r=" + r + " state=" + r.getState()); 2109 pausing = false; 2110 } else { 2111 return false; 2112 } 2113 } 2114 } 2115 } 2116 return pausing; 2117 } 2118 2119 /** 2120 * Find all visible task stacks containing {@param userId} and intercept them with an activity 2121 * to block out the contents and possibly start a credential-confirming intent. 2122 * 2123 * @param userId user handle for the locked managed profile. 2124 */ lockAllProfileTasks(@serIdInt int userId)2125 void lockAllProfileTasks(@UserIdInt int userId) { 2126 mWindowManager.deferSurfaceLayout(); 2127 try { 2128 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2129 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2130 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2131 final ActivityStack stack = display.getChildAt(stackNdx); 2132 final List<TaskRecord> tasks = stack.getAllTasks(); 2133 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) { 2134 final TaskRecord task = tasks.get(taskNdx); 2135 2136 // Check the task for a top activity belonging to userId, or returning a 2137 // result to an activity belonging to userId. Example case: a document 2138 // picker for personal files, opened by a work app, should still get locked. 2139 if (taskTopActivityIsUser(task, userId)) { 2140 mService.getTaskChangeNotificationController().notifyTaskProfileLocked( 2141 task.taskId, userId); 2142 } 2143 } 2144 } 2145 } 2146 } finally { 2147 mWindowManager.continueSurfaceLayout(); 2148 } 2149 } 2150 2151 /** 2152 * Detects whether we should show a lock screen in front of this task for a locked user. 2153 * <p> 2154 * We'll do this if either of the following holds: 2155 * <ul> 2156 * <li>The top activity explicitly belongs to {@param userId}.</li> 2157 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li> 2158 * </ul> 2159 * 2160 * @return {@code true} if the top activity looks like it belongs to {@param userId}. 2161 */ taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId)2162 private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) { 2163 // To handle the case that work app is in the task but just is not the top one. 2164 final ActivityRecord activityRecord = task.getTopActivity(); 2165 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null); 2166 2167 return (activityRecord != null && activityRecord.mUserId == userId) 2168 || (resultTo != null && resultTo.mUserId == userId); 2169 } 2170 cancelInitializingActivities()2171 void cancelInitializingActivities() { 2172 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2173 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2174 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2175 final ActivityStack stack = display.getChildAt(stackNdx); 2176 stack.cancelInitializingActivities(); 2177 } 2178 } 2179 } 2180 anyTaskForId(int id)2181 TaskRecord anyTaskForId(int id) { 2182 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE); 2183 } 2184 anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode)2185 TaskRecord anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode) { 2186 return anyTaskForId(id, matchMode, null, !ON_TOP); 2187 } 2188 2189 /** 2190 * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise. 2191 * @param id Id of the task we would like returned. 2192 * @param matchMode The mode to match the given task id in. 2193 * @param aOptions The activity options to use for restoration. Can be null. 2194 * @param onTop If the stack for the task should be the topmost on the display. 2195 */ anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode, @Nullable ActivityOptions aOptions, boolean onTop)2196 TaskRecord anyTaskForId(int id, @AnyTaskForIdMatchTaskMode int matchMode, 2197 @Nullable ActivityOptions aOptions, boolean onTop) { 2198 // If options are set, ensure that we are attempting to actually restore a task 2199 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) { 2200 throw new IllegalArgumentException("Should not specify activity options for non-restore" 2201 + " lookup"); 2202 } 2203 2204 int numDisplays = mActivityDisplays.size(); 2205 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2206 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2207 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2208 final ActivityStack stack = display.getChildAt(stackNdx); 2209 final TaskRecord task = stack.taskForIdLocked(id); 2210 if (task == null) { 2211 continue; 2212 } 2213 if (aOptions != null) { 2214 // Resolve the stack the task should be placed in now based on options 2215 // and reparent if needed. 2216 final ActivityStack launchStack = 2217 getLaunchStack(null, aOptions, task, onTop); 2218 if (launchStack != null && stack != launchStack) { 2219 final int reparentMode = onTop 2220 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE; 2221 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME, 2222 "anyTaskForId"); 2223 } 2224 } 2225 return task; 2226 } 2227 } 2228 2229 // If we are matching stack tasks only, return now 2230 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) { 2231 return null; 2232 } 2233 2234 // Otherwise, check the recent tasks and return if we find it there and we are not restoring 2235 // the task from recents 2236 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents"); 2237 final TaskRecord task = mStackSupervisor.mRecentTasks.getTask(id); 2238 2239 if (task == null) { 2240 if (DEBUG_RECENTS) { 2241 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents"); 2242 } 2243 2244 return null; 2245 } 2246 2247 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) { 2248 return task; 2249 } 2250 2251 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 2252 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) { 2253 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, 2254 "Couldn't restore task id=" + id + " found in recents"); 2255 return null; 2256 } 2257 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents"); 2258 return task; 2259 } 2260 isInAnyStack(IBinder token)2261 ActivityRecord isInAnyStack(IBinder token) { 2262 int numDisplays = mActivityDisplays.size(); 2263 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2264 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2265 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2266 final ActivityStack stack = display.getChildAt(stackNdx); 2267 final ActivityRecord r = stack.isInStackLocked(token); 2268 if (r != null) { 2269 return r; 2270 } 2271 } 2272 } 2273 return null; 2274 } 2275 2276 @VisibleForTesting getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list, @WindowConfiguration.ActivityType int ignoreActivityType, @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds)2277 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list, 2278 @WindowConfiguration.ActivityType int ignoreActivityType, 2279 @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid, 2280 boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) { 2281 mStackSupervisor.mRunningTasks.getTasks(maxNum, list, ignoreActivityType, 2282 ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser, profileIds); 2283 } 2284 sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity)2285 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) { 2286 boolean sendHint = forceSend; 2287 2288 if (!sendHint) { 2289 // Send power hint if we don't know what we're launching yet 2290 sendHint = targetActivity == null || targetActivity.app == null; 2291 } 2292 2293 if (!sendHint) { // targetActivity != null 2294 // Send power hint when the activity's process is different than the current resumed 2295 // activity on all displays, or if there are no resumed activities in the system. 2296 boolean noResumedActivities = true; 2297 boolean allFocusedProcessesDiffer = true; 2298 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2299 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx); 2300 final ActivityRecord resumedActivity = activityDisplay.getResumedActivity(); 2301 final WindowProcessController resumedActivityProcess = 2302 resumedActivity == null ? null : resumedActivity.app; 2303 2304 noResumedActivities &= resumedActivityProcess == null; 2305 if (resumedActivityProcess != null) { 2306 allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app); 2307 } 2308 } 2309 sendHint = noResumedActivities || allFocusedProcessesDiffer; 2310 } 2311 2312 if (sendHint && mService.mPowerManagerInternal != null) { 2313 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1); 2314 mPowerHintSent = true; 2315 } 2316 } 2317 sendPowerHintForLaunchEndIfNeeded()2318 void sendPowerHintForLaunchEndIfNeeded() { 2319 // Trigger launch power hint if activity is launched 2320 if (mPowerHintSent && mService.mPowerManagerInternal != null) { 2321 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0); 2322 mPowerHintSent = false; 2323 } 2324 } 2325 calculateDefaultMinimalSizeOfResizeableTasks()2326 private void calculateDefaultMinimalSizeOfResizeableTasks() { 2327 final Resources res = mService.mContext.getResources(); 2328 final float minimalSize = res.getDimension( 2329 com.android.internal.R.dimen.default_minimal_size_resizable_task); 2330 final DisplayMetrics dm = res.getDisplayMetrics(); 2331 2332 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density); 2333 } 2334 2335 /** 2336 * Dumps the activities matching the given {@param name} in the either the focused stack 2337 * or all visible stacks if {@param dumpVisibleStacks} is true. 2338 */ getDumpActivities(String name, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly)2339 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly, 2340 boolean dumpFocusedStackOnly) { 2341 if (dumpFocusedStackOnly) { 2342 return getTopDisplayFocusedStack().getDumpActivitiesLocked(name); 2343 } else { 2344 ArrayList<ActivityRecord> activities = new ArrayList<>(); 2345 int numDisplays = mActivityDisplays.size(); 2346 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2347 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2348 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2349 final ActivityStack stack = display.getChildAt(stackNdx); 2350 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) { 2351 activities.addAll(stack.getDumpActivitiesLocked(name)); 2352 } 2353 } 2354 } 2355 return activities; 2356 } 2357 } 2358 dump(PrintWriter pw, String prefix)2359 public void dump(PrintWriter pw, String prefix) { 2360 pw.print(prefix); 2361 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack()); 2362 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 2363 final ActivityDisplay display = mActivityDisplays.get(i); 2364 display.dump(pw, prefix); 2365 } 2366 } 2367 2368 /** 2369 * Dump all connected displays' configurations. 2370 * @param prefix Prefix to apply to each line of the dump. 2371 */ dumpDisplayConfigs(PrintWriter pw, String prefix)2372 void dumpDisplayConfigs(PrintWriter pw, String prefix) { 2373 pw.print(prefix); pw.println("Display override configurations:"); 2374 final int displayCount = mActivityDisplays.size(); 2375 for (int i = 0; i < displayCount; i++) { 2376 final ActivityDisplay activityDisplay = mActivityDisplays.get(i); 2377 pw.print(prefix); pw.print(" "); pw.print(activityDisplay.mDisplayId); pw.print(": "); 2378 pw.println(activityDisplay.getRequestedOverrideConfiguration()); 2379 } 2380 } 2381 dumpDisplays(PrintWriter pw)2382 public void dumpDisplays(PrintWriter pw) { 2383 for (int i = mActivityDisplays.size() - 1; i >= 0; --i) { 2384 final ActivityDisplay display = mActivityDisplays.get(i); 2385 pw.print("[id:" + display.mDisplayId + " stacks:"); 2386 display.dumpStacks(pw); 2387 pw.print("]"); 2388 } 2389 } 2390 dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage)2391 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, 2392 String dumpPackage) { 2393 boolean printed = false; 2394 boolean needSep = false; 2395 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { 2396 ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx); 2397 pw.print("Display #"); pw.print(activityDisplay.mDisplayId); 2398 pw.println(" (activities from top to bottom):"); 2399 final ActivityDisplay display = mActivityDisplays.get(displayNdx); 2400 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 2401 final ActivityStack stack = display.getChildAt(stackNdx); 2402 pw.println(); 2403 printed = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, needSep); 2404 needSep = printed; 2405 } 2406 printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep, 2407 " ResumedActivity:"); 2408 } 2409 2410 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ", 2411 "Fin", false, !dumpAll, 2412 false, dumpPackage, true, " Activities waiting to finish:", null); 2413 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ", 2414 "Stop", false, !dumpAll, 2415 false, dumpPackage, true, " Activities waiting to stop:", null); 2416 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities, 2417 " ", "Sleep", false, !dumpAll, 2418 false, dumpPackage, true, " Activities waiting to sleep:", null); 2419 2420 return printed; 2421 } 2422 writeToProto(ProtoOutputStream proto, long fieldId, @WindowTraceLogLevel int logLevel)2423 protected void writeToProto(ProtoOutputStream proto, long fieldId, 2424 @WindowTraceLogLevel int logLevel) { 2425 final long token = proto.start(fieldId); 2426 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel); 2427 for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { 2428 final ActivityDisplay activityDisplay = mActivityDisplays.get(displayNdx); 2429 activityDisplay.writeToProto(proto, DISPLAYS, logLevel); 2430 } 2431 mStackSupervisor.getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER); 2432 // TODO(b/111541062): Update tests to look for resumed activities on all displays 2433 final ActivityStack focusedStack = getTopDisplayFocusedStack(); 2434 if (focusedStack != null) { 2435 proto.write(FOCUSED_STACK_ID, focusedStack.mStackId); 2436 final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity(); 2437 if (focusedActivity != null) { 2438 focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY); 2439 } 2440 } else { 2441 proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID); 2442 } 2443 proto.write(IS_HOME_RECENTS_COMPONENT, 2444 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser)); 2445 mService.getActivityStartController().writeToProto(proto, PENDING_ACTIVITIES); 2446 proto.end(token); 2447 } 2448 2449 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken { 2450 private final String mTag; 2451 private final long mAcquireTime; 2452 private final int mDisplayId; 2453 SleepTokenImpl(String tag, int displayId)2454 public SleepTokenImpl(String tag, int displayId) { 2455 mTag = tag; 2456 mDisplayId = displayId; 2457 mAcquireTime = SystemClock.uptimeMillis(); 2458 } 2459 2460 @Override release()2461 public void release() { 2462 synchronized (mService.mGlobalLock) { 2463 removeSleepToken(this); 2464 } 2465 } 2466 2467 @Override toString()2468 public String toString() { 2469 return "{\"" + mTag + "\", display " + mDisplayId 2470 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}"; 2471 } 2472 } 2473 } 2474