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