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