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