1 /* 2 * Copyright (C) 2016 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_TASK_ID; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; 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_OR_SPLIT_SCREEN_SECONDARY; 27 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 28 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; 29 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 30 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 31 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; 32 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; 33 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 34 import static android.view.Display.DEFAULT_DISPLAY; 35 import static android.view.Display.INVALID_DISPLAY; 36 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 37 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE; 38 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; 39 import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; 40 import static android.view.WindowManager.TRANSIT_NONE; 41 import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY; 42 43 import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST; 44 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; 45 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 46 import static com.android.server.wm.ActivityStack.ActivityState.FINISHING; 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.dumpHistoryList; 54 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; 55 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; 56 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK; 57 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES; 58 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; 59 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS; 60 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS; 61 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE; 62 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES; 63 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS; 64 import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; 65 import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH; 66 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; 67 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON; 68 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; 69 import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; 70 import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; 71 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; 72 import static com.android.server.wm.RootWindowContainerProto.IS_HOME_RECENTS_COMPONENT; 73 import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER; 74 import static com.android.server.wm.RootWindowContainerProto.PENDING_ACTIVITIES; 75 import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER; 76 import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE; 77 import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT; 78 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; 79 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; 80 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; 81 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; 82 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 83 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 84 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT; 85 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; 86 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES; 87 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; 88 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE; 89 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; 90 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION; 91 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING; 92 93 import static java.lang.Integer.MAX_VALUE; 94 95 import android.annotation.IntDef; 96 import android.annotation.NonNull; 97 import android.annotation.Nullable; 98 import android.annotation.UserIdInt; 99 import android.app.ActivityManager; 100 import android.app.ActivityOptions; 101 import android.app.AppGlobals; 102 import android.app.WindowConfiguration; 103 import android.content.ComponentName; 104 import android.content.Context; 105 import android.content.Intent; 106 import android.content.pm.ActivityInfo; 107 import android.content.pm.ApplicationInfo; 108 import android.content.pm.ResolveInfo; 109 import android.content.res.Configuration; 110 import android.content.res.Resources; 111 import android.graphics.Rect; 112 import android.hardware.display.DisplayManager; 113 import android.hardware.display.DisplayManagerInternal; 114 import android.hardware.power.V1_0.PowerHint; 115 import android.net.Uri; 116 import android.os.Binder; 117 import android.os.Debug; 118 import android.os.FactoryTest; 119 import android.os.Handler; 120 import android.os.IBinder; 121 import android.os.Looper; 122 import android.os.Message; 123 import android.os.PowerManager; 124 import android.os.RemoteException; 125 import android.os.SystemClock; 126 import android.os.Trace; 127 import android.os.UserHandle; 128 import android.os.storage.StorageManager; 129 import android.provider.Settings; 130 import android.service.voice.IVoiceInteractionSession; 131 import android.util.ArraySet; 132 import android.util.DisplayMetrics; 133 import android.util.IntArray; 134 import android.util.Pair; 135 import android.util.Slog; 136 import android.util.SparseArray; 137 import android.util.SparseIntArray; 138 import android.util.TimeUtils; 139 import android.util.proto.ProtoOutputStream; 140 import android.view.Display; 141 import android.view.DisplayInfo; 142 import android.view.SurfaceControl; 143 import android.view.WindowManager; 144 import android.window.WindowContainerToken; 145 146 import com.android.internal.annotations.VisibleForTesting; 147 import com.android.internal.app.ResolverActivity; 148 import com.android.internal.util.function.pooled.PooledConsumer; 149 import com.android.internal.util.function.pooled.PooledFunction; 150 import com.android.internal.util.function.pooled.PooledLambda; 151 import com.android.internal.util.function.pooled.PooledPredicate; 152 import com.android.server.LocalServices; 153 import com.android.server.am.ActivityManagerService; 154 import com.android.server.am.AppTimeTracker; 155 import com.android.server.am.UserState; 156 import com.android.server.policy.WindowManagerPolicy; 157 import com.android.server.protolog.common.ProtoLog; 158 159 import java.io.FileDescriptor; 160 import java.io.PrintWriter; 161 import java.lang.annotation.Retention; 162 import java.lang.annotation.RetentionPolicy; 163 import java.util.ArrayList; 164 import java.util.HashMap; 165 import java.util.List; 166 import java.util.Objects; 167 import java.util.Set; 168 import java.util.function.Consumer; 169 import java.util.function.Function; 170 171 /** Root {@link WindowContainer} for the device. */ 172 class RootWindowContainer extends WindowContainer<DisplayContent> 173 implements DisplayManager.DisplayListener { 174 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM; 175 176 private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1; 177 private static final int SET_USER_ACTIVITY_TIMEOUT = 2; 178 static final String TAG_TASKS = TAG + POSTFIX_TASKS; 179 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; 180 static final String TAG_STATES = TAG + POSTFIX_STATES; 181 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 182 183 private Object mLastWindowFreezeSource = null; 184 private Session mHoldScreen = null; 185 private float mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT; 186 private long mUserActivityTimeout = -1; 187 private boolean mUpdateRotation = false; 188 // Following variables are for debugging screen wakelock only. 189 // Last window that requires screen wakelock 190 WindowState mHoldScreenWindow = null; 191 // Last window that obscures all windows below 192 WindowState mObscuringWindow = null; 193 // Only set while traversing the default display based on its content. 194 // Affects the behavior of mirroring on secondary displays. 195 private boolean mObscureApplicationContentOnSecondaryDisplays = false; 196 197 private boolean mSustainedPerformanceModeEnabled = false; 198 private boolean mSustainedPerformanceModeCurrent = false; 199 200 // During an orientation change, we track whether all windows have rendered 201 // at the new orientation, and this will be false from changing orientation until that occurs. 202 // For seamless rotation cases this always stays true, as the windows complete their orientation 203 // changes 1 by 1 without disturbing global state. 204 boolean mOrientationChangeComplete = true; 205 boolean mWallpaperActionPending = false; 206 207 private final Handler mHandler; 208 209 private String mCloseSystemDialogsReason; 210 211 // The ID of the display which is responsible for receiving display-unspecified key and pointer 212 // events. 213 private int mTopFocusedDisplayId = INVALID_DISPLAY; 214 215 // Map from the PID to the top most app which has a focused window of the process. 216 final HashMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new HashMap<>(); 217 218 // Only a separate transaction until we separate the apply surface changes 219 // transaction from the global transaction. 220 private final SurfaceControl.Transaction mDisplayTransaction; 221 222 /** 223 * The modes which affect which tasks are returned when calling 224 * {@link RootWindowContainer#anyTaskForId(int)}. 225 */ 226 @Retention(RetentionPolicy.SOURCE) 227 @IntDef({ 228 MATCH_TASK_IN_STACKS_ONLY, 229 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, 230 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 231 }) 232 public @interface AnyTaskForIdMatchTaskMode {} 233 // Match only tasks in the current stacks 234 static final int MATCH_TASK_IN_STACKS_ONLY = 0; 235 // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks 236 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1; 237 // Match either tasks in the current stacks, or in the recent tasks, restoring it to the 238 // provided stack id 239 static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2; 240 241 ActivityTaskManagerService mService; 242 ActivityStackSupervisor mStackSupervisor; 243 WindowManagerService mWindowManager; 244 DisplayManager mDisplayManager; 245 private DisplayManagerInternal mDisplayManagerInternal; 246 247 /** Reference to default display so we can quickly look it up. */ 248 private DisplayContent mDefaultDisplay; 249 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 250 251 /** The current user */ 252 int mCurrentUser; 253 /** Stack id of the front stack when user switched, indexed by userId. */ 254 SparseIntArray mUserStackInFront = new SparseIntArray(2); 255 256 /** 257 * A list of tokens that cause the top activity to be put to sleep. 258 * They are used by components that may hide and block interaction with underlying 259 * activities. 260 */ 261 final ArrayList<ActivityTaskManagerInternal.SleepToken> mSleepTokens = new ArrayList<>(); 262 263 /** Set when a power hint has started, but not ended. */ 264 private boolean mPowerHintSent; 265 266 // The default minimal size that will be used if the activity doesn't specify its minimal size. 267 // It will be calculated when the default display gets added. 268 int mDefaultMinSizeOfResizeableTaskDp = -1; 269 270 // Whether tasks have moved and we need to rank the tasks before next OOM scoring 271 private boolean mTaskLayersChanged = true; 272 private int mTmpTaskLayerRank; 273 274 private boolean mTmpBoolean; 275 private RemoteException mTmpRemoteException; 276 277 private String mDestroyAllActivitiesReason; 278 private final Runnable mDestroyAllActivitiesRunnable = new Runnable() { 279 @Override 280 public void run() { 281 synchronized (mService.mGlobalLock) { 282 try { 283 mStackSupervisor.beginDeferResume(); 284 285 final PooledConsumer c = PooledLambda.obtainConsumer( 286 RootWindowContainer::destroyActivity, RootWindowContainer.this, 287 PooledLambda.__(ActivityRecord.class)); 288 forAllActivities(c); 289 c.recycle(); 290 } finally { 291 mStackSupervisor.endDeferResume(); 292 resumeFocusedStacksTopActivities(); 293 } 294 } 295 } 296 297 }; 298 299 private final FindTaskResult mTmpFindTaskResult = new FindTaskResult(); 300 static class FindTaskResult implements Function<Task, Boolean> { 301 ActivityRecord mRecord; 302 boolean mIdealMatch; 303 304 private ActivityRecord mTarget; 305 private Intent intent; 306 private ActivityInfo info; 307 private ComponentName cls; 308 private int userId; 309 private boolean isDocument; 310 private Uri documentData; 311 312 /** 313 * Returns the top activity in any existing task matching the given Intent in the input 314 * result. Returns null if no such task is found. 315 */ process(ActivityRecord target, ActivityStack parent)316 void process(ActivityRecord target, ActivityStack parent) { 317 mTarget = target; 318 319 intent = target.intent; 320 info = target.info; 321 cls = intent.getComponent(); 322 if (info.targetActivity != null) { 323 cls = new ComponentName(info.packageName, info.targetActivity); 324 } 325 userId = UserHandle.getUserId(info.applicationInfo.uid); 326 isDocument = intent != null & intent.isDocument(); 327 // If documentData is non-null then it must match the existing task data. 328 documentData = isDocument ? intent.getData() : null; 329 330 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent); 331 parent.forAllLeafTasks(this); 332 } 333 clear()334 void clear() { 335 mRecord = null; 336 mIdealMatch = false; 337 } 338 setTo(FindTaskResult result)339 void setTo(FindTaskResult result) { 340 mRecord = result.mRecord; 341 mIdealMatch = result.mIdealMatch; 342 } 343 344 @Override apply(Task task)345 public Boolean apply(Task task) { 346 if (task.voiceSession != null) { 347 // We never match voice sessions; those always run independently. 348 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session"); 349 return false; 350 } 351 if (task.mUserId != userId) { 352 // Looking for a different task. 353 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": different user"); 354 return false; 355 } 356 357 // Overlays should not be considered as the task's logical top activity. 358 final ActivityRecord r = task.getTopNonFinishingActivity(false /* includeOverlays */); 359 if (r == null || r.finishing || r.mUserId != userId 360 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 361 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r); 362 return false; 363 } 364 if (!r.hasCompatibleActivityType(mTarget)) { 365 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type"); 366 return false; 367 } 368 369 final Intent taskIntent = task.intent; 370 final Intent affinityIntent = task.affinityIntent; 371 final boolean taskIsDocument; 372 final Uri taskDocumentData; 373 if (taskIntent != null && taskIntent.isDocument()) { 374 taskIsDocument = true; 375 taskDocumentData = taskIntent.getData(); 376 } else if (affinityIntent != null && affinityIntent.isDocument()) { 377 taskIsDocument = true; 378 taskDocumentData = affinityIntent.getData(); 379 } else { 380 taskIsDocument = false; 381 taskDocumentData = null; 382 } 383 384 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls=" 385 + (task.realActivity != null ? task.realActivity.flattenToShortString() : "") 386 + "/aff=" + r.getTask().rootAffinity + " to new cls=" 387 + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity); 388 // TODO Refactor to remove duplications. Check if logic can be simplified. 389 if (task.realActivity != null && task.realActivity.compareTo(cls) == 0 390 && Objects.equals(documentData, taskDocumentData)) { 391 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!"); 392 //dump(); 393 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 394 "For Intent " + intent + " bringing to top: " + r.intent); 395 mRecord = r; 396 mIdealMatch = true; 397 return true; 398 } else if (affinityIntent != null && affinityIntent.getComponent() != null 399 && affinityIntent.getComponent().compareTo(cls) == 0 && 400 Objects.equals(documentData, taskDocumentData)) { 401 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!"); 402 if (DEBUG_TASKS) Slog.d(TAG_TASKS, 403 "For Intent " + intent + " bringing to top: " + r.intent); 404 mRecord = r; 405 mIdealMatch = true; 406 return true; 407 } else if (!isDocument && !taskIsDocument 408 && mRecord == null && task.rootAffinity != null) { 409 if (task.rootAffinity.equals(mTarget.taskAffinity)) { 410 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching affinity candidate!"); 411 // It is possible for multiple tasks to have the same root affinity especially 412 // if they are in separate stacks. We save off this candidate, but keep looking 413 // to see if there is a better candidate. 414 mRecord = r; 415 mIdealMatch = false; 416 } 417 } else if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Not a match: " + task); 418 419 return false; 420 } 421 } 422 423 private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> { 424 if (w.mHasSurface) { 425 try { 426 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason); 427 } catch (RemoteException e) { 428 } 429 } 430 }; 431 432 private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> { 433 final ActivityRecord activity = w.mActivityRecord; 434 if (activity != null) { 435 activity.removeReplacedWindowIfNeeded(w); 436 } 437 }; 438 RootWindowContainer(WindowManagerService service)439 RootWindowContainer(WindowManagerService service) { 440 super(service); 441 mDisplayTransaction = service.mTransactionFactory.get(); 442 mHandler = new MyHandler(service.mH.getLooper()); 443 mService = service.mAtmService; 444 mStackSupervisor = mService.mStackSupervisor; 445 mStackSupervisor.mRootWindowContainer = this; 446 } 447 updateFocusedWindowLocked(int mode, boolean updateInputWindows)448 boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) { 449 mTopFocusedAppByProcess.clear(); 450 boolean changed = false; 451 int topFocusedDisplayId = INVALID_DISPLAY; 452 for (int i = mChildren.size() - 1; i >= 0; --i) { 453 final DisplayContent dc = mChildren.get(i); 454 changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId); 455 final WindowState newFocus = dc.mCurrentFocus; 456 if (newFocus != null) { 457 final int pidOfNewFocus = newFocus.mSession.mPid; 458 if (mTopFocusedAppByProcess.get(pidOfNewFocus) == null) { 459 mTopFocusedAppByProcess.put(pidOfNewFocus, newFocus.mActivityRecord); 460 } 461 if (topFocusedDisplayId == INVALID_DISPLAY) { 462 topFocusedDisplayId = dc.getDisplayId(); 463 } 464 } else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) { 465 // The top-most display that has a focused app should still be the top focused 466 // display even when the app window is not ready yet (process not attached or 467 // window not added yet). 468 topFocusedDisplayId = dc.getDisplayId(); 469 } 470 } 471 if (topFocusedDisplayId == INVALID_DISPLAY) { 472 topFocusedDisplayId = DEFAULT_DISPLAY; 473 } 474 if (mTopFocusedDisplayId != topFocusedDisplayId) { 475 mTopFocusedDisplayId = topFocusedDisplayId; 476 mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId); 477 mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId); 478 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d", 479 topFocusedDisplayId); 480 } 481 return changed; 482 } 483 getTopFocusedDisplayContent()484 DisplayContent getTopFocusedDisplayContent() { 485 final DisplayContent dc = getDisplayContent(mTopFocusedDisplayId); 486 return dc != null ? dc : getDisplayContent(DEFAULT_DISPLAY); 487 } 488 489 @Override isOnTop()490 boolean isOnTop() { 491 // Considered always on top 492 return true; 493 } 494 495 @Override onChildPositionChanged(WindowContainer child)496 void onChildPositionChanged(WindowContainer child) { 497 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, 498 !mWmService.mPerDisplayFocusEnabled /* updateInputWindows */); 499 } 500 501 /** 502 * Called when DisplayWindowSettings values may change. 503 */ onSettingsRetrieved()504 void onSettingsRetrieved() { 505 final int numDisplays = mChildren.size(); 506 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 507 final DisplayContent displayContent = mChildren.get(displayNdx); 508 final boolean changed = mWmService.mDisplayWindowSettings.updateSettingsForDisplay( 509 displayContent); 510 if (!changed) { 511 continue; 512 } 513 514 displayContent.reconfigureDisplayLocked(); 515 516 // We need to update global configuration as well if config of default display has 517 // changed. Do it inline because ATMS#retrieveSettings() will soon update the 518 // configuration inline, which will overwrite the new windowing mode. 519 if (displayContent.isDefaultDisplay) { 520 final Configuration newConfig = mWmService.computeNewConfiguration( 521 displayContent.getDisplayId()); 522 mWmService.mAtmService.updateConfigurationLocked(newConfig, null /* starting */, 523 false /* initLocale */); 524 } 525 } 526 } 527 isLayoutNeeded()528 boolean isLayoutNeeded() { 529 final int numDisplays = mChildren.size(); 530 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 531 final DisplayContent displayContent = mChildren.get(displayNdx); 532 if (displayContent.isLayoutNeeded()) { 533 return true; 534 } 535 } 536 return false; 537 } 538 getWindowsByName(ArrayList<WindowState> output, String name)539 void getWindowsByName(ArrayList<WindowState> output, String name) { 540 int objectId = 0; 541 // See if this is an object ID. 542 try { 543 objectId = Integer.parseInt(name, 16); 544 name = null; 545 } catch (RuntimeException e) { 546 } 547 548 getWindowsByName(output, name, objectId); 549 } 550 getWindowsByName(ArrayList<WindowState> output, String name, int objectId)551 private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) { 552 forAllWindows((w) -> { 553 if (name != null) { 554 if (w.mAttrs.getTitle().toString().contains(name)) { 555 output.add(w); 556 } 557 } else if (System.identityHashCode(w) == objectId) { 558 output.add(w); 559 } 560 }, true /* traverseTopToBottom */); 561 } 562 563 /** 564 * Returns {@code true} if the callingUid has any non-toast window currently visible to the 565 * user. Also ignores {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_STARTING}, 566 * since those windows don't belong to apps. 567 * @see WindowState#isNonToastOrStarting() 568 */ isAnyNonToastWindowVisibleForUid(int callingUid)569 boolean isAnyNonToastWindowVisibleForUid(int callingUid) { 570 final PooledPredicate p = PooledLambda.obtainPredicate( 571 WindowState::isNonToastWindowVisibleForUid, 572 PooledLambda.__(WindowState.class), callingUid); 573 574 final WindowState w = getWindow(p); 575 p.recycle(); 576 return w != null; 577 } 578 579 /** 580 * Returns the app window token for the input binder if it exist in the system. 581 * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since 582 * AppWindowToken represents an activity which can only exist on one display. 583 */ getActivityRecord(IBinder binder)584 ActivityRecord getActivityRecord(IBinder binder) { 585 for (int i = mChildren.size() - 1; i >= 0; --i) { 586 final DisplayContent dc = mChildren.get(i); 587 final ActivityRecord activity = dc.getActivityRecord(binder); 588 if (activity != null) { 589 return activity; 590 } 591 } 592 return null; 593 } 594 595 /** Returns the window token for the input binder if it exist in the system. */ getWindowToken(IBinder binder)596 WindowToken getWindowToken(IBinder binder) { 597 for (int i = mChildren.size() - 1; i >= 0; --i) { 598 final DisplayContent dc = mChildren.get(i); 599 final WindowToken wtoken = dc.getWindowToken(binder); 600 if (wtoken != null) { 601 return wtoken; 602 } 603 } 604 return null; 605 } 606 607 /** Returns the display object the input window token is currently mapped on. */ getWindowTokenDisplay(WindowToken token)608 DisplayContent getWindowTokenDisplay(WindowToken token) { 609 if (token == null) { 610 return null; 611 } 612 613 for (int i = mChildren.size() - 1; i >= 0; --i) { 614 final DisplayContent dc = mChildren.get(i); 615 final WindowToken current = dc.getWindowToken(token.token); 616 if (current == token) { 617 return dc; 618 } 619 } 620 621 return null; 622 } 623 624 /** 625 * Set new display override config. If called for the default display, global configuration 626 * will also be updated. 627 */ setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, @NonNull DisplayContent displayContent)628 void setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, 629 @NonNull DisplayContent displayContent) { 630 631 final Configuration currentConfig = displayContent.getRequestedOverrideConfiguration(); 632 final boolean configChanged = currentConfig.diff(newConfiguration) != 0; 633 if (!configChanged) { 634 return; 635 } 636 637 displayContent.onRequestedOverrideConfigurationChanged(newConfiguration); 638 639 if (displayContent.getDisplayId() == DEFAULT_DISPLAY) { 640 // Override configuration of the default display duplicates global config. In this case 641 // we also want to update the global config. 642 setGlobalConfigurationIfNeeded(newConfiguration); 643 } 644 } 645 setGlobalConfigurationIfNeeded(Configuration newConfiguration)646 private void setGlobalConfigurationIfNeeded(Configuration newConfiguration) { 647 final boolean configChanged = getConfiguration().diff(newConfiguration) != 0; 648 if (!configChanged) { 649 return; 650 } 651 onConfigurationChanged(newConfiguration); 652 } 653 654 @Override onConfigurationChanged(Configuration newParentConfig)655 public void onConfigurationChanged(Configuration newParentConfig) { 656 prepareFreezingTaskBounds(); 657 super.onConfigurationChanged(newParentConfig); 658 } 659 prepareFreezingTaskBounds()660 private void prepareFreezingTaskBounds() { 661 for (int i = mChildren.size() - 1; i >= 0; i--) { 662 mChildren.get(i).prepareFreezingTaskBounds(); 663 } 664 } 665 setSecureSurfaceState(int userId)666 void setSecureSurfaceState(int userId) { 667 forAllWindows((w) -> { 668 if (w.mHasSurface && userId == w.mShowUserId) { 669 w.mWinAnimator.setSecureLocked(w.isSecureLocked()); 670 } 671 }, true /* traverseTopToBottom */); 672 } 673 updateHiddenWhileSuspendedState(final ArraySet<String> packages, final boolean suspended)674 void updateHiddenWhileSuspendedState(final ArraySet<String> packages, final boolean suspended) { 675 forAllWindows((w) -> { 676 if (packages.contains(w.getOwningPackage())) { 677 w.setHiddenWhileSuspended(suspended); 678 } 679 }, false); 680 } 681 updateAppOpsState()682 void updateAppOpsState() { 683 forAllWindows((w) -> { 684 w.updateAppOpsState(); 685 }, false /* traverseTopToBottom */); 686 } 687 canShowStrictModeViolation(int pid)688 boolean canShowStrictModeViolation(int pid) { 689 final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw()); 690 return win != null; 691 } 692 closeSystemDialogs(String reason)693 void closeSystemDialogs(String reason) { 694 mCloseSystemDialogsReason = reason; 695 forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */); 696 } 697 removeReplacedWindows()698 void removeReplacedWindows() { 699 ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION removeReplacedWindows"); 700 mWmService.openSurfaceTransaction(); 701 try { 702 forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */); 703 } finally { 704 mWmService.closeSurfaceTransaction("removeReplacedWindows"); 705 ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION removeReplacedWindows"); 706 } 707 } 708 hasPendingLayoutChanges(WindowAnimator animator)709 boolean hasPendingLayoutChanges(WindowAnimator animator) { 710 boolean hasChanges = false; 711 712 final int count = mChildren.size(); 713 for (int i = 0; i < count; ++i) { 714 final int pendingChanges = mChildren.get(i).pendingLayoutChanges; 715 if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) { 716 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING; 717 } 718 if (pendingChanges != 0) { 719 hasChanges = true; 720 } 721 } 722 723 return hasChanges; 724 } 725 reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation, boolean secure)726 boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation, 727 boolean secure) { 728 final WindowSurfaceController surfaceController = winAnimator.mSurfaceController; 729 boolean leakedSurface = false; 730 boolean killedApps = false; 731 EventLogTags.writeWmNoSurfaceMemory(winAnimator.mWin.toString(), 732 winAnimator.mSession.mPid, operation); 733 final long callingIdentity = Binder.clearCallingIdentity(); 734 try { 735 // There was some problem...first, do a sanity check of the window list to make sure 736 // we haven't left any dangling surfaces around. 737 738 Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks..."); 739 final int numDisplays = mChildren.size(); 740 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 741 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces(); 742 } 743 744 if (!leakedSurface) { 745 Slog.w(TAG_WM, "No leaked surfaces; killing applications!"); 746 final SparseIntArray pidCandidates = new SparseIntArray(); 747 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 748 mChildren.get(displayNdx).forAllWindows((w) -> { 749 if (mWmService.mForceRemoves.contains(w)) { 750 return; 751 } 752 final WindowStateAnimator wsa = w.mWinAnimator; 753 if (wsa.mSurfaceController != null) { 754 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid); 755 } 756 }, false /* traverseTopToBottom */); 757 758 if (pidCandidates.size() > 0) { 759 int[] pids = new int[pidCandidates.size()]; 760 for (int i = 0; i < pids.length; i++) { 761 pids[i] = pidCandidates.keyAt(i); 762 } 763 try { 764 if (mWmService.mActivityManager.killPids(pids, "Free memory", secure)) { 765 killedApps = true; 766 } 767 } catch (RemoteException e) { 768 } 769 } 770 } 771 } 772 773 if (leakedSurface || killedApps) { 774 // We managed to reclaim some memory, so get rid of the trouble surface and ask the 775 // app to request another one. 776 Slog.w(TAG_WM, 777 "Looks like we have reclaimed some memory, clearing surface for retry."); 778 if (surfaceController != null) { 779 ProtoLog.i(WM_SHOW_SURFACE_ALLOC, 780 "SURFACE RECOVER DESTROY: %s", winAnimator.mWin); 781 winAnimator.destroySurface(); 782 if (winAnimator.mWin.mActivityRecord != null) { 783 winAnimator.mWin.mActivityRecord.removeStartingWindow(); 784 } 785 } 786 787 try { 788 winAnimator.mWin.mClient.dispatchGetNewSurface(); 789 } catch (RemoteException e) { 790 } 791 } 792 } finally { 793 Binder.restoreCallingIdentity(callingIdentity); 794 } 795 796 return leakedSurface || killedApps; 797 } 798 performSurfacePlacement()799 void performSurfacePlacement() { 800 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement"); 801 try { 802 performSurfacePlacementNoTrace(); 803 } finally { 804 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 805 } 806 } 807 808 // "Something has changed! Let's make it correct now." 809 // TODO: Super crazy long method that should be broken down... performSurfacePlacementNoTrace()810 void performSurfacePlacementNoTrace() { 811 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by " 812 + Debug.getCallers(3)); 813 814 int i; 815 816 if (mWmService.mFocusMayChange) { 817 mWmService.mFocusMayChange = false; 818 mWmService.updateFocusedWindowLocked( 819 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); 820 } 821 822 // Initialize state of exiting tokens. 823 final int numDisplays = mChildren.size(); 824 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 825 final DisplayContent displayContent = mChildren.get(displayNdx); 826 displayContent.setExitingTokensHasVisible(false); 827 } 828 829 mHoldScreen = null; 830 mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT; 831 mUserActivityTimeout = -1; 832 mObscureApplicationContentOnSecondaryDisplays = false; 833 mSustainedPerformanceModeCurrent = false; 834 mWmService.mTransactionSequence++; 835 836 // TODO(multi-display): recents animation & wallpaper need support multi-display. 837 final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked(); 838 final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked; 839 840 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 841 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); 842 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges"); 843 mWmService.openSurfaceTransaction(); 844 try { 845 applySurfaceChangesTransaction(); 846 } catch (RuntimeException e) { 847 Slog.wtf(TAG, "Unhandled exception in Window Manager", e); 848 } finally { 849 mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces"); 850 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 851 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 852 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); 853 } 854 mWmService.mAnimator.executeAfterPrepareSurfacesRunnables(); 855 856 checkAppTransitionReady(surfacePlacer); 857 858 // Defer starting the recents animation until the wallpaper has drawn 859 final RecentsAnimationController recentsAnimationController = 860 mWmService.getRecentsAnimationController(); 861 if (recentsAnimationController != null) { 862 recentsAnimationController.checkAnimationReady(defaultDisplay.mWallpaperController); 863 } 864 865 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 866 final DisplayContent displayContent = mChildren.get(displayNdx); 867 if (displayContent.mWallpaperMayChange) { 868 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting"); 869 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 870 if (DEBUG_LAYOUT_REPEATS) { 871 surfacePlacer.debugLayoutRepeats("WallpaperMayChange", 872 displayContent.pendingLayoutChanges); 873 } 874 } 875 } 876 877 if (mWmService.mFocusMayChange) { 878 mWmService.mFocusMayChange = false; 879 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, 880 false /*updateInputWindows*/); 881 } 882 883 if (isLayoutNeeded()) { 884 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT; 885 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded", 886 defaultDisplay.pendingLayoutChanges); 887 } 888 889 handleResizingWindows(); 890 891 if (mWmService.mDisplayFrozen) { 892 ProtoLog.v(WM_DEBUG_ORIENTATION, 893 "With display frozen, orientationChangeComplete=%b", 894 mOrientationChangeComplete); 895 } 896 if (mOrientationChangeComplete) { 897 if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) { 898 mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE; 899 mWmService.mLastFinishedFreezeSource = mLastWindowFreezeSource; 900 mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT); 901 } 902 mWmService.stopFreezingDisplayLocked(); 903 } 904 905 // Destroy the surface of any windows that are no longer visible. 906 i = mWmService.mDestroySurface.size(); 907 if (i > 0) { 908 do { 909 i--; 910 WindowState win = mWmService.mDestroySurface.get(i); 911 win.mDestroying = false; 912 final DisplayContent displayContent = win.getDisplayContent(); 913 if (displayContent.mInputMethodWindow == win) { 914 displayContent.setInputMethodWindowLocked(null); 915 } 916 if (displayContent.mWallpaperController.isWallpaperTarget(win)) { 917 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 918 } 919 win.destroySurfaceUnchecked(); 920 win.mWinAnimator.destroyPreservedSurfaceLocked(); 921 } while (i > 0); 922 mWmService.mDestroySurface.clear(); 923 } 924 925 // Time to remove any exiting tokens? 926 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 927 final DisplayContent displayContent = mChildren.get(displayNdx); 928 displayContent.removeExistingTokensIfPossible(); 929 } 930 931 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 932 final DisplayContent displayContent = mChildren.get(displayNdx); 933 if (displayContent.pendingLayoutChanges != 0) { 934 displayContent.setLayoutNeeded(); 935 } 936 } 937 938 mWmService.setHoldScreenLocked(mHoldScreen); 939 if (!mWmService.mDisplayFrozen) { 940 final float brightnessOverride = mScreenBrightnessOverride < PowerManager.BRIGHTNESS_MIN 941 || mScreenBrightnessOverride > PowerManager.BRIGHTNESS_MAX 942 ? PowerManager.BRIGHTNESS_INVALID_FLOAT : mScreenBrightnessOverride; 943 int brightnessFloatAsIntBits = Float.floatToIntBits(brightnessOverride); 944 // Post these on a handler such that we don't call into power manager service while 945 // holding the window manager lock to avoid lock contention with power manager lock. 946 mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightnessFloatAsIntBits, 947 0).sendToTarget(); 948 mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget(); 949 } 950 951 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) { 952 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent; 953 mWmService.mPowerManagerInternal.powerHint( 954 PowerHint.SUSTAINED_PERFORMANCE, 955 (mSustainedPerformanceModeEnabled ? 1 : 0)); 956 } 957 958 if (mUpdateRotation) { 959 ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation"); 960 mUpdateRotation = updateRotationUnchecked(); 961 } 962 963 if (!mWmService.mWaitingForDrawnCallbacks.isEmpty() 964 || (mOrientationChangeComplete && !isLayoutNeeded() 965 && !mUpdateRotation)) { 966 mWmService.checkDrawnWindowsLocked(); 967 } 968 969 final int N = mWmService.mPendingRemove.size(); 970 if (N > 0) { 971 if (mWmService.mPendingRemoveTmp.length < N) { 972 mWmService.mPendingRemoveTmp = new WindowState[N + 10]; 973 } 974 mWmService.mPendingRemove.toArray(mWmService.mPendingRemoveTmp); 975 mWmService.mPendingRemove.clear(); 976 ArrayList<DisplayContent> displayList = new ArrayList(); 977 for (i = 0; i < N; i++) { 978 final WindowState w = mWmService.mPendingRemoveTmp[i]; 979 w.removeImmediately(); 980 final DisplayContent displayContent = w.getDisplayContent(); 981 if (displayContent != null && !displayList.contains(displayContent)) { 982 displayList.add(displayContent); 983 } 984 } 985 986 for (int j = displayList.size() - 1; j >= 0; --j) { 987 final DisplayContent dc = displayList.get(j); 988 dc.assignWindowLayers(true /*setLayoutNeeded*/); 989 } 990 } 991 992 // Remove all deferred displays stacks, tasks, and activities. 993 handleCompleteDeferredRemoval(); 994 995 forAllDisplays(dc -> { 996 dc.getInputMonitor().updateInputWindowsLw(true /*force*/); 997 dc.updateSystemGestureExclusion(); 998 dc.updateTouchExcludeRegion(); 999 }); 1000 1001 // Check to see if we are now in a state where the screen should 1002 // be enabled, because the window obscured flags have changed. 1003 mWmService.enableScreenIfNeededLocked(); 1004 1005 mWmService.scheduleAnimationLocked(); 1006 1007 // Send any pending task-info changes that were queued-up during a layout deferment 1008 mWmService.mAtmService.mTaskOrganizerController.dispatchPendingTaskInfoChanges(); 1009 1010 if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit"); 1011 } 1012 checkAppTransitionReady(WindowSurfacePlacer surfacePlacer)1013 private void checkAppTransitionReady(WindowSurfacePlacer surfacePlacer) { 1014 // Trace all displays app transition by Z-order for pending layout change. 1015 for (int i = mChildren.size() - 1; i >= 0; --i) { 1016 final DisplayContent curDisplay = mChildren.get(i); 1017 1018 // If we are ready to perform an app transition, check through all of the app tokens 1019 // to be shown and see if they are ready to go. 1020 if (curDisplay.mAppTransition.isReady()) { 1021 // handleAppTransitionReady may modify curDisplay.pendingLayoutChanges. 1022 curDisplay.mAppTransitionController.handleAppTransitionReady(); 1023 if (DEBUG_LAYOUT_REPEATS) { 1024 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReady", 1025 curDisplay.pendingLayoutChanges); 1026 } 1027 } 1028 1029 if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppTransitioning()) { 1030 // We have finished the animation of an app transition. To do this, we have 1031 // delayed a lot of operations like showing and hiding apps, moving apps in 1032 // Z-order, etc. 1033 // The app token list reflects the correct Z-order, but the window list may now 1034 // be out of sync with it. So here we will just rebuild the entire app window 1035 // list. Fun! 1036 curDisplay.handleAnimatingStoppedAndTransition(); 1037 if (DEBUG_LAYOUT_REPEATS) { 1038 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock", 1039 curDisplay.pendingLayoutChanges); 1040 } 1041 } 1042 } 1043 } 1044 applySurfaceChangesTransaction()1045 private void applySurfaceChangesTransaction() { 1046 mHoldScreenWindow = null; 1047 mObscuringWindow = null; 1048 1049 // TODO(multi-display): Support these features on secondary screens. 1050 final DisplayContent defaultDc = mWmService.getDefaultDisplayContentLocked(); 1051 final DisplayInfo defaultInfo = defaultDc.getDisplayInfo(); 1052 final int defaultDw = defaultInfo.logicalWidth; 1053 final int defaultDh = defaultInfo.logicalHeight; 1054 if (mWmService.mWatermark != null) { 1055 mWmService.mWatermark.positionSurface(defaultDw, defaultDh, mDisplayTransaction); 1056 } 1057 if (mWmService.mStrictModeFlash != null) { 1058 mWmService.mStrictModeFlash.positionSurface(defaultDw, defaultDh, mDisplayTransaction); 1059 } 1060 if (mWmService.mEmulatorDisplayOverlay != null) { 1061 mWmService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh, 1062 mWmService.getDefaultDisplayRotation(), mDisplayTransaction); 1063 } 1064 1065 final int count = mChildren.size(); 1066 for (int j = 0; j < count; ++j) { 1067 final DisplayContent dc = mChildren.get(j); 1068 dc.applySurfaceChangesTransaction(); 1069 } 1070 1071 // Give the display manager a chance to adjust properties like display rotation if it needs 1072 // to. 1073 mWmService.mDisplayManagerInternal.performTraversal(mDisplayTransaction); 1074 SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction); 1075 } 1076 1077 /** 1078 * Handles resizing windows during surface placement. 1079 */ handleResizingWindows()1080 private void handleResizingWindows() { 1081 for (int i = mWmService.mResizingWindows.size() - 1; i >= 0; i--) { 1082 WindowState win = mWmService.mResizingWindows.get(i); 1083 if (win.mAppFreezing || win.getDisplayContent().mWaitingForConfig) { 1084 // Don't remove this window until rotation has completed and is not waiting for the 1085 // complete configuration. 1086 continue; 1087 } 1088 win.reportResized(); 1089 mWmService.mResizingWindows.remove(i); 1090 } 1091 } 1092 1093 /** 1094 * @param w WindowState this method is applied to. 1095 * @param obscured True if there is a window on top of this obscuring the display. 1096 * @param syswin System window? 1097 * @return True when the display contains content to show the user. When false, the display 1098 * manager may choose to mirror or blank the display. 1099 */ handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin)1100 boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) { 1101 final WindowManager.LayoutParams attrs = w.mAttrs; 1102 final int attrFlags = attrs.flags; 1103 final boolean onScreen = w.isOnScreen(); 1104 final boolean canBeSeen = w.isDisplayedLw(); 1105 final int privateflags = attrs.privateFlags; 1106 boolean displayHasContent = false; 1107 1108 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, 1109 "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w" 1110 + ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d", 1111 w, w.mHasSurface, onScreen, w.isDisplayedLw(), w.mAttrs.userActivityTimeout); 1112 if (w.mHasSurface && onScreen) { 1113 if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) { 1114 mUserActivityTimeout = w.mAttrs.userActivityTimeout; 1115 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "mUserActivityTimeout set to %d", 1116 mUserActivityTimeout); 1117 } 1118 } 1119 if (w.mHasSurface && canBeSeen) { 1120 if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) { 1121 mHoldScreen = w.mSession; 1122 mHoldScreenWindow = w; 1123 } else if (w == mWmService.mLastWakeLockHoldingWindow) { 1124 ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, 1125 "handleNotObscuredLocked: %s was holding screen wakelock but no longer " 1126 + "has FLAG_KEEP_SCREEN_ON!!! called by%s", 1127 w, Debug.getCallers(10)); 1128 } 1129 if (!syswin && w.mAttrs.screenBrightness >= 0 1130 && Float.isNaN(mScreenBrightnessOverride)) { 1131 mScreenBrightnessOverride = w.mAttrs.screenBrightness; 1132 } 1133 1134 final int type = attrs.type; 1135 // This function assumes that the contents of the default display are processed first 1136 // before secondary displays. 1137 final DisplayContent displayContent = w.getDisplayContent(); 1138 if (displayContent != null && displayContent.isDefaultDisplay) { 1139 // While a dream or keyguard is showing, obscure ordinary application content on 1140 // secondary displays (by forcibly enabling mirroring unless there is other content 1141 // we want to show) but still allow opaque keyguard dialogs to be shown. 1142 if (w.isDreamWindow() || mWmService.mPolicy.isKeyguardShowing()) { 1143 mObscureApplicationContentOnSecondaryDisplays = true; 1144 } 1145 displayHasContent = true; 1146 } else if (displayContent != null && 1147 (!mObscureApplicationContentOnSecondaryDisplays 1148 || (obscured && type == TYPE_KEYGUARD_DIALOG))) { 1149 // Allow full screen keyguard presentation dialogs to be seen. 1150 displayHasContent = true; 1151 } 1152 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) { 1153 mSustainedPerformanceModeCurrent = true; 1154 } 1155 } 1156 1157 return displayHasContent; 1158 } 1159 updateRotationUnchecked()1160 boolean updateRotationUnchecked() { 1161 boolean changed = false; 1162 for (int i = mChildren.size() - 1; i >= 0; i--) { 1163 if (mChildren.get(i).getDisplayRotation().updateRotationAndSendNewConfigIfChanged()) { 1164 changed = true; 1165 } 1166 } 1167 return changed; 1168 } 1169 copyAnimToLayoutParams()1170 boolean copyAnimToLayoutParams() { 1171 boolean doRequest = false; 1172 1173 final int bulkUpdateParams = mWmService.mAnimator.mBulkUpdateParams; 1174 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) { 1175 mUpdateRotation = true; 1176 doRequest = true; 1177 } 1178 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) { 1179 mOrientationChangeComplete = false; 1180 } else { 1181 mOrientationChangeComplete = true; 1182 mLastWindowFreezeSource = mWmService.mAnimator.mLastWindowFreezeSource; 1183 if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) { 1184 doRequest = true; 1185 } 1186 } 1187 1188 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) { 1189 mWallpaperActionPending = true; 1190 } 1191 1192 return doRequest; 1193 } 1194 1195 private final class MyHandler extends Handler { 1196 MyHandler(Looper looper)1197 public MyHandler(Looper looper) { 1198 super(looper); 1199 } 1200 1201 @Override handleMessage(Message msg)1202 public void handleMessage(Message msg) { 1203 switch (msg.what) { 1204 case SET_SCREEN_BRIGHTNESS_OVERRIDE: 1205 mWmService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager( 1206 Float.intBitsToFloat(msg.arg1)); 1207 break; 1208 case SET_USER_ACTIVITY_TIMEOUT: 1209 mWmService.mPowerManagerInternal. 1210 setUserActivityTimeoutOverrideFromWindowManager((Long) msg.obj); 1211 break; 1212 default: 1213 break; 1214 } 1215 } 1216 } 1217 dumpDisplayContents(PrintWriter pw)1218 void dumpDisplayContents(PrintWriter pw) { 1219 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)"); 1220 if (mWmService.mDisplayReady) { 1221 final int count = mChildren.size(); 1222 for (int i = 0; i < count; ++i) { 1223 final DisplayContent displayContent = mChildren.get(i); 1224 displayContent.dump(pw, " ", true /* dumpAll */); 1225 } 1226 } else { 1227 pw.println(" NO DISPLAY"); 1228 } 1229 } 1230 dumpTopFocusedDisplayId(PrintWriter pw)1231 void dumpTopFocusedDisplayId(PrintWriter pw) { 1232 pw.print(" mTopFocusedDisplayId="); pw.println(mTopFocusedDisplayId); 1233 } 1234 dumpLayoutNeededDisplayIds(PrintWriter pw)1235 void dumpLayoutNeededDisplayIds(PrintWriter pw) { 1236 if (!isLayoutNeeded()) { 1237 return; 1238 } 1239 pw.print(" mLayoutNeeded on displays="); 1240 final int count = mChildren.size(); 1241 for (int displayNdx = 0; displayNdx < count; ++displayNdx) { 1242 final DisplayContent displayContent = mChildren.get(displayNdx); 1243 if (displayContent.isLayoutNeeded()) { 1244 pw.print(displayContent.getDisplayId()); 1245 } 1246 } 1247 pw.println(); 1248 } 1249 dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows)1250 void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) { 1251 final int[] index = new int[1]; 1252 forAllWindows((w) -> { 1253 if (windows == null || windows.contains(w)) { 1254 pw.println(" Window #" + index[0] + " " + w + ":"); 1255 w.dump(pw, " ", dumpAll || windows != null); 1256 index[0] = index[0] + 1; 1257 } 1258 }, true /* traverseTopToBottom */); 1259 } 1260 dumpTokens(PrintWriter pw, boolean dumpAll)1261 void dumpTokens(PrintWriter pw, boolean dumpAll) { 1262 pw.println(" All tokens:"); 1263 for (int i = mChildren.size() - 1; i >= 0; --i) { 1264 mChildren.get(i).dumpTokens(pw, dumpAll); 1265 } 1266 } 1267 1268 @Override dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTraceLogLevel int logLevel)1269 public void dumpDebug(ProtoOutputStream proto, long fieldId, 1270 @WindowTraceLogLevel int logLevel) { 1271 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) { 1272 return; 1273 } 1274 1275 final long token = proto.start(fieldId); 1276 super.dumpDebug(proto, WINDOW_CONTAINER, logLevel); 1277 1278 mStackSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER); 1279 proto.write(IS_HOME_RECENTS_COMPONENT, 1280 mStackSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser)); 1281 mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES); 1282 1283 proto.end(token); 1284 } 1285 1286 @Override getName()1287 String getName() { 1288 return "ROOT"; 1289 } 1290 1291 @Override scheduleAnimation()1292 void scheduleAnimation() { 1293 mWmService.scheduleAnimationLocked(); 1294 } 1295 1296 @Override removeChild(DisplayContent dc)1297 protected void removeChild(DisplayContent dc) { 1298 super.removeChild(dc); 1299 if (mTopFocusedDisplayId == dc.getDisplayId()) { 1300 mWmService.updateFocusedWindowLocked( 1301 UPDATE_FOCUS_NORMAL, true /* updateInputWindows */); 1302 } 1303 } 1304 1305 /** 1306 * For all display at or below this call the callback. 1307 * 1308 * @param callback Callback to be called for every display. 1309 */ forAllDisplays(Consumer<DisplayContent> callback)1310 void forAllDisplays(Consumer<DisplayContent> callback) { 1311 for (int i = mChildren.size() - 1; i >= 0; --i) { 1312 callback.accept(mChildren.get(i)); 1313 } 1314 } 1315 forAllDisplayPolicies(Consumer<DisplayPolicy> callback)1316 void forAllDisplayPolicies(Consumer<DisplayPolicy> callback) { 1317 for (int i = mChildren.size() - 1; i >= 0; --i) { 1318 callback.accept(mChildren.get(i).getDisplayPolicy()); 1319 } 1320 } 1321 1322 /** 1323 * Get current topmost focused IME window in system. 1324 * Will look on all displays in current Z-order. 1325 */ getCurrentInputMethodWindow()1326 WindowState getCurrentInputMethodWindow() { 1327 for (int i = mChildren.size() - 1; i >= 0; --i) { 1328 final DisplayContent displayContent = mChildren.get(i); 1329 if (displayContent.mInputMethodWindow != null) { 1330 return displayContent.mInputMethodWindow; 1331 } 1332 } 1333 return null; 1334 } 1335 getDisplayContextsWithNonToastVisibleWindows(int pid, List<Context> outContexts)1336 void getDisplayContextsWithNonToastVisibleWindows(int pid, List<Context> outContexts) { 1337 if (outContexts == null) { 1338 return; 1339 } 1340 for (int i = mChildren.size() - 1; i >= 0; --i) { 1341 DisplayContent dc = mChildren.get(i); 1342 if (dc.isAnyNonToastWindowVisibleForPid(pid)) { 1343 outContexts.add(dc.getDisplayUiContext()); 1344 } 1345 } 1346 } 1347 getDisplayUiContext(int displayId)1348 @Nullable Context getDisplayUiContext(int displayId) { 1349 return getDisplayContent(displayId) != null 1350 ? getDisplayContent(displayId).getDisplayUiContext() : null; 1351 } 1352 setWindowManager(WindowManagerService wm)1353 void setWindowManager(WindowManagerService wm) { 1354 mWindowManager = wm; 1355 mDisplayManager = mService.mContext.getSystemService(DisplayManager.class); 1356 mDisplayManager.registerDisplayListener(this, mService.mUiHandler); 1357 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 1358 1359 final Display[] displays = mDisplayManager.getDisplays(); 1360 for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) { 1361 final Display display = displays[displayNdx]; 1362 final DisplayContent displayContent = new DisplayContent(display, this); 1363 addChild(displayContent, POSITION_BOTTOM); 1364 if (displayContent.mDisplayId == DEFAULT_DISPLAY) { 1365 mDefaultDisplay = displayContent; 1366 } 1367 } 1368 calculateDefaultMinimalSizeOfResizeableTasks(); 1369 1370 final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea(); 1371 defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP); 1372 positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent, 1373 false /* includingParents */); 1374 } 1375 1376 // TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display. getDefaultDisplay()1377 DisplayContent getDefaultDisplay() { 1378 return mDefaultDisplay; 1379 } 1380 1381 /** 1382 * Get the default display area on the device dedicated to app windows. This one should be used 1383 * only as a fallback location for activity launches when no target display area is specified, 1384 * or for cases when multi-instance is not supported yet (like Split-screen, Freeform, PiP or 1385 * Recents). 1386 */ getDefaultTaskDisplayArea()1387 TaskDisplayArea getDefaultTaskDisplayArea() { 1388 return mDefaultDisplay.getDefaultTaskDisplayArea(); 1389 } 1390 1391 /** 1392 * Get an existing instance of {@link DisplayContent} that has the given uniqueId. Unique ID is 1393 * defined in {@link DisplayInfo#uniqueId}. 1394 * 1395 * @param uniqueId the unique ID of the display 1396 * @return the {@link DisplayContent} or {@code null} if nothing is found. 1397 */ getDisplayContent(String uniqueId)1398 DisplayContent getDisplayContent(String uniqueId) { 1399 for (int i = getChildCount() - 1; i >= 0; --i) { 1400 final DisplayContent display = getChildAt(i); 1401 final boolean isValid = display.mDisplay.isValid(); 1402 if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) { 1403 return display; 1404 } 1405 } 1406 1407 return null; 1408 } 1409 1410 // TODO: Look into consolidating with getDisplayContentOrCreate() getDisplayContent(int displayId)1411 DisplayContent getDisplayContent(int displayId) { 1412 for (int i = getChildCount() - 1; i >= 0; --i) { 1413 final DisplayContent displayContent = getChildAt(i); 1414 if (displayContent.mDisplayId == displayId) { 1415 return displayContent; 1416 } 1417 } 1418 return null; 1419 } 1420 1421 /** 1422 * Get an existing instance of {@link DisplayContent} or create new if there is a 1423 * corresponding record in display manager. 1424 */ 1425 // TODO: Look into consolidating with getDisplayContent() getDisplayContentOrCreate(int displayId)1426 @Nullable DisplayContent getDisplayContentOrCreate(int displayId) { 1427 DisplayContent displayContent = getDisplayContent(displayId); 1428 if (displayContent != null) { 1429 return displayContent; 1430 } 1431 if (mDisplayManager == null) { 1432 // The system isn't fully initialized yet. 1433 return null; 1434 } 1435 final Display display = mDisplayManager.getDisplay(displayId); 1436 if (display == null) { 1437 // The display is not registered in DisplayManager. 1438 return null; 1439 } 1440 // The display hasn't been added to ActivityManager yet, create a new record now. 1441 displayContent = new DisplayContent(display, this); 1442 addChild(displayContent, POSITION_BOTTOM); 1443 return displayContent; 1444 } 1445 getDefaultDisplayHomeActivityForUser(int userId)1446 ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) { 1447 return getDefaultTaskDisplayArea().getHomeActivityForUser(userId); 1448 } 1449 startHomeOnAllDisplays(int userId, String reason)1450 boolean startHomeOnAllDisplays(int userId, String reason) { 1451 boolean homeStarted = false; 1452 for (int i = getChildCount() - 1; i >= 0; i--) { 1453 final int displayId = getChildAt(i).mDisplayId; 1454 homeStarted |= startHomeOnDisplay(userId, reason, displayId); 1455 } 1456 return homeStarted; 1457 } 1458 startHomeOnEmptyDisplays(String reason)1459 void startHomeOnEmptyDisplays(String reason) { 1460 for (int i = getChildCount() - 1; i >= 0; i--) { 1461 final DisplayContent display = getChildAt(i); 1462 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 1463 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 1464 if (taskDisplayArea.topRunningActivity() == null) { 1465 startHomeOnTaskDisplayArea(mCurrentUser, reason, taskDisplayArea, 1466 false /* allowInstrumenting */, false /* fromHomeKey */); 1467 } 1468 } 1469 } 1470 } 1471 startHomeOnDisplay(int userId, String reason, int displayId)1472 boolean startHomeOnDisplay(int userId, String reason, int displayId) { 1473 return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */, 1474 false /* fromHomeKey */); 1475 } 1476 startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey)1477 boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, 1478 boolean fromHomeKey) { 1479 // Fallback to top focused display or default display if the displayId is invalid. 1480 if (displayId == INVALID_DISPLAY) { 1481 final ActivityStack stack = getTopDisplayFocusedStack(); 1482 displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY; 1483 } 1484 1485 final DisplayContent display = getDisplayContent(displayId); 1486 boolean result = false; 1487 for (int tcNdx = display.getTaskDisplayAreaCount() - 1; tcNdx >= 0; --tcNdx) { 1488 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tcNdx); 1489 result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea, 1490 allowInstrumenting, fromHomeKey); 1491 } 1492 return result; 1493 } 1494 1495 /** 1496 * This starts home activity on display areas that can have system decorations based on 1497 * displayId - default display area always uses primary home component. 1498 * For secondary display areas, the home activity must have category SECONDARY_HOME and then 1499 * resolves according to the priorities listed below. 1500 * - If default home is not set, always use the secondary home defined in the config. 1501 * - Use currently selected primary home activity. 1502 * - Use the activity in the same package as currently selected primary home activity. 1503 * If there are multiple activities matched, use first one. 1504 * - Use the secondary home defined in the config. 1505 */ startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting, boolean fromHomeKey)1506 boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea, 1507 boolean allowInstrumenting, boolean fromHomeKey) { 1508 // Fallback to top focused display area if the provided one is invalid. 1509 if (taskDisplayArea == null) { 1510 final ActivityStack stack = getTopDisplayFocusedStack(); 1511 taskDisplayArea = stack != null ? stack.getDisplayArea() 1512 : getDefaultTaskDisplayArea(); 1513 } 1514 1515 Intent homeIntent = null; 1516 ActivityInfo aInfo = null; 1517 if (taskDisplayArea == getDefaultTaskDisplayArea()) { 1518 homeIntent = mService.getHomeIntent(); 1519 aInfo = resolveHomeActivity(userId, homeIntent); 1520 } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) { 1521 Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea); 1522 aInfo = info.first; 1523 homeIntent = info.second; 1524 } 1525 if (aInfo == null || homeIntent == null) { 1526 return false; 1527 } 1528 1529 if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) { 1530 return false; 1531 } 1532 1533 // Updates the home component of the intent. 1534 homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); 1535 homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK); 1536 // Updates the extra information of the intent. 1537 if (fromHomeKey) { 1538 homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true); 1539 mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity"); 1540 } 1541 // Update the reason for ANR debugging to verify if the user activity is the one that 1542 // actually launched. 1543 final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId( 1544 aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId(); 1545 mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason, 1546 taskDisplayArea); 1547 return true; 1548 } 1549 1550 /** 1551 * This resolves the home activity info. 1552 * @return the home activity info if any. 1553 */ 1554 @VisibleForTesting resolveHomeActivity(int userId, Intent homeIntent)1555 ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) { 1556 final int flags = ActivityManagerService.STOCK_PM_FLAGS; 1557 final ComponentName comp = homeIntent.getComponent(); 1558 ActivityInfo aInfo = null; 1559 try { 1560 if (comp != null) { 1561 // Factory test. 1562 aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 1563 } else { 1564 final String resolvedType = 1565 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver()); 1566 final ResolveInfo info = AppGlobals.getPackageManager() 1567 .resolveIntent(homeIntent, resolvedType, flags, userId); 1568 if (info != null) { 1569 aInfo = info.activityInfo; 1570 } 1571 } 1572 } catch (RemoteException e) { 1573 // ignore 1574 } 1575 1576 if (aInfo == null) { 1577 Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable()); 1578 return null; 1579 } 1580 1581 aInfo = new ActivityInfo(aInfo); 1582 aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId); 1583 return aInfo; 1584 } 1585 1586 @VisibleForTesting resolveSecondaryHomeActivity(int userId, @NonNull TaskDisplayArea taskDisplayArea)1587 Pair<ActivityInfo, Intent> resolveSecondaryHomeActivity(int userId, 1588 @NonNull TaskDisplayArea taskDisplayArea) { 1589 if (taskDisplayArea == getDefaultTaskDisplayArea()) { 1590 throw new IllegalArgumentException( 1591 "resolveSecondaryHomeActivity: Should not be default task container"); 1592 } 1593 // Resolve activities in the same package as currently selected primary home activity. 1594 Intent homeIntent = mService.getHomeIntent(); 1595 ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent); 1596 if (aInfo != null) { 1597 if (ResolverActivity.class.getName().equals(aInfo.name)) { 1598 // Always fallback to secondary home component if default home is not set. 1599 aInfo = null; 1600 } else { 1601 // Look for secondary home activities in the currently selected default home 1602 // package. 1603 homeIntent = mService.getSecondaryHomeIntent(aInfo.applicationInfo.packageName); 1604 final List<ResolveInfo> resolutions = resolveActivities(userId, homeIntent); 1605 final int size = resolutions.size(); 1606 final String targetName = aInfo.name; 1607 aInfo = null; 1608 for (int i = 0; i < size; i++) { 1609 ResolveInfo resolveInfo = resolutions.get(i); 1610 // We need to traverse all resolutions to check if the currently selected 1611 // default home activity is present. 1612 if (resolveInfo.activityInfo.name.equals(targetName)) { 1613 aInfo = resolveInfo.activityInfo; 1614 break; 1615 } 1616 } 1617 if (aInfo == null && size > 0) { 1618 // First one is the best. 1619 aInfo = resolutions.get(0).activityInfo; 1620 } 1621 } 1622 } 1623 1624 if (aInfo != null) { 1625 if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, false /* allowInstrumenting */)) { 1626 aInfo = null; 1627 } 1628 } 1629 1630 // Fallback to secondary home component. 1631 if (aInfo == null) { 1632 homeIntent = mService.getSecondaryHomeIntent(null); 1633 aInfo = resolveHomeActivity(userId, homeIntent); 1634 } 1635 return Pair.create(aInfo, homeIntent); 1636 } 1637 1638 /** 1639 * Retrieve all activities that match the given intent. 1640 * The list should already ordered from best to worst matched. 1641 * {@link android.content.pm.PackageManager#queryIntentActivities} 1642 */ 1643 @VisibleForTesting resolveActivities(int userId, Intent homeIntent)1644 List<ResolveInfo> resolveActivities(int userId, Intent homeIntent) { 1645 List<ResolveInfo> resolutions; 1646 try { 1647 final String resolvedType = 1648 homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver()); 1649 resolutions = AppGlobals.getPackageManager().queryIntentActivities(homeIntent, 1650 resolvedType, ActivityManagerService.STOCK_PM_FLAGS, userId).getList(); 1651 1652 } catch (RemoteException e) { 1653 resolutions = new ArrayList<>(); 1654 } 1655 return resolutions; 1656 } 1657 resumeHomeActivity(ActivityRecord prev, String reason, TaskDisplayArea taskDisplayArea)1658 boolean resumeHomeActivity(ActivityRecord prev, String reason, 1659 TaskDisplayArea taskDisplayArea) { 1660 if (!mService.isBooting() && !mService.isBooted()) { 1661 // Not ready yet! 1662 return false; 1663 } 1664 1665 if (taskDisplayArea == null) { 1666 taskDisplayArea = getDefaultTaskDisplayArea(); 1667 } 1668 1669 final ActivityRecord r = taskDisplayArea.getHomeActivity(); 1670 final String myReason = reason + " resumeHomeActivity"; 1671 1672 // Only resume home activity if isn't finishing. 1673 if (r != null && !r.finishing) { 1674 r.moveFocusableActivityToTop(myReason); 1675 return resumeFocusedStacksTopActivities(r.getRootTask(), prev, null); 1676 } 1677 return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea, 1678 false /* allowInstrumenting */, false /* fromHomeKey */); 1679 } 1680 1681 /** 1682 * Check if the display area is valid for secondary home activity. 1683 * @param taskDisplayArea The target display area. 1684 * @return {@code true} if allow to launch, {@code false} otherwise. 1685 */ shouldPlaceSecondaryHomeOnDisplayArea(TaskDisplayArea taskDisplayArea)1686 boolean shouldPlaceSecondaryHomeOnDisplayArea(TaskDisplayArea taskDisplayArea) { 1687 if (getDefaultTaskDisplayArea() == taskDisplayArea) { 1688 throw new IllegalArgumentException( 1689 "shouldPlaceSecondaryHomeOnDisplay: Should not be on default task container"); 1690 } else if (taskDisplayArea == null) { 1691 return false; 1692 } 1693 1694 if (taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) { 1695 // Can't launch home on secondary display if device does not support multi-display. 1696 return false; 1697 } 1698 1699 final boolean deviceProvisioned = Settings.Global.getInt( 1700 mService.mContext.getContentResolver(), 1701 Settings.Global.DEVICE_PROVISIONED, 0) != 0; 1702 if (!deviceProvisioned) { 1703 // Can't launch home on secondary display areas before device is provisioned. 1704 return false; 1705 } 1706 1707 if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) { 1708 // Can't launch home on secondary display areas if device is still locked. 1709 return false; 1710 } 1711 1712 final DisplayContent display = taskDisplayArea.getDisplayContent(); 1713 if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) { 1714 // Can't launch home on display that doesn't support system decorations. 1715 return false; 1716 } 1717 1718 return true; 1719 } 1720 1721 /** 1722 * Check if home activity start should be allowed on a display. 1723 * @param homeInfo {@code ActivityInfo} of the home activity that is going to be launched. 1724 * @param taskDisplayArea The target display area. 1725 * @param allowInstrumenting Whether launching home should be allowed if being instrumented. 1726 * @return {@code true} if allow to launch, {@code false} otherwise. 1727 */ canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting)1728 boolean canStartHomeOnDisplayArea(ActivityInfo homeInfo, TaskDisplayArea taskDisplayArea, 1729 boolean allowInstrumenting) { 1730 if (mService.mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 1731 && mService.mTopAction == null) { 1732 // We are running in factory test mode, but unable to find the factory test app, so 1733 // just sit around displaying the error message and don't try to start anything. 1734 return false; 1735 } 1736 1737 final WindowProcessController app = 1738 mService.getProcessController(homeInfo.processName, homeInfo.applicationInfo.uid); 1739 if (!allowInstrumenting && app != null && app.isInstrumenting()) { 1740 // Don't do this if the home app is currently being instrumented. 1741 return false; 1742 } 1743 1744 final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() 1745 : INVALID_DISPLAY; 1746 if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY 1747 && displayId == mService.mVr2dDisplayId)) { 1748 // No restrictions to default display or vr 2d display. 1749 return true; 1750 } 1751 1752 if (!shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) { 1753 return false; 1754 } 1755 1756 final boolean supportMultipleInstance = homeInfo.launchMode != LAUNCH_SINGLE_TASK 1757 && homeInfo.launchMode != LAUNCH_SINGLE_INSTANCE; 1758 if (!supportMultipleInstance) { 1759 // Can't launch home on secondary displays if it requested to be single instance. 1760 return false; 1761 } 1762 1763 return true; 1764 } 1765 1766 /** 1767 * Ensure all activities visibility, update orientation and configuration. 1768 * 1769 * @param starting The currently starting activity or {@code null} if there is none. 1770 * @param displayId The id of the display where operation is executed. 1771 * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to 1772 * {@code true} if config changed. 1773 * @param deferResume Whether to defer resume while updating config. 1774 * @return 'true' if starting activity was kept or wasn't provided, 'false' if it was relaunched 1775 * because of configuration update. 1776 */ ensureVisibilityAndConfig(ActivityRecord starting, int displayId, boolean markFrozenIfConfigChanged, boolean deferResume)1777 boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId, 1778 boolean markFrozenIfConfigChanged, boolean deferResume) { 1779 // First ensure visibility without updating the config just yet. We need this to know what 1780 // activities are affecting configuration now. 1781 // Passing null here for 'starting' param value, so that visibility of actual starting 1782 // activity will be properly updated. 1783 ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, 1784 false /* preserveWindows */, false /* notifyClients */); 1785 1786 if (displayId == INVALID_DISPLAY) { 1787 // The caller didn't provide a valid display id, skip updating config. 1788 return true; 1789 } 1790 1791 // Force-update the orientation from the WindowManager, since we need the true configuration 1792 // to send to the client now. 1793 final DisplayContent displayContent = getDisplayContent(displayId); 1794 Configuration config = null; 1795 if (displayContent != null) { 1796 config = displayContent.updateOrientation( 1797 getDisplayOverrideConfiguration(displayId), 1798 starting != null && starting.mayFreezeScreenLocked() 1799 ? starting.appToken : null, 1800 true /* forceUpdate */); 1801 } 1802 // Visibilities may change so let the starting activity have a chance to report. Can't do it 1803 // when visibility is changed in each AppWindowToken because it may trigger wrong 1804 // configuration push because the visibility of some activities may not be updated yet. 1805 if (starting != null) { 1806 starting.reportDescendantOrientationChangeIfNeeded(); 1807 } 1808 if (starting != null && markFrozenIfConfigChanged && config != null) { 1809 starting.frozenBeforeDestroy = true; 1810 } 1811 1812 if (displayContent != null) { 1813 // Update the configuration of the activities on the display. 1814 return displayContent.updateDisplayOverrideConfigurationLocked(config, starting, 1815 deferResume, null /* result */); 1816 } else { 1817 return true; 1818 } 1819 } 1820 1821 /** 1822 * @return a list of activities which are the top ones in each visible stack. The first 1823 * entry will be the focused activity. 1824 */ getTopVisibleActivities()1825 List<IBinder> getTopVisibleActivities() { 1826 final ArrayList<IBinder> topActivityTokens = new ArrayList<>(); 1827 final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); 1828 // Traverse all displays. 1829 for (int dNdx = getChildCount() - 1; dNdx >= 0; dNdx--) { 1830 final DisplayContent display = getChildAt(dNdx); 1831 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 1832 final TaskDisplayArea taskDisplayArea = 1833 display.getTaskDisplayAreaAt(tdaNdx); 1834 // Traverse all stacks on a display area. 1835 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 1836 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 1837 // Get top activity from a visible stack and add it to the list. 1838 if (stack.shouldBeVisible(null /* starting */)) { 1839 final ActivityRecord top = stack.getTopNonFinishingActivity(); 1840 if (top != null) { 1841 if (stack == topFocusedStack) { 1842 topActivityTokens.add(0, top.appToken); 1843 } else { 1844 topActivityTokens.add(top.appToken); 1845 } 1846 } 1847 } 1848 } 1849 } 1850 } 1851 return topActivityTokens; 1852 } 1853 getTopDisplayFocusedStack()1854 ActivityStack getTopDisplayFocusedStack() { 1855 for (int i = getChildCount() - 1; i >= 0; --i) { 1856 final ActivityStack focusedStack = getChildAt(i).getFocusedStack(); 1857 if (focusedStack != null) { 1858 return focusedStack; 1859 } 1860 } 1861 return null; 1862 } 1863 getTopResumedActivity()1864 ActivityRecord getTopResumedActivity() { 1865 final ActivityStack focusedStack = getTopDisplayFocusedStack(); 1866 if (focusedStack == null) { 1867 return null; 1868 } 1869 final ActivityRecord resumedActivity = focusedStack.getResumedActivity(); 1870 if (resumedActivity != null && resumedActivity.app != null) { 1871 return resumedActivity; 1872 } 1873 // The top focused stack might not have a resumed activity yet - look on all displays in 1874 // focus order. 1875 for (int i = getChildCount() - 1; i >= 0; --i) { 1876 final DisplayContent display = getChildAt(i); 1877 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 1878 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 1879 final ActivityRecord resumedActivityOnTaskContainer = taskDisplayArea 1880 .getFocusedActivity(); 1881 if (resumedActivityOnTaskContainer != null) { 1882 return resumedActivityOnTaskContainer; 1883 } 1884 } 1885 } 1886 return null; 1887 } 1888 isTopDisplayFocusedStack(ActivityStack stack)1889 boolean isTopDisplayFocusedStack(ActivityStack stack) { 1890 return stack != null && stack == getTopDisplayFocusedStack(); 1891 } 1892 updatePreviousProcess(ActivityRecord r)1893 void updatePreviousProcess(ActivityRecord r) { 1894 // Now that this process has stopped, we may want to consider it to be the previous app to 1895 // try to keep around in case the user wants to return to it. 1896 1897 // First, found out what is currently the foreground app, so that we don't blow away the 1898 // previous app if this activity is being hosted by the process that is actually still the 1899 // foreground. 1900 WindowProcessController fgApp = null; 1901 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 1902 final DisplayContent display = getChildAt(displayNdx); 1903 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 1904 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 1905 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 1906 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 1907 if (isTopDisplayFocusedStack(stack)) { 1908 final ActivityRecord resumedActivity = stack.getResumedActivity(); 1909 if (resumedActivity != null) { 1910 fgApp = resumedActivity.app; 1911 } else if (stack.mPausingActivity != null) { 1912 fgApp = stack.mPausingActivity.app; 1913 } 1914 break; 1915 } 1916 } 1917 } 1918 } 1919 1920 // Now set this one as the previous process, only if that really makes sense to. 1921 if (r.hasProcess() && fgApp != null && r.app != fgApp 1922 && r.lastVisibleTime > mService.mPreviousProcessVisibleTime 1923 && r.app != mService.mHomeProcess) { 1924 mService.mPreviousProcess = r.app; 1925 mService.mPreviousProcessVisibleTime = r.lastVisibleTime; 1926 } 1927 } 1928 attachApplication(WindowProcessController app)1929 boolean attachApplication(WindowProcessController app) throws RemoteException { 1930 final String processName = app.mName; 1931 boolean didSomething = false; 1932 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 1933 final DisplayContent display = getChildAt(displayNdx); 1934 final ActivityStack stack = display.getFocusedStack(); 1935 if (stack == null) { 1936 continue; 1937 } 1938 1939 mTmpRemoteException = null; 1940 mTmpBoolean = false; // Set to true if an activity was started. 1941 final PooledFunction c = PooledLambda.obtainFunction( 1942 RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this, 1943 PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity()); 1944 stack.forAllActivities(c); 1945 c.recycle(); 1946 if (mTmpRemoteException != null) { 1947 throw mTmpRemoteException; 1948 } 1949 didSomething |= mTmpBoolean; 1950 } 1951 if (!didSomething) { 1952 ensureActivitiesVisible(null, 0, false /* preserve_windows */); 1953 } 1954 return didSomething; 1955 } 1956 startActivityForAttachedApplicationIfNeeded(ActivityRecord r, WindowProcessController app, ActivityRecord top)1957 private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r, 1958 WindowProcessController app, ActivityRecord top) { 1959 if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null 1960 || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) { 1961 return false; 1962 } 1963 1964 try { 1965 if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/, 1966 true /*checkConfig*/)) { 1967 mTmpBoolean = true; 1968 } 1969 } catch (RemoteException e) { 1970 Slog.w(TAG, "Exception in new application when starting activity " 1971 + top.intent.getComponent().flattenToShortString(), e); 1972 mTmpRemoteException = e; 1973 return true; 1974 } 1975 return false; 1976 } 1977 1978 /** 1979 * Make sure that all activities that need to be visible in the system actually are and update 1980 * their configuration. 1981 */ ensureActivitiesVisible(ActivityRecord starting, int configChanges, boolean preserveWindows)1982 void ensureActivitiesVisible(ActivityRecord starting, int configChanges, 1983 boolean preserveWindows) { 1984 ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */); 1985 } 1986 1987 /** 1988 * @see #ensureActivitiesVisible(ActivityRecord, int, boolean) 1989 */ ensureActivitiesVisible(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients)1990 void ensureActivitiesVisible(ActivityRecord starting, int configChanges, 1991 boolean preserveWindows, boolean notifyClients) { 1992 if (mStackSupervisor.inActivityVisibilityUpdate()) { 1993 // Don't do recursive work. 1994 return; 1995 } 1996 1997 try { 1998 mStackSupervisor.beginActivityVisibilityUpdate(); 1999 // First the front stacks. In case any are not fullscreen and are in front of home. 2000 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2001 final DisplayContent display = getChildAt(displayNdx); 2002 display.ensureActivitiesVisible(starting, configChanges, preserveWindows, 2003 notifyClients); 2004 } 2005 } finally { 2006 mStackSupervisor.endActivityVisibilityUpdate(); 2007 } 2008 } 2009 switchUser(int userId, UserState uss)2010 boolean switchUser(int userId, UserState uss) { 2011 final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); 2012 final int focusStackId = topFocusedStack != null 2013 ? topFocusedStack.getRootTaskId() : INVALID_TASK_ID; 2014 // We dismiss the docked stack whenever we switch users. 2015 if (getDefaultTaskDisplayArea().isSplitScreenModeActivated()) { 2016 getDefaultTaskDisplayArea().onSplitScreenModeDismissed(); 2017 } 2018 // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will 2019 // also cause all tasks to be moved to the fullscreen stack at a position that is 2020 // appropriate. 2021 removeStacksInWindowingModes(WINDOWING_MODE_PINNED); 2022 2023 mUserStackInFront.put(mCurrentUser, focusStackId); 2024 mCurrentUser = userId; 2025 2026 mStackSupervisor.mStartingUsers.add(uss); 2027 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2028 final DisplayContent display = getChildAt(displayNdx); 2029 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2030 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2031 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 2032 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 2033 stack.switchUser(userId); 2034 } 2035 } 2036 } 2037 2038 final int restoreStackId = mUserStackInFront.get(userId); 2039 ActivityStack stack = getStack(restoreStackId); 2040 if (stack == null) { 2041 stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask(); 2042 } 2043 final boolean homeInFront = stack.isActivityTypeHome(); 2044 if (stack.isOnHomeDisplay()) { 2045 stack.moveToFront("switchUserOnHomeDisplay"); 2046 } else { 2047 // Stack was moved to another display while user was swapped out. 2048 resumeHomeActivity(null, "switchUserOnOtherDisplay", getDefaultTaskDisplayArea()); 2049 } 2050 return homeInFront; 2051 } 2052 removeUser(int userId)2053 void removeUser(int userId) { 2054 mUserStackInFront.delete(userId); 2055 } 2056 2057 /** 2058 * Update the last used stack id for non-current user (current user's last 2059 * used stack is the focused stack) 2060 */ updateUserStack(int userId, ActivityStack stack)2061 void updateUserStack(int userId, ActivityStack stack) { 2062 if (userId != mCurrentUser) { 2063 if (stack == null) { 2064 stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask(); 2065 } 2066 2067 mUserStackInFront.put(userId, stack.getRootTaskId()); 2068 } 2069 } 2070 2071 /** 2072 * Move stack with all its existing content to specified task display area. 2073 * @param stackId Id of stack to move. 2074 * @param taskDisplayArea The task display area to move stack to. 2075 * @param onTop Indicates whether container should be place on top or on bottom. 2076 */ moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop)2077 void moveStackToTaskDisplayArea(int stackId, TaskDisplayArea taskDisplayArea, boolean onTop) { 2078 final ActivityStack stack = getStack(stackId); 2079 if (stack == null) { 2080 throw new IllegalArgumentException("moveStackToTaskDisplayArea: Unknown stackId=" 2081 + stackId); 2082 } 2083 2084 final TaskDisplayArea currentTaskDisplayArea = stack.getDisplayArea(); 2085 if (currentTaskDisplayArea == null) { 2086 throw new IllegalStateException("moveStackToTaskDisplayArea: stack=" + stack 2087 + " is not attached to any task display area."); 2088 } 2089 2090 if (taskDisplayArea == null) { 2091 throw new IllegalArgumentException( 2092 "moveStackToTaskDisplayArea: Unknown taskDisplayArea=" + taskDisplayArea); 2093 } 2094 2095 if (currentTaskDisplayArea == taskDisplayArea) { 2096 throw new IllegalArgumentException("Trying to move stack=" + stack 2097 + " to its current taskDisplayArea=" + taskDisplayArea); 2098 } 2099 stack.reparent(taskDisplayArea, onTop); 2100 // TODO(multi-display): resize stacks properly if moved from split-screen. 2101 } 2102 2103 /** 2104 * Move stack with all its existing content to specified display. 2105 * @param stackId Id of stack to move. 2106 * @param displayId Id of display to move stack to. 2107 * @param onTop Indicates whether container should be place on top or on bottom. 2108 */ moveStackToDisplay(int stackId, int displayId, boolean onTop)2109 void moveStackToDisplay(int stackId, int displayId, boolean onTop) { 2110 final DisplayContent displayContent = getDisplayContentOrCreate(displayId); 2111 if (displayContent == null) { 2112 throw new IllegalArgumentException("moveStackToDisplay: Unknown displayId=" 2113 + displayId); 2114 } 2115 2116 if (displayContent.isSingleTaskInstance() && displayContent.getStackCount() > 0) { 2117 // We don't allow moving stacks to single instance display that already has a child. 2118 Slog.e(TAG, "Can not move stackId=" + stackId 2119 + " to single task instance display=" + displayContent); 2120 return; 2121 } 2122 2123 moveStackToTaskDisplayArea(stackId, displayContent.getDefaultTaskDisplayArea(), onTop); 2124 } 2125 moveTopStackActivityToPinnedStack(int stackId)2126 boolean moveTopStackActivityToPinnedStack(int stackId) { 2127 final ActivityStack stack = getStack(stackId); 2128 if (stack == null) { 2129 throw new IllegalArgumentException( 2130 "moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId); 2131 } 2132 2133 final ActivityRecord r = stack.topRunningActivity(); 2134 if (r == null) { 2135 Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity" 2136 + " in stack=" + stack); 2137 return false; 2138 } 2139 2140 if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { 2141 Slog.w(TAG, "moveTopStackActivityToPinnedStack: Picture-In-Picture not supported for " 2142 + " r=" + r); 2143 return false; 2144 } 2145 2146 moveActivityToPinnedStack(r, "moveTopActivityToPinnedStack"); 2147 return true; 2148 } 2149 moveActivityToPinnedStack(ActivityRecord r, String reason)2150 void moveActivityToPinnedStack(ActivityRecord r, String reason) { 2151 mService.deferWindowLayout(); 2152 2153 final TaskDisplayArea taskDisplayArea = r.getDisplayArea(); 2154 2155 try { 2156 final Task task = r.getTask(); 2157 final ActivityStack pinnedStack = taskDisplayArea.getRootPinnedTask(); 2158 2159 // This will change the pinned stack's windowing mode to its original mode, ensuring 2160 // we only have one stack that is in pinned mode. 2161 if (pinnedStack != null) { 2162 pinnedStack.dismissPip(); 2163 } 2164 2165 // Set a transition to ensure that we don't immediately try and update the visibility 2166 // of the activity entering PIP 2167 r.getDisplayContent().prepareAppTransition(TRANSIT_NONE, false); 2168 2169 final boolean singleActivity = task.getChildCount() == 1; 2170 final ActivityStack stack; 2171 if (singleActivity) { 2172 stack = (ActivityStack) task; 2173 } else { 2174 // In the case of multiple activities, we will create a new task for it and then 2175 // move the PIP activity into the task. 2176 stack = taskDisplayArea.createStack(WINDOWING_MODE_UNDEFINED, r.getActivityType(), 2177 ON_TOP, r.info, r.intent, false /* createdByOrganizer */); 2178 // It's possible the task entering PIP is in freeform, so save the last 2179 // non-fullscreen bounds. Then when this new PIP task exits PIP, it can restore 2180 // to its previous freeform bounds. 2181 stack.setLastNonFullscreenBounds(task.mLastNonFullscreenBounds); 2182 2183 // There are multiple activities in the task and moving the top activity should 2184 // reveal/leave the other activities in their original task. 2185 // On the other hand, ActivityRecord#onParentChanged takes care of setting the 2186 // up-to-dated pinned stack information on this newly created stack. 2187 r.reparent(stack, MAX_VALUE, reason); 2188 } 2189 // The intermediate windowing mode to be set on the ActivityRecord later. 2190 // This needs to happen before the re-parenting, otherwise we will always set the 2191 // ActivityRecord to be fullscreen. 2192 final int intermediateWindowingMode = stack.getWindowingMode(); 2193 if (stack.getParent() != taskDisplayArea) { 2194 // stack is nested, but pinned tasks need to be direct children of their 2195 // display area, so reparent. 2196 stack.reparent(taskDisplayArea, true /* onTop */); 2197 } 2198 // Defer the windowing mode change until after the transition to prevent the activity 2199 // from doing work and changing the activity visuals while animating 2200 // TODO(task-org): Figure-out more structured way to do this long term. 2201 r.setWindowingMode(intermediateWindowingMode); 2202 stack.setWindowingMode(WINDOWING_MODE_PINNED); 2203 2204 // Reset the state that indicates it can enter PiP while pausing after we've moved it 2205 // to the pinned stack 2206 r.supportsEnterPipOnTaskSwitch = false; 2207 } finally { 2208 mService.continueWindowLayout(); 2209 } 2210 2211 ensureActivitiesVisible(null, 0, false /* preserveWindows */); 2212 resumeFocusedStacksTopActivities(); 2213 2214 mService.getTaskChangeNotificationController().notifyActivityPinned(r); 2215 } 2216 executeAppTransitionForAllDisplay()2217 void executeAppTransitionForAllDisplay() { 2218 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2219 final DisplayContent display = getChildAt(displayNdx); 2220 display.mDisplayContent.executeAppTransition(); 2221 } 2222 } 2223 findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea)2224 ActivityRecord findTask(ActivityRecord r, TaskDisplayArea preferredTaskDisplayArea) { 2225 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r); 2226 mTmpFindTaskResult.clear(); 2227 2228 // Looking up task on preferred display area first 2229 if (preferredTaskDisplayArea != null) { 2230 preferredTaskDisplayArea.findTaskLocked(r, true /* isPreferredDisplay */, 2231 mTmpFindTaskResult); 2232 if (mTmpFindTaskResult.mIdealMatch) { 2233 return mTmpFindTaskResult.mRecord; 2234 } 2235 } 2236 2237 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2238 final DisplayContent display = getChildAt(displayNdx); 2239 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2240 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2241 if (taskDisplayArea == preferredTaskDisplayArea) { 2242 continue; 2243 } 2244 2245 taskDisplayArea.findTaskLocked(r, false /* isPreferredDisplay */, 2246 mTmpFindTaskResult); 2247 if (mTmpFindTaskResult.mIdealMatch) { 2248 return mTmpFindTaskResult.mRecord; 2249 } 2250 } 2251 } 2252 2253 if (DEBUG_TASKS && mTmpFindTaskResult.mRecord == null) Slog.d(TAG_TASKS, "No task found"); 2254 return mTmpFindTaskResult.mRecord; 2255 } 2256 2257 /** 2258 * Finish the topmost activities in all stacks that belong to the crashed app. 2259 * @param app The app that crashed. 2260 * @param reason Reason to perform this action. 2261 * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished. 2262 */ finishTopCrashedActivities(WindowProcessController app, String reason)2263 int finishTopCrashedActivities(WindowProcessController app, String reason) { 2264 Task finishedTask = null; 2265 ActivityStack focusedStack = getTopDisplayFocusedStack(); 2266 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2267 final DisplayContent display = getChildAt(displayNdx); 2268 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2269 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2270 // It is possible that request to finish activity might also remove its task and 2271 // stack, so we need to be careful with indexes in the loop and check child count 2272 // every time. 2273 for (int stackNdx = 0; stackNdx < taskDisplayArea.getStackCount(); ++stackNdx) { 2274 final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx); 2275 final Task t = stack.finishTopCrashedActivityLocked(app, reason); 2276 if (stack == focusedStack || finishedTask == null) { 2277 finishedTask = t; 2278 } 2279 } 2280 } 2281 } 2282 return finishedTask != null ? finishedTask.mTaskId : INVALID_TASK_ID; 2283 } 2284 resumeFocusedStacksTopActivities()2285 boolean resumeFocusedStacksTopActivities() { 2286 return resumeFocusedStacksTopActivities(null, null, null); 2287 } 2288 resumeFocusedStacksTopActivities( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions)2289 boolean resumeFocusedStacksTopActivities( 2290 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 2291 2292 if (!mStackSupervisor.readyToResume()) { 2293 return false; 2294 } 2295 2296 boolean result = false; 2297 if (targetStack != null && (targetStack.isTopStackInDisplayArea() 2298 || getTopDisplayFocusedStack() == targetStack)) { 2299 result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 2300 } 2301 2302 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2303 boolean resumedOnDisplay = false; 2304 final DisplayContent display = getChildAt(displayNdx); 2305 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2306 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2307 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 2308 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 2309 final ActivityRecord topRunningActivity = stack.topRunningActivity(); 2310 if (!stack.isFocusableAndVisible() || topRunningActivity == null) { 2311 continue; 2312 } 2313 if (stack == targetStack) { 2314 // Simply update the result for targetStack because the targetStack had 2315 // already resumed in above. We don't want to resume it again, especially in 2316 // some cases, it would cause a second launch failure if app process was 2317 // dead. 2318 resumedOnDisplay |= result; 2319 continue; 2320 } 2321 if (taskDisplayArea.isTopStack(stack) && topRunningActivity.isState(RESUMED)) { 2322 // Kick off any lingering app transitions form the MoveTaskToFront 2323 // operation, but only consider the top task and stack on that display. 2324 stack.executeAppTransition(targetOptions); 2325 } else { 2326 resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target); 2327 } 2328 } 2329 } 2330 if (!resumedOnDisplay) { 2331 // In cases when there are no valid activities (e.g. device just booted or launcher 2332 // crashed) it's possible that nothing was resumed on a display. Requesting resume 2333 // of top activity in focused stack explicitly will make sure that at least home 2334 // activity is started and resumed, and no recursion occurs. 2335 final ActivityStack focusedStack = display.getFocusedStack(); 2336 if (focusedStack != null) { 2337 result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); 2338 } else if (targetStack == null) { 2339 result |= resumeHomeActivity(null /* prev */, "no-focusable-task", 2340 display.getDefaultTaskDisplayArea()); 2341 } 2342 } 2343 } 2344 2345 return result; 2346 } 2347 applySleepTokens(boolean applyToStacks)2348 void applySleepTokens(boolean applyToStacks) { 2349 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2350 // Set the sleeping state of the display. 2351 final DisplayContent display = getChildAt(displayNdx); 2352 final boolean displayShouldSleep = display.shouldSleep(); 2353 if (displayShouldSleep == display.isSleeping()) { 2354 continue; 2355 } 2356 display.setIsSleeping(displayShouldSleep); 2357 2358 if (!applyToStacks) { 2359 continue; 2360 } 2361 2362 // Set the sleeping state of the stacks on the display. 2363 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2364 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2365 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 2366 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 2367 if (displayShouldSleep) { 2368 stack.goToSleepIfPossible(false /* shuttingDown */); 2369 } else { 2370 // When the display which can only contain one task turns on, start a 2371 // special transition. 2372 // {@link AppTransitionController#handleAppTransitionReady} later picks up 2373 // the transition, and schedules 2374 // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is 2375 // triggered after contents are drawn on the display. 2376 if (display.isSingleTaskInstance()) { 2377 display.mDisplayContent.prepareAppTransition( 2378 TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false, 2379 0 /* flags */, true /* forceOverride*/); 2380 } 2381 stack.awakeFromSleepingLocked(); 2382 if (display.isSingleTaskInstance()) { 2383 display.executeAppTransition(); 2384 } 2385 if (stack.isFocusedStackOnDisplay() 2386 && !mStackSupervisor.getKeyguardController() 2387 .isKeyguardOrAodShowing(display.mDisplayId)) { 2388 // If the keyguard is unlocked - resume immediately. 2389 // It is possible that the display will not be awake at the time we 2390 // process the keyguard going away, which can happen before the sleep 2391 // token is released. As a result, it is important we resume the 2392 // activity here. 2393 resumeFocusedStacksTopActivities(); 2394 } 2395 // The visibility update must not be called before resuming the top, so the 2396 // display orientation can be updated first if needed. Otherwise there may 2397 // have redundant configuration changes due to apply outdated display 2398 // orientation (from keyguard) to activity. 2399 stack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, 2400 false /* preserveWindows */); 2401 } 2402 } 2403 } 2404 } 2405 } 2406 getStack(int stackId)2407 protected ActivityStack getStack(int stackId) { 2408 for (int i = getChildCount() - 1; i >= 0; --i) { 2409 final ActivityStack stack = getChildAt(i).getStack(stackId); 2410 if (stack != null) { 2411 return stack; 2412 } 2413 } 2414 return null; 2415 } 2416 2417 /** @see DisplayContent#getStack(int, int) */ getStack(int windowingMode, int activityType)2418 ActivityStack getStack(int windowingMode, int activityType) { 2419 for (int i = getChildCount() - 1; i >= 0; --i) { 2420 final ActivityStack stack = getChildAt(i).getStack(windowingMode, activityType); 2421 if (stack != null) { 2422 return stack; 2423 } 2424 } 2425 return null; 2426 } 2427 getStack(int windowingMode, int activityType, int displayId)2428 private ActivityStack getStack(int windowingMode, int activityType, 2429 int displayId) { 2430 DisplayContent display = getDisplayContent(displayId); 2431 if (display == null) { 2432 return null; 2433 } 2434 return display.getStack(windowingMode, activityType); 2435 } 2436 getStackInfo(ActivityStack stack)2437 private ActivityManager.StackInfo getStackInfo(ActivityStack stack) { 2438 final TaskDisplayArea taskDisplayArea = stack.getDisplayArea(); 2439 ActivityManager.StackInfo info = new ActivityManager.StackInfo(); 2440 stack.getBounds(info.bounds); 2441 info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY; 2442 info.stackId = stack.mTaskId; 2443 info.stackToken = stack.mRemoteToken.toWindowContainerToken(); 2444 info.userId = stack.mCurrentUser; 2445 info.visible = stack.shouldBeVisible(null); 2446 // A stack might be not attached to a display. 2447 // TODO: Can be removed since no one is using it. 2448 info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(stack) : 0; 2449 info.configuration.setTo(stack.getConfiguration()); 2450 2451 final int numTasks = stack.getDescendantTaskCount(); 2452 info.taskIds = new int[numTasks]; 2453 info.taskNames = new String[numTasks]; 2454 info.taskBounds = new Rect[numTasks]; 2455 info.taskUserIds = new int[numTasks]; 2456 final int[] currentIndex = {0}; 2457 2458 final PooledConsumer c = PooledLambda.obtainConsumer( 2459 RootWindowContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info, 2460 currentIndex); 2461 stack.forAllLeafTasks(c, false /* traverseTopToBottom */); 2462 c.recycle(); 2463 2464 final ActivityRecord top = stack.topRunningActivity(); 2465 info.topActivity = top != null ? top.intent.getComponent() : null; 2466 return info; 2467 } 2468 processTaskForStackInfo( Task task, ActivityManager.StackInfo info, int[] currentIndex)2469 private static void processTaskForStackInfo( 2470 Task task, ActivityManager.StackInfo info, int[] currentIndex) { 2471 int i = currentIndex[0]; 2472 info.taskIds[i] = task.mTaskId; 2473 info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 2474 : task.realActivity != null ? task.realActivity.flattenToString() 2475 : task.getTopNonFinishingActivity() != null 2476 ? task.getTopNonFinishingActivity().packageName : "unknown"; 2477 info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId); 2478 info.taskUserIds[i] = task.mUserId; 2479 currentIndex[0] = ++i; 2480 } 2481 getStackInfo(int stackId)2482 ActivityManager.StackInfo getStackInfo(int stackId) { 2483 ActivityStack stack = getStack(stackId); 2484 if (stack != null) { 2485 return getStackInfo(stack); 2486 } 2487 return null; 2488 } 2489 getStackInfo(int windowingMode, int activityType)2490 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) { 2491 final ActivityStack stack = getStack(windowingMode, activityType); 2492 return (stack != null) ? getStackInfo(stack) : null; 2493 } 2494 getStackInfo(int windowingMode, int activityType, int displayId)2495 ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) { 2496 final ActivityStack stack = getStack(windowingMode, activityType, displayId); 2497 return (stack != null) ? getStackInfo(stack) : null; 2498 } 2499 2500 /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */ getAllStackInfos(int displayId)2501 ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) { 2502 ArrayList<ActivityManager.StackInfo> list = new ArrayList<>(); 2503 if (displayId == INVALID_DISPLAY) { 2504 for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) { 2505 final DisplayContent display = getChildAt(displayNdx); 2506 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2507 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2508 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 2509 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 2510 list.add(getStackInfo(stack)); 2511 } 2512 } 2513 } 2514 return list; 2515 } 2516 final DisplayContent display = getDisplayContent(displayId); 2517 if (display == null) { 2518 return list; 2519 } 2520 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2521 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2522 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 2523 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 2524 list.add(getStackInfo(stack)); 2525 } 2526 } 2527 return list; 2528 } 2529 2530 @Override onDisplayAdded(int displayId)2531 public void onDisplayAdded(int displayId) { 2532 if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); 2533 synchronized (mService.mGlobalLock) { 2534 final DisplayContent display = getDisplayContentOrCreate(displayId); 2535 if (display == null) { 2536 return; 2537 } 2538 // Do not start home before booting, or it may accidentally finish booting before it 2539 // starts. Instead, we expect home activities to be launched when the system is ready 2540 // (ActivityManagerService#systemReady). 2541 if (mService.isBooted() || mService.isBooting()) { 2542 startSystemDecorations(display.mDisplayContent); 2543 } 2544 } 2545 } 2546 startSystemDecorations(final DisplayContent displayContent)2547 private void startSystemDecorations(final DisplayContent displayContent) { 2548 startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId()); 2549 displayContent.getDisplayPolicy().notifyDisplayReady(); 2550 } 2551 2552 @Override onDisplayRemoved(int displayId)2553 public void onDisplayRemoved(int displayId) { 2554 if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); 2555 if (displayId == DEFAULT_DISPLAY) { 2556 throw new IllegalArgumentException("Can't remove the primary display."); 2557 } 2558 2559 synchronized (mService.mGlobalLock) { 2560 final DisplayContent displayContent = getDisplayContent(displayId); 2561 if (displayContent == null) { 2562 return; 2563 } 2564 2565 displayContent.remove(); 2566 } 2567 } 2568 2569 @Override onDisplayChanged(int displayId)2570 public void onDisplayChanged(int displayId) { 2571 if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); 2572 synchronized (mService.mGlobalLock) { 2573 final DisplayContent displayContent = getDisplayContent(displayId); 2574 if (displayContent != null) { 2575 displayContent.onDisplayChanged(); 2576 } 2577 } 2578 } 2579 2580 /** Update lists of UIDs that are present on displays and have access to them. */ updateUIDsPresentOnDisplay()2581 void updateUIDsPresentOnDisplay() { 2582 mDisplayAccessUIDs.clear(); 2583 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2584 final DisplayContent displayContent = getChildAt(displayNdx); 2585 // Only bother calculating the whitelist for private displays 2586 if (displayContent.isPrivate()) { 2587 mDisplayAccessUIDs.append( 2588 displayContent.mDisplayId, displayContent.getPresentUIDs()); 2589 } 2590 } 2591 // Store updated lists in DisplayManager. Callers from outside of AM should get them there. 2592 mDisplayManagerInternal.setDisplayAccessUIDs(mDisplayAccessUIDs); 2593 } 2594 findStackBehind(ActivityStack stack)2595 ActivityStack findStackBehind(ActivityStack stack) { 2596 final TaskDisplayArea taskDisplayArea = stack.getDisplayArea(); 2597 if (taskDisplayArea != null) { 2598 for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; i--) { 2599 if (taskDisplayArea.getStackAt(i) == stack && i > 0) { 2600 return taskDisplayArea.getStackAt(i - 1); 2601 } 2602 } 2603 } 2604 throw new IllegalStateException("Failed to find a stack behind stack=" + stack 2605 + " in=" + taskDisplayArea); 2606 } 2607 2608 @Override positionChildAt(int position, DisplayContent child, boolean includingParents)2609 void positionChildAt(int position, DisplayContent child, boolean includingParents) { 2610 super.positionChildAt(position, child, includingParents); 2611 mStackSupervisor.updateTopResumedActivityIfNeeded(); 2612 } 2613 getDisplayOverrideConfiguration(int displayId)2614 Configuration getDisplayOverrideConfiguration(int displayId) { 2615 final DisplayContent displayContent = getDisplayContentOrCreate(displayId); 2616 if (displayContent == null) { 2617 throw new IllegalArgumentException("No display found with id: " + displayId); 2618 } 2619 2620 return displayContent.getRequestedOverrideConfiguration(); 2621 } 2622 setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId)2623 void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) { 2624 final DisplayContent displayContent = getDisplayContentOrCreate(displayId); 2625 if (displayContent == null) { 2626 throw new IllegalArgumentException("No display found with id: " + displayId); 2627 } 2628 2629 displayContent.onRequestedOverrideConfigurationChanged(overrideConfiguration); 2630 } 2631 prepareForShutdown()2632 void prepareForShutdown() { 2633 for (int i = 0; i < getChildCount(); i++) { 2634 createSleepToken("shutdown", getChildAt(i).mDisplayId); 2635 } 2636 } 2637 createSleepToken(String tag, int displayId)2638 ActivityTaskManagerInternal.SleepToken createSleepToken(String tag, int displayId) { 2639 final DisplayContent display = getDisplayContent(displayId); 2640 if (display == null) { 2641 throw new IllegalArgumentException("Invalid display: " + displayId); 2642 } 2643 2644 final SleepTokenImpl token = new SleepTokenImpl(tag, displayId); 2645 mSleepTokens.add(token); 2646 display.mAllSleepTokens.add(token); 2647 return token; 2648 } 2649 removeSleepToken(SleepTokenImpl token)2650 private void removeSleepToken(SleepTokenImpl token) { 2651 mSleepTokens.remove(token); 2652 2653 final DisplayContent display = getDisplayContent(token.mDisplayId); 2654 if (display != null) { 2655 display.mAllSleepTokens.remove(token); 2656 if (display.mAllSleepTokens.isEmpty()) { 2657 mService.updateSleepIfNeededLocked(); 2658 } 2659 } 2660 } 2661 addStartingWindowsForVisibleActivities()2662 void addStartingWindowsForVisibleActivities() { 2663 forAllActivities((r) -> { 2664 if (r.mVisibleRequested) { 2665 r.showStartingWindow(null /* prev */, false /* newTask */, true /*taskSwitch*/); 2666 } 2667 }); 2668 } 2669 invalidateTaskLayers()2670 void invalidateTaskLayers() { 2671 mTaskLayersChanged = true; 2672 } 2673 rankTaskLayersIfNeeded()2674 void rankTaskLayersIfNeeded() { 2675 if (!mTaskLayersChanged) { 2676 return; 2677 } 2678 mTaskLayersChanged = false; 2679 mTmpTaskLayerRank = 0; 2680 final PooledConsumer c = PooledLambda.obtainConsumer( 2681 RootWindowContainer::rankTaskLayerForActivity, this, 2682 PooledLambda.__(ActivityRecord.class)); 2683 forAllActivities(c); 2684 c.recycle(); 2685 } 2686 rankTaskLayerForActivity(ActivityRecord r)2687 private void rankTaskLayerForActivity(ActivityRecord r) { 2688 if (r.canBeTopRunning() && r.mVisibleRequested) { 2689 r.getTask().mLayerRank = ++mTmpTaskLayerRank; 2690 } else { 2691 r.getTask().mLayerRank = -1; 2692 } 2693 } 2694 clearOtherAppTimeTrackers(AppTimeTracker except)2695 void clearOtherAppTimeTrackers(AppTimeTracker except) { 2696 final PooledConsumer c = PooledLambda.obtainConsumer( 2697 RootWindowContainer::clearOtherAppTimeTrackers, 2698 PooledLambda.__(ActivityRecord.class), except); 2699 forAllActivities(c); 2700 c.recycle(); 2701 } 2702 clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except)2703 private static void clearOtherAppTimeTrackers(ActivityRecord r, AppTimeTracker except) { 2704 if (r.appTimeTracker != except) { 2705 r.appTimeTracker = null; 2706 } 2707 } 2708 scheduleDestroyAllActivities(String reason)2709 void scheduleDestroyAllActivities(String reason) { 2710 mDestroyAllActivitiesReason = reason; 2711 mService.mH.post(mDestroyAllActivitiesRunnable); 2712 } 2713 destroyActivity(ActivityRecord r)2714 private void destroyActivity(ActivityRecord r) { 2715 if (r.finishing || !r.isDestroyable()) return; 2716 2717 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.getState() 2718 + " resumed=" + r.getStack().mResumedActivity + " pausing=" 2719 + r.getStack().mPausingActivity + " for reason " + mDestroyAllActivitiesReason); 2720 2721 r.destroyImmediately(true /* removeFromTask */, mDestroyAllActivitiesReason); 2722 } 2723 2724 // Tries to put all activity stacks to sleep. Returns true if all stacks were 2725 // successfully put to sleep. putStacksToSleep(boolean allowDelay, boolean shuttingDown)2726 boolean putStacksToSleep(boolean allowDelay, boolean shuttingDown) { 2727 boolean allSleep = true; 2728 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2729 final DisplayContent display = getChildAt(displayNdx); 2730 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 2731 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 2732 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 2733 // Stacks and activities could be removed while putting activities to sleep if 2734 // the app process was gone. This prevents us getting exception by accessing an 2735 // invalid stack index. 2736 if (sNdx >= taskDisplayArea.getStackCount()) { 2737 continue; 2738 } 2739 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 2740 if (allowDelay) { 2741 allSleep &= stack.goToSleepIfPossible(shuttingDown); 2742 } else { 2743 stack.goToSleep(); 2744 } 2745 } 2746 } 2747 } 2748 return allSleep; 2749 } 2750 handleAppCrash(WindowProcessController app)2751 void handleAppCrash(WindowProcessController app) { 2752 final PooledConsumer c = PooledLambda.obtainConsumer( 2753 RootWindowContainer::handleAppCrash, PooledLambda.__(ActivityRecord.class), app); 2754 forAllActivities(c); 2755 c.recycle(); 2756 } 2757 handleAppCrash(ActivityRecord r, WindowProcessController app)2758 private static void handleAppCrash(ActivityRecord r, WindowProcessController app) { 2759 if (r.app != app) return; 2760 Slog.w(TAG, " Force finishing activity " 2761 + r.intent.getComponent().flattenToShortString()); 2762 r.app = null; 2763 r.getDisplay().mDisplayContent.prepareAppTransition( 2764 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */); 2765 r.destroyIfPossible("handleAppCrashed"); 2766 } 2767 findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters)2768 ActivityRecord findActivity(Intent intent, ActivityInfo info, boolean compareIntentFilters) { 2769 ComponentName cls = intent.getComponent(); 2770 if (info.targetActivity != null) { 2771 cls = new ComponentName(info.packageName, info.targetActivity); 2772 } 2773 final int userId = UserHandle.getUserId(info.applicationInfo.uid); 2774 2775 final PooledPredicate p = PooledLambda.obtainPredicate( 2776 RootWindowContainer::matchesActivity, PooledLambda.__(ActivityRecord.class), 2777 userId, compareIntentFilters, intent, cls); 2778 final ActivityRecord r = getActivity(p); 2779 p.recycle(); 2780 return r; 2781 } 2782 matchesActivity(ActivityRecord r, int userId, boolean compareIntentFilters, Intent intent, ComponentName cls)2783 private static boolean matchesActivity(ActivityRecord r, int userId, 2784 boolean compareIntentFilters, Intent intent, ComponentName cls) { 2785 if (!r.canBeTopRunning() || r.mUserId != userId) return false; 2786 2787 if (compareIntentFilters) { 2788 if (r.intent.filterEquals(intent)) { 2789 return true; 2790 } 2791 } else { 2792 // Compare the target component instead of intent component so we don't miss if the 2793 // activity uses alias. 2794 if (r.mActivityComponent.equals(cls)) { 2795 return true; 2796 } 2797 } 2798 return false; 2799 } 2800 hasAwakeDisplay()2801 boolean hasAwakeDisplay() { 2802 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 2803 final DisplayContent display = getChildAt(displayNdx); 2804 if (!display.shouldSleep()) { 2805 return true; 2806 } 2807 } 2808 return false; 2809 } 2810 getLaunchStack(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop)2811 ActivityStack getLaunchStack(@Nullable ActivityRecord r, 2812 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) { 2813 return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */, 2814 -1 /* no realCallingPid */, -1 /* no realCallingUid */); 2815 } 2816 2817 /** 2818 * Returns the right stack to use for launching factoring in all the input parameters. 2819 * 2820 * @param r The activity we are trying to launch. Can be null. 2821 * @param options The activity options used to the launch. Can be null. 2822 * @param candidateTask The possible task the activity might be launched in. Can be null. 2823 * @param launchParams The resolved launch params to use. 2824 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} 2825 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} 2826 * 2827 * @return The stack to use for the launch or INVALID_STACK_ID. 2828 */ getLaunchStack(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop, @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, int realCallingUid)2829 ActivityStack getLaunchStack(@Nullable ActivityRecord r, 2830 @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop, 2831 @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, 2832 int realCallingUid) { 2833 int taskId = INVALID_TASK_ID; 2834 int displayId = INVALID_DISPLAY; 2835 TaskDisplayArea taskDisplayArea = null; 2836 2837 // We give preference to the launch preference in activity options. 2838 if (options != null) { 2839 taskId = options.getLaunchTaskId(); 2840 displayId = options.getLaunchDisplayId(); 2841 final WindowContainerToken daToken = options.getLaunchTaskDisplayArea(); 2842 taskDisplayArea = daToken != null 2843 ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null; 2844 } 2845 2846 // First preference for stack goes to the task Id set in the activity options. Use the stack 2847 // associated with that if possible. 2848 if (taskId != INVALID_TASK_ID) { 2849 // Temporarily set the task id to invalid in case in re-entry. 2850 options.setLaunchTaskId(INVALID_TASK_ID); 2851 final Task task = anyTaskForId(taskId, 2852 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop); 2853 options.setLaunchTaskId(taskId); 2854 if (task != null) { 2855 return task.getStack(); 2856 } 2857 } 2858 2859 final int activityType = resolveActivityType(r, options, candidateTask); 2860 ActivityStack stack = null; 2861 2862 // Next preference for stack goes to the taskDisplayArea candidate. 2863 if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) { 2864 taskDisplayArea = launchParams.mPreferredTaskDisplayArea; 2865 } 2866 2867 if (taskDisplayArea == null && displayId != INVALID_DISPLAY) { 2868 final DisplayContent displayContent = getDisplayContent(displayId); 2869 if (displayContent != null) { 2870 taskDisplayArea = displayContent.getDefaultTaskDisplayArea(); 2871 } 2872 } 2873 2874 if (taskDisplayArea != null) { 2875 final int tdaDisplayId = taskDisplayArea.getDisplayId(); 2876 final boolean canLaunchOnDisplayFromStartRequest = 2877 realCallingPid != 0 && realCallingUid > 0 && r != null 2878 && mStackSupervisor.canPlaceEntityOnDisplay(tdaDisplayId, 2879 realCallingPid, realCallingUid, r.info); 2880 if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) { 2881 if (r != null) { 2882 final ActivityStack result = getValidLaunchStackInTaskDisplayArea( 2883 taskDisplayArea, r, candidateTask, options, launchParams); 2884 if (result != null) { 2885 return result; 2886 } 2887 } 2888 // Falling back to default task container 2889 taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea(); 2890 stack = taskDisplayArea.getOrCreateStack(r, options, candidateTask, activityType, 2891 onTop); 2892 if (stack != null) { 2893 return stack; 2894 } 2895 } 2896 } 2897 2898 // Give preference to the stack and display of the input task and activity if they match the 2899 // mode we want to launch into. 2900 TaskDisplayArea container = null; 2901 if (candidateTask != null) { 2902 stack = candidateTask.getStack(); 2903 } 2904 if (stack == null && r != null) { 2905 stack = r.getRootTask(); 2906 } 2907 int windowingMode = launchParams != null ? launchParams.mWindowingMode 2908 : WindowConfiguration.WINDOWING_MODE_UNDEFINED; 2909 if (stack != null) { 2910 container = stack.getDisplayArea(); 2911 if (container != null && canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) { 2912 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) { 2913 windowingMode = container.resolveWindowingMode(r, options, candidateTask, 2914 activityType); 2915 } 2916 // Always allow organized tasks that created by organizer since the activity type 2917 // of an organized task is decided by the activity type of its top child, which 2918 // could be incompatible with the given windowing mode and activity type. 2919 if (stack.isCompatible(windowingMode, activityType) || stack.mCreatedByOrganizer) { 2920 return stack; 2921 } 2922 if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY 2923 && container.getRootSplitScreenPrimaryTask() == stack 2924 && candidateTask == stack.getTopMostTask()) { 2925 // This is a special case when we try to launch an activity that is currently on 2926 // top of split-screen primary stack, but is targeting split-screen secondary. 2927 // In this case we don't want to move it to another stack. 2928 // TODO(b/78788972): Remove after differentiating between preferred and required 2929 // launch options. 2930 return stack; 2931 } 2932 } 2933 } 2934 2935 if (container == null 2936 || !canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) { 2937 container = getDefaultTaskDisplayArea(); 2938 if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) { 2939 windowingMode = container.resolveWindowingMode(r, options, candidateTask, 2940 activityType); 2941 } 2942 } 2943 2944 return container.getOrCreateStack(r, options, candidateTask, activityType, onTop); 2945 } 2946 2947 /** @return true if activity record is null or can be launched on provided display. */ canLaunchOnDisplay(ActivityRecord r, int displayId)2948 private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) { 2949 if (r == null) { 2950 return true; 2951 } 2952 return r.canBeLaunchedOnDisplay(displayId); 2953 } 2954 2955 /** 2956 * Get a topmost stack on the display area, that is a valid launch stack for specified activity. 2957 * If there is no such stack, new dynamic stack can be created. 2958 * @param taskDisplayArea Target display area. 2959 * @param r Activity that should be launched there. 2960 * @param candidateTask The possible task the activity might be put in. 2961 * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. 2962 */ 2963 @VisibleForTesting getValidLaunchStackInTaskDisplayArea(@onNull TaskDisplayArea taskDisplayArea, @NonNull ActivityRecord r, @Nullable Task candidateTask, @Nullable ActivityOptions options, @Nullable LaunchParamsController.LaunchParams launchParams)2964 ActivityStack getValidLaunchStackInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea, 2965 @NonNull ActivityRecord r, @Nullable Task candidateTask, 2966 @Nullable ActivityOptions options, 2967 @Nullable LaunchParamsController.LaunchParams launchParams) { 2968 if (!r.canBeLaunchedOnDisplay(taskDisplayArea.getDisplayId())) { 2969 return null; 2970 } 2971 2972 // If {@code r} is already in target display area and its task is the same as the candidate 2973 // task, the intention should be getting a launch stack for the reusable activity, so we can 2974 // use the existing stack. 2975 if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) { 2976 // TODO(b/153920825): Fix incorrect evaluation of attached state 2977 final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null 2978 ? r.getTask().getDisplayArea() : r.getDisplayArea(); 2979 if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) { 2980 return candidateTask.getStack(); 2981 } 2982 // Or the candidate task is already a root task that can be reused by reparenting 2983 // it to the target display. 2984 if (candidateTask.isRootTask()) { 2985 final ActivityStack stack = candidateTask.getStack(); 2986 stack.reparent(taskDisplayArea, true /* onTop */); 2987 return stack; 2988 } 2989 } 2990 2991 int windowingMode; 2992 if (launchParams != null) { 2993 // When launch params is not null, we always defer to its windowing mode. Sometimes 2994 // it could be unspecified, which indicates it should inherit windowing mode from 2995 // display. 2996 windowingMode = launchParams.mWindowingMode; 2997 } else { 2998 windowingMode = options != null ? options.getLaunchWindowingMode() 2999 : r.getWindowingMode(); 3000 } 3001 windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask, 3002 r.getActivityType()); 3003 3004 // Return the topmost valid stack on the display. 3005 for (int i = taskDisplayArea.getStackCount() - 1; i >= 0; --i) { 3006 final ActivityStack stack = taskDisplayArea.getStackAt(i); 3007 if (isValidLaunchStack(stack, r, windowingMode)) { 3008 return stack; 3009 } 3010 } 3011 3012 // If there is no valid stack on the secondary display area - check if new dynamic stack 3013 // will do. 3014 if (taskDisplayArea != getDisplayContent(taskDisplayArea.getDisplayId()) 3015 .getDefaultTaskDisplayArea()) { 3016 final int activityType = 3017 options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED 3018 ? options.getLaunchActivityType() : r.getActivityType(); 3019 return taskDisplayArea.createStack(windowingMode, activityType, true /*onTop*/); 3020 } 3021 3022 return null; 3023 } 3024 3025 // TODO: Can probably be consolidated into getLaunchStack()... isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode)3026 private boolean isValidLaunchStack(ActivityStack stack, ActivityRecord r, int windowingMode) { 3027 switch (stack.getActivityType()) { 3028 case ACTIVITY_TYPE_HOME: return r.isActivityTypeHome(); 3029 case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents(); 3030 case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant(); 3031 case ACTIVITY_TYPE_DREAM: return r.isActivityTypeDream(); 3032 } 3033 if (stack.mCreatedByOrganizer) { 3034 // Don't launch directly into task created by organizer...but why can't we? 3035 return false; 3036 } 3037 // There is a 1-to-1 relationship between stack and task when not in 3038 // primary split-windowing mode. 3039 if (stack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY 3040 && r.supportsSplitScreenWindowingMode() 3041 && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY 3042 || windowingMode == WINDOWING_MODE_UNDEFINED)) { 3043 return true; 3044 } 3045 return false; 3046 } 3047 resolveActivityType(@ullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task task)3048 int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options, 3049 @Nullable Task task) { 3050 // Preference is given to the activity type for the activity then the task since the type 3051 // once set shouldn't change. 3052 int activityType = r != null ? r.getActivityType() : ACTIVITY_TYPE_UNDEFINED; 3053 if (activityType == ACTIVITY_TYPE_UNDEFINED && task != null) { 3054 activityType = task.getActivityType(); 3055 } 3056 if (activityType != ACTIVITY_TYPE_UNDEFINED) { 3057 return activityType; 3058 } 3059 if (options != null) { 3060 activityType = options.getLaunchActivityType(); 3061 } 3062 return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD; 3063 } 3064 3065 /** 3066 * Get next focusable stack in the system. This will search through the stack on the same 3067 * display as the current focused stack, looking for a focusable and visible stack, different 3068 * from the target stack. If no valid candidates will be found, it will then go through all 3069 * displays and stacks in last-focused order. 3070 * 3071 * @param currentFocus The stack that previously had focus. 3072 * @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next 3073 * candidate. 3074 * @return Next focusable {@link ActivityStack}, {@code null} if not found. 3075 */ getNextFocusableStack(@onNull ActivityStack currentFocus, boolean ignoreCurrent)3076 ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus, 3077 boolean ignoreCurrent) { 3078 // First look for next focusable stack on the same display 3079 TaskDisplayArea preferredDisplayArea = currentFocus.getDisplayArea(); 3080 if (preferredDisplayArea == null) { 3081 // Stack is currently detached because it is being removed. Use the previous display it 3082 // was on. 3083 preferredDisplayArea = getDisplayContent(currentFocus.mPrevDisplayId) 3084 .getDefaultTaskDisplayArea(); 3085 } 3086 final ActivityStack preferredFocusableStack = preferredDisplayArea.getNextFocusableStack( 3087 currentFocus, ignoreCurrent); 3088 if (preferredFocusableStack != null) { 3089 return preferredFocusableStack; 3090 } 3091 if (preferredDisplayArea.mDisplayContent.supportsSystemDecorations()) { 3092 // Stop looking for focusable stack on other displays because the preferred display 3093 // supports system decorations. Home activity would be launched on the same display if 3094 // no focusable stack found. 3095 return null; 3096 } 3097 3098 // Now look through all displays 3099 for (int i = getChildCount() - 1; i >= 0; --i) { 3100 final DisplayContent display = getChildAt(i); 3101 if (display == preferredDisplayArea.mDisplayContent) { 3102 // We've already checked this one 3103 continue; 3104 } 3105 final ActivityStack nextFocusableStack = display.getDefaultTaskDisplayArea() 3106 .getNextFocusableStack(currentFocus, ignoreCurrent); 3107 if (nextFocusableStack != null) { 3108 return nextFocusableStack; 3109 } 3110 } 3111 3112 return null; 3113 } 3114 handleAppDied(WindowProcessController app)3115 boolean handleAppDied(WindowProcessController app) { 3116 boolean hasVisibleActivities = false; 3117 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 3118 final DisplayContent display = getChildAt(displayNdx); 3119 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3120 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 3121 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 3122 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 3123 hasVisibleActivities |= stack.handleAppDied(app); 3124 } 3125 } 3126 } 3127 return hasVisibleActivities; 3128 } 3129 closeSystemDialogActivities(String reason)3130 void closeSystemDialogActivities(String reason) { 3131 forAllActivities((r) -> { 3132 if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0 3133 || shouldCloseAssistant(r, reason)) { 3134 r.finishIfPossible(reason, true /* oomAdj */); 3135 } 3136 }); 3137 } 3138 shouldCloseAssistant(ActivityRecord r, String reason)3139 private boolean shouldCloseAssistant(ActivityRecord r, String reason) { 3140 if (!r.isActivityTypeAssistant()) return false; 3141 if (reason == SYSTEM_DIALOG_REASON_ASSIST) return false; 3142 // When the assistant is configured to be on top of the dream, it will have higher z-order 3143 // than other activities. If it is also opaque, it will prevent other activities from 3144 // starting. We want to close the assistant on closeSystemDialogs to allow other activities 3145 // to start, e.g. on home button press. 3146 return mWmService.mAssistantOnTopOfDream; 3147 } 3148 3149 FinishDisabledPackageActivitiesHelper mFinishDisabledPackageActivitiesHelper = 3150 new FinishDisabledPackageActivitiesHelper(); 3151 class FinishDisabledPackageActivitiesHelper { 3152 private boolean mDidSomething; 3153 private String mPackageName; 3154 private Set<String> mFilterByClasses; 3155 private boolean mDoit; 3156 private boolean mEvenPersistent; 3157 private int mUserId; 3158 private Task mLastTask; 3159 private ComponentName mHomeActivity; 3160 reset(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId)3161 private void reset(String packageName, Set<String> filterByClasses, 3162 boolean doit, boolean evenPersistent, int userId) { 3163 mDidSomething = false; 3164 mPackageName = packageName; 3165 mFilterByClasses = filterByClasses; 3166 mDoit = doit; 3167 mEvenPersistent = evenPersistent; 3168 mUserId = userId; 3169 mLastTask = null; 3170 mHomeActivity = null; 3171 } 3172 process(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId)3173 boolean process(String packageName, Set<String> filterByClasses, 3174 boolean doit, boolean evenPersistent, int userId) { 3175 reset(packageName, filterByClasses, doit, evenPersistent, userId); 3176 3177 final PooledFunction f = PooledLambda.obtainFunction( 3178 FinishDisabledPackageActivitiesHelper::processActivity, this, 3179 PooledLambda.__(ActivityRecord.class)); 3180 forAllActivities(f); 3181 f.recycle(); 3182 return mDidSomething; 3183 } 3184 processActivity(ActivityRecord r)3185 private boolean processActivity(ActivityRecord r) { 3186 final boolean sameComponent = 3187 (r.packageName.equals(mPackageName) && (mFilterByClasses == null 3188 || mFilterByClasses.contains(r.mActivityComponent.getClassName()))) 3189 || (mPackageName == null && r.mUserId == mUserId); 3190 if ((mUserId == UserHandle.USER_ALL || r.mUserId == mUserId) 3191 && (sameComponent || r.getTask() == mLastTask) 3192 && (r.app == null || mEvenPersistent || !r.app.isPersistent())) { 3193 if (!mDoit) { 3194 if (r.finishing) { 3195 // If this activity is just finishing, then it is not 3196 // interesting as far as something to stop. 3197 return false; 3198 } 3199 return true; 3200 } 3201 if (r.isActivityTypeHome()) { 3202 if (mHomeActivity != null && mHomeActivity.equals(r.mActivityComponent)) { 3203 Slog.i(TAG, "Skip force-stop again " + r); 3204 return false; 3205 } else { 3206 mHomeActivity = r.mActivityComponent; 3207 } 3208 } 3209 mDidSomething = true; 3210 Slog.i(TAG, " Force finishing activity " + r); 3211 mLastTask = r.getTask(); 3212 r.finishIfPossible("force-stop", true); 3213 } 3214 3215 return false; 3216 } 3217 } 3218 3219 /** @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)3220 boolean finishDisabledPackageActivities(String packageName, Set<String> filterByClasses, 3221 boolean doit, boolean evenPersistent, int userId) { 3222 return mFinishDisabledPackageActivitiesHelper.process(packageName, filterByClasses, doit, 3223 evenPersistent, userId); 3224 } 3225 updateActivityApplicationInfo(ApplicationInfo aInfo)3226 void updateActivityApplicationInfo(ApplicationInfo aInfo) { 3227 final String packageName = aInfo.packageName; 3228 final int userId = UserHandle.getUserId(aInfo.uid); 3229 final PooledConsumer c = PooledLambda.obtainConsumer( 3230 RootWindowContainer::updateActivityApplicationInfo, 3231 PooledLambda.__(ActivityRecord.class), aInfo, userId, packageName); 3232 forAllActivities(c); 3233 c.recycle(); 3234 } 3235 updateActivityApplicationInfo( ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName)3236 private static void updateActivityApplicationInfo( 3237 ActivityRecord r, ApplicationInfo aInfo, int userId, String packageName) { 3238 if (r.mUserId == userId && packageName.equals(r.packageName)) { 3239 r.updateApplicationInfo(aInfo); 3240 } 3241 } 3242 finishVoiceTask(IVoiceInteractionSession session)3243 void finishVoiceTask(IVoiceInteractionSession session) { 3244 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 3245 final DisplayContent display = getChildAt(displayNdx); 3246 int numTaskContainers = display.getTaskDisplayAreaCount(); 3247 for (int tdaNdx = 0; tdaNdx < numTaskContainers; tdaNdx++) { 3248 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 3249 final int numStacks = display.getStackCount(); 3250 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 3251 final ActivityStack stack = taskDisplayArea.getStackAt(stackNdx); 3252 stack.finishVoiceTask(session); 3253 } 3254 } 3255 } 3256 } 3257 3258 /** 3259 * Removes stacks in the input windowing modes from the system if they are of activity type 3260 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED 3261 */ removeStacksInWindowingModes(int... windowingModes)3262 void removeStacksInWindowingModes(int... windowingModes) { 3263 for (int i = getChildCount() - 1; i >= 0; --i) { 3264 getChildAt(i).removeStacksInWindowingModes(windowingModes); 3265 } 3266 } 3267 removeStacksWithActivityTypes(int... activityTypes)3268 void removeStacksWithActivityTypes(int... activityTypes) { 3269 for (int i = getChildCount() - 1; i >= 0; --i) { 3270 getChildAt(i).removeStacksWithActivityTypes(activityTypes); 3271 } 3272 } 3273 topRunningActivity()3274 ActivityRecord topRunningActivity() { 3275 for (int i = getChildCount() - 1; i >= 0; --i) { 3276 final ActivityRecord topActivity = getChildAt(i).topRunningActivity(); 3277 if (topActivity != null) { 3278 return topActivity; 3279 } 3280 } 3281 return null; 3282 } 3283 allResumedActivitiesIdle()3284 boolean allResumedActivitiesIdle() { 3285 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 3286 // TODO(b/117135575): Check resumed activities on all visible stacks. 3287 final DisplayContent display = getChildAt(displayNdx); 3288 if (display.isSleeping()) { 3289 // No resumed activities while display is sleeping. 3290 continue; 3291 } 3292 3293 // If the focused stack is not null or not empty, there should have some activities 3294 // resuming or resumed. Make sure these activities are idle. 3295 final ActivityStack stack = display.getFocusedStack(); 3296 if (stack == null || !stack.hasActivity()) { 3297 continue; 3298 } 3299 final ActivityRecord resumedActivity = stack.getResumedActivity(); 3300 if (resumedActivity == null || !resumedActivity.idle) { 3301 if (DEBUG_STATES) { 3302 Slog.d(TAG_STATES, "allResumedActivitiesIdle: stack=" 3303 + stack.getRootTaskId() + " " + resumedActivity + " not idle"); 3304 } 3305 return false; 3306 } 3307 } 3308 // Send launch end powerhint when idle 3309 sendPowerHintForLaunchEndIfNeeded(); 3310 return true; 3311 } 3312 allResumedActivitiesVisible()3313 boolean allResumedActivitiesVisible() { 3314 boolean foundResumed = false; 3315 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 3316 final DisplayContent display = getChildAt(displayNdx); 3317 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3318 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 3319 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 3320 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 3321 final ActivityRecord r = stack.getResumedActivity(); 3322 if (r != null) { 3323 if (!r.nowVisible) { 3324 return false; 3325 } 3326 foundResumed = true; 3327 } 3328 } 3329 } 3330 } 3331 return foundResumed; 3332 } 3333 allPausedActivitiesComplete()3334 boolean allPausedActivitiesComplete() { 3335 boolean pausing = true; 3336 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 3337 final DisplayContent display = getChildAt(displayNdx); 3338 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3339 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 3340 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 3341 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 3342 final ActivityRecord r = stack.mPausingActivity; 3343 if (r != null && !r.isState(PAUSED, STOPPED, STOPPING, FINISHING)) { 3344 if (DEBUG_STATES) { 3345 Slog.d(TAG_STATES, "allPausedActivitiesComplete: r=" + r 3346 + " state=" + r.getState()); 3347 pausing = false; 3348 } else { 3349 return false; 3350 } 3351 } 3352 } 3353 } 3354 } 3355 return pausing; 3356 } 3357 3358 /** 3359 * Find all visible task stacks containing {@param userId} and intercept them with an activity 3360 * to block out the contents and possibly start a credential-confirming intent. 3361 * 3362 * @param userId user handle for the locked managed profile. 3363 */ lockAllProfileTasks(@serIdInt int userId)3364 void lockAllProfileTasks(@UserIdInt int userId) { 3365 mService.deferWindowLayout(); 3366 try { 3367 final PooledConsumer c = PooledLambda.obtainConsumer( 3368 RootWindowContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class), 3369 userId); 3370 forAllLeafTasks(c, true /* traverseTopToBottom */); 3371 c.recycle(); 3372 } finally { 3373 mService.continueWindowLayout(); 3374 } 3375 } 3376 3377 /** 3378 * Detects whether we should show a lock screen in front of this task for a locked user. 3379 * <p> 3380 * We'll do this if either of the following holds: 3381 * <ul> 3382 * <li>The top activity explicitly belongs to {@param userId}.</li> 3383 * <li>The top activity returns a result to an activity belonging to {@param userId}.</li> 3384 * </ul> 3385 * 3386 * @return {@code true} if the top activity looks like it belongs to {@param userId}. 3387 */ taskTopActivityIsUser(Task task, @UserIdInt int userId)3388 private void taskTopActivityIsUser(Task task, @UserIdInt int userId) { 3389 // To handle the case that work app is in the task but just is not the top one. 3390 final ActivityRecord activityRecord = task.getTopNonFinishingActivity(); 3391 final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null); 3392 3393 // Check the task for a top activity belonging to userId, or returning a 3394 // result to an activity belonging to userId. Example case: a document 3395 // picker for personal files, opened by a work app, should still get locked. 3396 if ((activityRecord != null && activityRecord.mUserId == userId) 3397 || (resultTo != null && resultTo.mUserId == userId)) { 3398 mService.getTaskChangeNotificationController().notifyTaskProfileLocked( 3399 task.mTaskId, userId); 3400 } 3401 } 3402 cancelInitializingActivities()3403 void cancelInitializingActivities() { 3404 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 3405 final DisplayContent display = getChildAt(displayNdx); 3406 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3407 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 3408 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 3409 taskDisplayArea.getStackAt(sNdx).cancelInitializingActivities(); 3410 } 3411 } 3412 } 3413 } 3414 anyTaskForId(int id)3415 Task anyTaskForId(int id) { 3416 return anyTaskForId(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE); 3417 } 3418 anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode)3419 Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode) { 3420 return anyTaskForId(id, matchMode, null, !ON_TOP); 3421 } 3422 3423 /** 3424 * Returns a {@link Task} for the input id if available. {@code null} otherwise. 3425 * @param id Id of the task we would like returned. 3426 * @param matchMode The mode to match the given task id in. 3427 * @param aOptions The activity options to use for restoration. Can be null. 3428 * @param onTop If the stack for the task should be the topmost on the display. 3429 */ anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode, @Nullable ActivityOptions aOptions, boolean onTop)3430 Task anyTaskForId(int id, @RootWindowContainer.AnyTaskForIdMatchTaskMode int matchMode, 3431 @Nullable ActivityOptions aOptions, boolean onTop) { 3432 // If options are set, ensure that we are attempting to actually restore a task 3433 if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) { 3434 throw new IllegalArgumentException("Should not specify activity options for non-restore" 3435 + " lookup"); 3436 } 3437 3438 final PooledPredicate p = PooledLambda.obtainPredicate( 3439 Task::isTaskId, PooledLambda.__(Task.class), id); 3440 Task task = getTask(p); 3441 p.recycle(); 3442 3443 if (task != null) { 3444 if (aOptions != null) { 3445 // Resolve the stack the task should be placed in now based on options 3446 // and reparent if needed. 3447 final ActivityStack launchStack = 3448 getLaunchStack(null, aOptions, task, onTop); 3449 if (launchStack != null && task.getStack() != launchStack) { 3450 final int reparentMode = onTop 3451 ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE; 3452 task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME, 3453 "anyTaskForId"); 3454 } 3455 } 3456 return task; 3457 } 3458 3459 // If we are matching stack tasks only, return now 3460 if (matchMode == MATCH_TASK_IN_STACKS_ONLY) { 3461 return null; 3462 } 3463 3464 // Otherwise, check the recent tasks and return if we find it there and we are not restoring 3465 // the task from recents 3466 if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents"); 3467 task = mStackSupervisor.mRecentTasks.getTask(id); 3468 3469 if (task == null) { 3470 if (DEBUG_RECENTS) { 3471 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents"); 3472 } 3473 3474 return null; 3475 } 3476 3477 if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) { 3478 return task; 3479 } 3480 3481 // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE 3482 if (!mStackSupervisor.restoreRecentTaskLocked(task, aOptions, onTop)) { 3483 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, 3484 "Couldn't restore task id=" + id + " found in recents"); 3485 return null; 3486 } 3487 if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Restored task id=" + id + " from in recents"); 3488 return task; 3489 } 3490 isInAnyStack(IBinder token)3491 ActivityRecord isInAnyStack(IBinder token) { 3492 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 3493 return (r != null && r.isDescendantOf(this)) ? r : null; 3494 } 3495 3496 @VisibleForTesting getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list, boolean filterOnlyVisibleRecents, int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds)3497 void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list, 3498 boolean filterOnlyVisibleRecents, int callingUid, boolean allowed, boolean crossUser, 3499 ArraySet<Integer> profileIds) { 3500 mStackSupervisor.getRunningTasks().getTasks(maxNum, list, filterOnlyVisibleRecents, this, 3501 callingUid, allowed, crossUser, profileIds); 3502 } 3503 sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity)3504 void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) { 3505 boolean sendHint = forceSend; 3506 3507 if (!sendHint) { 3508 // Send power hint if we don't know what we're launching yet 3509 sendHint = targetActivity == null || targetActivity.app == null; 3510 } 3511 3512 if (!sendHint) { // targetActivity != null 3513 // Send power hint when the activity's process is different than the current top resumed 3514 // activity on all display areas, or if there are no resumed activities in the system. 3515 boolean noResumedActivities = true; 3516 boolean allFocusedProcessesDiffer = true; 3517 for (int displayNdx = 0; displayNdx < getChildCount(); ++displayNdx) { 3518 final DisplayContent dc = getChildAt(displayNdx); 3519 for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3520 final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx); 3521 final ActivityRecord resumedActivity = taskDisplayArea.getFocusedActivity(); 3522 final WindowProcessController resumedActivityProcess = 3523 resumedActivity == null ? null : resumedActivity.app; 3524 3525 noResumedActivities &= resumedActivityProcess == null; 3526 if (resumedActivityProcess != null) { 3527 allFocusedProcessesDiffer &= !resumedActivityProcess.equals( 3528 targetActivity.app); 3529 } 3530 } 3531 } 3532 sendHint = noResumedActivities || allFocusedProcessesDiffer; 3533 } 3534 3535 if (sendHint && mService.mPowerManagerInternal != null) { 3536 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1); 3537 mPowerHintSent = true; 3538 } 3539 } 3540 sendPowerHintForLaunchEndIfNeeded()3541 void sendPowerHintForLaunchEndIfNeeded() { 3542 // Trigger launch power hint if activity is launched 3543 if (mPowerHintSent && mService.mPowerManagerInternal != null) { 3544 mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0); 3545 mPowerHintSent = false; 3546 } 3547 } 3548 calculateDefaultMinimalSizeOfResizeableTasks()3549 private void calculateDefaultMinimalSizeOfResizeableTasks() { 3550 final Resources res = mService.mContext.getResources(); 3551 final float minimalSize = res.getDimension( 3552 com.android.internal.R.dimen.default_minimal_size_resizable_task); 3553 final DisplayMetrics dm = res.getDisplayMetrics(); 3554 3555 mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density); 3556 } 3557 3558 /** 3559 * Dumps the activities matching the given {@param name} in the either the focused stack 3560 * or all visible stacks if {@param dumpVisibleStacks} is true. 3561 */ getDumpActivities(String name, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly)3562 ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleStacksOnly, 3563 boolean dumpFocusedStackOnly) { 3564 if (dumpFocusedStackOnly) { 3565 final ActivityStack topFocusedStack = getTopDisplayFocusedStack(); 3566 if (topFocusedStack != null) { 3567 return topFocusedStack.getDumpActivitiesLocked(name); 3568 } else { 3569 return new ArrayList<>(); 3570 } 3571 } else { 3572 ArrayList<ActivityRecord> activities = new ArrayList<>(); 3573 int numDisplays = getChildCount(); 3574 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 3575 final DisplayContent display = getChildAt(displayNdx); 3576 for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3577 final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); 3578 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 3579 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 3580 if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) { 3581 activities.addAll(stack.getDumpActivitiesLocked(name)); 3582 } 3583 } 3584 } 3585 } 3586 return activities; 3587 } 3588 } 3589 3590 @Override dump(PrintWriter pw, String prefix, boolean dumpAll)3591 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 3592 super.dump(pw, prefix, dumpAll); 3593 pw.print(prefix); 3594 pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack()); 3595 for (int i = getChildCount() - 1; i >= 0; --i) { 3596 final DisplayContent display = getChildAt(i); 3597 display.dump(pw, prefix, dumpAll); 3598 } 3599 pw.println(); 3600 } 3601 3602 /** 3603 * Dump all connected displays' configurations. 3604 * @param prefix Prefix to apply to each line of the dump. 3605 */ dumpDisplayConfigs(PrintWriter pw, String prefix)3606 void dumpDisplayConfigs(PrintWriter pw, String prefix) { 3607 pw.print(prefix); pw.println("Display override configurations:"); 3608 final int displayCount = getChildCount(); 3609 for (int i = 0; i < displayCount; i++) { 3610 final DisplayContent displayContent = getChildAt(i); 3611 pw.print(prefix); pw.print(" "); pw.print(displayContent.mDisplayId); pw.print(": "); 3612 pw.println(displayContent.getRequestedOverrideConfiguration()); 3613 } 3614 } 3615 dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, String dumpPackage)3616 boolean dumpActivities(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, 3617 String dumpPackage) { 3618 boolean printed = false; 3619 boolean needSep = false; 3620 for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { 3621 DisplayContent displayContent = getChildAt(displayNdx); 3622 if (printed) { 3623 pw.println(); 3624 } 3625 pw.print("Display #"); pw.print(displayContent.mDisplayId); 3626 pw.println(" (activities from top to bottom):"); 3627 for (int tdaNdx = displayContent.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3628 final TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(tdaNdx); 3629 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { 3630 final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); 3631 if (needSep) { 3632 pw.println(); 3633 } 3634 needSep = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, false); 3635 printed |= needSep; 3636 } 3637 } 3638 for (int tdaNdx = displayContent.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { 3639 final TaskDisplayArea taskDisplayArea = displayContent.getTaskDisplayAreaAt(tdaNdx); 3640 printed |= printThisActivity(pw, taskDisplayArea.getFocusedActivity(), 3641 dumpPackage, needSep, " Resumed: ", () -> { 3642 pw.println(" Resumed activities in task display areas" 3643 + " (from top to bottom):"); 3644 }); 3645 } 3646 } 3647 3648 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mFinishingActivities, " ", 3649 "Fin", false, !dumpAll, 3650 false, dumpPackage, true, 3651 () -> { pw.println(" Activities waiting to finish:"); }, null); 3652 printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ", 3653 "Stop", false, !dumpAll, 3654 false, dumpPackage, true, 3655 () -> { pw.println(" Activities waiting to stop:"); }, null); 3656 3657 return printed; 3658 } 3659 3660 private final class SleepTokenImpl extends ActivityTaskManagerInternal.SleepToken { 3661 private final String mTag; 3662 private final long mAcquireTime; 3663 private final int mDisplayId; 3664 SleepTokenImpl(String tag, int displayId)3665 public SleepTokenImpl(String tag, int displayId) { 3666 mTag = tag; 3667 mDisplayId = displayId; 3668 mAcquireTime = SystemClock.uptimeMillis(); 3669 } 3670 3671 @Override release()3672 public void release() { 3673 synchronized (mService.mGlobalLock) { 3674 removeSleepToken(this); 3675 } 3676 } 3677 3678 @Override toString()3679 public String toString() { 3680 return "{\"" + mTag + "\", display " + mDisplayId 3681 + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}"; 3682 } 3683 } 3684 } 3685