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