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