1 /* 2 * Copyright (C) 2007 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.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; 20 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 21 import static android.Manifest.permission.MANAGE_APP_TOKENS; 22 import static android.Manifest.permission.READ_FRAME_BUFFER; 23 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS; 24 import static android.Manifest.permission.RESTRICTED_VR_ACCESS; 25 import static android.Manifest.permission.WRITE_SECURE_SETTINGS; 26 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; 27 import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; 28 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; 29 import static android.app.StatusBarManager.DISABLE_MASK; 30 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; 31 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 32 import static android.os.Process.SYSTEM_UID; 33 import static android.os.Process.myPid; 34 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 35 import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE; 36 import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP; 37 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS; 38 import static android.view.Display.DEFAULT_DISPLAY; 39 import static android.view.Display.INVALID_DISPLAY; 40 import static android.view.WindowManager.DOCKED_INVALID; 41 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; 42 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 43 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 44 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; 45 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 46 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 47 import static android.view.WindowManager.LayoutParams.FLAG_SECURE; 48 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 49 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 50 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL; 51 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 52 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 53 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; 54 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; 55 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 56 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 57 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 58 import static android.view.WindowManager.LayoutParams.TYPE_DRAG; 59 import static android.view.WindowManager.LayoutParams.TYPE_DREAM; 60 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 61 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 62 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 63 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; 64 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; 65 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; 66 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; 67 import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 68 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; 69 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 70 import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED; 71 import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY; 72 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; 73 import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID; 74 75 import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN; 76 import static com.android.server.LockGuard.INDEX_WINDOW; 77 import static com.android.server.LockGuard.installLock; 78 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 79 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; 80 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; 81 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; 82 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; 83 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; 84 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; 85 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; 86 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; 87 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD; 88 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON; 89 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; 90 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; 91 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; 92 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON; 93 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; 94 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 95 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; 96 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; 97 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; 98 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS; 99 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; 100 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS; 101 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON; 102 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 103 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 104 import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN; 105 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP; 106 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_WINDOW; 107 import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW; 108 import static com.android.server.wm.WindowManagerServiceDumpProto.LAST_ORIENTATION; 109 import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY; 110 import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER; 111 import static com.android.server.wm.WindowManagerServiceDumpProto.ROTATION; 112 113 import android.Manifest; 114 import android.Manifest.permission; 115 import android.animation.ValueAnimator; 116 import android.annotation.IntDef; 117 import android.annotation.NonNull; 118 import android.annotation.Nullable; 119 import android.app.ActivityManager; 120 import android.app.ActivityManager.TaskSnapshot; 121 import android.app.ActivityManagerInternal; 122 import android.app.ActivityTaskManager; 123 import android.app.ActivityThread; 124 import android.app.AppOpsManager; 125 import android.app.IActivityManager; 126 import android.app.IActivityTaskManager; 127 import android.app.IAssistDataReceiver; 128 import android.app.WindowConfiguration; 129 import android.app.admin.DevicePolicyCache; 130 import android.content.BroadcastReceiver; 131 import android.content.ContentResolver; 132 import android.content.Context; 133 import android.content.Intent; 134 import android.content.IntentFilter; 135 import android.content.pm.ApplicationInfo; 136 import android.content.pm.PackageManager; 137 import android.content.pm.PackageManagerInternal; 138 import android.content.res.Configuration; 139 import android.database.ContentObserver; 140 import android.graphics.Bitmap; 141 import android.graphics.Insets; 142 import android.graphics.Matrix; 143 import android.graphics.PixelFormat; 144 import android.graphics.Point; 145 import android.graphics.Rect; 146 import android.graphics.RectF; 147 import android.graphics.Region; 148 import android.hardware.configstore.V1_0.ISurfaceFlingerConfigs; 149 import android.hardware.configstore.V1_0.OptionalBool; 150 import android.hardware.display.DisplayManager; 151 import android.hardware.display.DisplayManagerInternal; 152 import android.hardware.input.InputManager; 153 import android.hardware.input.InputManagerInternal; 154 import android.net.Uri; 155 import android.os.Binder; 156 import android.os.Build; 157 import android.os.Bundle; 158 import android.os.Debug; 159 import android.os.Handler; 160 import android.os.HandlerExecutor; 161 import android.os.IBinder; 162 import android.os.IRemoteCallback; 163 import android.os.Looper; 164 import android.os.Message; 165 import android.os.Parcel; 166 import android.os.ParcelFileDescriptor; 167 import android.os.PowerManager; 168 import android.os.PowerManager.ServiceType; 169 import android.os.PowerManagerInternal; 170 import android.os.PowerSaveState; 171 import android.os.RemoteException; 172 import android.os.ResultReceiver; 173 import android.os.ServiceManager; 174 import android.os.ShellCallback; 175 import android.os.StrictMode; 176 import android.os.SystemClock; 177 import android.os.SystemProperties; 178 import android.os.SystemService; 179 import android.os.Trace; 180 import android.os.UserHandle; 181 import android.os.WorkSource; 182 import android.provider.DeviceConfig; 183 import android.provider.Settings; 184 import android.service.vr.IVrManager; 185 import android.service.vr.IVrStateCallbacks; 186 import android.text.format.DateUtils; 187 import android.util.ArrayMap; 188 import android.util.ArraySet; 189 import android.util.DisplayMetrics; 190 import android.util.EventLog; 191 import android.util.Log; 192 import android.util.MergedConfiguration; 193 import android.util.Slog; 194 import android.util.SparseArray; 195 import android.util.SparseBooleanArray; 196 import android.util.TimeUtils; 197 import android.util.TypedValue; 198 import android.util.proto.ProtoOutputStream; 199 import android.view.Choreographer; 200 import android.view.Display; 201 import android.view.DisplayCutout; 202 import android.view.DisplayInfo; 203 import android.view.Gravity; 204 import android.view.IAppTransitionAnimationSpecsFuture; 205 import android.view.IDisplayFoldListener; 206 import android.view.IDockedStackListener; 207 import android.view.IInputFilter; 208 import android.view.IOnKeyguardExitResult; 209 import android.view.IPinnedStackListener; 210 import android.view.IRecentsAnimationRunner; 211 import android.view.IRotationWatcher; 212 import android.view.ISystemGestureExclusionListener; 213 import android.view.IWallpaperVisibilityListener; 214 import android.view.IWindow; 215 import android.view.IWindowId; 216 import android.view.IWindowManager; 217 import android.view.IWindowSession; 218 import android.view.IWindowSessionCallback; 219 import android.view.InputChannel; 220 import android.view.InputDevice; 221 import android.view.InputEvent; 222 import android.view.InputEventReceiver; 223 import android.view.InsetsState; 224 import android.view.KeyEvent; 225 import android.view.MagnificationSpec; 226 import android.view.MotionEvent; 227 import android.view.PointerIcon; 228 import android.view.RemoteAnimationAdapter; 229 import android.view.Surface; 230 import android.view.SurfaceControl; 231 import android.view.SurfaceSession; 232 import android.view.View; 233 import android.view.WindowContentFrameStats; 234 import android.view.WindowManager; 235 import android.view.WindowManager.LayoutParams; 236 import android.view.WindowManager.RemoveContentMode; 237 import android.view.WindowManager.TransitionType; 238 import android.view.WindowManagerGlobal; 239 import android.view.WindowManagerPolicyConstants.PointerEventListener; 240 241 import com.android.internal.R; 242 import com.android.internal.annotations.VisibleForTesting; 243 import com.android.internal.os.BackgroundThread; 244 import com.android.internal.os.IResultReceiver; 245 import com.android.internal.policy.IKeyguardDismissCallback; 246 import com.android.internal.policy.IShortcutService; 247 import com.android.internal.util.DumpUtils; 248 import com.android.internal.util.FastPrintWriter; 249 import com.android.internal.util.LatencyTracker; 250 import com.android.internal.util.Preconditions; 251 import com.android.internal.util.function.pooled.PooledLambda; 252 import com.android.internal.view.WindowManagerPolicyThread; 253 import com.android.server.AnimationThread; 254 import com.android.server.DisplayThread; 255 import com.android.server.EventLogTags; 256 import com.android.server.FgThread; 257 import com.android.server.LocalServices; 258 import com.android.server.UiThread; 259 import com.android.server.Watchdog; 260 import com.android.server.input.InputManagerService; 261 import com.android.server.policy.WindowManagerPolicy; 262 import com.android.server.policy.WindowManagerPolicy.ScreenOffListener; 263 import com.android.server.power.ShutdownThread; 264 import com.android.server.utils.PriorityDump; 265 266 import java.io.BufferedWriter; 267 import java.io.DataInputStream; 268 import java.io.File; 269 import java.io.FileDescriptor; 270 import java.io.FileInputStream; 271 import java.io.FileNotFoundException; 272 import java.io.IOException; 273 import java.io.OutputStream; 274 import java.io.OutputStreamWriter; 275 import java.io.PrintWriter; 276 import java.io.StringWriter; 277 import java.lang.annotation.Retention; 278 import java.lang.annotation.RetentionPolicy; 279 import java.net.Socket; 280 import java.text.DateFormat; 281 import java.util.ArrayList; 282 import java.util.Arrays; 283 import java.util.Date; 284 import java.util.List; 285 286 /** {@hide} */ 287 public class WindowManagerService extends IWindowManager.Stub 288 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { 289 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowManagerService" : TAG_WM; 290 291 static final int LAYOUT_REPEAT_THRESHOLD = 4; 292 293 static final boolean PROFILE_ORIENTATION = false; 294 static final boolean localLOGV = DEBUG; 295 296 /** How much to multiply the policy's type layer, to reserve room 297 * for multiple windows of the same type and Z-ordering adjustment 298 * with TYPE_LAYER_OFFSET. */ 299 static final int TYPE_LAYER_MULTIPLIER = 10000; 300 301 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above 302 * or below others in the same layer. */ 303 static final int TYPE_LAYER_OFFSET = 1000; 304 305 /** How much to increment the layer for each window, to reserve room 306 * for effect surfaces between them. 307 */ 308 static final int WINDOW_LAYER_MULTIPLIER = 5; 309 310 /** 311 * Dim surface layer is immediately below target window. 312 */ 313 static final int LAYER_OFFSET_DIM = 1; 314 315 /** 316 * Animation thumbnail is as far as possible below the window above 317 * the thumbnail (or in other words as far as possible above the window 318 * below it). 319 */ 320 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER - 1; 321 322 /** The maximum length we will accept for a loaded animation duration: 323 * this is 10 seconds. 324 */ 325 static final int MAX_ANIMATION_DURATION = 10 * 1000; 326 327 /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */ 328 static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000; 329 330 /** Amount of time (in milliseconds) to delay before declaring a seamless rotation timeout. */ 331 static final int SEAMLESS_ROTATION_TIMEOUT_DURATION = 2000; 332 333 /** Amount of time (in milliseconds) to delay before declaring a window replacement timeout. */ 334 static final int WINDOW_REPLACEMENT_TIMEOUT_DURATION = 2000; 335 336 /** Amount of time to allow a last ANR message to exist before freeing the memory. */ 337 static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours 338 /** 339 * If true, the window manager will do its own custom freezing and general 340 * management of the screen during rotation. 341 */ 342 static final boolean CUSTOM_SCREEN_ROTATION = true; 343 344 // Maximum number of milliseconds to wait for input devices to be enumerated before 345 // proceding with safe mode detection. 346 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000; 347 348 // Default input dispatching timeout in nanoseconds. 349 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L; 350 351 // Poll interval in milliseconds for watching boot animation finished. 352 private static final int BOOT_ANIMATION_POLL_INTERVAL = 200; 353 354 // The name of the boot animation service in init.rc. 355 private static final String BOOT_ANIMATION_SERVICE = "bootanim"; 356 357 static final int UPDATE_FOCUS_NORMAL = 0; 358 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1; 359 static final int UPDATE_FOCUS_PLACING_SURFACES = 2; 360 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3; 361 /** Indicates we are removing the focused window when updating the focus. */ 362 static final int UPDATE_FOCUS_REMOVING_FOCUS = 4; 363 364 private static final String SYSTEM_SECURE = "ro.secure"; 365 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 366 367 private static final String DENSITY_OVERRIDE = "ro.config.density_override"; 368 private static final String SIZE_OVERRIDE = "ro.config.size_override"; 369 370 private static final int MAX_SCREENSHOT_RETRIES = 3; 371 372 private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular"; 373 374 // Used to indicate that if there is already a transition set, it should be preserved when 375 // trying to apply a new one. 376 private static final boolean ALWAYS_KEEP_CURRENT = true; 377 378 // Enums for animation scale update types. 379 @Retention(RetentionPolicy.SOURCE) 380 @IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE}) 381 private @interface UpdateAnimationScaleMode {}; 382 private static final int WINDOW_ANIMATION_SCALE = 0; 383 private static final int TRANSITION_ANIMATION_SCALE = 1; 384 private static final int ANIMATION_DURATION_SCALE = 2; 385 386 private static final int ANIMATION_COMPLETED_TIMEOUT_MS = 5000; 387 388 private static final int MIN_GESTURE_EXCLUSION_LIMIT_DP = 200; 389 390 final WindowTracing mWindowTracing; 391 392 final private KeyguardDisableHandler mKeyguardDisableHandler; 393 // TODO: eventually unify all keyguard state in a common place instead of having it spread over 394 // AM's KeyguardController and the policy's KeyguardServiceDelegate. 395 boolean mKeyguardGoingAway; 396 boolean mKeyguardOrAodShowingOnDefaultDisplay; 397 // VR Vr2d Display Id. 398 int mVr2dDisplayId = INVALID_DISPLAY; 399 boolean mVrModeEnabled = false; 400 401 private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { 402 @Override 403 public void onVrStateChanged(boolean enabled) { 404 synchronized (mGlobalLock) { 405 mVrModeEnabled = enabled; 406 mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer( 407 DisplayPolicy::onVrStateChangedLw, PooledLambda.__(), enabled)); 408 } 409 } 410 }; 411 412 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 413 @Override 414 public void onReceive(Context context, Intent intent) { 415 switch (intent.getAction()) { 416 case ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED: 417 mKeyguardDisableHandler.updateKeyguardEnabled(getSendingUserId()); 418 break; 419 } 420 } 421 }; 422 final WindowSurfacePlacer mWindowPlacerLocked; 423 424 private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() { 425 @Override 426 public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, 427 boolean asProto) { 428 // Bugreport dumps the trace 2x, 1x as proto and 1x as text. Save file to disk only 1x. 429 if (asProto && mWindowTracing.isEnabled()) { 430 mWindowTracing.stopTrace(null, false /* writeToFile */); 431 BackgroundThread.getHandler().post(() -> { 432 mWindowTracing.writeTraceToFile(); 433 mWindowTracing.startTrace(null); 434 }); 435 } 436 doDump(fd, pw, new String[] {"-a"}, asProto); 437 } 438 439 @Override 440 public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { 441 doDump(fd, pw, args, asProto); 442 } 443 }; 444 445 /** 446 * Current user when multi-user is enabled. Don't show windows of 447 * non-current user. Also see mCurrentProfileIds. 448 */ 449 int mCurrentUserId; 450 /** 451 * Users that are profiles of the current user. These are also allowed to show windows 452 * on the current user. 453 */ 454 int[] mCurrentProfileIds = new int[] {}; 455 456 final Context mContext; 457 458 final boolean mHasPermanentDpad; 459 final long mDrawLockTimeoutMillis; 460 final boolean mAllowAnimationsInLowPowerMode; 461 462 // TODO(b/122671846) Remove the flag below in favor of isLowRam once feature is stable 463 /** 464 * Use very low resolution task snapshots. Replaces task snapshot starting windows with 465 * splashscreen starting windows. Used on low RAM devices to save memory. 466 */ 467 final boolean mLowRamTaskSnapshotsAndRecents; 468 469 final boolean mAllowBootMessages; 470 471 final boolean mLimitedAlphaCompositing; 472 final int mMaxUiWidth; 473 474 @VisibleForTesting 475 WindowManagerPolicy mPolicy; 476 477 final IActivityManager mActivityManager; 478 // TODO: Probably not needed once activities are fully in WM. 479 final IActivityTaskManager mActivityTaskManager; 480 final ActivityManagerInternal mAmInternal; 481 final ActivityTaskManagerInternal mAtmInternal; 482 483 final AppOpsManager mAppOps; 484 final PackageManagerInternal mPmInternal; 485 486 final DisplayWindowSettings mDisplayWindowSettings; 487 488 /** If the system should display notifications for apps displaying an alert window. */ 489 boolean mShowAlertWindowNotifications = true; 490 491 /** 492 * All currently active sessions with clients. 493 */ 494 final ArraySet<Session> mSessions = new ArraySet<>(); 495 496 /** Mapping from an IWindow IBinder to the server's Window object. */ 497 final WindowHashMap mWindowMap = new WindowHashMap(); 498 499 /** Global service lock used by the package the owns this service. */ 500 final WindowManagerGlobalLock mGlobalLock; 501 502 /** 503 * List of app window tokens that are waiting for replacing windows. If the 504 * replacement doesn't come in time the stale windows needs to be disposed of. 505 */ 506 final ArrayList<AppWindowToken> mWindowReplacementTimeouts = new ArrayList<>(); 507 508 /** 509 * Windows that are being resized. Used so we can tell the client about 510 * the resize after closing the transaction in which we resized the 511 * underlying surface. 512 */ 513 final ArrayList<WindowState> mResizingWindows = new ArrayList<>(); 514 515 /** 516 * Windows whose animations have ended and now must be removed. 517 */ 518 final ArrayList<WindowState> mPendingRemove = new ArrayList<>(); 519 520 /** 521 * Used when processing mPendingRemove to avoid working on the original array. 522 */ 523 WindowState[] mPendingRemoveTmp = new WindowState[20]; 524 525 // TODO: use WindowProcessController once go/wm-unified is done. 526 /** Mapping of process pids to configurations */ 527 final SparseArray<Configuration> mProcessConfigurations = new SparseArray<>(); 528 529 /** 530 * Windows whose surface should be destroyed. 531 */ 532 final ArrayList<WindowState> mDestroySurface = new ArrayList<>(); 533 534 /** 535 * Windows with a preserved surface waiting to be destroyed. These windows 536 * are going through a surface change. We keep the old surface around until 537 * the first frame on the new surface finishes drawing. 538 */ 539 final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>(); 540 541 /** 542 * This is set when we have run out of memory, and will either be an empty 543 * list or contain windows that need to be force removed. 544 */ 545 final ArrayList<WindowState> mForceRemoves = new ArrayList<>(); 546 547 /** 548 * Windows that clients are waiting to have drawn. 549 */ 550 ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>(); 551 /** 552 * And the callback to make when they've all been drawn. 553 */ 554 Runnable mWaitingForDrawnCallback; 555 556 /** List of window currently causing non-system overlay windows to be hidden. */ 557 private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>(); 558 559 AccessibilityController mAccessibilityController; 560 private RecentsAnimationController mRecentsAnimationController; 561 562 Watermark mWatermark; 563 StrictModeFlash mStrictModeFlash; 564 CircularDisplayMask mCircularDisplayMask; 565 EmulatorDisplayOverlay mEmulatorDisplayOverlay; 566 567 final float[] mTmpFloats = new float[9]; 568 final Rect mTmpRect = new Rect(); 569 final Rect mTmpRect2 = new Rect(); 570 final Rect mTmpRect3 = new Rect(); 571 final RectF mTmpRectF = new RectF(); 572 573 final Matrix mTmpTransform = new Matrix(); 574 575 boolean mDisplayReady; 576 boolean mSafeMode; 577 boolean mDisplayEnabled = false; 578 boolean mSystemBooted = false; 579 boolean mForceDisplayEnabled = false; 580 boolean mShowingBootMessages = false; 581 boolean mBootAnimationStopped = false; 582 boolean mSystemReady = false; 583 584 // Following variables are for debugging screen wakelock only. 585 WindowState mLastWakeLockHoldingWindow = null; 586 WindowState mLastWakeLockObscuringWindow = null; 587 588 /** Dump of the windows and app tokens at the time of the last ANR. Cleared after 589 * LAST_ANR_LIFETIME_DURATION_MSECS */ 590 String mLastANRState; 591 592 // The root of the device window hierarchy. 593 RootWindowContainer mRoot; 594 595 int mDockedStackCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; 596 Rect mDockedStackCreateBounds; 597 598 boolean mForceResizableTasks; 599 boolean mSupportsPictureInPicture; 600 boolean mSupportsFreeformWindowManagement; 601 boolean mIsPc; 602 /** 603 * Flag that indicates that desktop mode is forced for public secondary screens. 604 * 605 * This includes several settings: 606 * - Set freeform windowing mode on external screen if it's supported and enabled. 607 * - Enable system decorations and IME on external screen. 608 * - TODO: Show mouse pointer on external screen. 609 */ 610 boolean mForceDesktopModeOnExternalDisplays; 611 612 boolean mDisableTransitionAnimation; 613 getDragLayerLocked()614 int getDragLayerLocked() { 615 return mPolicy.getWindowLayerFromTypeLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; 616 } 617 618 class RotationWatcher { 619 final IRotationWatcher mWatcher; 620 final IBinder.DeathRecipient mDeathRecipient; 621 final int mDisplayId; RotationWatcher(IRotationWatcher watcher, IBinder.DeathRecipient deathRecipient, int displayId)622 RotationWatcher(IRotationWatcher watcher, IBinder.DeathRecipient deathRecipient, 623 int displayId) { 624 mWatcher = watcher; 625 mDeathRecipient = deathRecipient; 626 mDisplayId = displayId; 627 } 628 } 629 630 ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>(); 631 final WallpaperVisibilityListeners mWallpaperVisibilityListeners = 632 new WallpaperVisibilityListeners(); 633 634 boolean mDisplayFrozen = false; 635 long mDisplayFreezeTime = 0; 636 int mLastDisplayFreezeDuration = 0; 637 Object mLastFinishedFreezeSource = null; 638 boolean mSwitchingUser = false; 639 640 final static int WINDOWS_FREEZING_SCREENS_NONE = 0; 641 final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1; 642 final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2; 643 int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE; 644 645 boolean mClientFreezingScreen = false; 646 int mAppsFreezingScreen = 0; 647 648 @VisibleForTesting 649 boolean mPerDisplayFocusEnabled; 650 651 // State while inside of layoutAndPlaceSurfacesLocked(). 652 boolean mFocusMayChange; 653 654 // This is held as long as we have the screen frozen, to give us time to 655 // perform a rotation animation when turning off shows the lock screen which 656 // changes the orientation. 657 private final PowerManager.WakeLock mScreenFrozenLock; 658 659 final TaskSnapshotController mTaskSnapshotController; 660 661 boolean mIsTouchDevice; 662 663 final H mH = new H(); 664 665 /** 666 * Handler for things to run that have direct impact on an animation, i.e. animation tick, 667 * layout, starting window creation, whereas {@link H} runs things that are still important, but 668 * not as critical. 669 */ 670 final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper()); 671 672 boolean mHardKeyboardAvailable; 673 WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; 674 SettingsObserver mSettingsObserver; 675 676 /** 677 * A count of the windows which are 'seamlessly rotated', e.g. a surface 678 * at an old orientation is being transformed. We freeze orientation updates 679 * while any windows are seamlessly rotated, so we need to track when this 680 * hits zero so we can apply deferred orientation updates. 681 */ 682 private int mSeamlessRotationCount = 0; 683 /** 684 * True in the interval from starting seamless rotation until the last rotated 685 * window draws in the new orientation. 686 */ 687 private boolean mRotatingSeamlessly = false; 688 689 private final class SettingsObserver extends ContentObserver { 690 private final Uri mDisplayInversionEnabledUri = 691 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); 692 private final Uri mWindowAnimationScaleUri = 693 Settings.Global.getUriFor(Settings.Global.WINDOW_ANIMATION_SCALE); 694 private final Uri mTransitionAnimationScaleUri = 695 Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE); 696 private final Uri mAnimationDurationScaleUri = 697 Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE); 698 private final Uri mImmersiveModeConfirmationsUri = 699 Settings.Secure.getUriFor(Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS); 700 private final Uri mPolicyControlUri = 701 Settings.Global.getUriFor(Settings.Global.POLICY_CONTROL); 702 private final Uri mPointerLocationUri = 703 Settings.System.getUriFor(Settings.System.POINTER_LOCATION); 704 SettingsObserver()705 public SettingsObserver() { 706 super(new Handler()); 707 ContentResolver resolver = mContext.getContentResolver(); 708 resolver.registerContentObserver(mDisplayInversionEnabledUri, false, this, 709 UserHandle.USER_ALL); 710 resolver.registerContentObserver(mWindowAnimationScaleUri, false, this, 711 UserHandle.USER_ALL); 712 resolver.registerContentObserver(mTransitionAnimationScaleUri, false, this, 713 UserHandle.USER_ALL); 714 resolver.registerContentObserver(mAnimationDurationScaleUri, false, this, 715 UserHandle.USER_ALL); 716 resolver.registerContentObserver(mImmersiveModeConfirmationsUri, false, this, 717 UserHandle.USER_ALL); 718 resolver.registerContentObserver(mPolicyControlUri, false, this, UserHandle.USER_ALL); 719 resolver.registerContentObserver(mPointerLocationUri, false, this, UserHandle.USER_ALL); 720 } 721 722 @Override onChange(boolean selfChange, Uri uri)723 public void onChange(boolean selfChange, Uri uri) { 724 if (uri == null) { 725 return; 726 } 727 728 if (mImmersiveModeConfirmationsUri.equals(uri) || mPolicyControlUri.equals(uri)) { 729 updateSystemUiSettings(); 730 return; 731 } 732 733 if (mDisplayInversionEnabledUri.equals(uri)) { 734 updateCircularDisplayMaskIfNeeded(); 735 return; 736 } 737 738 if (mPointerLocationUri.equals(uri)) { 739 updatePointerLocation(); 740 return; 741 } 742 743 @UpdateAnimationScaleMode 744 final int mode; 745 if (mWindowAnimationScaleUri.equals(uri)) { 746 mode = WINDOW_ANIMATION_SCALE; 747 } else if (mTransitionAnimationScaleUri.equals(uri)) { 748 mode = TRANSITION_ANIMATION_SCALE; 749 } else if (mAnimationDurationScaleUri.equals(uri)) { 750 mode = ANIMATION_DURATION_SCALE; 751 } else { 752 // Ignoring unrecognized content changes 753 return; 754 } 755 Message m = mH.obtainMessage(H.UPDATE_ANIMATION_SCALE, mode, 0); 756 mH.sendMessage(m); 757 } 758 updateSystemUiSettings()759 void updateSystemUiSettings() { 760 boolean changed; 761 synchronized (mGlobalLock) { 762 changed = ImmersiveModeConfirmation.loadSetting(mCurrentUserId, mContext) 763 || PolicyControl.reloadFromSetting(mContext); 764 } 765 if (changed) { 766 updateRotation(false /* alwaysSendConfiguration */, false /* forceRelayout */); 767 } 768 } 769 updatePointerLocation()770 void updatePointerLocation() { 771 ContentResolver resolver = mContext.getContentResolver(); 772 final boolean enablePointerLocation = Settings.System.getIntForUser(resolver, 773 Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT) != 0; 774 775 if (mPointerLocationEnabled == enablePointerLocation) { 776 return; 777 } 778 mPointerLocationEnabled = enablePointerLocation; 779 synchronized (mGlobalLock) { 780 mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer( 781 DisplayPolicy::setPointerLocationEnabled, PooledLambda.__(), 782 mPointerLocationEnabled)); 783 } 784 } 785 } 786 787 PowerManager mPowerManager; 788 PowerManagerInternal mPowerManagerInternal; 789 790 private float mWindowAnimationScaleSetting = 1.0f; 791 private float mTransitionAnimationScaleSetting = 1.0f; 792 private float mAnimatorDurationScaleSetting = 1.0f; 793 private boolean mAnimationsDisabled = false; 794 boolean mPointerLocationEnabled = false; 795 796 final InputManagerService mInputManager; 797 final DisplayManagerInternal mDisplayManagerInternal; 798 final DisplayManager mDisplayManager; 799 final ActivityTaskManagerService mAtmService; 800 801 /** Indicates whether this device supports wide color gamut / HDR rendering */ 802 private boolean mHasWideColorGamutSupport; 803 private boolean mHasHdrSupport; 804 805 /** Who is holding the screen on. */ 806 private Session mHoldingScreenOn; 807 private PowerManager.WakeLock mHoldingScreenWakeLock; 808 809 /** Whether or not a layout can cause a wake up when theater mode is enabled. */ 810 boolean mAllowTheaterModeWakeFromLayout; 811 812 final TaskPositioningController mTaskPositioningController; 813 final DragDropController mDragDropController; 814 815 /** For frozen screen animations. */ 816 private int mExitAnimId, mEnterAnimId; 817 818 /** The display that the rotation animation is applying to. */ 819 private int mFrozenDisplayId; 820 821 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this 822 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */ 823 int mTransactionSequence; 824 825 final WindowAnimator mAnimator; 826 final SurfaceAnimationRunner mSurfaceAnimationRunner; 827 828 /** 829 * Keeps track of which animations got transferred to which animators. Entries will get cleaned 830 * up when the animation finishes. 831 */ 832 final ArrayMap<AnimationAdapter, SurfaceAnimator> mAnimationTransferMap = new ArrayMap<>(); 833 834 private WindowContentFrameStats mTempWindowRenderStats; 835 836 private final LatencyTracker mLatencyTracker; 837 838 /** 839 * Whether the UI is currently running in touch mode (not showing 840 * navigational focus because the user is directly pressing the screen). 841 */ 842 boolean mInTouchMode; 843 844 private ViewServer mViewServer; 845 final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>(); 846 boolean mWindowsChanged = false; 847 848 int mSystemGestureExclusionLimitDp; 849 boolean mSystemGestureExcludedByPreQStickyImmersive; 850 851 public interface WindowChangeListener { windowsChanged()852 public void windowsChanged(); focusChanged()853 public void focusChanged(); 854 } 855 856 final Configuration mTempConfiguration = new Configuration(); 857 858 final HighRefreshRateBlacklist mHighRefreshRateBlacklist = HighRefreshRateBlacklist.create(); 859 860 // If true, only the core apps and services are being launched because the device 861 // is in a special boot mode, such as being encrypted or waiting for a decryption password. 862 // For example, when this flag is true, there will be no wallpaper service. 863 final boolean mOnlyCore; 864 865 static WindowManagerThreadPriorityBooster sThreadPriorityBooster = 866 new WindowManagerThreadPriorityBooster(); 867 868 SurfaceBuilderFactory mSurfaceBuilderFactory = SurfaceControl.Builder::new; 869 TransactionFactory mTransactionFactory = SurfaceControl.Transaction::new; 870 SurfaceFactory mSurfaceFactory = Surface::new; 871 872 private final SurfaceControl.Transaction mTransaction; 873 boostPriorityForLockedSection()874 static void boostPriorityForLockedSection() { 875 sThreadPriorityBooster.boost(); 876 } 877 resetPriorityAfterLockedSection()878 static void resetPriorityAfterLockedSection() { 879 sThreadPriorityBooster.reset(); 880 } 881 openSurfaceTransaction()882 void openSurfaceTransaction() { 883 try { 884 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction"); 885 synchronized (mGlobalLock) { 886 SurfaceControl.openTransaction(); 887 } 888 } finally { 889 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 890 } 891 } 892 893 /** 894 * Closes a surface transaction. 895 * @param where debug string indicating where the transaction originated 896 */ closeSurfaceTransaction(String where)897 void closeSurfaceTransaction(String where) { 898 try { 899 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction"); 900 synchronized (mGlobalLock) { 901 SurfaceControl.closeTransaction(); 902 mWindowTracing.logState(where); 903 } 904 } finally { 905 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 906 } 907 } 908 /** Listener to notify activity manager about app transitions. */ 909 final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier 910 = new WindowManagerInternal.AppTransitionListener() { 911 912 @Override 913 public void onAppTransitionCancelledLocked(int transit) { 914 mAtmInternal.notifyAppTransitionCancelled(); 915 } 916 917 @Override 918 public void onAppTransitionFinishedLocked(IBinder token) { 919 mAtmInternal.notifyAppTransitionFinished(); 920 final AppWindowToken atoken = mRoot.getAppWindowToken(token); 921 if (atoken == null) { 922 return; 923 } 924 if (atoken.mLaunchTaskBehind) { 925 try { 926 mActivityTaskManager.notifyLaunchTaskBehindComplete(atoken.token); 927 } catch (RemoteException e) { 928 } 929 atoken.mLaunchTaskBehind = false; 930 } else { 931 atoken.updateReportedVisibilityLocked(); 932 if (atoken.mEnteringAnimation) { 933 if (getRecentsAnimationController() != null 934 && getRecentsAnimationController().isTargetApp(atoken)) { 935 // Currently running a recents animation, this will get called early because 936 // we show the recents animation target activity immediately when the 937 // animation starts. In this case, we should defer sending the finished 938 // callback until the animation successfully finishes 939 return; 940 } else { 941 atoken.mEnteringAnimation = false; 942 try { 943 mActivityTaskManager.notifyEnterAnimationComplete(atoken.token); 944 } catch (RemoteException e) { 945 } 946 } 947 } 948 } 949 } 950 }; 951 952 final ArrayList<AppFreezeListener> mAppFreezeListeners = new ArrayList<>(); 953 954 interface AppFreezeListener { onAppFreezeTimeout()955 void onAppFreezeTimeout(); 956 } 957 958 private static WindowManagerService sInstance; getInstance()959 static WindowManagerService getInstance() { 960 return sInstance; 961 } 962 main(final Context context, final InputManagerService im, final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm)963 public static WindowManagerService main(final Context context, final InputManagerService im, 964 final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, 965 ActivityTaskManagerService atm) { 966 return main(context, im, showBootMsgs, onlyCore, policy, atm, 967 SurfaceControl.Transaction::new); 968 } 969 970 /** 971 * Creates and returns an instance of the WindowManagerService. This call allows the caller 972 * to override the {@link TransactionFactory} to stub functionality under test. 973 */ 974 @VisibleForTesting main(final Context context, final InputManagerService im, final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm, TransactionFactory transactionFactory)975 public static WindowManagerService main(final Context context, final InputManagerService im, 976 final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, 977 ActivityTaskManagerService atm, TransactionFactory transactionFactory) { 978 DisplayThread.getHandler().runWithScissors(() -> 979 sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, 980 atm, transactionFactory), 0); 981 return sInstance; 982 } 983 initPolicy()984 private void initPolicy() { 985 UiThread.getHandler().runWithScissors(new Runnable() { 986 @Override 987 public void run() { 988 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper()); 989 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this); 990 } 991 }, 0); 992 } 993 994 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver result)995 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 996 String[] args, ShellCallback callback, ResultReceiver result) { 997 new WindowManagerShellCommand(this).exec(this, in, out, err, args, callback, result); 998 } 999 WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm, TransactionFactory transactionFactory)1000 private WindowManagerService(Context context, InputManagerService inputManager, 1001 boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy, 1002 ActivityTaskManagerService atm, TransactionFactory transactionFactory) { 1003 installLock(this, INDEX_WINDOW); 1004 mGlobalLock = atm.getGlobalLock(); 1005 mAtmService = atm; 1006 mContext = context; 1007 mAllowBootMessages = showBootMsgs; 1008 mOnlyCore = onlyCore; 1009 mLimitedAlphaCompositing = context.getResources().getBoolean( 1010 com.android.internal.R.bool.config_sf_limitedAlpha); 1011 mHasPermanentDpad = context.getResources().getBoolean( 1012 com.android.internal.R.bool.config_hasPermanentDpad); 1013 mInTouchMode = context.getResources().getBoolean( 1014 com.android.internal.R.bool.config_defaultInTouchMode); 1015 mDrawLockTimeoutMillis = context.getResources().getInteger( 1016 com.android.internal.R.integer.config_drawLockTimeoutMillis); 1017 mAllowAnimationsInLowPowerMode = context.getResources().getBoolean( 1018 com.android.internal.R.bool.config_allowAnimationsInLowPowerMode); 1019 mMaxUiWidth = context.getResources().getInteger( 1020 com.android.internal.R.integer.config_maxUiWidth); 1021 mDisableTransitionAnimation = context.getResources().getBoolean( 1022 com.android.internal.R.bool.config_disableTransitionAnimation); 1023 mPerDisplayFocusEnabled = context.getResources().getBoolean( 1024 com.android.internal.R.bool.config_perDisplayFocusEnabled); 1025 mLowRamTaskSnapshotsAndRecents = context.getResources().getBoolean( 1026 com.android.internal.R.bool.config_lowRamTaskSnapshotsAndRecents); 1027 mInputManager = inputManager; // Must be before createDisplayContentLocked. 1028 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 1029 mDisplayWindowSettings = new DisplayWindowSettings(this); 1030 1031 mTransactionFactory = transactionFactory; 1032 mTransaction = mTransactionFactory.make(); 1033 mPolicy = policy; 1034 mAnimator = new WindowAnimator(this); 1035 mRoot = new RootWindowContainer(this); 1036 1037 mWindowPlacerLocked = new WindowSurfacePlacer(this); 1038 mTaskSnapshotController = new TaskSnapshotController(this); 1039 1040 mWindowTracing = WindowTracing.createDefaultAndStartLooper(this, 1041 Choreographer.getInstance()); 1042 1043 LocalServices.addService(WindowManagerPolicy.class, mPolicy); 1044 1045 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); 1046 1047 mKeyguardDisableHandler = KeyguardDisableHandler.create(mContext, mPolicy, mH); 1048 1049 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1050 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 1051 1052 if (mPowerManagerInternal != null) { 1053 mPowerManagerInternal.registerLowPowerModeObserver( 1054 new PowerManagerInternal.LowPowerModeListener() { 1055 @Override 1056 public int getServiceType() { 1057 return ServiceType.ANIMATION; 1058 } 1059 1060 @Override 1061 public void onLowPowerModeChanged(PowerSaveState result) { 1062 synchronized (mGlobalLock) { 1063 final boolean enabled = result.batterySaverEnabled; 1064 if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) { 1065 mAnimationsDisabled = enabled; 1066 dispatchNewAnimatorScaleLocked(null); 1067 } 1068 } 1069 } 1070 }); 1071 mAnimationsDisabled = mPowerManagerInternal 1072 .getLowPowerState(ServiceType.ANIMATION).batterySaverEnabled; 1073 } 1074 mScreenFrozenLock = mPowerManager.newWakeLock( 1075 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN"); 1076 mScreenFrozenLock.setReferenceCounted(false); 1077 1078 mActivityManager = ActivityManager.getService(); 1079 mActivityTaskManager = ActivityTaskManager.getService(); 1080 mAmInternal = LocalServices.getService(ActivityManagerInternal.class); 1081 mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); 1082 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 1083 AppOpsManager.OnOpChangedInternalListener opListener = 1084 new AppOpsManager.OnOpChangedInternalListener() { 1085 @Override public void onOpChanged(int op, String packageName) { 1086 updateAppOpsState(); 1087 } 1088 }; 1089 mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener); 1090 mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener); 1091 1092 mPmInternal = LocalServices.getService(PackageManagerInternal.class); 1093 final IntentFilter suspendPackagesFilter = new IntentFilter(); 1094 suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 1095 suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED); 1096 context.registerReceiverAsUser(new BroadcastReceiver() { 1097 @Override 1098 public void onReceive(Context context, Intent intent) { 1099 final String[] affectedPackages = 1100 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 1101 final boolean suspended = 1102 Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction()); 1103 updateHiddenWhileSuspendedState(new ArraySet<>(Arrays.asList(affectedPackages)), 1104 suspended); 1105 } 1106 }, UserHandle.ALL, suspendPackagesFilter, null, null); 1107 1108 final ContentResolver resolver = context.getContentResolver(); 1109 // Get persisted window scale setting 1110 mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver, 1111 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting); 1112 mTransitionAnimationScaleSetting = Settings.Global.getFloat(resolver, 1113 Settings.Global.TRANSITION_ANIMATION_SCALE, 1114 context.getResources().getFloat( 1115 R.dimen.config_appTransitionAnimationDurationScaleDefault)); 1116 1117 setAnimatorDurationScale(Settings.Global.getFloat(resolver, 1118 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting)); 1119 1120 mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver, 1121 DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0; 1122 1123 IntentFilter filter = new IntentFilter(); 1124 // Track changes to DevicePolicyManager state so we can enable/disable keyguard. 1125 filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 1126 mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); 1127 1128 mLatencyTracker = LatencyTracker.getInstance(context); 1129 1130 mSettingsObserver = new SettingsObserver(); 1131 1132 mHoldingScreenWakeLock = mPowerManager.newWakeLock( 1133 PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM); 1134 mHoldingScreenWakeLock.setReferenceCounted(false); 1135 1136 mSurfaceAnimationRunner = new SurfaceAnimationRunner(mPowerManagerInternal); 1137 1138 mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean( 1139 com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout); 1140 1141 mTaskPositioningController = new TaskPositioningController( 1142 this, mInputManager, mActivityTaskManager, mH.getLooper()); 1143 mDragDropController = new DragDropController(this, mH.getLooper()); 1144 1145 mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP, 1146 DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER, 1147 KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0)); 1148 mSystemGestureExcludedByPreQStickyImmersive = 1149 DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER, 1150 KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false); 1151 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER, 1152 new HandlerExecutor(mH), properties -> { 1153 synchronized (mGlobalLock) { 1154 final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP, 1155 properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0)); 1156 final boolean excludedByPreQSticky = DeviceConfig.getBoolean( 1157 DeviceConfig.NAMESPACE_WINDOW_MANAGER, 1158 KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false); 1159 if (mSystemGestureExcludedByPreQStickyImmersive != excludedByPreQSticky 1160 || mSystemGestureExclusionLimitDp != exclusionLimitDp) { 1161 mSystemGestureExclusionLimitDp = exclusionLimitDp; 1162 mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky; 1163 mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit); 1164 } 1165 } 1166 }); 1167 1168 LocalServices.addService(WindowManagerInternal.class, new LocalService()); 1169 } 1170 1171 /** 1172 * Called after all entities (such as the {@link ActivityManagerService}) have been set up and 1173 * associated with the {@link WindowManagerService}. 1174 */ onInitReady()1175 public void onInitReady() { 1176 initPolicy(); 1177 1178 // Add ourself to the Watchdog monitors. 1179 Watchdog.getInstance().addMonitor(this); 1180 1181 openSurfaceTransaction(); 1182 try { 1183 createWatermarkInTransaction(); 1184 } finally { 1185 closeSurfaceTransaction("createWatermarkInTransaction"); 1186 } 1187 1188 showEmulatorDisplayOverlayIfNeeded(); 1189 } 1190 getInputManagerCallback()1191 public InputManagerCallback getInputManagerCallback() { 1192 return mInputManagerCallback; 1193 } 1194 1195 @Override onTransact(int code, Parcel data, Parcel reply, int flags)1196 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1197 throws RemoteException { 1198 try { 1199 return super.onTransact(code, data, reply, flags); 1200 } catch (RuntimeException e) { 1201 // The window manager only throws security exceptions, so let's 1202 // log all others. 1203 if (!(e instanceof SecurityException)) { 1204 Slog.wtf(TAG_WM, "Window Manager Crash", e); 1205 } 1206 throw e; 1207 } 1208 } 1209 excludeWindowTypeFromTapOutTask(int windowType)1210 static boolean excludeWindowTypeFromTapOutTask(int windowType) { 1211 switch (windowType) { 1212 case TYPE_STATUS_BAR: 1213 case TYPE_NAVIGATION_BAR: 1214 case TYPE_INPUT_METHOD_DIALOG: 1215 return true; 1216 } 1217 return false; 1218 } 1219 addWindow(Session session, IWindow client, int seq, LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel, InsetsState outInsetsState)1220 public int addWindow(Session session, IWindow client, int seq, 1221 LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, 1222 Rect outContentInsets, Rect outStableInsets, Rect outOutsets, 1223 DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel, 1224 InsetsState outInsetsState) { 1225 int[] appOp = new int[1]; 1226 int res = mPolicy.checkAddPermission(attrs, appOp); 1227 if (res != WindowManagerGlobal.ADD_OKAY) { 1228 return res; 1229 } 1230 1231 boolean reportNewConfig = false; 1232 WindowState parentWindow = null; 1233 long origId; 1234 final int callingUid = Binder.getCallingUid(); 1235 final int type = attrs.type; 1236 1237 synchronized (mGlobalLock) { 1238 if (!mDisplayReady) { 1239 throw new IllegalStateException("Display has not been initialialized"); 1240 } 1241 1242 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token); 1243 1244 if (displayContent == null) { 1245 Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: " 1246 + displayId + ". Aborting."); 1247 return WindowManagerGlobal.ADD_INVALID_DISPLAY; 1248 } 1249 if (!displayContent.hasAccess(session.mUid)) { 1250 Slog.w(TAG_WM, "Attempted to add window to a display for which the application " 1251 + "does not have access: " + displayId + ". Aborting."); 1252 return WindowManagerGlobal.ADD_INVALID_DISPLAY; 1253 } 1254 1255 if (mWindowMap.containsKey(client.asBinder())) { 1256 Slog.w(TAG_WM, "Window " + client + " is already added"); 1257 return WindowManagerGlobal.ADD_DUPLICATE_ADD; 1258 } 1259 1260 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) { 1261 parentWindow = windowForClientLocked(null, attrs.token, false); 1262 if (parentWindow == null) { 1263 Slog.w(TAG_WM, "Attempted to add window with token that is not a window: " 1264 + attrs.token + ". Aborting."); 1265 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; 1266 } 1267 if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW 1268 && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) { 1269 Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: " 1270 + attrs.token + ". Aborting."); 1271 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; 1272 } 1273 } 1274 1275 if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) { 1276 Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display. Aborting."); 1277 return WindowManagerGlobal.ADD_PERMISSION_DENIED; 1278 } 1279 1280 if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { 1281 Slog.w(TAG_WM, 1282 "Attempted to add presentation window to a non-suitable display. " 1283 + "Aborting."); 1284 return WindowManagerGlobal.ADD_INVALID_DISPLAY; 1285 } 1286 1287 AppWindowToken atoken = null; 1288 final boolean hasParent = parentWindow != null; 1289 // Use existing parent window token for child windows since they go in the same token 1290 // as there parent window so we can apply the same policy on them. 1291 WindowToken token = displayContent.getWindowToken( 1292 hasParent ? parentWindow.mAttrs.token : attrs.token); 1293 // If this is a child window, we want to apply the same type checking rules as the 1294 // parent window type. 1295 final int rootType = hasParent ? parentWindow.mAttrs.type : type; 1296 1297 boolean addToastWindowRequiresToken = false; 1298 1299 if (token == null) { 1300 if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { 1301 Slog.w(TAG_WM, "Attempted to add application window with unknown token " 1302 + attrs.token + ". Aborting."); 1303 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1304 } 1305 if (rootType == TYPE_INPUT_METHOD) { 1306 Slog.w(TAG_WM, "Attempted to add input method window with unknown token " 1307 + attrs.token + ". Aborting."); 1308 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1309 } 1310 if (rootType == TYPE_VOICE_INTERACTION) { 1311 Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token " 1312 + attrs.token + ". Aborting."); 1313 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1314 } 1315 if (rootType == TYPE_WALLPAPER) { 1316 Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token " 1317 + attrs.token + ". Aborting."); 1318 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1319 } 1320 if (rootType == TYPE_DREAM) { 1321 Slog.w(TAG_WM, "Attempted to add Dream window with unknown token " 1322 + attrs.token + ". Aborting."); 1323 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1324 } 1325 if (rootType == TYPE_QS_DIALOG) { 1326 Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token " 1327 + attrs.token + ". Aborting."); 1328 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1329 } 1330 if (rootType == TYPE_ACCESSIBILITY_OVERLAY) { 1331 Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token " 1332 + attrs.token + ". Aborting."); 1333 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1334 } 1335 if (type == TYPE_TOAST) { 1336 // Apps targeting SDK above N MR1 cannot arbitrary add toast windows. 1337 if (doesAddToastWindowRequireToken(attrs.packageName, callingUid, 1338 parentWindow)) { 1339 Slog.w(TAG_WM, "Attempted to add a toast window with unknown token " 1340 + attrs.token + ". Aborting."); 1341 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1342 } 1343 } 1344 final IBinder binder = attrs.token != null ? attrs.token : client.asBinder(); 1345 final boolean isRoundedCornerOverlay = 1346 (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0; 1347 token = new WindowToken(this, binder, type, false, displayContent, 1348 session.mCanAddInternalSystemWindow, isRoundedCornerOverlay); 1349 } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { 1350 atoken = token.asAppWindowToken(); 1351 if (atoken == null) { 1352 Slog.w(TAG_WM, "Attempted to add window with non-application token " 1353 + token + ". Aborting."); 1354 return WindowManagerGlobal.ADD_NOT_APP_TOKEN; 1355 } else if (atoken.removed) { 1356 Slog.w(TAG_WM, "Attempted to add window with exiting application token " 1357 + token + ". Aborting."); 1358 return WindowManagerGlobal.ADD_APP_EXITING; 1359 } else if (type == TYPE_APPLICATION_STARTING && atoken.startingWindow != null) { 1360 Slog.w(TAG_WM, "Attempted to add starting window to token with already existing" 1361 + " starting window"); 1362 return WindowManagerGlobal.ADD_DUPLICATE_ADD; 1363 } 1364 } else if (rootType == TYPE_INPUT_METHOD) { 1365 if (token.windowType != TYPE_INPUT_METHOD) { 1366 Slog.w(TAG_WM, "Attempted to add input method window with bad token " 1367 + attrs.token + ". Aborting."); 1368 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1369 } 1370 } else if (rootType == TYPE_VOICE_INTERACTION) { 1371 if (token.windowType != TYPE_VOICE_INTERACTION) { 1372 Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token " 1373 + attrs.token + ". Aborting."); 1374 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1375 } 1376 } else if (rootType == TYPE_WALLPAPER) { 1377 if (token.windowType != TYPE_WALLPAPER) { 1378 Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token " 1379 + attrs.token + ". Aborting."); 1380 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1381 } 1382 } else if (rootType == TYPE_DREAM) { 1383 if (token.windowType != TYPE_DREAM) { 1384 Slog.w(TAG_WM, "Attempted to add Dream window with bad token " 1385 + attrs.token + ". Aborting."); 1386 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1387 } 1388 } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) { 1389 if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) { 1390 Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token " 1391 + attrs.token + ". Aborting."); 1392 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1393 } 1394 } else if (type == TYPE_TOAST) { 1395 // Apps targeting SDK above N MR1 cannot arbitrary add toast windows. 1396 addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName, 1397 callingUid, parentWindow); 1398 if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) { 1399 Slog.w(TAG_WM, "Attempted to add a toast window with bad token " 1400 + attrs.token + ". Aborting."); 1401 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1402 } 1403 } else if (type == TYPE_QS_DIALOG) { 1404 if (token.windowType != TYPE_QS_DIALOG) { 1405 Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token " 1406 + attrs.token + ". Aborting."); 1407 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 1408 } 1409 } else if (token.asAppWindowToken() != null) { 1410 Slog.w(TAG_WM, "Non-null appWindowToken for system window of rootType=" + rootType); 1411 // It is not valid to use an app token with other system types; we will 1412 // instead make a new token for it (as if null had been passed in for the token). 1413 attrs.token = null; 1414 token = new WindowToken(this, client.asBinder(), type, false, displayContent, 1415 session.mCanAddInternalSystemWindow); 1416 } 1417 1418 final WindowState win = new WindowState(this, session, client, token, parentWindow, 1419 appOp[0], seq, attrs, viewVisibility, session.mUid, 1420 session.mCanAddInternalSystemWindow); 1421 if (win.mDeathRecipient == null) { 1422 // Client has apparently died, so there is no reason to 1423 // continue. 1424 Slog.w(TAG_WM, "Adding window client " + client.asBinder() 1425 + " that is dead, aborting."); 1426 return WindowManagerGlobal.ADD_APP_EXITING; 1427 } 1428 1429 if (win.getDisplayContent() == null) { 1430 Slog.w(TAG_WM, "Adding window to Display that has been removed."); 1431 return WindowManagerGlobal.ADD_INVALID_DISPLAY; 1432 } 1433 1434 final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy(); 1435 displayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(), 1436 Binder.getCallingUid()); 1437 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs)); 1438 1439 res = displayPolicy.prepareAddWindowLw(win, attrs); 1440 if (res != WindowManagerGlobal.ADD_OKAY) { 1441 return res; 1442 } 1443 1444 final boolean openInputChannels = (outInputChannel != null 1445 && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0); 1446 if (openInputChannels) { 1447 win.openInputChannel(outInputChannel); 1448 } 1449 1450 // If adding a toast requires a token for this app we always schedule hiding 1451 // toast windows to make sure they don't stick around longer then necessary. 1452 // We hide instead of remove such windows as apps aren't prepared to handle 1453 // windows being removed under them. 1454 // 1455 // If the app is older it can add toasts without a token and hence overlay 1456 // other apps. To be maximally compatible with these apps we will hide the 1457 // window after the toast timeout only if the focused window is from another 1458 // UID, otherwise we allow unlimited duration. When a UID looses focus we 1459 // schedule hiding all of its toast windows. 1460 if (type == TYPE_TOAST) { 1461 if (!displayContent.canAddToastWindowForUid(callingUid)) { 1462 Slog.w(TAG_WM, "Adding more than one toast window for UID at a time."); 1463 return WindowManagerGlobal.ADD_DUPLICATE_ADD; 1464 } 1465 // Make sure this happens before we moved focus as one can make the 1466 // toast focusable to force it not being hidden after the timeout. 1467 // Focusable toasts are always timed out to prevent a focused app to 1468 // show a focusable toasts while it has focus which will be kept on 1469 // the screen after the activity goes away. 1470 if (addToastWindowRequiresToken 1471 || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0 1472 || displayContent.mCurrentFocus == null 1473 || displayContent.mCurrentFocus.mOwnerUid != callingUid) { 1474 mH.sendMessageDelayed( 1475 mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win), 1476 win.mAttrs.hideTimeoutMilliseconds); 1477 } 1478 } 1479 1480 // From now on, no exceptions or errors allowed! 1481 1482 res = WindowManagerGlobal.ADD_OKAY; 1483 if (displayContent.mCurrentFocus == null) { 1484 displayContent.mWinAddedSinceNullFocus.add(win); 1485 } 1486 1487 if (excludeWindowTypeFromTapOutTask(type)) { 1488 displayContent.mTapExcludedWindows.add(win); 1489 } 1490 1491 origId = Binder.clearCallingIdentity(); 1492 1493 win.attach(); 1494 mWindowMap.put(client.asBinder(), win); 1495 1496 win.initAppOpsState(); 1497 1498 final boolean suspended = mPmInternal.isPackageSuspended(win.getOwningPackage(), 1499 UserHandle.getUserId(win.getOwningUid())); 1500 win.setHiddenWhileSuspended(suspended); 1501 1502 final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty(); 1503 win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows); 1504 1505 final AppWindowToken aToken = token.asAppWindowToken(); 1506 if (type == TYPE_APPLICATION_STARTING && aToken != null) { 1507 aToken.startingWindow = win; 1508 if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + aToken 1509 + " startingWindow=" + win); 1510 } 1511 1512 boolean imMayMove = true; 1513 1514 win.mToken.addWindow(win); 1515 if (type == TYPE_INPUT_METHOD) { 1516 displayContent.setInputMethodWindowLocked(win); 1517 imMayMove = false; 1518 } else if (type == TYPE_INPUT_METHOD_DIALOG) { 1519 displayContent.computeImeTarget(true /* updateImeTarget */); 1520 imMayMove = false; 1521 } else { 1522 if (type == TYPE_WALLPAPER) { 1523 displayContent.mWallpaperController.clearLastWallpaperTimeoutTime(); 1524 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 1525 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { 1526 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 1527 } else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) { 1528 // If there is currently a wallpaper being shown, and 1529 // the base layer of the new window is below the current 1530 // layer of the target window, then adjust the wallpaper. 1531 // This is to avoid a new window being placed between the 1532 // wallpaper and its target. 1533 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 1534 } 1535 } 1536 1537 // If the window is being added to a stack that's currently adjusted for IME, 1538 // make sure to apply the same adjust to this new window. 1539 win.applyAdjustForImeIfNeeded(); 1540 1541 if (type == TYPE_DOCK_DIVIDER) { 1542 mRoot.getDisplayContent(displayId).getDockedDividerController().setWindow(win); 1543 } 1544 1545 final WindowStateAnimator winAnimator = win.mWinAnimator; 1546 winAnimator.mEnterAnimationPending = true; 1547 winAnimator.mEnteringAnimation = true; 1548 // Check if we need to prepare a transition for replacing window first. 1549 if (atoken != null && atoken.isVisible() 1550 && !prepareWindowReplacementTransition(atoken)) { 1551 // If not, check if need to set up a dummy transition during display freeze 1552 // so that the unfreeze wait for the apps to draw. This might be needed if 1553 // the app is relaunching. 1554 prepareNoneTransitionForRelaunching(atoken); 1555 } 1556 1557 final DisplayFrames displayFrames = displayContent.mDisplayFrames; 1558 // TODO: Not sure if onDisplayInfoUpdated() call is needed. 1559 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 1560 displayFrames.onDisplayInfoUpdated(displayInfo, 1561 displayContent.calculateDisplayCutoutForRotation(displayInfo.rotation)); 1562 final Rect taskBounds; 1563 final boolean floatingStack; 1564 if (atoken != null && atoken.getTask() != null) { 1565 taskBounds = mTmpRect; 1566 atoken.getTask().getBounds(mTmpRect); 1567 floatingStack = atoken.getTask().isFloating(); 1568 } else { 1569 taskBounds = null; 1570 floatingStack = false; 1571 } 1572 if (displayPolicy.getLayoutHintLw(win.mAttrs, taskBounds, displayFrames, floatingStack, 1573 outFrame, outContentInsets, outStableInsets, outOutsets, outDisplayCutout)) { 1574 res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS; 1575 } 1576 outInsetsState.set(displayContent.getInsetsStateController().getInsetsForDispatch(win)); 1577 1578 if (mInTouchMode) { 1579 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE; 1580 } 1581 if (win.mAppToken == null || !win.mAppToken.isClientHidden()) { 1582 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE; 1583 } 1584 1585 displayContent.getInputMonitor().setUpdateInputWindowsNeededLw(); 1586 1587 boolean focusChanged = false; 1588 if (win.canReceiveKeys()) { 1589 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS, 1590 false /*updateInputWindows*/); 1591 if (focusChanged) { 1592 imMayMove = false; 1593 } 1594 } 1595 1596 if (imMayMove) { 1597 displayContent.computeImeTarget(true /* updateImeTarget */); 1598 } 1599 1600 // Don't do layout here, the window must call 1601 // relayout to be displayed, so we'll do it there. 1602 win.getParent().assignChildLayers(); 1603 1604 if (focusChanged) { 1605 displayContent.getInputMonitor().setInputFocusLw(displayContent.mCurrentFocus, 1606 false /*updateInputWindows*/); 1607 } 1608 displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/); 1609 1610 if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addWindow: New client " 1611 + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5)); 1612 1613 if (win.isVisibleOrAdding() && displayContent.updateOrientationFromAppTokens()) { 1614 reportNewConfig = true; 1615 } 1616 } 1617 1618 if (reportNewConfig) { 1619 sendNewConfiguration(displayId); 1620 } 1621 1622 Binder.restoreCallingIdentity(origId); 1623 1624 return res; 1625 } 1626 1627 /** 1628 * Get existing {@link DisplayContent} or create a new one if the display is registered in 1629 * DisplayManager. 1630 * 1631 * NOTE: This should only be used in cases when there is a chance that a {@link DisplayContent} 1632 * that corresponds to a display just added to DisplayManager has not yet been created. This 1633 * usually means that the call of this method was initiated from outside of Activity or Window 1634 * Manager. In most cases the regular getter should be used. 1635 * @param displayId The preferred display Id. 1636 * @param token The window token associated with the window we are trying to get display for. 1637 * if not null then the display of the window token will be returned. Set to null 1638 * is there isn't an a token associated with the request. 1639 * @see RootWindowContainer#getDisplayContent(int) 1640 */ getDisplayContentOrCreate(int displayId, IBinder token)1641 private DisplayContent getDisplayContentOrCreate(int displayId, IBinder token) { 1642 if (token != null) { 1643 final WindowToken wToken = mRoot.getWindowToken(token); 1644 if (wToken != null) { 1645 return wToken.getDisplayContent(); 1646 } 1647 } 1648 1649 DisplayContent displayContent = mRoot.getDisplayContent(displayId); 1650 1651 // Create an instance if possible instead of waiting for the ActivityManagerService to drive 1652 // the creation. 1653 if (displayContent == null) { 1654 final Display display = mDisplayManager.getDisplay(displayId); 1655 1656 if (display != null) { 1657 displayContent = mRoot.createDisplayContent(display, null /* controller */); 1658 } 1659 } 1660 1661 return displayContent; 1662 } 1663 doesAddToastWindowRequireToken(String packageName, int callingUid, WindowState attachedWindow)1664 private boolean doesAddToastWindowRequireToken(String packageName, int callingUid, 1665 WindowState attachedWindow) { 1666 // Try using the target SDK of the root window 1667 if (attachedWindow != null) { 1668 return attachedWindow.mAppToken != null 1669 && attachedWindow.mAppToken.mTargetSdk >= Build.VERSION_CODES.O; 1670 } else { 1671 // Otherwise, look at the package 1672 try { 1673 ApplicationInfo appInfo = mContext.getPackageManager() 1674 .getApplicationInfoAsUser(packageName, 0, 1675 UserHandle.getUserId(callingUid)); 1676 if (appInfo.uid != callingUid) { 1677 throw new SecurityException("Package " + packageName + " not in UID " 1678 + callingUid); 1679 } 1680 if (appInfo.targetSdkVersion >= Build.VERSION_CODES.O) { 1681 return true; 1682 } 1683 } catch (PackageManager.NameNotFoundException e) { 1684 /* ignore */ 1685 } 1686 } 1687 return false; 1688 } 1689 1690 /** 1691 * Returns true if we're done setting up any transitions. 1692 */ prepareWindowReplacementTransition(AppWindowToken atoken)1693 private boolean prepareWindowReplacementTransition(AppWindowToken atoken) { 1694 atoken.clearAllDrawn(); 1695 final WindowState replacedWindow = atoken.getReplacingWindow(); 1696 if (replacedWindow == null) { 1697 // We expect to already receive a request to remove the old window. If it did not 1698 // happen, let's just simply add a window. 1699 return false; 1700 } 1701 // We use the visible frame, because we want the animation to morph the window from what 1702 // was visible to the user to the final destination of the new window. 1703 Rect frame = replacedWindow.getVisibleFrameLw(); 1704 // We treat this as if this activity was opening, so we can trigger the app transition 1705 // animation and piggy-back on existing transition animation infrastructure. 1706 final DisplayContent dc = atoken.getDisplayContent(); 1707 dc.mOpeningApps.add(atoken); 1708 dc.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_RELAUNCH, ALWAYS_KEEP_CURRENT, 1709 0 /* flags */, false /* forceOverride */); 1710 dc.mAppTransition.overridePendingAppTransitionClipReveal(frame.left, frame.top, 1711 frame.width(), frame.height()); 1712 dc.executeAppTransition(); 1713 return true; 1714 } 1715 prepareNoneTransitionForRelaunching(AppWindowToken atoken)1716 private void prepareNoneTransitionForRelaunching(AppWindowToken atoken) { 1717 // Set up a none-transition and add the app to opening apps, so that the display 1718 // unfreeze wait for the apps to be drawn. 1719 // Note that if the display unfroze already because app unfreeze timed out, 1720 // we don't set up the transition anymore and just let it go. 1721 final DisplayContent dc = atoken.getDisplayContent(); 1722 if (mDisplayFrozen && !dc.mOpeningApps.contains(atoken) && atoken.isRelaunching()) { 1723 dc.mOpeningApps.add(atoken); 1724 dc.prepareAppTransition(WindowManager.TRANSIT_NONE, !ALWAYS_KEEP_CURRENT, 0 /* flags */, 1725 false /* forceOverride */); 1726 dc.executeAppTransition(); 1727 } 1728 } 1729 isSecureLocked(WindowState w)1730 boolean isSecureLocked(WindowState w) { 1731 if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { 1732 return true; 1733 } 1734 if (DevicePolicyCache.getInstance().getScreenCaptureDisabled( 1735 UserHandle.getUserId(w.mOwnerUid))) { 1736 return true; 1737 } 1738 return false; 1739 } 1740 1741 /** 1742 * Set whether screen capture is disabled for all windows of a specific user from 1743 * the device policy cache. 1744 */ 1745 @Override refreshScreenCaptureDisabled(int userId)1746 public void refreshScreenCaptureDisabled(int userId) { 1747 int callingUid = Binder.getCallingUid(); 1748 if (callingUid != SYSTEM_UID) { 1749 throw new SecurityException("Only system can call refreshScreenCaptureDisabled."); 1750 } 1751 1752 synchronized (mGlobalLock) { 1753 // Update secure surface for all windows belonging to this user. 1754 mRoot.setSecureSurfaceState(userId, 1755 DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId)); 1756 } 1757 } 1758 removeWindow(Session session, IWindow client)1759 void removeWindow(Session session, IWindow client) { 1760 synchronized (mGlobalLock) { 1761 WindowState win = windowForClientLocked(session, client, false); 1762 if (win == null) { 1763 return; 1764 } 1765 win.removeIfPossible(); 1766 } 1767 } 1768 1769 /** 1770 * Performs some centralized bookkeeping clean-up on the window that is being removed. 1771 * NOTE: Should only be called from {@link WindowState#removeImmediately()} 1772 * TODO: Maybe better handled with a method {@link WindowContainer#removeChild} if we can 1773 * figure-out a good way to have all parents of a WindowState doing the same thing without 1774 * forgetting to add the wiring when a new parent of WindowState is added. 1775 */ postWindowRemoveCleanupLocked(WindowState win)1776 void postWindowRemoveCleanupLocked(WindowState win) { 1777 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win); 1778 mWindowMap.remove(win.mClient.asBinder()); 1779 1780 markForSeamlessRotation(win, false); 1781 1782 win.resetAppOpsState(); 1783 1784 final DisplayContent dc = win.getDisplayContent(); 1785 if (dc.mCurrentFocus == null) { 1786 dc.mWinRemovedSinceNullFocus.add(win); 1787 } 1788 mPendingRemove.remove(win); 1789 mResizingWindows.remove(win); 1790 updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */); 1791 mWindowsChanged = true; 1792 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win); 1793 1794 final DisplayContent displayContent = win.getDisplayContent(); 1795 if (displayContent.mInputMethodWindow == win) { 1796 displayContent.setInputMethodWindowLocked(null); 1797 } 1798 1799 final WindowToken token = win.mToken; 1800 final AppWindowToken atoken = win.mAppToken; 1801 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token); 1802 // Window will already be removed from token before this post clean-up method is called. 1803 if (token.isEmpty()) { 1804 if (!token.mPersistOnEmpty) { 1805 token.removeImmediately(); 1806 } else if (atoken != null) { 1807 // TODO: Should this be moved into AppWindowToken.removeWindow? Might go away after 1808 // re-factor. 1809 atoken.firstWindowDrawn = false; 1810 atoken.clearAllDrawn(); 1811 final TaskStack stack = atoken.getStack(); 1812 if (stack != null) { 1813 stack.mExitingAppTokens.remove(atoken); 1814 } 1815 } 1816 } 1817 1818 if (atoken != null) { 1819 atoken.postWindowRemoveStartingWindowCleanup(win); 1820 } 1821 1822 if (win.mAttrs.type == TYPE_WALLPAPER) { 1823 dc.mWallpaperController.clearLastWallpaperTimeoutTime(); 1824 dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 1825 } else if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { 1826 dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 1827 } 1828 1829 if (dc != null && !mWindowPlacerLocked.isInLayout()) { 1830 dc.assignWindowLayers(true /* setLayoutNeeded */); 1831 mWindowPlacerLocked.performSurfacePlacement(); 1832 if (win.mAppToken != null) { 1833 win.mAppToken.updateReportedVisibilityLocked(); 1834 } 1835 } 1836 1837 dc.getInputMonitor().updateInputWindowsLw(true /*force*/); 1838 } 1839 updateHiddenWhileSuspendedState(ArraySet<String> packages, boolean suspended)1840 private void updateHiddenWhileSuspendedState(ArraySet<String> packages, boolean suspended) { 1841 synchronized (mGlobalLock) { 1842 mRoot.updateHiddenWhileSuspendedState(packages, suspended); 1843 } 1844 } 1845 updateAppOpsState()1846 private void updateAppOpsState() { 1847 synchronized (mGlobalLock) { 1848 mRoot.updateAppOpsState(); 1849 } 1850 } 1851 logSurface(WindowState w, String msg, boolean withStackTrace)1852 static void logSurface(WindowState w, String msg, boolean withStackTrace) { 1853 String str = " SURFACE " + msg + ": " + w; 1854 if (withStackTrace) { 1855 logWithStack(TAG, str); 1856 } else { 1857 Slog.i(TAG_WM, str); 1858 } 1859 } 1860 logSurface(SurfaceControl s, String title, String msg)1861 static void logSurface(SurfaceControl s, String title, String msg) { 1862 String str = " SURFACE " + s + ": " + msg + " / " + title; 1863 Slog.i(TAG_WM, str); 1864 } 1865 logWithStack(String tag, String s)1866 static void logWithStack(String tag, String s) { 1867 RuntimeException e = null; 1868 if (SHOW_STACK_CRAWLS) { 1869 e = new RuntimeException(); 1870 e.fillInStackTrace(); 1871 } 1872 Slog.i(tag, s, e); 1873 } 1874 setTransparentRegionWindow(Session session, IWindow client, Region region)1875 void setTransparentRegionWindow(Session session, IWindow client, Region region) { 1876 long origId = Binder.clearCallingIdentity(); 1877 try { 1878 synchronized (mGlobalLock) { 1879 WindowState w = windowForClientLocked(session, client, false); 1880 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1881 "transparentRegionHint=" + region, false); 1882 1883 if ((w != null) && w.mHasSurface) { 1884 w.mWinAnimator.setTransparentRegionHintLocked(region); 1885 } 1886 } 1887 } finally { 1888 Binder.restoreCallingIdentity(origId); 1889 } 1890 } 1891 setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets, Rect visibleInsets, Region touchableRegion)1892 void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets, 1893 Rect visibleInsets, Region touchableRegion) { 1894 long origId = Binder.clearCallingIdentity(); 1895 try { 1896 synchronized (mGlobalLock) { 1897 WindowState w = windowForClientLocked(session, client, false); 1898 if (DEBUG_LAYOUT) Slog.d(TAG, "setInsetsWindow " + w 1899 + ", contentInsets=" + w.mGivenContentInsets + " -> " + contentInsets 1900 + ", visibleInsets=" + w.mGivenVisibleInsets + " -> " + visibleInsets 1901 + ", touchableRegion=" + w.mGivenTouchableRegion + " -> " + touchableRegion 1902 + ", touchableInsets " + w.mTouchableInsets + " -> " + touchableInsets); 1903 if (w != null) { 1904 w.mGivenInsetsPending = false; 1905 w.mGivenContentInsets.set(contentInsets); 1906 w.mGivenVisibleInsets.set(visibleInsets); 1907 w.mGivenTouchableRegion.set(touchableRegion); 1908 w.mTouchableInsets = touchableInsets; 1909 if (w.mGlobalScale != 1) { 1910 w.mGivenContentInsets.scale(w.mGlobalScale); 1911 w.mGivenVisibleInsets.scale(w.mGlobalScale); 1912 w.mGivenTouchableRegion.scale(w.mGlobalScale); 1913 } 1914 w.setDisplayLayoutNeeded(); 1915 mWindowPlacerLocked.performSurfacePlacement(); 1916 1917 // We need to report touchable region changes to accessibility. 1918 if (mAccessibilityController != null 1919 && (w.getDisplayContent().getDisplayId() == DEFAULT_DISPLAY 1920 || w.getDisplayContent().getParentWindow() != null)) { 1921 mAccessibilityController.onSomeWindowResizedOrMovedLocked(); 1922 } 1923 } 1924 } 1925 } finally { 1926 Binder.restoreCallingIdentity(origId); 1927 } 1928 } 1929 getWindowDisplayFrame(Session session, IWindow client, Rect outDisplayFrame)1930 public void getWindowDisplayFrame(Session session, IWindow client, 1931 Rect outDisplayFrame) { 1932 synchronized (mGlobalLock) { 1933 WindowState win = windowForClientLocked(session, client, false); 1934 if (win == null) { 1935 outDisplayFrame.setEmpty(); 1936 return; 1937 } 1938 outDisplayFrame.set(win.getDisplayFrameLw()); 1939 if (win.inSizeCompatMode()) { 1940 outDisplayFrame.scale(win.mInvGlobalScale); 1941 } 1942 } 1943 } 1944 onRectangleOnScreenRequested(IBinder token, Rect rectangle)1945 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) { 1946 synchronized (mGlobalLock) { 1947 if (mAccessibilityController != null) { 1948 WindowState window = mWindowMap.get(token); 1949 if (window != null) { 1950 mAccessibilityController.onRectangleOnScreenRequestedLocked( 1951 window.getDisplayId(), rectangle); 1952 } 1953 } 1954 } 1955 } 1956 getWindowId(IBinder token)1957 public IWindowId getWindowId(IBinder token) { 1958 synchronized (mGlobalLock) { 1959 WindowState window = mWindowMap.get(token); 1960 return window != null ? window.mWindowId : null; 1961 } 1962 } 1963 pokeDrawLock(Session session, IBinder token)1964 public void pokeDrawLock(Session session, IBinder token) { 1965 synchronized (mGlobalLock) { 1966 WindowState window = windowForClientLocked(session, token, false); 1967 if (window != null) { 1968 window.pokeDrawLockLw(mDrawLockTimeoutMillis); 1969 } 1970 } 1971 } 1972 hasStatusBarPermission(int pid, int uid)1973 private boolean hasStatusBarPermission(int pid, int uid) { 1974 return mContext.checkPermission(permission.STATUS_BAR, pid, uid) 1975 == PackageManager.PERMISSION_GRANTED; 1976 } 1977 relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState)1978 public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs, 1979 int requestedWidth, int requestedHeight, int viewVisibility, int flags, 1980 long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, 1981 Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, 1982 DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, 1983 SurfaceControl outSurfaceControl, InsetsState outInsetsState) { 1984 int result = 0; 1985 boolean configChanged; 1986 final int pid = Binder.getCallingPid(); 1987 final int uid = Binder.getCallingUid(); 1988 long origId = Binder.clearCallingIdentity(); 1989 final int displayId; 1990 synchronized (mGlobalLock) { 1991 final WindowState win = windowForClientLocked(session, client, false); 1992 if (win == null) { 1993 return 0; 1994 } 1995 displayId = win.getDisplayId(); 1996 final DisplayContent displayContent = win.getDisplayContent(); 1997 final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy(); 1998 1999 WindowStateAnimator winAnimator = win.mWinAnimator; 2000 if (viewVisibility != View.GONE) { 2001 win.setRequestedSize(requestedWidth, requestedHeight); 2002 } 2003 2004 win.setFrameNumber(frameNumber); 2005 2006 final DisplayContent dc = win.getDisplayContent(); 2007 if (!dc.mWaitingForConfig) { 2008 win.finishSeamlessRotation(false /* timeout */); 2009 } 2010 2011 int attrChanges = 0; 2012 int flagChanges = 0; 2013 if (attrs != null) { 2014 displayPolicy.adjustWindowParamsLw(win, attrs, pid, uid); 2015 // if they don't have the permission, mask out the status bar bits 2016 if (seq == win.mSeq) { 2017 int systemUiVisibility = attrs.systemUiVisibility 2018 | attrs.subtreeSystemUiVisibility; 2019 if ((systemUiVisibility & DISABLE_MASK) != 0) { 2020 if (!hasStatusBarPermission(pid, uid)) { 2021 systemUiVisibility &= ~DISABLE_MASK; 2022 } 2023 } 2024 win.mSystemUiVisibility = systemUiVisibility; 2025 } 2026 if (win.mAttrs.type != attrs.type) { 2027 throw new IllegalArgumentException( 2028 "Window type can not be changed after the window is added."); 2029 } 2030 2031 // Odd choice but less odd than embedding in copyFrom() 2032 if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY) 2033 != 0) { 2034 attrs.x = win.mAttrs.x; 2035 attrs.y = win.mAttrs.y; 2036 attrs.width = win.mAttrs.width; 2037 attrs.height = win.mAttrs.height; 2038 } 2039 2040 flagChanges = win.mAttrs.flags ^= attrs.flags; 2041 attrChanges = win.mAttrs.copyFrom(attrs); 2042 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED 2043 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) { 2044 win.mLayoutNeeded = true; 2045 } 2046 if (win.mAppToken != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0 2047 || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) { 2048 win.mAppToken.checkKeyguardFlagsChanged(); 2049 } 2050 if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0) 2051 && (mAccessibilityController != null) 2052 && (win.getDisplayId() == DEFAULT_DISPLAY 2053 || win.getDisplayContent().getParentWindow() != null)) { 2054 // No move or resize, but the controller checks for title changes as well 2055 mAccessibilityController.onSomeWindowResizedOrMovedLocked(); 2056 } 2057 2058 if ((flagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { 2059 updateNonSystemOverlayWindowsVisibilityIfNeeded( 2060 win, win.mWinAnimator.getShown()); 2061 } 2062 if ((attrChanges & (WindowManager.LayoutParams.PRIVATE_FLAGS_CHANGED)) != 0) { 2063 winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags 2064 & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0); 2065 } 2066 } 2067 2068 if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility 2069 + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs); 2070 winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0; 2071 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) { 2072 winAnimator.mAlpha = attrs.alpha; 2073 } 2074 win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight); 2075 2076 if (win.mAttrs.surfaceInsets.left != 0 2077 || win.mAttrs.surfaceInsets.top != 0 2078 || win.mAttrs.surfaceInsets.right != 0 2079 || win.mAttrs.surfaceInsets.bottom != 0) { 2080 winAnimator.setOpaqueLocked(false); 2081 } 2082 2083 final int oldVisibility = win.mViewVisibility; 2084 2085 // If the window is becoming visible, visibleOrAdding may change which may in turn 2086 // change the IME target. 2087 final boolean becameVisible = 2088 (oldVisibility == View.INVISIBLE || oldVisibility == View.GONE) 2089 && viewVisibility == View.VISIBLE; 2090 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0 2091 || becameVisible; 2092 boolean focusMayChange = win.mViewVisibility != viewVisibility 2093 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) 2094 || (!win.mRelayoutCalled); 2095 2096 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility 2097 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0; 2098 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0; 2099 if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) { 2100 winAnimator.mSurfaceController.setSecure(isSecureLocked(win)); 2101 } 2102 2103 win.mRelayoutCalled = true; 2104 win.mInRelayout = true; 2105 2106 win.mViewVisibility = viewVisibility; 2107 if (DEBUG_SCREEN_ON) { 2108 RuntimeException stack = new RuntimeException(); 2109 stack.fillInStackTrace(); 2110 Slog.i(TAG_WM, "Relayout " + win + ": oldVis=" + oldVisibility 2111 + " newVis=" + viewVisibility, stack); 2112 } 2113 2114 win.setDisplayLayoutNeeded(); 2115 win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0; 2116 2117 // We should only relayout if the view is visible, it is a starting window, or the 2118 // associated appToken is not hidden. 2119 final boolean shouldRelayout = viewVisibility == View.VISIBLE && 2120 (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING 2121 || !win.mAppToken.isClientHidden()); 2122 2123 // If we are not currently running the exit animation, we need to see about starting 2124 // one. 2125 // We don't want to animate visibility of windows which are pending replacement. 2126 // In the case of activity relaunch child windows could request visibility changes as 2127 // they are detached from the main application window during the tear down process. 2128 // If we satisfied these visibility changes though, we would cause a visual glitch 2129 // hiding the window before it's replacement was available. So we just do nothing on 2130 // our side. 2131 // This must be called before the call to performSurfacePlacement. 2132 if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) { 2133 if (DEBUG_VISIBILITY) { 2134 Slog.i(TAG_WM, 2135 "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit); 2136 } 2137 result |= RELAYOUT_RES_SURFACE_CHANGED; 2138 if (!win.mWillReplaceWindow) { 2139 focusMayChange = tryStartExitingAnimation(win, winAnimator, focusMayChange); 2140 } 2141 } 2142 2143 // We may be deferring layout passes at the moment, but since the client is interested 2144 // in the new out values right now we need to force a layout. 2145 mWindowPlacerLocked.performSurfacePlacement(true /* force */); 2146 2147 if (shouldRelayout) { 2148 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1"); 2149 2150 result = win.relayoutVisibleWindow(result, attrChanges); 2151 2152 try { 2153 result = createSurfaceControl(outSurfaceControl, result, win, winAnimator); 2154 } catch (Exception e) { 2155 displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/); 2156 2157 Slog.w(TAG_WM, "Exception thrown when creating surface for client " 2158 + client + " (" + win.mAttrs.getTitle() + ")", 2159 e); 2160 Binder.restoreCallingIdentity(origId); 2161 return 0; 2162 } 2163 if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { 2164 focusMayChange = true; 2165 } 2166 if (win.mAttrs.type == TYPE_INPUT_METHOD 2167 && displayContent.mInputMethodWindow == null) { 2168 displayContent.setInputMethodWindowLocked(win); 2169 imMayMove = true; 2170 } 2171 win.adjustStartingWindowFlags(); 2172 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2173 } else { 2174 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2"); 2175 2176 winAnimator.mEnterAnimationPending = false; 2177 winAnimator.mEnteringAnimation = false; 2178 2179 if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) { 2180 // We already told the client to go invisible, but the message may not be 2181 // handled yet, or it might want to draw a last frame. If we already have a 2182 // surface, let the client use that, but don't create new surface at this point. 2183 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface"); 2184 winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl); 2185 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2186 } else { 2187 if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win); 2188 2189 try { 2190 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_" 2191 + win.mAttrs.getTitle()); 2192 outSurfaceControl.release(); 2193 } finally { 2194 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2195 } 2196 } 2197 2198 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2199 } 2200 2201 if (focusMayChange) { 2202 if (updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/)) { 2203 imMayMove = false; 2204 } 2205 } 2206 2207 // updateFocusedWindowLocked() already assigned layers so we only need to 2208 // reassign them at this point if the IM window state gets shuffled 2209 boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0; 2210 if (imMayMove) { 2211 displayContent.computeImeTarget(true /* updateImeTarget */); 2212 if (toBeDisplayed) { 2213 // Little hack here -- we -should- be able to rely on the function to return 2214 // true if the IME has moved and needs its layer recomputed. However, if the IME 2215 // was hidden and isn't actually moved in the list, its layer may be out of data 2216 // so we make sure to recompute it. 2217 displayContent.assignWindowLayers(false /* setLayoutNeeded */); 2218 } 2219 } 2220 2221 if (wallpaperMayMove) { 2222 displayContent.pendingLayoutChanges |= 2223 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 2224 } 2225 2226 if (win.mAppToken != null) { 2227 displayContent.mUnknownAppVisibilityController.notifyRelayouted(win.mAppToken); 2228 } 2229 2230 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, 2231 "relayoutWindow: updateOrientationFromAppTokens"); 2232 configChanged = displayContent.updateOrientationFromAppTokens(); 2233 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2234 2235 if (toBeDisplayed && win.mIsWallpaper) { 2236 DisplayInfo displayInfo = displayContent.getDisplayInfo(); 2237 displayContent.mWallpaperController.updateWallpaperOffset( 2238 win, displayInfo.logicalWidth, displayInfo.logicalHeight, false); 2239 } 2240 if (win.mAppToken != null) { 2241 win.mAppToken.updateReportedVisibilityLocked(); 2242 } 2243 if (winAnimator.mReportSurfaceResized) { 2244 winAnimator.mReportSurfaceResized = false; 2245 result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED; 2246 } 2247 if (displayPolicy.areSystemBarsForcedShownLw(win)) { 2248 result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; 2249 } 2250 if (!win.isGoneForLayoutLw()) { 2251 win.mResizedWhileGone = false; 2252 } 2253 2254 // We must always send the latest {@link MergedConfiguration}, regardless of whether we 2255 // have already reported it. The client might not have processed the previous value yet 2256 // and needs process it before handling the corresponding window frame. the variable 2257 // {@code mergedConfiguration} is an out parameter that will be passed back to the 2258 // client over IPC and checked there. 2259 // Note: in the cases where the window is tied to an activity, we should not send a 2260 // configuration update when the window has requested to be hidden. Doing so can lead 2261 // to the client erroneously accepting a configuration that would have otherwise caused 2262 // an activity restart. We instead hand back the last reported 2263 // {@link MergedConfiguration}. 2264 if (shouldRelayout) { 2265 win.getMergedConfiguration(mergedConfiguration); 2266 } else { 2267 win.getLastReportedMergedConfiguration(mergedConfiguration); 2268 } 2269 2270 win.setLastReportedMergedConfiguration(mergedConfiguration); 2271 2272 // Update the last inset values here because the values are sent back to the client. 2273 // The last inset values represent the last client state. 2274 win.updateLastInsetValues(); 2275 2276 win.getCompatFrame(outFrame); 2277 win.getInsetsForRelayout(outOverscanInsets, outContentInsets, outVisibleInsets, 2278 outStableInsets, outOutsets); 2279 outCutout.set(win.getWmDisplayCutout().getDisplayCutout()); 2280 outBackdropFrame.set(win.getBackdropFrame(win.getFrameLw())); 2281 outInsetsState.set(displayContent.getInsetsStateController().getInsetsForDispatch(win)); 2282 if (localLOGV) Slog.v( 2283 TAG_WM, "Relayout given client " + client.asBinder() 2284 + ", requestedWidth=" + requestedWidth 2285 + ", requestedHeight=" + requestedHeight 2286 + ", viewVisibility=" + viewVisibility 2287 + "\nRelayout returning frame=" + outFrame 2288 + ", surface=" + outSurfaceControl); 2289 2290 if (localLOGV || DEBUG_FOCUS) Slog.v( 2291 TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange); 2292 2293 result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0; 2294 2295 if (DEBUG_LAYOUT) { 2296 Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString()); 2297 } 2298 win.mInRelayout = false; 2299 } 2300 2301 if (configChanged) { 2302 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: sendNewConfiguration"); 2303 sendNewConfiguration(displayId); 2304 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2305 } 2306 Binder.restoreCallingIdentity(origId); 2307 return result; 2308 } 2309 tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator, boolean focusMayChange)2310 private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator, 2311 boolean focusMayChange) { 2312 // Try starting an animation; if there isn't one, we 2313 // can destroy the surface right away. 2314 int transit = WindowManagerPolicy.TRANSIT_EXIT; 2315 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { 2316 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; 2317 } 2318 if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) { 2319 focusMayChange = true; 2320 win.mAnimatingExit = true; 2321 } else if (win.isAnimating()) { 2322 // Currently in a hide animation... turn this into 2323 // an exit. 2324 win.mAnimatingExit = true; 2325 } else if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) { 2326 // If the wallpaper is currently behind this 2327 // window, we need to change both of them inside 2328 // of a transaction to avoid artifacts. 2329 win.mAnimatingExit = true; 2330 } else { 2331 final DisplayContent displayContent = win.getDisplayContent(); 2332 if (displayContent.mInputMethodWindow == win) { 2333 displayContent.setInputMethodWindowLocked(null); 2334 } 2335 boolean stopped = win.mAppToken != null ? win.mAppToken.mAppStopped : true; 2336 // We set mDestroying=true so AppWindowToken#notifyAppStopped in-to destroy surfaces 2337 // will later actually destroy the surface if we do not do so here. Normally we leave 2338 // this to the exit animation. 2339 win.mDestroying = true; 2340 win.destroySurface(false, stopped); 2341 } 2342 if (mAccessibilityController != null) { 2343 mAccessibilityController.onWindowTransitionLocked(win, transit); 2344 } 2345 2346 // When we start the exit animation we take the Surface from the client 2347 // so it will stop perturbing it. We need to likewise takeaway the SurfaceFlinger 2348 // side child surfaces, so they will remain preserved in their current state 2349 // (rather than be cleaned up immediately by the app code). 2350 SurfaceControl.openTransaction(); 2351 winAnimator.detachChildren(); 2352 SurfaceControl.closeTransaction(); 2353 2354 return focusMayChange; 2355 } 2356 createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win, WindowStateAnimator winAnimator)2357 private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win, 2358 WindowStateAnimator winAnimator) { 2359 if (!win.mHasSurface) { 2360 result |= RELAYOUT_RES_SURFACE_CHANGED; 2361 } 2362 2363 WindowSurfaceController surfaceController; 2364 try { 2365 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl"); 2366 surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid); 2367 } finally { 2368 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2369 } 2370 if (surfaceController != null) { 2371 surfaceController.getSurfaceControl(outSurfaceControl); 2372 if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurfaceControl + ": copied"); 2373 } else { 2374 // For some reason there isn't a surface. Clear the 2375 // caller's object so they see the same state. 2376 Slog.w(TAG_WM, "Failed to create surface control for " + win); 2377 outSurfaceControl.release(); 2378 } 2379 2380 return result; 2381 } 2382 outOfMemoryWindow(Session session, IWindow client)2383 public boolean outOfMemoryWindow(Session session, IWindow client) { 2384 final long origId = Binder.clearCallingIdentity(); 2385 2386 try { 2387 synchronized (mGlobalLock) { 2388 WindowState win = windowForClientLocked(session, client, false); 2389 if (win == null) { 2390 return false; 2391 } 2392 return mRoot.reclaimSomeSurfaceMemory(win.mWinAnimator, "from-client", false); 2393 } 2394 } finally { 2395 Binder.restoreCallingIdentity(origId); 2396 } 2397 } 2398 finishDrawingWindow(Session session, IWindow client)2399 void finishDrawingWindow(Session session, IWindow client) { 2400 final long origId = Binder.clearCallingIdentity(); 2401 try { 2402 synchronized (mGlobalLock) { 2403 WindowState win = windowForClientLocked(session, client, false); 2404 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState=" 2405 + (win != null ? win.mWinAnimator.drawStateToString() : "null")); 2406 if (win != null && win.mWinAnimator.finishDrawingLocked()) { 2407 if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { 2408 win.getDisplayContent().pendingLayoutChanges |= 2409 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 2410 } 2411 win.setDisplayLayoutNeeded(); 2412 mWindowPlacerLocked.requestTraversal(); 2413 } 2414 } 2415 } finally { 2416 Binder.restoreCallingIdentity(origId); 2417 } 2418 } 2419 checkCallingPermission(String permission, String func)2420 boolean checkCallingPermission(String permission, String func) { 2421 // Quick check: if the calling permission is me, it's all okay. 2422 if (Binder.getCallingPid() == myPid()) { 2423 return true; 2424 } 2425 2426 if (mContext.checkCallingPermission(permission) 2427 == PackageManager.PERMISSION_GRANTED) { 2428 return true; 2429 } 2430 final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() 2431 + ", uid=" + Binder.getCallingUid() + " requires " + permission; 2432 Slog.w(TAG_WM, msg); 2433 return false; 2434 } 2435 2436 @Override addWindowToken(IBinder binder, int type, int displayId)2437 public void addWindowToken(IBinder binder, int type, int displayId) { 2438 if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) { 2439 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 2440 } 2441 2442 synchronized (mGlobalLock) { 2443 final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */); 2444 if (dc == null) { 2445 Slog.w(TAG_WM, "addWindowToken: Attempted to add token: " + binder 2446 + " for non-exiting displayId=" + displayId); 2447 return; 2448 } 2449 2450 WindowToken token = dc.getWindowToken(binder); 2451 if (token != null) { 2452 Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder 2453 + " for already created window token: " + token 2454 + " displayId=" + displayId); 2455 return; 2456 } 2457 if (type == TYPE_WALLPAPER) { 2458 new WallpaperWindowToken(this, binder, true, dc, 2459 true /* ownerCanManageAppTokens */); 2460 } else { 2461 new WindowToken(this, binder, type, true, dc, true /* ownerCanManageAppTokens */); 2462 } 2463 } 2464 } 2465 2466 @Override removeWindowToken(IBinder binder, int displayId)2467 public void removeWindowToken(IBinder binder, int displayId) { 2468 if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeWindowToken()")) { 2469 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 2470 } 2471 2472 final long origId = Binder.clearCallingIdentity(); 2473 try { 2474 synchronized (mGlobalLock) { 2475 final DisplayContent dc = mRoot.getDisplayContent(displayId); 2476 if (dc == null) { 2477 Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder 2478 + " for non-exiting displayId=" + displayId); 2479 return; 2480 } 2481 2482 final WindowToken token = dc.removeWindowToken(binder); 2483 if (token == null) { 2484 Slog.w(TAG_WM, 2485 "removeWindowToken: Attempted to remove non-existing token: " + binder); 2486 return; 2487 } 2488 2489 dc.getInputMonitor().updateInputWindowsLw(true /*force*/); 2490 } 2491 } finally { 2492 Binder.restoreCallingIdentity(origId); 2493 } 2494 } 2495 setNewDisplayOverrideConfiguration(Configuration overrideConfig, @NonNull DisplayContent dc)2496 void setNewDisplayOverrideConfiguration(Configuration overrideConfig, 2497 @NonNull DisplayContent dc) { 2498 if (dc.mWaitingForConfig) { 2499 dc.mWaitingForConfig = false; 2500 mLastFinishedFreezeSource = "new-config"; 2501 } 2502 2503 mRoot.setDisplayOverrideConfigurationIfNeeded(overrideConfig, dc); 2504 } 2505 2506 // TODO(multi-display): remove when no default display use case. 2507 // (i.e. KeyguardController / RecentsAnimation) 2508 @Override prepareAppTransition(@ransitionType int transit, boolean alwaysKeepCurrent)2509 public void prepareAppTransition(@TransitionType int transit, boolean alwaysKeepCurrent) { 2510 if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) { 2511 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 2512 } 2513 getDefaultDisplayContentLocked().prepareAppTransition(transit, 2514 alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */); 2515 } 2516 2517 @Override overridePendingAppTransitionMultiThumbFuture( IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback, boolean scaleUp, int displayId)2518 public void overridePendingAppTransitionMultiThumbFuture( 2519 IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback, 2520 boolean scaleUp, int displayId) { 2521 synchronized (mGlobalLock) { 2522 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 2523 if (displayContent == null) { 2524 Slog.w(TAG, "Attempted to call overridePendingAppTransitionMultiThumbFuture" 2525 + " for the display " + displayId + " that does not exist."); 2526 return; 2527 } 2528 displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(specsFuture, 2529 callback, scaleUp); 2530 } 2531 } 2532 2533 @Override overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter, int displayId)2534 public void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter, 2535 int displayId) { 2536 if (!checkCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, 2537 "overridePendingAppTransitionRemote()")) { 2538 throw new SecurityException( 2539 "Requires CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS permission"); 2540 } 2541 synchronized (mGlobalLock) { 2542 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 2543 if (displayContent == null) { 2544 Slog.w(TAG, "Attempted to call overridePendingAppTransitionRemote" 2545 + " for the display " + displayId + " that does not exist."); 2546 return; 2547 } 2548 displayContent.mAppTransition.overridePendingAppTransitionRemote( 2549 remoteAnimationAdapter); 2550 } 2551 } 2552 2553 @Override endProlongedAnimations()2554 public void endProlongedAnimations() { 2555 // TODO: Remove once clients are updated. 2556 } 2557 2558 // TODO(multi-display): remove when no default display use case. 2559 // (i.e. KeyguardController / RecentsAnimation) 2560 @Override executeAppTransition()2561 public void executeAppTransition() { 2562 if (!checkCallingPermission(MANAGE_APP_TOKENS, "executeAppTransition()")) { 2563 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 2564 } 2565 getDefaultDisplayContentLocked().executeAppTransition(); 2566 } 2567 initializeRecentsAnimation(int targetActivityType, IRecentsAnimationRunner recentsAnimationRunner, RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId, SparseBooleanArray recentTaskIds)2568 public void initializeRecentsAnimation(int targetActivityType, 2569 IRecentsAnimationRunner recentsAnimationRunner, 2570 RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId, 2571 SparseBooleanArray recentTaskIds) { 2572 synchronized (mGlobalLock) { 2573 mRecentsAnimationController = new RecentsAnimationController(this, 2574 recentsAnimationRunner, callbacks, displayId); 2575 mRoot.getDisplayContent(displayId).mAppTransition.updateBooster(); 2576 mRecentsAnimationController.initialize(targetActivityType, recentTaskIds); 2577 } 2578 } 2579 2580 @VisibleForTesting setRecentsAnimationController(RecentsAnimationController controller)2581 void setRecentsAnimationController(RecentsAnimationController controller) { 2582 mRecentsAnimationController = controller; 2583 } 2584 getRecentsAnimationController()2585 public RecentsAnimationController getRecentsAnimationController() { 2586 return mRecentsAnimationController; 2587 } 2588 2589 /** 2590 * @return Whether the next recents animation can continue to start. Called from 2591 * {@link RecentsAnimation#startRecentsActivity}. 2592 */ canStartRecentsAnimation()2593 public boolean canStartRecentsAnimation() { 2594 synchronized (mGlobalLock) { 2595 // TODO(multi-display): currently only default display support recent activity 2596 if (getDefaultDisplayContentLocked().mAppTransition.isTransitionSet()) { 2597 return false; 2598 } 2599 return true; 2600 } 2601 } 2602 2603 /** 2604 * Cancels any running recents animation. The caller should NOT hold the WM lock while calling 2605 * this method, as it will call back into AM and may cause a deadlock. Any locking will be done 2606 * in the animation controller itself. 2607 */ cancelRecentsAnimationSynchronously( @ecentsAnimationController.ReorderMode int reorderMode, String reason)2608 public void cancelRecentsAnimationSynchronously( 2609 @RecentsAnimationController.ReorderMode int reorderMode, String reason) { 2610 if (mRecentsAnimationController != null) { 2611 // This call will call through to cleanupAnimation() below after the animation is 2612 // canceled 2613 mRecentsAnimationController.cancelAnimationSynchronously(reorderMode, reason); 2614 } 2615 } 2616 cleanupRecentsAnimation(@ecentsAnimationController.ReorderMode int reorderMode)2617 public void cleanupRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) { 2618 synchronized (mGlobalLock) { 2619 if (mRecentsAnimationController != null) { 2620 final RecentsAnimationController controller = mRecentsAnimationController; 2621 mRecentsAnimationController = null; 2622 controller.cleanupAnimation(reorderMode); 2623 // TODO(mult-display): currently only default display support recents animation. 2624 getDefaultDisplayContentLocked().mAppTransition.updateBooster(); 2625 } 2626 } 2627 } 2628 setAppFullscreen(IBinder token, boolean toOpaque)2629 public void setAppFullscreen(IBinder token, boolean toOpaque) { 2630 synchronized (mGlobalLock) { 2631 final AppWindowToken atoken = mRoot.getAppWindowToken(token); 2632 if (atoken != null) { 2633 atoken.setFillsParent(toOpaque); 2634 setWindowOpaqueLocked(token, toOpaque); 2635 mWindowPlacerLocked.requestTraversal(); 2636 } 2637 } 2638 } 2639 setWindowOpaque(IBinder token, boolean isOpaque)2640 public void setWindowOpaque(IBinder token, boolean isOpaque) { 2641 synchronized (mGlobalLock) { 2642 setWindowOpaqueLocked(token, isOpaque); 2643 } 2644 } 2645 setWindowOpaqueLocked(IBinder token, boolean isOpaque)2646 private void setWindowOpaqueLocked(IBinder token, boolean isOpaque) { 2647 final AppWindowToken wtoken = mRoot.getAppWindowToken(token); 2648 if (wtoken != null) { 2649 final WindowState win = wtoken.findMainWindow(); 2650 if (win == null) { 2651 return; 2652 } 2653 isOpaque = isOpaque & !PixelFormat.formatHasAlpha(win.getAttrs().format); 2654 win.mWinAnimator.setOpaqueLocked(isOpaque); 2655 } 2656 } 2657 setDockedStackCreateState(int mode, Rect bounds)2658 public void setDockedStackCreateState(int mode, Rect bounds) { 2659 synchronized (mGlobalLock) { 2660 setDockedStackCreateStateLocked(mode, bounds); 2661 } 2662 } 2663 setDockedStackCreateStateLocked(int mode, Rect bounds)2664 void setDockedStackCreateStateLocked(int mode, Rect bounds) { 2665 mDockedStackCreateMode = mode; 2666 mDockedStackCreateBounds = bounds; 2667 } 2668 checkSplitScreenMinimizedChanged(boolean animate)2669 public void checkSplitScreenMinimizedChanged(boolean animate) { 2670 synchronized (mGlobalLock) { 2671 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 2672 displayContent.getDockedDividerController().checkMinimizeChanged(animate); 2673 } 2674 } 2675 isValidPictureInPictureAspectRatio(int displayId, float aspectRatio)2676 public boolean isValidPictureInPictureAspectRatio(int displayId, float aspectRatio) { 2677 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 2678 return displayContent.getPinnedStackController().isValidPictureInPictureAspectRatio( 2679 aspectRatio); 2680 } 2681 2682 @Override getStackBounds(int windowingMode, int activityType, Rect bounds)2683 public void getStackBounds(int windowingMode, int activityType, Rect bounds) { 2684 synchronized (mGlobalLock) { 2685 final TaskStack stack = mRoot.getStack(windowingMode, activityType); 2686 if (stack != null) { 2687 stack.getBounds(bounds); 2688 return; 2689 } 2690 bounds.setEmpty(); 2691 } 2692 } 2693 2694 /** 2695 * Notifies window manager that {@link DisplayPolicy#isShowingDreamLw} has changed. 2696 */ notifyShowingDreamChanged()2697 public void notifyShowingDreamChanged() { 2698 // TODO(multi-display): support show dream in multi-display. 2699 notifyKeyguardFlagsChanged(null /* callback */, DEFAULT_DISPLAY); 2700 } 2701 2702 @Override getInputMethodWindowLw()2703 public WindowManagerPolicy.WindowState getInputMethodWindowLw() { 2704 return mRoot.getCurrentInputMethodWindow(); 2705 } 2706 2707 @Override notifyKeyguardTrustedChanged()2708 public void notifyKeyguardTrustedChanged() { 2709 mAtmInternal.notifyKeyguardTrustedChanged(); 2710 } 2711 2712 @Override screenTurningOff(ScreenOffListener listener)2713 public void screenTurningOff(ScreenOffListener listener) { 2714 mTaskSnapshotController.screenTurningOff(listener); 2715 } 2716 2717 @Override triggerAnimationFailsafe()2718 public void triggerAnimationFailsafe() { 2719 mH.sendEmptyMessage(H.ANIMATION_FAILSAFE); 2720 } 2721 2722 @Override onKeyguardShowingAndNotOccludedChanged()2723 public void onKeyguardShowingAndNotOccludedChanged() { 2724 mH.sendEmptyMessage(H.RECOMPUTE_FOCUS); 2725 } 2726 2727 @Override onPowerKeyDown(boolean isScreenOn)2728 public void onPowerKeyDown(boolean isScreenOn) { 2729 mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer( 2730 DisplayPolicy::onPowerKeyDown, PooledLambda.__(), isScreenOn)); 2731 } 2732 2733 @Override onUserSwitched()2734 public void onUserSwitched() { 2735 mSettingsObserver.updateSystemUiSettings(); 2736 synchronized (mGlobalLock) { 2737 // force a re-application of focused window sysui visibility on each display. 2738 mRoot.forAllDisplayPolicies(DisplayPolicy::resetSystemUiVisibilityLw); 2739 } 2740 } 2741 2742 @Override moveDisplayToTop(int displayId)2743 public void moveDisplayToTop(int displayId) { 2744 synchronized (mGlobalLock) { 2745 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 2746 if (displayContent != null && mRoot.getTopChild() != displayContent) { 2747 mRoot.positionChildAt(WindowContainer.POSITION_TOP, displayContent, 2748 true /* includingParents */); 2749 } 2750 } 2751 } 2752 2753 /** 2754 * Starts deferring layout passes. Useful when doing multiple changes but to optimize 2755 * performance, only one layout pass should be done. This can be called multiple times, and 2756 * layouting will be resumed once the last caller has called 2757 * {@link #continueSurfaceLayout}. 2758 */ deferSurfaceLayout()2759 void deferSurfaceLayout() { 2760 mWindowPlacerLocked.deferLayout(); 2761 } 2762 2763 /** Resumes layout passes after deferring them. See {@link #deferSurfaceLayout()} */ continueSurfaceLayout()2764 void continueSurfaceLayout() { 2765 mWindowPlacerLocked.continueLayout(); 2766 } 2767 2768 /** 2769 * Notifies activity manager that some Keyguard flags have changed and that it needs to 2770 * reevaluate the visibilities of the activities. 2771 * @param callback Runnable to be called when activity manager is done reevaluating visibilities 2772 */ notifyKeyguardFlagsChanged(@ullable Runnable callback, int displayId)2773 void notifyKeyguardFlagsChanged(@Nullable Runnable callback, int displayId) { 2774 mAtmInternal.notifyKeyguardFlagsChanged(callback, displayId); 2775 } 2776 isKeyguardTrusted()2777 public boolean isKeyguardTrusted() { 2778 synchronized (mGlobalLock) { 2779 return mPolicy.isKeyguardTrustedLw(); 2780 } 2781 } 2782 setKeyguardGoingAway(boolean keyguardGoingAway)2783 public void setKeyguardGoingAway(boolean keyguardGoingAway) { 2784 synchronized (mGlobalLock) { 2785 mKeyguardGoingAway = keyguardGoingAway; 2786 } 2787 } 2788 setKeyguardOrAodShowingOnDefaultDisplay(boolean showing)2789 public void setKeyguardOrAodShowingOnDefaultDisplay(boolean showing) { 2790 synchronized (mGlobalLock) { 2791 mKeyguardOrAodShowingOnDefaultDisplay = showing; 2792 } 2793 } 2794 2795 // ------------------------------------------------------------- 2796 // Misc IWindowSession methods 2797 // ------------------------------------------------------------- 2798 2799 @Override startFreezingScreen(int exitAnim, int enterAnim)2800 public void startFreezingScreen(int exitAnim, int enterAnim) { 2801 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN, 2802 "startFreezingScreen()")) { 2803 throw new SecurityException("Requires FREEZE_SCREEN permission"); 2804 } 2805 2806 synchronized (mGlobalLock) { 2807 if (!mClientFreezingScreen) { 2808 mClientFreezingScreen = true; 2809 final long origId = Binder.clearCallingIdentity(); 2810 try { 2811 startFreezingDisplayLocked(exitAnim, enterAnim); 2812 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); 2813 mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000); 2814 } finally { 2815 Binder.restoreCallingIdentity(origId); 2816 } 2817 } 2818 } 2819 } 2820 2821 @Override stopFreezingScreen()2822 public void stopFreezingScreen() { 2823 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN, 2824 "stopFreezingScreen()")) { 2825 throw new SecurityException("Requires FREEZE_SCREEN permission"); 2826 } 2827 2828 synchronized (mGlobalLock) { 2829 if (mClientFreezingScreen) { 2830 mClientFreezingScreen = false; 2831 mLastFinishedFreezeSource = "client"; 2832 final long origId = Binder.clearCallingIdentity(); 2833 try { 2834 stopFreezingDisplayLocked(); 2835 } finally { 2836 Binder.restoreCallingIdentity(origId); 2837 } 2838 } 2839 } 2840 } 2841 2842 @Override disableKeyguard(IBinder token, String tag, int userId)2843 public void disableKeyguard(IBinder token, String tag, int userId) { 2844 userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 2845 userId, false /* allowAll */, ALLOW_FULL_ONLY, "disableKeyguard", null); 2846 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 2847 != PackageManager.PERMISSION_GRANTED) { 2848 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 2849 } 2850 final int callingUid = Binder.getCallingUid(); 2851 final long origIdentity = Binder.clearCallingIdentity(); 2852 try { 2853 mKeyguardDisableHandler.disableKeyguard(token, tag, callingUid, userId); 2854 } finally { 2855 Binder.restoreCallingIdentity(origIdentity); 2856 } 2857 } 2858 2859 @Override reenableKeyguard(IBinder token, int userId)2860 public void reenableKeyguard(IBinder token, int userId) { 2861 userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 2862 userId, false /* allowAll */, ALLOW_FULL_ONLY, "reenableKeyguard", null); 2863 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 2864 != PackageManager.PERMISSION_GRANTED) { 2865 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 2866 } 2867 Preconditions.checkNotNull(token, "token is null"); 2868 final int callingUid = Binder.getCallingUid(); 2869 final long origIdentity = Binder.clearCallingIdentity(); 2870 try { 2871 mKeyguardDisableHandler.reenableKeyguard(token, callingUid, userId); 2872 } finally { 2873 Binder.restoreCallingIdentity(origIdentity); 2874 } 2875 } 2876 2877 /** 2878 * @see android.app.KeyguardManager#exitKeyguardSecurely 2879 */ 2880 @Override exitKeyguardSecurely(final IOnKeyguardExitResult callback)2881 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) { 2882 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 2883 != PackageManager.PERMISSION_GRANTED) { 2884 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 2885 } 2886 2887 if (callback == null) { 2888 throw new IllegalArgumentException("callback == null"); 2889 } 2890 2891 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() { 2892 @Override 2893 public void onKeyguardExitResult(boolean success) { 2894 try { 2895 callback.onKeyguardExitResult(success); 2896 } catch (RemoteException e) { 2897 // Client has died, we don't care. 2898 } 2899 } 2900 }); 2901 } 2902 2903 @Override isKeyguardLocked()2904 public boolean isKeyguardLocked() { 2905 return mPolicy.isKeyguardLocked(); 2906 } 2907 isKeyguardShowingAndNotOccluded()2908 public boolean isKeyguardShowingAndNotOccluded() { 2909 return mPolicy.isKeyguardShowingAndNotOccluded(); 2910 } 2911 2912 @Override isKeyguardSecure(int userId)2913 public boolean isKeyguardSecure(int userId) { 2914 if (userId != UserHandle.getCallingUserId() 2915 && !checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS, 2916 "isKeyguardSecure")) { 2917 throw new SecurityException("Requires INTERACT_ACROSS_USERS permission"); 2918 } 2919 2920 long origId = Binder.clearCallingIdentity(); 2921 try { 2922 return mPolicy.isKeyguardSecure(userId); 2923 } finally { 2924 Binder.restoreCallingIdentity(origId); 2925 } 2926 } 2927 isShowingDream()2928 public boolean isShowingDream() { 2929 synchronized (mGlobalLock) { 2930 // TODO(b/123372519): Fix this when dream can be shown on non-default display. 2931 return getDefaultDisplayContentLocked().getDisplayPolicy().isShowingDreamLw(); 2932 } 2933 } 2934 2935 @Override dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message)2936 public void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message) { 2937 if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) { 2938 throw new SecurityException("Requires CONTROL_KEYGUARD permission"); 2939 } 2940 synchronized (mGlobalLock) { 2941 mPolicy.dismissKeyguardLw(callback, message); 2942 } 2943 } 2944 onKeyguardOccludedChanged(boolean occluded)2945 public void onKeyguardOccludedChanged(boolean occluded) { 2946 synchronized (mGlobalLock) { 2947 mPolicy.onKeyguardOccludedChangedLw(occluded); 2948 } 2949 } 2950 2951 @Override setSwitchingUser(boolean switching)2952 public void setSwitchingUser(boolean switching) { 2953 if (!checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, 2954 "setSwitchingUser()")) { 2955 throw new SecurityException("Requires INTERACT_ACROSS_USERS_FULL permission"); 2956 } 2957 mPolicy.setSwitchingUser(switching); 2958 synchronized (mGlobalLock) { 2959 mSwitchingUser = switching; 2960 } 2961 } 2962 showGlobalActions()2963 void showGlobalActions() { 2964 mPolicy.showGlobalActions(); 2965 } 2966 2967 @Override closeSystemDialogs(String reason)2968 public void closeSystemDialogs(String reason) { 2969 synchronized (mGlobalLock) { 2970 mRoot.closeSystemDialogs(reason); 2971 } 2972 } 2973 fixScale(float scale)2974 static float fixScale(float scale) { 2975 if (scale < 0) scale = 0; 2976 else if (scale > 20) scale = 20; 2977 return Math.abs(scale); 2978 } 2979 2980 @Override setAnimationScale(int which, float scale)2981 public void setAnimationScale(int which, float scale) { 2982 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE, 2983 "setAnimationScale()")) { 2984 throw new SecurityException("Requires SET_ANIMATION_SCALE permission"); 2985 } 2986 2987 scale = fixScale(scale); 2988 switch (which) { 2989 case 0: mWindowAnimationScaleSetting = scale; break; 2990 case 1: mTransitionAnimationScaleSetting = scale; break; 2991 case 2: mAnimatorDurationScaleSetting = scale; break; 2992 } 2993 2994 // Persist setting 2995 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE); 2996 } 2997 2998 @Override setAnimationScales(float[] scales)2999 public void setAnimationScales(float[] scales) { 3000 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE, 3001 "setAnimationScale()")) { 3002 throw new SecurityException("Requires SET_ANIMATION_SCALE permission"); 3003 } 3004 3005 if (scales != null) { 3006 if (scales.length >= 1) { 3007 mWindowAnimationScaleSetting = fixScale(scales[0]); 3008 } 3009 if (scales.length >= 2) { 3010 mTransitionAnimationScaleSetting = fixScale(scales[1]); 3011 } 3012 if (scales.length >= 3) { 3013 mAnimatorDurationScaleSetting = fixScale(scales[2]); 3014 dispatchNewAnimatorScaleLocked(null); 3015 } 3016 } 3017 3018 // Persist setting 3019 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE); 3020 } 3021 setAnimatorDurationScale(float scale)3022 private void setAnimatorDurationScale(float scale) { 3023 mAnimatorDurationScaleSetting = scale; 3024 ValueAnimator.setDurationScale(scale); 3025 } 3026 getWindowAnimationScaleLocked()3027 public float getWindowAnimationScaleLocked() { 3028 return mAnimationsDisabled ? 0 : mWindowAnimationScaleSetting; 3029 } 3030 getTransitionAnimationScaleLocked()3031 public float getTransitionAnimationScaleLocked() { 3032 return mAnimationsDisabled ? 0 : mTransitionAnimationScaleSetting; 3033 } 3034 3035 @Override getAnimationScale(int which)3036 public float getAnimationScale(int which) { 3037 switch (which) { 3038 case 0: return mWindowAnimationScaleSetting; 3039 case 1: return mTransitionAnimationScaleSetting; 3040 case 2: return mAnimatorDurationScaleSetting; 3041 } 3042 return 0; 3043 } 3044 3045 @Override getAnimationScales()3046 public float[] getAnimationScales() { 3047 return new float[] { mWindowAnimationScaleSetting, mTransitionAnimationScaleSetting, 3048 mAnimatorDurationScaleSetting }; 3049 } 3050 3051 @Override getCurrentAnimatorScale()3052 public float getCurrentAnimatorScale() { 3053 synchronized (mGlobalLock) { 3054 return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting; 3055 } 3056 } 3057 dispatchNewAnimatorScaleLocked(Session session)3058 void dispatchNewAnimatorScaleLocked(Session session) { 3059 mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget(); 3060 } 3061 3062 @Override registerPointerEventListener(PointerEventListener listener, int displayId)3063 public void registerPointerEventListener(PointerEventListener listener, int displayId) { 3064 synchronized (mGlobalLock) { 3065 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 3066 if (displayContent != null) { 3067 displayContent.registerPointerEventListener(listener); 3068 } 3069 } 3070 } 3071 3072 @Override unregisterPointerEventListener(PointerEventListener listener, int displayId)3073 public void unregisterPointerEventListener(PointerEventListener listener, int displayId) { 3074 synchronized (mGlobalLock) { 3075 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 3076 if (displayContent != null) { 3077 displayContent.unregisterPointerEventListener(listener); 3078 } 3079 } 3080 } 3081 3082 // Called by window manager policy. Not exposed externally. 3083 @Override getLidState()3084 public int getLidState() { 3085 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, 3086 InputManagerService.SW_LID); 3087 if (sw > 0) { 3088 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL. 3089 return LID_CLOSED; 3090 } else if (sw == 0) { 3091 // Switch state: AKEY_STATE_UP. 3092 return LID_OPEN; 3093 } else { 3094 // Switch state: AKEY_STATE_UNKNOWN. 3095 return LID_ABSENT; 3096 } 3097 } 3098 3099 // Called by window manager policy. Not exposed externally. 3100 @Override lockDeviceNow()3101 public void lockDeviceNow() { 3102 lockNow(null); 3103 } 3104 3105 // Called by window manager policy. Not exposed externally. 3106 @Override getCameraLensCoverState()3107 public int getCameraLensCoverState() { 3108 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, 3109 InputManagerService.SW_CAMERA_LENS_COVER); 3110 if (sw > 0) { 3111 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL. 3112 return CAMERA_LENS_COVERED; 3113 } else if (sw == 0) { 3114 // Switch state: AKEY_STATE_UP. 3115 return CAMERA_LENS_UNCOVERED; 3116 } else { 3117 // Switch state: AKEY_STATE_UNKNOWN. 3118 return CAMERA_LENS_COVER_ABSENT; 3119 } 3120 } 3121 3122 // Called by window manager policy. Not exposed externally. 3123 @Override switchKeyboardLayout(int deviceId, int direction)3124 public void switchKeyboardLayout(int deviceId, int direction) { 3125 mInputManager.switchKeyboardLayout(deviceId, direction); 3126 } 3127 3128 // Called by window manager policy. Not exposed externally. 3129 @Override shutdown(boolean confirm)3130 public void shutdown(boolean confirm) { 3131 // Pass in the UI context, since ShutdownThread requires it (to show UI). 3132 ShutdownThread.shutdown(ActivityThread.currentActivityThread().getSystemUiContext(), 3133 PowerManager.SHUTDOWN_USER_REQUESTED, confirm); 3134 } 3135 3136 // Called by window manager policy. Not exposed externally. 3137 @Override reboot(boolean confirm)3138 public void reboot(boolean confirm) { 3139 // Pass in the UI context, since ShutdownThread requires it (to show UI). 3140 ShutdownThread.reboot(ActivityThread.currentActivityThread().getSystemUiContext(), 3141 PowerManager.SHUTDOWN_USER_REQUESTED, confirm); 3142 } 3143 3144 // Called by window manager policy. Not exposed externally. 3145 @Override rebootSafeMode(boolean confirm)3146 public void rebootSafeMode(boolean confirm) { 3147 // Pass in the UI context, since ShutdownThread requires it (to show UI). 3148 ShutdownThread.rebootSafeMode(ActivityThread.currentActivityThread().getSystemUiContext(), 3149 confirm); 3150 } 3151 setCurrentProfileIds(final int[] currentProfileIds)3152 public void setCurrentProfileIds(final int[] currentProfileIds) { 3153 synchronized (mGlobalLock) { 3154 mCurrentProfileIds = currentProfileIds; 3155 } 3156 } 3157 setCurrentUser(final int newUserId, final int[] currentProfileIds)3158 public void setCurrentUser(final int newUserId, final int[] currentProfileIds) { 3159 synchronized (mGlobalLock) { 3160 mCurrentUserId = newUserId; 3161 mCurrentProfileIds = currentProfileIds; 3162 mPolicy.setCurrentUserLw(newUserId); 3163 mKeyguardDisableHandler.setCurrentUser(newUserId); 3164 3165 // Hide windows that should not be seen by the new user. 3166 mRoot.switchUser(); 3167 mWindowPlacerLocked.performSurfacePlacement(); 3168 3169 // Notify whether the docked stack exists for the current user 3170 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 3171 final TaskStack stack = 3172 displayContent.getSplitScreenPrimaryStackIgnoringVisibility(); 3173 displayContent.mDividerControllerLocked.notifyDockedStackExistsChanged( 3174 stack != null && stack.hasTaskForUser(newUserId)); 3175 3176 mRoot.forAllDisplays(dc -> dc.mAppTransition.setCurrentUser(newUserId)); 3177 3178 // If the display is already prepared, update the density. 3179 // Otherwise, we'll update it when it's prepared. 3180 if (mDisplayReady) { 3181 final int forcedDensity = getForcedDisplayDensityForUserLocked(newUserId); 3182 final int targetDensity = forcedDensity != 0 ? forcedDensity 3183 : displayContent.mInitialDisplayDensity; 3184 displayContent.setForcedDensity(targetDensity, UserHandle.USER_CURRENT); 3185 } 3186 } 3187 } 3188 3189 /* Called by WindowState */ isCurrentProfileLocked(int userId)3190 boolean isCurrentProfileLocked(int userId) { 3191 if (userId == mCurrentUserId) return true; 3192 for (int i = 0; i < mCurrentProfileIds.length; i++) { 3193 if (mCurrentProfileIds[i] == userId) return true; 3194 } 3195 return false; 3196 } 3197 enableScreenAfterBoot()3198 public void enableScreenAfterBoot() { 3199 synchronized (mGlobalLock) { 3200 if (DEBUG_BOOT) { 3201 RuntimeException here = new RuntimeException("here"); 3202 here.fillInStackTrace(); 3203 Slog.i(TAG_WM, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled 3204 + " mForceDisplayEnabled=" + mForceDisplayEnabled 3205 + " mShowingBootMessages=" + mShowingBootMessages 3206 + " mSystemBooted=" + mSystemBooted, here); 3207 } 3208 if (mSystemBooted) { 3209 return; 3210 } 3211 mSystemBooted = true; 3212 hideBootMessagesLocked(); 3213 // If the screen still doesn't come up after 30 seconds, give 3214 // up and turn it on. 3215 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000); 3216 } 3217 3218 mPolicy.systemBooted(); 3219 3220 performEnableScreen(); 3221 } 3222 3223 @Override enableScreenIfNeeded()3224 public void enableScreenIfNeeded() { 3225 synchronized (mGlobalLock) { 3226 enableScreenIfNeededLocked(); 3227 } 3228 } 3229 enableScreenIfNeededLocked()3230 void enableScreenIfNeededLocked() { 3231 if (DEBUG_BOOT) { 3232 RuntimeException here = new RuntimeException("here"); 3233 here.fillInStackTrace(); 3234 Slog.i(TAG_WM, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled 3235 + " mForceDisplayEnabled=" + mForceDisplayEnabled 3236 + " mShowingBootMessages=" + mShowingBootMessages 3237 + " mSystemBooted=" + mSystemBooted, here); 3238 } 3239 if (mDisplayEnabled) { 3240 return; 3241 } 3242 if (!mSystemBooted && !mShowingBootMessages) { 3243 return; 3244 } 3245 mH.sendEmptyMessage(H.ENABLE_SCREEN); 3246 } 3247 performBootTimeout()3248 public void performBootTimeout() { 3249 synchronized (mGlobalLock) { 3250 if (mDisplayEnabled) { 3251 return; 3252 } 3253 Slog.w(TAG_WM, "***** BOOT TIMEOUT: forcing display enabled"); 3254 mForceDisplayEnabled = true; 3255 } 3256 performEnableScreen(); 3257 } 3258 3259 /** 3260 * Called when System UI has been started. 3261 */ onSystemUiStarted()3262 public void onSystemUiStarted() { 3263 mPolicy.onSystemUiStarted(); 3264 } 3265 performEnableScreen()3266 private void performEnableScreen() { 3267 synchronized (mGlobalLock) { 3268 if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled 3269 + " mForceDisplayEnabled=" + mForceDisplayEnabled 3270 + " mShowingBootMessages=" + mShowingBootMessages 3271 + " mSystemBooted=" + mSystemBooted 3272 + " mOnlyCore=" + mOnlyCore, 3273 new RuntimeException("here").fillInStackTrace()); 3274 if (mDisplayEnabled) { 3275 return; 3276 } 3277 if (!mSystemBooted && !mShowingBootMessages) { 3278 return; 3279 } 3280 3281 if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) { 3282 return; 3283 } 3284 3285 // Don't enable the screen until all existing windows have been drawn. 3286 if (!mForceDisplayEnabled 3287 // TODO(multidisplay): Expand to all displays? 3288 && getDefaultDisplayContentLocked().checkWaitingForWindows()) { 3289 return; 3290 } 3291 3292 if (!mBootAnimationStopped) { 3293 Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0); 3294 // stop boot animation 3295 // formerly we would just kill the process, but we now ask it to exit so it 3296 // can choose where to stop the animation. 3297 SystemProperties.set("service.bootanim.exit", "1"); 3298 mBootAnimationStopped = true; 3299 } 3300 3301 if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) { 3302 if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: Waiting for anim complete"); 3303 return; 3304 } 3305 3306 try { 3307 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger"); 3308 if (surfaceFlinger != null) { 3309 Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!"); 3310 Parcel data = Parcel.obtain(); 3311 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 3312 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED 3313 data, null, 0); 3314 data.recycle(); 3315 } 3316 } catch (RemoteException ex) { 3317 Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!"); 3318 } 3319 3320 EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis()); 3321 Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0); 3322 mDisplayEnabled = true; 3323 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******************** ENABLING SCREEN!"); 3324 3325 // Enable input dispatch. 3326 mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled); 3327 } 3328 3329 try { 3330 mActivityManager.bootAnimationComplete(); 3331 } catch (RemoteException e) { 3332 } 3333 3334 mPolicy.enableScreenAfterBoot(); 3335 3336 // Make sure the last requested orientation has been applied. 3337 updateRotationUnchecked(false, false); 3338 } 3339 checkBootAnimationCompleteLocked()3340 private boolean checkBootAnimationCompleteLocked() { 3341 if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) { 3342 mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED); 3343 mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED, 3344 BOOT_ANIMATION_POLL_INTERVAL); 3345 if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Waiting for anim complete"); 3346 return false; 3347 } 3348 if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Animation complete!"); 3349 return true; 3350 } 3351 showBootMessage(final CharSequence msg, final boolean always)3352 public void showBootMessage(final CharSequence msg, final boolean always) { 3353 boolean first = false; 3354 synchronized (mGlobalLock) { 3355 if (DEBUG_BOOT) { 3356 RuntimeException here = new RuntimeException("here"); 3357 here.fillInStackTrace(); 3358 Slog.i(TAG_WM, "showBootMessage: msg=" + msg + " always=" + always 3359 + " mAllowBootMessages=" + mAllowBootMessages 3360 + " mShowingBootMessages=" + mShowingBootMessages 3361 + " mSystemBooted=" + mSystemBooted, here); 3362 } 3363 if (!mAllowBootMessages) { 3364 return; 3365 } 3366 if (!mShowingBootMessages) { 3367 if (!always) { 3368 return; 3369 } 3370 first = true; 3371 } 3372 if (mSystemBooted) { 3373 return; 3374 } 3375 mShowingBootMessages = true; 3376 mPolicy.showBootMessage(msg, always); 3377 } 3378 if (first) { 3379 performEnableScreen(); 3380 } 3381 } 3382 hideBootMessagesLocked()3383 public void hideBootMessagesLocked() { 3384 if (DEBUG_BOOT) { 3385 RuntimeException here = new RuntimeException("here"); 3386 here.fillInStackTrace(); 3387 Slog.i(TAG_WM, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled 3388 + " mForceDisplayEnabled=" + mForceDisplayEnabled 3389 + " mShowingBootMessages=" + mShowingBootMessages 3390 + " mSystemBooted=" + mSystemBooted, here); 3391 } 3392 if (mShowingBootMessages) { 3393 mShowingBootMessages = false; 3394 mPolicy.hideBootMessages(); 3395 } 3396 } 3397 3398 @Override setInTouchMode(boolean mode)3399 public void setInTouchMode(boolean mode) { 3400 synchronized (mGlobalLock) { 3401 mInTouchMode = mode; 3402 } 3403 } 3404 updateCircularDisplayMaskIfNeeded()3405 private void updateCircularDisplayMaskIfNeeded() { 3406 if (mContext.getResources().getConfiguration().isScreenRound() 3407 && mContext.getResources().getBoolean( 3408 com.android.internal.R.bool.config_windowShowCircularMask)) { 3409 final int currentUserId; 3410 synchronized (mGlobalLock) { 3411 currentUserId = mCurrentUserId; 3412 } 3413 // Device configuration calls for a circular display mask, but we only enable the mask 3414 // if the accessibility color inversion feature is disabled, as the inverted mask 3415 // causes artifacts. 3416 int inversionState = Settings.Secure.getIntForUser(mContext.getContentResolver(), 3417 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, currentUserId); 3418 int showMask = (inversionState == 1) ? 0 : 1; 3419 Message m = mH.obtainMessage(H.SHOW_CIRCULAR_DISPLAY_MASK); 3420 m.arg1 = showMask; 3421 mH.sendMessage(m); 3422 } 3423 } 3424 showEmulatorDisplayOverlayIfNeeded()3425 public void showEmulatorDisplayOverlayIfNeeded() { 3426 if (mContext.getResources().getBoolean( 3427 com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay) 3428 && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false) 3429 && Build.IS_EMULATOR) { 3430 mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY)); 3431 } 3432 } 3433 showCircularMask(boolean visible)3434 public void showCircularMask(boolean visible) { 3435 synchronized (mGlobalLock) { 3436 3437 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, 3438 ">>> OPEN TRANSACTION showCircularMask(visible=" + visible + ")"); 3439 openSurfaceTransaction(); 3440 try { 3441 if (visible) { 3442 // TODO(multi-display): support multiple displays 3443 if (mCircularDisplayMask == null) { 3444 int screenOffset = mContext.getResources().getInteger( 3445 com.android.internal.R.integer.config_windowOutsetBottom); 3446 int maskThickness = mContext.getResources().getDimensionPixelSize( 3447 com.android.internal.R.dimen.circular_display_mask_thickness); 3448 3449 mCircularDisplayMask = new CircularDisplayMask( 3450 getDefaultDisplayContentLocked(), 3451 mPolicy.getWindowLayerFromTypeLw( 3452 WindowManager.LayoutParams.TYPE_POINTER) 3453 * TYPE_LAYER_MULTIPLIER + 10, screenOffset, maskThickness); 3454 } 3455 mCircularDisplayMask.setVisibility(true); 3456 } else if (mCircularDisplayMask != null) { 3457 mCircularDisplayMask.setVisibility(false); 3458 mCircularDisplayMask = null; 3459 } 3460 } finally { 3461 closeSurfaceTransaction("showCircularMask"); 3462 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, 3463 "<<< CLOSE TRANSACTION showCircularMask(visible=" + visible + ")"); 3464 } 3465 } 3466 } 3467 showEmulatorDisplayOverlay()3468 public void showEmulatorDisplayOverlay() { 3469 synchronized (mGlobalLock) { 3470 3471 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, 3472 ">>> OPEN TRANSACTION showEmulatorDisplayOverlay"); 3473 openSurfaceTransaction(); 3474 try { 3475 if (mEmulatorDisplayOverlay == null) { 3476 mEmulatorDisplayOverlay = new EmulatorDisplayOverlay( 3477 mContext, 3478 getDefaultDisplayContentLocked(), 3479 mPolicy.getWindowLayerFromTypeLw( 3480 WindowManager.LayoutParams.TYPE_POINTER) 3481 * TYPE_LAYER_MULTIPLIER + 10); 3482 } 3483 mEmulatorDisplayOverlay.setVisibility(true); 3484 } finally { 3485 closeSurfaceTransaction("showEmulatorDisplayOverlay"); 3486 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, 3487 "<<< CLOSE TRANSACTION showEmulatorDisplayOverlay"); 3488 } 3489 } 3490 } 3491 3492 // TODO: more accounting of which pid(s) turned it on, keep count, 3493 // only allow disables from pids which have count on, etc. 3494 @Override showStrictModeViolation(boolean on)3495 public void showStrictModeViolation(boolean on) { 3496 final int pid = Binder.getCallingPid(); 3497 if (on) { 3498 // Show the visualization, and enqueue a second message to tear it 3499 // down if we don't hear back from the app. 3500 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 1, pid)); 3501 mH.sendMessageDelayed(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid), 3502 DateUtils.SECOND_IN_MILLIS); 3503 } else { 3504 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid)); 3505 } 3506 } 3507 showStrictModeViolation(int arg, int pid)3508 private void showStrictModeViolation(int arg, int pid) { 3509 final boolean on = arg != 0; 3510 synchronized (mGlobalLock) { 3511 // Ignoring requests to enable the red border from clients which aren't on screen. 3512 // (e.g. Broadcast Receivers in the background..) 3513 if (on && !mRoot.canShowStrictModeViolation(pid)) { 3514 return; 3515 } 3516 3517 if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM, 3518 ">>> OPEN TRANSACTION showStrictModeViolation"); 3519 // TODO: Modify this to use the surface trace once it is not going crazy. 3520 // b/31532461 3521 SurfaceControl.openTransaction(); 3522 try { 3523 // TODO(multi-display): support multiple displays 3524 if (mStrictModeFlash == null) { 3525 mStrictModeFlash = new StrictModeFlash( 3526 getDefaultDisplayContentLocked()); 3527 } 3528 mStrictModeFlash.setVisibility(on); 3529 } finally { 3530 SurfaceControl.closeTransaction(); 3531 if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM, 3532 "<<< CLOSE TRANSACTION showStrictModeViolation"); 3533 } 3534 } 3535 } 3536 3537 @Override setStrictModeVisualIndicatorPreference(String value)3538 public void setStrictModeVisualIndicatorPreference(String value) { 3539 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value); 3540 } 3541 3542 @Override screenshotWallpaper()3543 public Bitmap screenshotWallpaper() { 3544 if (!checkCallingPermission(READ_FRAME_BUFFER, "screenshotWallpaper()")) { 3545 throw new SecurityException("Requires READ_FRAME_BUFFER permission"); 3546 } 3547 try { 3548 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper"); 3549 synchronized (mGlobalLock) { 3550 // TODO(b/115486823) Screenshot at secondary displays if needed. 3551 final DisplayContent dc = mRoot.getDisplayContent(DEFAULT_DISPLAY); 3552 return dc.mWallpaperController.screenshotWallpaperLocked(); 3553 } 3554 } finally { 3555 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 3556 } 3557 } 3558 3559 /** 3560 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen. 3561 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension 3562 * of the target image. 3563 */ 3564 @Override requestAssistScreenshot(final IAssistDataReceiver receiver)3565 public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) { 3566 if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) { 3567 throw new SecurityException("Requires READ_FRAME_BUFFER permission"); 3568 } 3569 3570 final Bitmap bm; 3571 synchronized (mGlobalLock) { 3572 final DisplayContent displayContent = mRoot.getDisplayContent(DEFAULT_DISPLAY); 3573 if (displayContent == null) { 3574 if (DEBUG_SCREENSHOT) { 3575 Slog.i(TAG_WM, "Screenshot returning null. No Display for displayId=" 3576 + DEFAULT_DISPLAY); 3577 } 3578 bm = null; 3579 } else { 3580 bm = displayContent.screenshotDisplayLocked(Bitmap.Config.ARGB_8888); 3581 } 3582 } 3583 3584 FgThread.getHandler().post(() -> { 3585 try { 3586 receiver.onHandleAssistScreenshot(bm); 3587 } catch (RemoteException e) { 3588 } 3589 }); 3590 3591 return true; 3592 } 3593 getTaskSnapshot(int taskId, int userId, boolean reducedResolution, boolean restoreFromDisk)3594 public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean reducedResolution, 3595 boolean restoreFromDisk) { 3596 return mTaskSnapshotController.getSnapshot(taskId, userId, restoreFromDisk, 3597 reducedResolution); 3598 } 3599 3600 /** 3601 * In case a task write/delete operation was lost because the system crashed, this makes sure to 3602 * clean up the directory to remove obsolete files. 3603 * 3604 * @param persistentTaskIds A set of task ids that exist in our in-memory model. 3605 * @param runningUserIds The ids of the list of users that have tasks loaded in our in-memory 3606 * model. 3607 */ removeObsoleteTaskFiles(ArraySet<Integer> persistentTaskIds, int[] runningUserIds)3608 public void removeObsoleteTaskFiles(ArraySet<Integer> persistentTaskIds, int[] runningUserIds) { 3609 synchronized (mGlobalLock) { 3610 mTaskSnapshotController.removeObsoleteTaskFiles(persistentTaskIds, runningUserIds); 3611 } 3612 } 3613 setRotateForApp(int displayId, @DisplayRotation.FixedToUserRotation int fixedToUserRotation)3614 void setRotateForApp(int displayId, 3615 @DisplayRotation.FixedToUserRotation int fixedToUserRotation) { 3616 synchronized (mGlobalLock) { 3617 final DisplayContent display = mRoot.getDisplayContent(displayId); 3618 if (display == null) { 3619 Slog.w(TAG, "Trying to set rotate for app for a missing display."); 3620 return; 3621 } 3622 display.getDisplayRotation().setFixedToUserRotation(fixedToUserRotation); 3623 } 3624 } 3625 3626 @Override freezeRotation(int rotation)3627 public void freezeRotation(int rotation) { 3628 freezeDisplayRotation(Display.DEFAULT_DISPLAY, rotation); 3629 } 3630 3631 /** 3632 * Freeze rotation changes. (Enable "rotation lock".) 3633 * Persists across reboots. 3634 * @param displayId The ID of the display to freeze. 3635 * @param rotation The desired rotation to freeze to, or -1 to use the current rotation. 3636 */ 3637 @Override freezeDisplayRotation(int displayId, int rotation)3638 public void freezeDisplayRotation(int displayId, int rotation) { 3639 // TODO(multi-display): Track which display is rotated. 3640 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, 3641 "freezeRotation()")) { 3642 throw new SecurityException("Requires SET_ORIENTATION permission"); 3643 } 3644 if (rotation < -1 || rotation > Surface.ROTATION_270) { 3645 throw new IllegalArgumentException("Rotation argument must be -1 or a valid " 3646 + "rotation constant."); 3647 } 3648 3649 long origId = Binder.clearCallingIdentity(); 3650 try { 3651 synchronized (mGlobalLock) { 3652 final DisplayContent display = mRoot.getDisplayContent(displayId); 3653 if (display == null) { 3654 Slog.w(TAG, "Trying to freeze rotation for a missing display."); 3655 return; 3656 } 3657 display.getDisplayRotation().freezeRotation(rotation); 3658 } 3659 } finally { 3660 Binder.restoreCallingIdentity(origId); 3661 } 3662 3663 updateRotationUnchecked(false, false); 3664 } 3665 3666 @Override thawRotation()3667 public void thawRotation() { 3668 thawDisplayRotation(Display.DEFAULT_DISPLAY); 3669 } 3670 3671 /** 3672 * Thaw rotation changes. (Disable "rotation lock".) 3673 * Persists across reboots. 3674 */ 3675 @Override thawDisplayRotation(int displayId)3676 public void thawDisplayRotation(int displayId) { 3677 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, 3678 "thawRotation()")) { 3679 throw new SecurityException("Requires SET_ORIENTATION permission"); 3680 } 3681 3682 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "thawRotation: mRotation=" 3683 + getDefaultDisplayRotation()); 3684 3685 long origId = Binder.clearCallingIdentity(); 3686 try { 3687 synchronized (mGlobalLock) { 3688 final DisplayContent display = mRoot.getDisplayContent(displayId); 3689 if (display == null) { 3690 Slog.w(TAG, "Trying to thaw rotation for a missing display."); 3691 return; 3692 } 3693 display.getDisplayRotation().thawRotation(); 3694 } 3695 } finally { 3696 Binder.restoreCallingIdentity(origId); 3697 } 3698 3699 updateRotationUnchecked(false, false); 3700 } 3701 3702 @Override isRotationFrozen()3703 public boolean isRotationFrozen() { 3704 return isDisplayRotationFrozen(Display.DEFAULT_DISPLAY); 3705 } 3706 3707 @Override isDisplayRotationFrozen(int displayId)3708 public boolean isDisplayRotationFrozen(int displayId) { 3709 synchronized (mGlobalLock) { 3710 final DisplayContent display = mRoot.getDisplayContent(displayId); 3711 if (display == null) { 3712 Slog.w(TAG, "Trying to thaw rotation for a missing display."); 3713 return false; 3714 } 3715 return display.getDisplayRotation().isRotationFrozen(); 3716 } 3717 } 3718 3719 /** 3720 * Recalculate the current rotation. 3721 * 3722 * Called by the window manager policy whenever the state of the system changes 3723 * such that the current rotation might need to be updated, such as when the 3724 * device is docked or rotated into a new posture. 3725 */ 3726 @Override updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout)3727 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { 3728 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout); 3729 } 3730 updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout)3731 private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) { 3732 if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:" 3733 + " alwaysSendConfiguration=" + alwaysSendConfiguration 3734 + " forceRelayout=" + forceRelayout); 3735 3736 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation"); 3737 3738 long origId = Binder.clearCallingIdentity(); 3739 3740 try { 3741 synchronized (mGlobalLock) { 3742 boolean layoutNeeded = false; 3743 final int displayCount = mRoot.mChildren.size(); 3744 for (int i = 0; i < displayCount; ++i) { 3745 final DisplayContent displayContent = mRoot.mChildren.get(i); 3746 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display"); 3747 final boolean rotationChanged = displayContent.updateRotationUnchecked(); 3748 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 3749 3750 if (!rotationChanged || forceRelayout) { 3751 displayContent.setLayoutNeeded(); 3752 layoutNeeded = true; 3753 } 3754 if (rotationChanged || alwaysSendConfiguration) { 3755 displayContent.sendNewConfiguration(); 3756 } 3757 } 3758 3759 if (layoutNeeded) { 3760 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, 3761 "updateRotation: performSurfacePlacement"); 3762 mWindowPlacerLocked.performSurfacePlacement(); 3763 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 3764 } 3765 } 3766 } finally { 3767 Binder.restoreCallingIdentity(origId); 3768 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 3769 } 3770 } 3771 3772 @Override getDefaultDisplayRotation()3773 public int getDefaultDisplayRotation() { 3774 synchronized (mGlobalLock) { 3775 return getDefaultDisplayContentLocked().getRotation(); 3776 } 3777 } 3778 3779 @Override watchRotation(IRotationWatcher watcher, int displayId)3780 public int watchRotation(IRotationWatcher watcher, int displayId) { 3781 final DisplayContent displayContent; 3782 synchronized (mGlobalLock) { 3783 displayContent = mRoot.getDisplayContent(displayId); 3784 } 3785 if (displayContent == null) { 3786 throw new IllegalArgumentException("Trying to register rotation event " 3787 + "for invalid display: " + displayId); 3788 } 3789 3790 final IBinder watcherBinder = watcher.asBinder(); 3791 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() { 3792 @Override 3793 public void binderDied() { 3794 synchronized (mGlobalLock) { 3795 for (int i=0; i<mRotationWatchers.size(); i++) { 3796 if (watcherBinder == mRotationWatchers.get(i).mWatcher.asBinder()) { 3797 RotationWatcher removed = mRotationWatchers.remove(i); 3798 IBinder binder = removed.mWatcher.asBinder(); 3799 if (binder != null) { 3800 binder.unlinkToDeath(this, 0); 3801 } 3802 i--; 3803 } 3804 } 3805 } 3806 } 3807 }; 3808 3809 synchronized (mGlobalLock) { 3810 try { 3811 watcher.asBinder().linkToDeath(dr, 0); 3812 mRotationWatchers.add(new RotationWatcher(watcher, dr, displayId)); 3813 } catch (RemoteException e) { 3814 // Client died, no cleanup needed. 3815 } 3816 3817 return displayContent.getRotation(); 3818 } 3819 } 3820 3821 @Override removeRotationWatcher(IRotationWatcher watcher)3822 public void removeRotationWatcher(IRotationWatcher watcher) { 3823 final IBinder watcherBinder = watcher.asBinder(); 3824 synchronized (mGlobalLock) { 3825 for (int i=0; i<mRotationWatchers.size(); i++) { 3826 RotationWatcher rotationWatcher = mRotationWatchers.get(i); 3827 if (watcherBinder == rotationWatcher.mWatcher.asBinder()) { 3828 RotationWatcher removed = mRotationWatchers.remove(i); 3829 IBinder binder = removed.mWatcher.asBinder(); 3830 if (binder != null) { 3831 binder.unlinkToDeath(removed.mDeathRecipient, 0); 3832 } 3833 i--; 3834 } 3835 } 3836 } 3837 } 3838 3839 @Override registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener, int displayId)3840 public boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener, 3841 int displayId) { 3842 synchronized (mGlobalLock) { 3843 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 3844 if (displayContent == null) { 3845 throw new IllegalArgumentException("Trying to register visibility event " 3846 + "for invalid display: " + displayId); 3847 } 3848 mWallpaperVisibilityListeners.registerWallpaperVisibilityListener(listener, displayId); 3849 return displayContent.mWallpaperController.isWallpaperVisible(); 3850 } 3851 } 3852 3853 @Override unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener, int displayId)3854 public void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener, 3855 int displayId) { 3856 synchronized (mGlobalLock) { 3857 mWallpaperVisibilityListeners 3858 .unregisterWallpaperVisibilityListener(listener, displayId); 3859 } 3860 } 3861 3862 @Override registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener, int displayId)3863 public void registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener, 3864 int displayId) { 3865 synchronized (mGlobalLock) { 3866 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 3867 if (displayContent == null) { 3868 throw new IllegalArgumentException("Trying to register visibility event " 3869 + "for invalid display: " + displayId); 3870 } 3871 displayContent.registerSystemGestureExclusionListener(listener); 3872 } 3873 } 3874 3875 @Override unregisterSystemGestureExclusionListener(ISystemGestureExclusionListener listener, int displayId)3876 public void unregisterSystemGestureExclusionListener(ISystemGestureExclusionListener listener, 3877 int displayId) { 3878 synchronized (mGlobalLock) { 3879 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 3880 if (displayContent == null) { 3881 throw new IllegalArgumentException("Trying to register visibility event " 3882 + "for invalid display: " + displayId); 3883 } 3884 displayContent.unregisterSystemGestureExclusionListener(listener); 3885 } 3886 } 3887 reportSystemGestureExclusionChanged(Session session, IWindow window, List<Rect> exclusionRects)3888 void reportSystemGestureExclusionChanged(Session session, IWindow window, 3889 List<Rect> exclusionRects) { 3890 synchronized (mGlobalLock) { 3891 final WindowState win = windowForClientLocked(session, window, true); 3892 if (win.setSystemGestureExclusion(exclusionRects)) { 3893 win.getDisplayContent().updateSystemGestureExclusion(); 3894 } 3895 } 3896 } 3897 3898 @Override registerDisplayFoldListener(IDisplayFoldListener listener)3899 public void registerDisplayFoldListener(IDisplayFoldListener listener) { 3900 mPolicy.registerDisplayFoldListener(listener); 3901 } 3902 3903 @Override unregisterDisplayFoldListener(IDisplayFoldListener listener)3904 public void unregisterDisplayFoldListener(IDisplayFoldListener listener) { 3905 mPolicy.unregisterDisplayFoldListener(listener); 3906 } 3907 3908 /** 3909 * Overrides the folded area. 3910 * 3911 * @param area the overriding folded area or an empty {@code Rect} to clear the override. 3912 */ setOverrideFoldedArea(@onNull Rect area)3913 void setOverrideFoldedArea(@NonNull Rect area) { 3914 if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS) 3915 != PackageManager.PERMISSION_GRANTED) { 3916 throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS); 3917 } 3918 3919 long origId = Binder.clearCallingIdentity(); 3920 try { 3921 synchronized (mGlobalLock) { 3922 mPolicy.setOverrideFoldedArea(area); 3923 } 3924 } finally { 3925 Binder.restoreCallingIdentity(origId); 3926 } 3927 } 3928 3929 /** 3930 * Get the display folded area. 3931 */ getFoldedArea()3932 @NonNull Rect getFoldedArea() { 3933 long origId = Binder.clearCallingIdentity(); 3934 try { 3935 synchronized (mGlobalLock) { 3936 return mPolicy.getFoldedArea(); 3937 } 3938 } finally { 3939 Binder.restoreCallingIdentity(origId); 3940 } 3941 } 3942 3943 @Override getPreferredOptionsPanelGravity(int displayId)3944 public int getPreferredOptionsPanelGravity(int displayId) { 3945 synchronized (mGlobalLock) { 3946 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 3947 if (displayContent == null) { 3948 return Gravity.CENTER | Gravity.BOTTOM; 3949 } 3950 return displayContent.getPreferredOptionsPanelGravity(); 3951 } 3952 } 3953 3954 /** 3955 * Starts the view server on the specified port. 3956 * 3957 * @param port The port to listener to. 3958 * 3959 * @return True if the server was successfully started, false otherwise. 3960 * 3961 * @see com.android.server.wm.ViewServer 3962 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT 3963 */ 3964 @Override startViewServer(int port)3965 public boolean startViewServer(int port) { 3966 if (isSystemSecure()) { 3967 return false; 3968 } 3969 3970 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) { 3971 return false; 3972 } 3973 3974 if (port < 1024) { 3975 return false; 3976 } 3977 3978 if (mViewServer != null) { 3979 if (!mViewServer.isRunning()) { 3980 try { 3981 return mViewServer.start(); 3982 } catch (IOException e) { 3983 Slog.w(TAG_WM, "View server did not start"); 3984 } 3985 } 3986 return false; 3987 } 3988 3989 try { 3990 mViewServer = new ViewServer(this, port); 3991 return mViewServer.start(); 3992 } catch (IOException e) { 3993 Slog.w(TAG_WM, "View server did not start"); 3994 } 3995 return false; 3996 } 3997 isSystemSecure()3998 private boolean isSystemSecure() { 3999 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) && 4000 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4001 } 4002 4003 /** 4004 * Stops the view server if it exists. 4005 * 4006 * @return True if the server stopped, false if it wasn't started or 4007 * couldn't be stopped. 4008 * 4009 * @see com.android.server.wm.ViewServer 4010 */ 4011 @Override stopViewServer()4012 public boolean stopViewServer() { 4013 if (isSystemSecure()) { 4014 return false; 4015 } 4016 4017 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) { 4018 return false; 4019 } 4020 4021 if (mViewServer != null) { 4022 return mViewServer.stop(); 4023 } 4024 return false; 4025 } 4026 4027 /** 4028 * Indicates whether the view server is running. 4029 * 4030 * @return True if the server is running, false otherwise. 4031 * 4032 * @see com.android.server.wm.ViewServer 4033 */ 4034 @Override isViewServerRunning()4035 public boolean isViewServerRunning() { 4036 if (isSystemSecure()) { 4037 return false; 4038 } 4039 4040 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) { 4041 return false; 4042 } 4043 4044 return mViewServer != null && mViewServer.isRunning(); 4045 } 4046 4047 /** 4048 * Lists all available windows in the system. The listing is written in the specified Socket's 4049 * output stream with the following syntax: windowHashCodeInHexadecimal windowName 4050 * Each line of the output represents a different window. 4051 * 4052 * @param client The remote client to send the listing to. 4053 * @return false if an error occurred, true otherwise. 4054 */ viewServerListWindows(Socket client)4055 boolean viewServerListWindows(Socket client) { 4056 if (isSystemSecure()) { 4057 return false; 4058 } 4059 4060 boolean result = true; 4061 4062 final ArrayList<WindowState> windows = new ArrayList(); 4063 synchronized (mGlobalLock) { 4064 mRoot.forAllWindows(w -> { 4065 windows.add(w); 4066 }, false /* traverseTopToBottom */); 4067 } 4068 4069 BufferedWriter out = null; 4070 4071 // Any uncaught exception will crash the system process 4072 try { 4073 OutputStream clientStream = client.getOutputStream(); 4074 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024); 4075 4076 final int count = windows.size(); 4077 for (int i = 0; i < count; i++) { 4078 final WindowState w = windows.get(i); 4079 out.write(Integer.toHexString(System.identityHashCode(w))); 4080 out.write(' '); 4081 out.append(w.mAttrs.getTitle()); 4082 out.write('\n'); 4083 } 4084 4085 out.write("DONE.\n"); 4086 out.flush(); 4087 } catch (Exception e) { 4088 result = false; 4089 } finally { 4090 if (out != null) { 4091 try { 4092 out.close(); 4093 } catch (IOException e) { 4094 result = false; 4095 } 4096 } 4097 } 4098 4099 return result; 4100 } 4101 4102 // TODO(multidisplay): Extend to multiple displays. 4103 /** 4104 * Returns the focused window in the following format: 4105 * windowHashCodeInHexadecimal windowName 4106 * 4107 * @param client The remote client to send the listing to. 4108 * @return False if an error occurred, true otherwise. 4109 */ viewServerGetFocusedWindow(Socket client)4110 boolean viewServerGetFocusedWindow(Socket client) { 4111 if (isSystemSecure()) { 4112 return false; 4113 } 4114 4115 boolean result = true; 4116 4117 WindowState focusedWindow = getFocusedWindow(); 4118 4119 BufferedWriter out = null; 4120 4121 // Any uncaught exception will crash the system process 4122 try { 4123 OutputStream clientStream = client.getOutputStream(); 4124 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024); 4125 4126 if(focusedWindow != null) { 4127 out.write(Integer.toHexString(System.identityHashCode(focusedWindow))); 4128 out.write(' '); 4129 out.append(focusedWindow.mAttrs.getTitle()); 4130 } 4131 out.write('\n'); 4132 out.flush(); 4133 } catch (Exception e) { 4134 result = false; 4135 } finally { 4136 if (out != null) { 4137 try { 4138 out.close(); 4139 } catch (IOException e) { 4140 result = false; 4141 } 4142 } 4143 } 4144 4145 return result; 4146 } 4147 4148 /** 4149 * Sends a command to a target window. The result of the command, if any, will be 4150 * written in the output stream of the specified socket. 4151 * 4152 * The parameters must follow this syntax: 4153 * windowHashcode extra 4154 * 4155 * Where XX is the length in characeters of the windowTitle. 4156 * 4157 * The first parameter is the target window. The window with the specified hashcode 4158 * will be the target. If no target can be found, nothing happens. The extra parameters 4159 * will be delivered to the target window and as parameters to the command itself. 4160 * 4161 * @param client The remote client to sent the result, if any, to. 4162 * @param command The command to execute. 4163 * @param parameters The command parameters. 4164 * 4165 * @return True if the command was successfully delivered, false otherwise. This does 4166 * not indicate whether the command itself was successful. 4167 */ viewServerWindowCommand(Socket client, String command, String parameters)4168 boolean viewServerWindowCommand(Socket client, String command, String parameters) { 4169 if (isSystemSecure()) { 4170 return false; 4171 } 4172 4173 boolean success = true; 4174 Parcel data = null; 4175 Parcel reply = null; 4176 4177 BufferedWriter out = null; 4178 4179 // Any uncaught exception will crash the system process 4180 try { 4181 // Find the hashcode of the window 4182 int index = parameters.indexOf(' '); 4183 if (index == -1) { 4184 index = parameters.length(); 4185 } 4186 final String code = parameters.substring(0, index); 4187 int hashCode = (int) Long.parseLong(code, 16); 4188 4189 // Extract the command's parameter after the window description 4190 if (index < parameters.length()) { 4191 parameters = parameters.substring(index + 1); 4192 } else { 4193 parameters = ""; 4194 } 4195 4196 final WindowState window = findWindow(hashCode); 4197 if (window == null) { 4198 return false; 4199 } 4200 4201 data = Parcel.obtain(); 4202 data.writeInterfaceToken("android.view.IWindow"); 4203 data.writeString(command); 4204 data.writeString(parameters); 4205 data.writeInt(1); 4206 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0); 4207 4208 reply = Parcel.obtain(); 4209 4210 final IBinder binder = window.mClient.asBinder(); 4211 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER 4212 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0); 4213 4214 reply.readException(); 4215 4216 if (!client.isOutputShutdown()) { 4217 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); 4218 out.write("DONE\n"); 4219 out.flush(); 4220 } 4221 4222 } catch (Exception e) { 4223 Slog.w(TAG_WM, "Could not send command " + command + " with parameters " + parameters, e); 4224 success = false; 4225 } finally { 4226 if (data != null) { 4227 data.recycle(); 4228 } 4229 if (reply != null) { 4230 reply.recycle(); 4231 } 4232 if (out != null) { 4233 try { 4234 out.close(); 4235 } catch (IOException e) { 4236 4237 } 4238 } 4239 } 4240 4241 return success; 4242 } 4243 addWindowChangeListener(WindowChangeListener listener)4244 public void addWindowChangeListener(WindowChangeListener listener) { 4245 synchronized (mGlobalLock) { 4246 mWindowChangeListeners.add(listener); 4247 } 4248 } 4249 removeWindowChangeListener(WindowChangeListener listener)4250 public void removeWindowChangeListener(WindowChangeListener listener) { 4251 synchronized (mGlobalLock) { 4252 mWindowChangeListeners.remove(listener); 4253 } 4254 } 4255 notifyWindowsChanged()4256 private void notifyWindowsChanged() { 4257 WindowChangeListener[] windowChangeListeners; 4258 synchronized (mGlobalLock) { 4259 if(mWindowChangeListeners.isEmpty()) { 4260 return; 4261 } 4262 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()]; 4263 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners); 4264 } 4265 int N = windowChangeListeners.length; 4266 for(int i = 0; i < N; i++) { 4267 windowChangeListeners[i].windowsChanged(); 4268 } 4269 } 4270 notifyFocusChanged()4271 private void notifyFocusChanged() { 4272 WindowChangeListener[] windowChangeListeners; 4273 synchronized (mGlobalLock) { 4274 if(mWindowChangeListeners.isEmpty()) { 4275 return; 4276 } 4277 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()]; 4278 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners); 4279 } 4280 int N = windowChangeListeners.length; 4281 for(int i = 0; i < N; i++) { 4282 windowChangeListeners[i].focusChanged(); 4283 } 4284 } 4285 findWindow(int hashCode)4286 private WindowState findWindow(int hashCode) { 4287 if (hashCode == -1) { 4288 // TODO(multidisplay): Extend to multiple displays. 4289 return getFocusedWindow(); 4290 } 4291 4292 synchronized (mGlobalLock) { 4293 return mRoot.getWindow((w) -> System.identityHashCode(w) == hashCode); 4294 } 4295 } 4296 4297 /** 4298 * Instruct the Activity Manager to fetch and update the current display's configuration and 4299 * broadcast them to config-changed listeners if appropriate. 4300 * NOTE: Can't be called with the window manager lock held since it call into activity manager. 4301 */ sendNewConfiguration(int displayId)4302 void sendNewConfiguration(int displayId) { 4303 try { 4304 final boolean configUpdated = mActivityTaskManager.updateDisplayOverrideConfiguration( 4305 null /* values */, displayId); 4306 if (!configUpdated) { 4307 // Something changed (E.g. device rotation), but no configuration update is needed. 4308 // E.g. changing device rotation by 180 degrees. Go ahead and perform surface 4309 // placement to unfreeze the display since we froze it when the rotation was updated 4310 // in DisplayContent#updateRotationUnchecked. 4311 synchronized (mGlobalLock) { 4312 final DisplayContent dc = mRoot.getDisplayContent(displayId); 4313 if (dc != null && dc.mWaitingForConfig) { 4314 dc.mWaitingForConfig = false; 4315 mLastFinishedFreezeSource = "config-unchanged"; 4316 dc.setLayoutNeeded(); 4317 mWindowPlacerLocked.performSurfacePlacement(); 4318 } 4319 } 4320 } 4321 } catch (RemoteException e) { 4322 } 4323 } 4324 computeNewConfiguration(int displayId)4325 public Configuration computeNewConfiguration(int displayId) { 4326 synchronized (mGlobalLock) { 4327 return computeNewConfigurationLocked(displayId); 4328 } 4329 } 4330 computeNewConfigurationLocked(int displayId)4331 private Configuration computeNewConfigurationLocked(int displayId) { 4332 if (!mDisplayReady) { 4333 return null; 4334 } 4335 final Configuration config = new Configuration(); 4336 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 4337 displayContent.computeScreenConfiguration(config); 4338 return config; 4339 } 4340 notifyHardKeyboardStatusChange()4341 void notifyHardKeyboardStatusChange() { 4342 final boolean available; 4343 final WindowManagerInternal.OnHardKeyboardStatusChangeListener listener; 4344 synchronized (mGlobalLock) { 4345 listener = mHardKeyboardStatusChangeListener; 4346 available = mHardKeyboardAvailable; 4347 } 4348 if (listener != null) { 4349 listener.onHardKeyboardStatusChange(available); 4350 } 4351 } 4352 4353 // ------------------------------------------------------------- 4354 // Input Events and Focus Management 4355 // ------------------------------------------------------------- 4356 4357 final InputManagerCallback mInputManagerCallback = new InputManagerCallback(this); 4358 private boolean mEventDispatchingEnabled; 4359 4360 @Override setEventDispatching(boolean enabled)4361 public void setEventDispatching(boolean enabled) { 4362 if (!checkCallingPermission(MANAGE_APP_TOKENS, "setEventDispatching()")) { 4363 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4364 } 4365 4366 synchronized (mGlobalLock) { 4367 mEventDispatchingEnabled = enabled; 4368 if (mDisplayEnabled) { 4369 mInputManagerCallback.setEventDispatchingLw(enabled); 4370 } 4371 } 4372 } 4373 getFocusedWindow()4374 private WindowState getFocusedWindow() { 4375 synchronized (mGlobalLock) { 4376 return getFocusedWindowLocked(); 4377 } 4378 } 4379 getFocusedWindowLocked()4380 private WindowState getFocusedWindowLocked() { 4381 // Return the focused window in the focused display. 4382 return mRoot.getTopFocusedDisplayContent().mCurrentFocus; 4383 } 4384 getImeFocusStackLocked()4385 TaskStack getImeFocusStackLocked() { 4386 // Don't use mCurrentFocus.getStack() because it returns home stack for system windows. 4387 // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE 4388 // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved 4389 // to make room for IME, but the window is not the focused window that's taking input. 4390 // TODO (b/111080190): Consider the case of multiple IMEs on multi-display. 4391 final DisplayContent topFocusedDisplay = mRoot.getTopFocusedDisplayContent(); 4392 final AppWindowToken focusedApp = topFocusedDisplay.mFocusedApp; 4393 return (focusedApp != null && focusedApp.getTask() != null) 4394 ? focusedApp.getTask().mStack : null; 4395 } 4396 detectSafeMode()4397 public boolean detectSafeMode() { 4398 if (!mInputManagerCallback.waitForInputDevicesReady( 4399 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) { 4400 Slog.w(TAG_WM, "Devices still not ready after waiting " 4401 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS 4402 + " milliseconds before attempting to detect safe mode."); 4403 } 4404 4405 if (Settings.Global.getInt( 4406 mContext.getContentResolver(), Settings.Global.SAFE_BOOT_DISALLOWED, 0) != 0) { 4407 return false; 4408 } 4409 4410 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, 4411 KeyEvent.KEYCODE_MENU); 4412 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S); 4413 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, 4414 KeyEvent.KEYCODE_DPAD_CENTER); 4415 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, 4416 InputManagerService.BTN_MOUSE); 4417 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, 4418 KeyEvent.KEYCODE_VOLUME_DOWN); 4419 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0 4420 || volumeDownState > 0; 4421 try { 4422 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0 4423 || SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) != 0) { 4424 mSafeMode = true; 4425 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, ""); 4426 } 4427 } catch (IllegalArgumentException e) { 4428 } 4429 if (mSafeMode) { 4430 Log.i(TAG_WM, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState 4431 + " dpad=" + dpadState + " trackball=" + trackballState + ")"); 4432 // May already be set if (for instance) this process has crashed 4433 if (SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) == 0) { 4434 SystemProperties.set(ShutdownThread.RO_SAFEMODE_PROPERTY, "1"); 4435 } 4436 } else { 4437 Log.i(TAG_WM, "SAFE MODE not enabled"); 4438 } 4439 mPolicy.setSafeMode(mSafeMode); 4440 return mSafeMode; 4441 } 4442 displayReady()4443 public void displayReady() { 4444 synchronized (mGlobalLock) { 4445 if (mMaxUiWidth > 0) { 4446 mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth)); 4447 } 4448 final boolean changed = applyForcedPropertiesForDefaultDisplay(); 4449 mAnimator.ready(); 4450 mDisplayReady = true; 4451 if (changed) { 4452 reconfigureDisplayLocked(getDefaultDisplayContentLocked()); 4453 } 4454 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature( 4455 PackageManager.FEATURE_TOUCHSCREEN); 4456 } 4457 4458 try { 4459 mActivityTaskManager.updateConfiguration(null); 4460 } catch (RemoteException e) { 4461 } 4462 4463 updateCircularDisplayMaskIfNeeded(); 4464 } 4465 systemReady()4466 public void systemReady() { 4467 mSystemReady = true; 4468 mPolicy.systemReady(); 4469 mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady); 4470 mTaskSnapshotController.systemReady(); 4471 mHasWideColorGamutSupport = queryWideColorGamutSupport(); 4472 mHasHdrSupport = queryHdrSupport(); 4473 UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings); 4474 UiThread.getHandler().post(mSettingsObserver::updatePointerLocation); 4475 IVrManager vrManager = IVrManager.Stub.asInterface( 4476 ServiceManager.getService(Context.VR_SERVICE)); 4477 if (vrManager != null) { 4478 try { 4479 final boolean vrModeEnabled = vrManager.getVrModeState(); 4480 synchronized (mGlobalLock) { 4481 vrManager.registerListener(mVrStateCallbacks); 4482 if (vrModeEnabled) { 4483 mVrModeEnabled = vrModeEnabled; 4484 mVrStateCallbacks.onVrStateChanged(vrModeEnabled); 4485 } 4486 } 4487 } catch (RemoteException e) { 4488 // Ignore, we cannot do anything if we failed to register VR mode listener 4489 } 4490 } 4491 } 4492 queryWideColorGamutSupport()4493 private static boolean queryWideColorGamutSupport() { 4494 try { 4495 ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService(); 4496 OptionalBool hasWideColor = surfaceFlinger.hasWideColorDisplay(); 4497 if (hasWideColor != null) { 4498 return hasWideColor.value; 4499 } 4500 } catch (RemoteException e) { 4501 // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store 4502 } 4503 return false; 4504 } 4505 queryHdrSupport()4506 private static boolean queryHdrSupport() { 4507 try { 4508 ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService(); 4509 OptionalBool hasHdr = surfaceFlinger.hasHDRDisplay(); 4510 if (hasHdr != null) { 4511 return hasHdr.value; 4512 } 4513 } catch (RemoteException e) { 4514 // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store 4515 } 4516 return false; 4517 } 4518 4519 // ------------------------------------------------------------- 4520 // Async Handler 4521 // ------------------------------------------------------------- 4522 4523 final class H extends android.os.Handler { 4524 public static final int REPORT_FOCUS_CHANGE = 2; 4525 public static final int REPORT_LOSING_FOCUS = 3; 4526 public static final int WINDOW_FREEZE_TIMEOUT = 11; 4527 4528 public static final int PERSIST_ANIMATION_SCALE = 14; 4529 public static final int FORCE_GC = 15; 4530 public static final int ENABLE_SCREEN = 16; 4531 public static final int APP_FREEZE_TIMEOUT = 17; 4532 public static final int SEND_NEW_CONFIGURATION = 18; 4533 public static final int REPORT_WINDOWS_CHANGE = 19; 4534 4535 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22; 4536 public static final int BOOT_TIMEOUT = 23; 4537 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24; 4538 public static final int SHOW_STRICT_MODE_VIOLATION = 25; 4539 4540 public static final int CLIENT_FREEZE_TIMEOUT = 30; 4541 public static final int NOTIFY_ACTIVITY_DRAWN = 32; 4542 4543 public static final int ALL_WINDOWS_DRAWN = 33; 4544 4545 public static final int NEW_ANIMATOR_SCALE = 34; 4546 4547 public static final int SHOW_CIRCULAR_DISPLAY_MASK = 35; 4548 public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36; 4549 4550 public static final int CHECK_IF_BOOT_ANIMATION_FINISHED = 37; 4551 public static final int RESET_ANR_MESSAGE = 38; 4552 public static final int WALLPAPER_DRAW_PENDING_TIMEOUT = 39; 4553 4554 public static final int UPDATE_DOCKED_STACK_DIVIDER = 41; 4555 4556 public static final int WINDOW_REPLACEMENT_TIMEOUT = 46; 4557 4558 public static final int UPDATE_ANIMATION_SCALE = 51; 4559 public static final int WINDOW_HIDE_TIMEOUT = 52; 4560 public static final int SEAMLESS_ROTATION_TIMEOUT = 54; 4561 public static final int RESTORE_POINTER_ICON = 55; 4562 public static final int SET_HAS_OVERLAY_UI = 58; 4563 public static final int SET_RUNNING_REMOTE_ANIMATION = 59; 4564 public static final int ANIMATION_FAILSAFE = 60; 4565 public static final int RECOMPUTE_FOCUS = 61; 4566 public static final int ON_POINTER_DOWN_OUTSIDE_FOCUS = 62; 4567 4568 /** 4569 * Used to denote that an integer field in a message will not be used. 4570 */ 4571 public static final int UNUSED = 0; 4572 4573 @Override handleMessage(Message msg)4574 public void handleMessage(Message msg) { 4575 if (DEBUG_WINDOW_TRACE) { 4576 Slog.v(TAG_WM, "handleMessage: entry what=" + msg.what); 4577 } 4578 switch (msg.what) { 4579 case REPORT_FOCUS_CHANGE: { 4580 final DisplayContent displayContent = (DisplayContent) msg.obj; 4581 WindowState lastFocus; 4582 WindowState newFocus; 4583 4584 AccessibilityController accessibilityController = null; 4585 4586 synchronized (mGlobalLock) { 4587 // TODO(multidisplay): Accessibility supported only of default desiplay. 4588 if (mAccessibilityController != null && displayContent.isDefaultDisplay) { 4589 accessibilityController = mAccessibilityController; 4590 } 4591 4592 lastFocus = displayContent.mLastFocus; 4593 newFocus = displayContent.mCurrentFocus; 4594 } 4595 if (lastFocus == newFocus) { 4596 // Focus is not changing, so nothing to do. 4597 return; 4598 } 4599 synchronized (mGlobalLock) { 4600 displayContent.mLastFocus = newFocus; 4601 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Focus moving from " + lastFocus + 4602 " to " + newFocus + " displayId=" + displayContent.getDisplayId()); 4603 if (newFocus != null && lastFocus != null && !newFocus.isDisplayedLw()) { 4604 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Delaying loss of focus..."); 4605 displayContent.mLosingFocus.add(lastFocus); 4606 lastFocus = null; 4607 } 4608 } 4609 4610 // First notify the accessibility manager for the change so it has 4611 // the windows before the newly focused one starts firing eventgs. 4612 if (accessibilityController != null) { 4613 accessibilityController.onWindowFocusChangedNotLocked(); 4614 } 4615 4616 if (newFocus != null) { 4617 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Gaining focus: " + newFocus); 4618 newFocus.reportFocusChangedSerialized(true, mInTouchMode); 4619 notifyFocusChanged(); 4620 } 4621 4622 if (lastFocus != null) { 4623 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing focus: " + lastFocus); 4624 lastFocus.reportFocusChangedSerialized(false, mInTouchMode); 4625 } 4626 break; 4627 } 4628 4629 case REPORT_LOSING_FOCUS: { 4630 final DisplayContent displayContent = (DisplayContent) msg.obj; 4631 ArrayList<WindowState> losers; 4632 4633 synchronized (mGlobalLock) { 4634 losers = displayContent.mLosingFocus; 4635 displayContent.mLosingFocus = new ArrayList<>(); 4636 } 4637 4638 final int N = losers.size(); 4639 for (int i = 0; i < N; i++) { 4640 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing delayed focus: " + 4641 losers.get(i)); 4642 losers.get(i).reportFocusChangedSerialized(false, mInTouchMode); 4643 } 4644 break; 4645 } 4646 4647 case WINDOW_FREEZE_TIMEOUT: { 4648 final DisplayContent displayContent = (DisplayContent) msg.obj; 4649 synchronized (mGlobalLock) { 4650 displayContent.onWindowFreezeTimeout(); 4651 } 4652 break; 4653 } 4654 4655 case PERSIST_ANIMATION_SCALE: { 4656 Settings.Global.putFloat(mContext.getContentResolver(), 4657 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting); 4658 Settings.Global.putFloat(mContext.getContentResolver(), 4659 Settings.Global.TRANSITION_ANIMATION_SCALE, 4660 mTransitionAnimationScaleSetting); 4661 Settings.Global.putFloat(mContext.getContentResolver(), 4662 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting); 4663 break; 4664 } 4665 4666 case UPDATE_ANIMATION_SCALE: { 4667 @UpdateAnimationScaleMode 4668 final int mode = msg.arg1; 4669 switch (mode) { 4670 case WINDOW_ANIMATION_SCALE: { 4671 mWindowAnimationScaleSetting = Settings.Global.getFloat( 4672 mContext.getContentResolver(), 4673 Settings.Global.WINDOW_ANIMATION_SCALE, 4674 mWindowAnimationScaleSetting); 4675 break; 4676 } 4677 case TRANSITION_ANIMATION_SCALE: { 4678 mTransitionAnimationScaleSetting = Settings.Global.getFloat( 4679 mContext.getContentResolver(), 4680 Settings.Global.TRANSITION_ANIMATION_SCALE, 4681 mTransitionAnimationScaleSetting); 4682 break; 4683 } 4684 case ANIMATION_DURATION_SCALE: { 4685 mAnimatorDurationScaleSetting = Settings.Global.getFloat( 4686 mContext.getContentResolver(), 4687 Settings.Global.ANIMATOR_DURATION_SCALE, 4688 mAnimatorDurationScaleSetting); 4689 dispatchNewAnimatorScaleLocked(null); 4690 break; 4691 } 4692 } 4693 break; 4694 } 4695 4696 case FORCE_GC: { 4697 synchronized (mGlobalLock) { 4698 // Since we're holding both mWindowMap and mAnimator we don't need to 4699 // hold mAnimator.mLayoutToAnim. 4700 if (mAnimator.isAnimating() || mAnimator.isAnimationScheduled()) { 4701 // If we are animating, don't do the gc now but 4702 // delay a bit so we don't interrupt the animation. 4703 sendEmptyMessageDelayed(H.FORCE_GC, 2000); 4704 return; 4705 } 4706 // If we are currently rotating the display, it will 4707 // schedule a new message when done. 4708 if (mDisplayFrozen) { 4709 return; 4710 } 4711 } 4712 Runtime.getRuntime().gc(); 4713 break; 4714 } 4715 4716 case ENABLE_SCREEN: { 4717 performEnableScreen(); 4718 break; 4719 } 4720 4721 case APP_FREEZE_TIMEOUT: { 4722 synchronized (mGlobalLock) { 4723 Slog.w(TAG_WM, "App freeze timeout expired."); 4724 mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT; 4725 for (int i = mAppFreezeListeners.size() - 1; i >=0 ; --i) { 4726 mAppFreezeListeners.get(i).onAppFreezeTimeout(); 4727 } 4728 } 4729 break; 4730 } 4731 4732 case CLIENT_FREEZE_TIMEOUT: { 4733 synchronized (mGlobalLock) { 4734 if (mClientFreezingScreen) { 4735 mClientFreezingScreen = false; 4736 mLastFinishedFreezeSource = "client-timeout"; 4737 stopFreezingDisplayLocked(); 4738 } 4739 } 4740 break; 4741 } 4742 4743 case SEND_NEW_CONFIGURATION: { 4744 final DisplayContent displayContent = (DisplayContent) msg.obj; 4745 removeMessages(SEND_NEW_CONFIGURATION, displayContent); 4746 if (displayContent.isReady()) { 4747 sendNewConfiguration(displayContent.getDisplayId()); 4748 } else { 4749 // Message could come after display has already been removed. 4750 if (DEBUG_CONFIGURATION) { 4751 final String reason = displayContent.getParent() == null 4752 ? "detached" : "unready"; 4753 Slog.w(TAG, "Trying to send configuration to " + reason + " display=" 4754 + displayContent); 4755 } 4756 } 4757 break; 4758 } 4759 4760 case REPORT_WINDOWS_CHANGE: { 4761 if (mWindowsChanged) { 4762 synchronized (mGlobalLock) { 4763 mWindowsChanged = false; 4764 } 4765 notifyWindowsChanged(); 4766 } 4767 break; 4768 } 4769 4770 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: { 4771 notifyHardKeyboardStatusChange(); 4772 break; 4773 } 4774 4775 case BOOT_TIMEOUT: { 4776 performBootTimeout(); 4777 break; 4778 } 4779 4780 case WAITING_FOR_DRAWN_TIMEOUT: { 4781 Runnable callback = null; 4782 synchronized (mGlobalLock) { 4783 Slog.w(TAG_WM, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn); 4784 mWaitingForDrawn.clear(); 4785 callback = mWaitingForDrawnCallback; 4786 mWaitingForDrawnCallback = null; 4787 } 4788 if (callback != null) { 4789 callback.run(); 4790 } 4791 break; 4792 } 4793 4794 case SHOW_STRICT_MODE_VIOLATION: { 4795 showStrictModeViolation(msg.arg1, msg.arg2); 4796 break; 4797 } 4798 4799 case SHOW_CIRCULAR_DISPLAY_MASK: { 4800 showCircularMask(msg.arg1 == 1); 4801 break; 4802 } 4803 4804 case SHOW_EMULATOR_DISPLAY_OVERLAY: { 4805 showEmulatorDisplayOverlay(); 4806 break; 4807 } 4808 4809 case NOTIFY_ACTIVITY_DRAWN: { 4810 try { 4811 mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj); 4812 } catch (RemoteException e) { 4813 } 4814 break; 4815 } 4816 case ALL_WINDOWS_DRAWN: { 4817 Runnable callback; 4818 synchronized (mGlobalLock) { 4819 callback = mWaitingForDrawnCallback; 4820 mWaitingForDrawnCallback = null; 4821 } 4822 if (callback != null) { 4823 callback.run(); 4824 } 4825 break; 4826 } 4827 case NEW_ANIMATOR_SCALE: { 4828 float scale = getCurrentAnimatorScale(); 4829 ValueAnimator.setDurationScale(scale); 4830 Session session = (Session)msg.obj; 4831 if (session != null) { 4832 try { 4833 session.mCallback.onAnimatorScaleChanged(scale); 4834 } catch (RemoteException e) { 4835 } 4836 } else { 4837 ArrayList<IWindowSessionCallback> callbacks 4838 = new ArrayList<IWindowSessionCallback>(); 4839 synchronized (mGlobalLock) { 4840 for (int i=0; i<mSessions.size(); i++) { 4841 callbacks.add(mSessions.valueAt(i).mCallback); 4842 } 4843 4844 } 4845 for (int i=0; i<callbacks.size(); i++) { 4846 try { 4847 callbacks.get(i).onAnimatorScaleChanged(scale); 4848 } catch (RemoteException e) { 4849 } 4850 } 4851 } 4852 break; 4853 } 4854 case CHECK_IF_BOOT_ANIMATION_FINISHED: { 4855 final boolean bootAnimationComplete; 4856 synchronized (mGlobalLock) { 4857 if (DEBUG_BOOT) Slog.i(TAG_WM, "CHECK_IF_BOOT_ANIMATION_FINISHED:"); 4858 bootAnimationComplete = checkBootAnimationCompleteLocked(); 4859 } 4860 if (bootAnimationComplete) { 4861 performEnableScreen(); 4862 } 4863 break; 4864 } 4865 case RESET_ANR_MESSAGE: { 4866 synchronized (mGlobalLock) { 4867 mLastANRState = null; 4868 } 4869 mAtmInternal.clearSavedANRState(); 4870 break; 4871 } 4872 case WALLPAPER_DRAW_PENDING_TIMEOUT: { 4873 synchronized (mGlobalLock) { 4874 final WallpaperController wallpaperController = 4875 (WallpaperController) msg.obj; 4876 if (wallpaperController != null 4877 && wallpaperController.processWallpaperDrawPendingTimeout()) { 4878 mWindowPlacerLocked.performSurfacePlacement(); 4879 } 4880 } 4881 break; 4882 } 4883 case UPDATE_DOCKED_STACK_DIVIDER: { 4884 synchronized (mGlobalLock) { 4885 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 4886 displayContent.getDockedDividerController().reevaluateVisibility(false); 4887 displayContent.adjustForImeIfNeeded(); 4888 } 4889 break; 4890 } 4891 case WINDOW_REPLACEMENT_TIMEOUT: { 4892 synchronized (mGlobalLock) { 4893 for (int i = mWindowReplacementTimeouts.size() - 1; i >= 0; i--) { 4894 final AppWindowToken token = mWindowReplacementTimeouts.get(i); 4895 token.onWindowReplacementTimeout(); 4896 } 4897 mWindowReplacementTimeouts.clear(); 4898 } 4899 break; 4900 } 4901 case WINDOW_HIDE_TIMEOUT: { 4902 final WindowState window = (WindowState) msg.obj; 4903 synchronized (mGlobalLock) { 4904 // TODO: This is all about fixing b/21693547 4905 // where partially initialized Toasts get stuck 4906 // around and keep the screen on. We'd like 4907 // to just remove the toast...but this can cause clients 4908 // who miss the timeout due to normal circumstances (e.g. 4909 // running under debugger) to crash (b/29105388). The windows will 4910 // eventually be removed when the client process finishes. 4911 // The best we can do for now is remove the FLAG_KEEP_SCREEN_ON 4912 // and prevent the symptoms of b/21693547. Since apps don't 4913 // support windows being removed under them we hide the window 4914 // and it will be removed when the app dies. 4915 window.mAttrs.flags &= ~FLAG_KEEP_SCREEN_ON; 4916 window.hidePermanentlyLw(); 4917 window.setDisplayLayoutNeeded(); 4918 mWindowPlacerLocked.performSurfacePlacement(); 4919 } 4920 break; 4921 } 4922 case RESTORE_POINTER_ICON: { 4923 synchronized (mGlobalLock) { 4924 restorePointerIconLocked((DisplayContent)msg.obj, msg.arg1, msg.arg2); 4925 } 4926 break; 4927 } 4928 case SEAMLESS_ROTATION_TIMEOUT: { 4929 final DisplayContent displayContent = (DisplayContent) msg.obj; 4930 synchronized (mGlobalLock) { 4931 displayContent.onSeamlessRotationTimeout(); 4932 } 4933 break; 4934 } 4935 case SET_HAS_OVERLAY_UI: { 4936 mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1); 4937 break; 4938 } 4939 case SET_RUNNING_REMOTE_ANIMATION: { 4940 mAmInternal.setRunningRemoteAnimation(msg.arg1, msg.arg2 == 1); 4941 break; 4942 } 4943 case ANIMATION_FAILSAFE: { 4944 synchronized (mGlobalLock) { 4945 if (mRecentsAnimationController != null) { 4946 mRecentsAnimationController.scheduleFailsafe(); 4947 } 4948 } 4949 break; 4950 } 4951 case RECOMPUTE_FOCUS: { 4952 synchronized (mGlobalLock) { 4953 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, 4954 true /* updateInputWindows */); 4955 } 4956 break; 4957 } 4958 case ON_POINTER_DOWN_OUTSIDE_FOCUS: { 4959 synchronized (mGlobalLock) { 4960 final IBinder touchedToken = (IBinder) msg.obj; 4961 onPointerDownOutsideFocusLocked(touchedToken); 4962 } 4963 break; 4964 } 4965 } 4966 if (DEBUG_WINDOW_TRACE) { 4967 Slog.v(TAG_WM, "handleMessage: exit"); 4968 } 4969 } 4970 4971 /** Remove the previous messages with the same 'what' and 'obj' then send the new one. */ sendNewMessageDelayed(int what, Object obj, long delayMillis)4972 void sendNewMessageDelayed(int what, Object obj, long delayMillis) { 4973 removeMessages(what, obj); 4974 sendMessageDelayed(obtainMessage(what, obj), delayMillis); 4975 } 4976 } 4977 destroyPreservedSurfaceLocked()4978 void destroyPreservedSurfaceLocked() { 4979 for (int i = mDestroyPreservedSurface.size() - 1; i >= 0 ; i--) { 4980 final WindowState w = mDestroyPreservedSurface.get(i); 4981 w.mWinAnimator.destroyPreservedSurfaceLocked(); 4982 } 4983 mDestroyPreservedSurface.clear(); 4984 } 4985 4986 // ------------------------------------------------------------- 4987 // IWindowManager API 4988 // ------------------------------------------------------------- 4989 4990 @Override openSession(IWindowSessionCallback callback)4991 public IWindowSession openSession(IWindowSessionCallback callback) { 4992 return new Session(this, callback); 4993 } 4994 4995 @Override getInitialDisplaySize(int displayId, Point size)4996 public void getInitialDisplaySize(int displayId, Point size) { 4997 synchronized (mGlobalLock) { 4998 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 4999 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 5000 size.x = displayContent.mInitialDisplayWidth; 5001 size.y = displayContent.mInitialDisplayHeight; 5002 } 5003 } 5004 } 5005 5006 @Override getBaseDisplaySize(int displayId, Point size)5007 public void getBaseDisplaySize(int displayId, Point size) { 5008 synchronized (mGlobalLock) { 5009 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5010 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 5011 size.x = displayContent.mBaseDisplayWidth; 5012 size.y = displayContent.mBaseDisplayHeight; 5013 } 5014 } 5015 } 5016 5017 @Override setForcedDisplaySize(int displayId, int width, int height)5018 public void setForcedDisplaySize(int displayId, int width, int height) { 5019 if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS) 5020 != PackageManager.PERMISSION_GRANTED) { 5021 throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS); 5022 } 5023 5024 final long ident = Binder.clearCallingIdentity(); 5025 try { 5026 synchronized (mGlobalLock) { 5027 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5028 if (displayContent != null) { 5029 displayContent.setForcedSize(width, height); 5030 } 5031 } 5032 } finally { 5033 Binder.restoreCallingIdentity(ident); 5034 } 5035 } 5036 5037 @Override setForcedDisplayScalingMode(int displayId, int mode)5038 public void setForcedDisplayScalingMode(int displayId, int mode) { 5039 if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS) 5040 != PackageManager.PERMISSION_GRANTED) { 5041 throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS); 5042 } 5043 5044 final long ident = Binder.clearCallingIdentity(); 5045 try { 5046 synchronized (mGlobalLock) { 5047 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5048 if (displayContent != null) { 5049 displayContent.setForcedScalingMode(mode); 5050 } 5051 } 5052 } finally { 5053 Binder.restoreCallingIdentity(ident); 5054 } 5055 } 5056 5057 /** The global settings only apply to default display. */ applyForcedPropertiesForDefaultDisplay()5058 private boolean applyForcedPropertiesForDefaultDisplay() { 5059 boolean changed = false; 5060 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 5061 // Display size. 5062 String sizeStr = Settings.Global.getString(mContext.getContentResolver(), 5063 Settings.Global.DISPLAY_SIZE_FORCED); 5064 if (sizeStr == null || sizeStr.length() == 0) { 5065 sizeStr = SystemProperties.get(SIZE_OVERRIDE, null); 5066 } 5067 if (sizeStr != null && sizeStr.length() > 0) { 5068 final int pos = sizeStr.indexOf(','); 5069 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) { 5070 int width, height; 5071 try { 5072 width = Integer.parseInt(sizeStr.substring(0, pos)); 5073 height = Integer.parseInt(sizeStr.substring(pos+1)); 5074 if (displayContent.mBaseDisplayWidth != width 5075 || displayContent.mBaseDisplayHeight != height) { 5076 Slog.i(TAG_WM, "FORCED DISPLAY SIZE: " + width + "x" + height); 5077 displayContent.updateBaseDisplayMetrics(width, height, 5078 displayContent.mBaseDisplayDensity); 5079 changed = true; 5080 } 5081 } catch (NumberFormatException ex) { 5082 } 5083 } 5084 } 5085 5086 // Display density. 5087 final int density = getForcedDisplayDensityForUserLocked(mCurrentUserId); 5088 if (density != 0 && density != displayContent.mBaseDisplayDensity) { 5089 displayContent.mBaseDisplayDensity = density; 5090 changed = true; 5091 } 5092 5093 // Display scaling mode. 5094 int mode = Settings.Global.getInt(mContext.getContentResolver(), 5095 Settings.Global.DISPLAY_SCALING_FORCE, 0); 5096 if (displayContent.mDisplayScalingDisabled != (mode != 0)) { 5097 Slog.i(TAG_WM, "FORCED DISPLAY SCALING DISABLED"); 5098 displayContent.mDisplayScalingDisabled = true; 5099 changed = true; 5100 } 5101 return changed; 5102 } 5103 5104 @Override clearForcedDisplaySize(int displayId)5105 public void clearForcedDisplaySize(int displayId) { 5106 if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS) 5107 != PackageManager.PERMISSION_GRANTED) { 5108 throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS); 5109 } 5110 5111 final long ident = Binder.clearCallingIdentity(); 5112 try { 5113 synchronized (mGlobalLock) { 5114 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5115 if (displayContent != null) { 5116 displayContent.setForcedSize(displayContent.mInitialDisplayWidth, 5117 displayContent.mInitialDisplayHeight); 5118 } 5119 } 5120 } finally { 5121 Binder.restoreCallingIdentity(ident); 5122 } 5123 } 5124 5125 @Override getInitialDisplayDensity(int displayId)5126 public int getInitialDisplayDensity(int displayId) { 5127 synchronized (mGlobalLock) { 5128 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5129 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 5130 return displayContent.mInitialDisplayDensity; 5131 } 5132 } 5133 return -1; 5134 } 5135 5136 @Override getBaseDisplayDensity(int displayId)5137 public int getBaseDisplayDensity(int displayId) { 5138 synchronized (mGlobalLock) { 5139 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5140 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 5141 return displayContent.mBaseDisplayDensity; 5142 } 5143 } 5144 return -1; 5145 } 5146 5147 @Override setForcedDisplayDensityForUser(int displayId, int density, int userId)5148 public void setForcedDisplayDensityForUser(int displayId, int density, int userId) { 5149 if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS) 5150 != PackageManager.PERMISSION_GRANTED) { 5151 throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS); 5152 } 5153 5154 final int targetUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 5155 Binder.getCallingUid(), userId, false, true, "setForcedDisplayDensityForUser", 5156 null); 5157 final long ident = Binder.clearCallingIdentity(); 5158 try { 5159 synchronized (mGlobalLock) { 5160 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5161 if (displayContent != null) { 5162 displayContent.setForcedDensity(density, targetUserId); 5163 } 5164 } 5165 } finally { 5166 Binder.restoreCallingIdentity(ident); 5167 } 5168 } 5169 5170 @Override clearForcedDisplayDensityForUser(int displayId, int userId)5171 public void clearForcedDisplayDensityForUser(int displayId, int userId) { 5172 if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS) 5173 != PackageManager.PERMISSION_GRANTED) { 5174 throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS); 5175 } 5176 5177 final int callingUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 5178 Binder.getCallingUid(), userId, false, true, "clearForcedDisplayDensityForUser", 5179 null); 5180 final long ident = Binder.clearCallingIdentity(); 5181 try { 5182 synchronized (mGlobalLock) { 5183 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5184 if (displayContent != null) { 5185 displayContent.setForcedDensity(displayContent.mInitialDisplayDensity, 5186 callingUserId); 5187 } 5188 } 5189 } finally { 5190 Binder.restoreCallingIdentity(ident); 5191 } 5192 } 5193 5194 /** 5195 * @param userId the ID of the user 5196 * @return the forced display density for the specified user, if set, or 5197 * {@code 0} if not set 5198 */ getForcedDisplayDensityForUserLocked(int userId)5199 private int getForcedDisplayDensityForUserLocked(int userId) { 5200 String densityStr = Settings.Secure.getStringForUser(mContext.getContentResolver(), 5201 Settings.Secure.DISPLAY_DENSITY_FORCED, userId); 5202 if (densityStr == null || densityStr.length() == 0) { 5203 densityStr = SystemProperties.get(DENSITY_OVERRIDE, null); 5204 } 5205 if (densityStr != null && densityStr.length() > 0) { 5206 try { 5207 return Integer.parseInt(densityStr); 5208 } catch (NumberFormatException ex) { 5209 } 5210 } 5211 return 0; 5212 } 5213 reconfigureDisplayLocked(@onNull DisplayContent displayContent)5214 void reconfigureDisplayLocked(@NonNull DisplayContent displayContent) { 5215 if (!displayContent.isReady()) { 5216 return; 5217 } 5218 displayContent.configureDisplayPolicy(); 5219 displayContent.setLayoutNeeded(); 5220 5221 boolean configChanged = displayContent.updateOrientationFromAppTokens(); 5222 final Configuration currentDisplayConfig = displayContent.getConfiguration(); 5223 mTempConfiguration.setTo(currentDisplayConfig); 5224 displayContent.computeScreenConfiguration(mTempConfiguration); 5225 configChanged |= currentDisplayConfig.diff(mTempConfiguration) != 0; 5226 5227 if (configChanged) { 5228 displayContent.mWaitingForConfig = true; 5229 startFreezingDisplayLocked(0 /* exitAnim */, 5230 0 /* enterAnim */, displayContent); 5231 displayContent.sendNewConfiguration(); 5232 } 5233 5234 mWindowPlacerLocked.performSurfacePlacement(); 5235 } 5236 5237 @Override setOverscan(int displayId, int left, int top, int right, int bottom)5238 public void setOverscan(int displayId, int left, int top, int right, int bottom) { 5239 if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS) 5240 != PackageManager.PERMISSION_GRANTED) { 5241 throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS); 5242 } 5243 final long ident = Binder.clearCallingIdentity(); 5244 try { 5245 synchronized (mGlobalLock) { 5246 DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5247 if (displayContent != null) { 5248 setOverscanLocked(displayContent, left, top, right, bottom); 5249 } 5250 } 5251 } finally { 5252 Binder.restoreCallingIdentity(ident); 5253 } 5254 } 5255 setOverscanLocked(DisplayContent displayContent, int left, int top, int right, int bottom)5256 private void setOverscanLocked(DisplayContent displayContent, 5257 int left, int top, int right, int bottom) { 5258 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 5259 displayInfo.overscanLeft = left; 5260 displayInfo.overscanTop = top; 5261 displayInfo.overscanRight = right; 5262 displayInfo.overscanBottom = bottom; 5263 5264 mDisplayWindowSettings.setOverscanLocked(displayInfo, left, top, right, bottom); 5265 5266 reconfigureDisplayLocked(displayContent); 5267 } 5268 5269 @Override startWindowTrace()5270 public void startWindowTrace(){ 5271 mWindowTracing.startTrace(null /* printwriter */); 5272 } 5273 5274 @Override stopWindowTrace()5275 public void stopWindowTrace(){ 5276 mWindowTracing.stopTrace(null /* printwriter */); 5277 } 5278 5279 @Override isWindowTraceEnabled()5280 public boolean isWindowTraceEnabled() { 5281 return mWindowTracing.isEnabled(); 5282 } 5283 5284 // ------------------------------------------------------------- 5285 // Internals 5286 // ------------------------------------------------------------- 5287 windowForClientLocked(Session session, IWindow client, boolean throwOnError)5288 final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) { 5289 return windowForClientLocked(session, client.asBinder(), throwOnError); 5290 } 5291 windowForClientLocked(Session session, IBinder client, boolean throwOnError)5292 final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) { 5293 WindowState win = mWindowMap.get(client); 5294 if (localLOGV) Slog.v(TAG_WM, "Looking up client " + client + ": " + win); 5295 if (win == null) { 5296 if (throwOnError) { 5297 throw new IllegalArgumentException( 5298 "Requested window " + client + " does not exist"); 5299 } 5300 Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3)); 5301 return null; 5302 } 5303 if (session != null && win.mSession != session) { 5304 if (throwOnError) { 5305 throw new IllegalArgumentException("Requested window " + client + " is in session " 5306 + win.mSession + ", not " + session); 5307 } 5308 Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3)); 5309 return null; 5310 } 5311 5312 return win; 5313 } 5314 makeWindowFreezingScreenIfNeededLocked(WindowState w)5315 void makeWindowFreezingScreenIfNeededLocked(WindowState w) { 5316 // If the screen is currently frozen or off, then keep 5317 // it frozen/off until this window draws at its new 5318 // orientation. 5319 if (!w.mToken.okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) { 5320 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w); 5321 w.setOrientationChanging(true); 5322 w.mLastFreezeDuration = 0; 5323 mRoot.mOrientationChangeComplete = false; 5324 if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) { 5325 mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE; 5326 // XXX should probably keep timeout from 5327 // when we first froze the display. 5328 mH.sendNewMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, w.getDisplayContent(), 5329 WINDOW_FREEZE_TIMEOUT_DURATION); 5330 } 5331 } 5332 } 5333 checkDrawnWindowsLocked()5334 void checkDrawnWindowsLocked() { 5335 if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) { 5336 return; 5337 } 5338 for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) { 5339 WindowState win = mWaitingForDrawn.get(j); 5340 if (DEBUG_SCREEN_ON) Slog.i(TAG_WM, "Waiting for drawn " + win + 5341 ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() + 5342 " mHasSurface=" + win.mHasSurface + 5343 " drawState=" + win.mWinAnimator.mDrawState); 5344 if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) { 5345 // Window has been removed or hidden; no draw will now happen, so stop waiting. 5346 if (DEBUG_SCREEN_ON) Slog.w(TAG_WM, "Aborted waiting for drawn: " + win); 5347 mWaitingForDrawn.remove(win); 5348 } else if (win.hasDrawnLw()) { 5349 // Window is now drawn (and shown). 5350 if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "Window drawn win=" + win); 5351 mWaitingForDrawn.remove(win); 5352 } 5353 } 5354 if (mWaitingForDrawn.isEmpty()) { 5355 if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "All windows drawn!"); 5356 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT); 5357 mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN); 5358 } 5359 } 5360 setHoldScreenLocked(final Session newHoldScreen)5361 void setHoldScreenLocked(final Session newHoldScreen) { 5362 final boolean hold = newHoldScreen != null; 5363 5364 if (hold && mHoldingScreenOn != newHoldScreen) { 5365 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid)); 5366 } 5367 mHoldingScreenOn = newHoldScreen; 5368 5369 final boolean state = mHoldingScreenWakeLock.isHeld(); 5370 if (hold != state) { 5371 if (hold) { 5372 if (DEBUG_KEEP_SCREEN_ON) { 5373 Slog.d(TAG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to " 5374 + mRoot.mHoldScreenWindow); 5375 } 5376 mLastWakeLockHoldingWindow = mRoot.mHoldScreenWindow; 5377 mLastWakeLockObscuringWindow = null; 5378 mHoldingScreenWakeLock.acquire(); 5379 mPolicy.keepScreenOnStartedLw(); 5380 } else { 5381 if (DEBUG_KEEP_SCREEN_ON) { 5382 Slog.d(TAG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by " 5383 + mRoot.mObscuringWindow); 5384 } 5385 mLastWakeLockHoldingWindow = null; 5386 mLastWakeLockObscuringWindow = mRoot.mObscuringWindow; 5387 mPolicy.keepScreenOnStoppedLw(); 5388 mHoldingScreenWakeLock.release(); 5389 } 5390 } 5391 } 5392 requestTraversal()5393 void requestTraversal() { 5394 synchronized (mGlobalLock) { 5395 mWindowPlacerLocked.requestTraversal(); 5396 } 5397 } 5398 5399 /** Note that Locked in this case is on mLayoutToAnim */ scheduleAnimationLocked()5400 void scheduleAnimationLocked() { 5401 if (mAnimator != null) { 5402 mAnimator.scheduleAnimation(); 5403 } 5404 } 5405 updateFocusedWindowLocked(int mode, boolean updateInputWindows)5406 boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) { 5407 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus"); 5408 boolean changed = mRoot.updateFocusedWindowLocked(mode, updateInputWindows); 5409 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 5410 return changed; 5411 } 5412 startFreezingDisplayLocked(int exitAnim, int enterAnim)5413 void startFreezingDisplayLocked(int exitAnim, int enterAnim) { 5414 startFreezingDisplayLocked(exitAnim, enterAnim, 5415 getDefaultDisplayContentLocked()); 5416 } 5417 startFreezingDisplayLocked(int exitAnim, int enterAnim, DisplayContent displayContent)5418 void startFreezingDisplayLocked(int exitAnim, int enterAnim, 5419 DisplayContent displayContent) { 5420 if (mDisplayFrozen || mRotatingSeamlessly) { 5421 return; 5422 } 5423 5424 if (!displayContent.isReady() || !mPolicy.isScreenOn() || !displayContent.okToAnimate()) { 5425 // No need to freeze the screen before the display is ready, if the screen is off, 5426 // or we can't currently animate. 5427 return; 5428 } 5429 5430 if (DEBUG_ORIENTATION) Slog.d(TAG_WM, 5431 "startFreezingDisplayLocked: exitAnim=" 5432 + exitAnim + " enterAnim=" + enterAnim 5433 + " called by " + Debug.getCallers(8)); 5434 mScreenFrozenLock.acquire(); 5435 5436 mDisplayFrozen = true; 5437 mDisplayFreezeTime = SystemClock.elapsedRealtime(); 5438 mLastFinishedFreezeSource = null; 5439 5440 // {@link mDisplayFrozen} prevents us from freezing on multiple displays at the same time. 5441 // As a result, we only track the display that has initially froze the screen. 5442 mFrozenDisplayId = displayContent.getDisplayId(); 5443 5444 mInputManagerCallback.freezeInputDispatchingLw(); 5445 5446 if (displayContent.mAppTransition.isTransitionSet()) { 5447 displayContent.mAppTransition.freeze(); 5448 } 5449 5450 if (PROFILE_ORIENTATION) { 5451 File file = new File("/data/system/frozen"); 5452 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 5453 } 5454 5455 mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN); 5456 if (CUSTOM_SCREEN_ROTATION) { 5457 mExitAnimId = exitAnim; 5458 mEnterAnimId = enterAnim; 5459 ScreenRotationAnimation screenRotationAnimation = 5460 mAnimator.getScreenRotationAnimationLocked(mFrozenDisplayId); 5461 if (screenRotationAnimation != null) { 5462 screenRotationAnimation.kill(); 5463 } 5464 5465 // Check whether the current screen contains any secure content. 5466 boolean isSecure = displayContent.hasSecureWindowOnScreen(); 5467 5468 displayContent.updateDisplayInfo(); 5469 screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent, 5470 displayContent.getDisplayRotation().isFixedToUserRotation(), isSecure, 5471 this); 5472 mAnimator.setScreenRotationAnimationLocked(mFrozenDisplayId, 5473 screenRotationAnimation); 5474 } 5475 } 5476 stopFreezingDisplayLocked()5477 void stopFreezingDisplayLocked() { 5478 if (!mDisplayFrozen) { 5479 return; 5480 } 5481 5482 final DisplayContent displayContent = mRoot.getDisplayContent(mFrozenDisplayId); 5483 final boolean waitingForConfig = displayContent != null && displayContent.mWaitingForConfig; 5484 final int numOpeningApps = displayContent != null ? displayContent.mOpeningApps.size() : 0; 5485 if (waitingForConfig || mAppsFreezingScreen > 0 5486 || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE 5487 || mClientFreezingScreen || numOpeningApps > 0) { 5488 if (DEBUG_ORIENTATION) Slog.d(TAG_WM, 5489 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + waitingForConfig 5490 + ", mAppsFreezingScreen=" + mAppsFreezingScreen 5491 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen 5492 + ", mClientFreezingScreen=" + mClientFreezingScreen 5493 + ", mOpeningApps.size()=" + numOpeningApps); 5494 return; 5495 } 5496 5497 if (DEBUG_ORIENTATION) Slog.d(TAG_WM, 5498 "stopFreezingDisplayLocked: Unfreezing now"); 5499 5500 5501 // We must make a local copy of the displayId as it can be potentially overwritten later on 5502 // in this method. For example, {@link startFreezingDisplayLocked} may be called as a result 5503 // of update rotation, but we reference the frozen display after that call in this method. 5504 final int displayId = mFrozenDisplayId; 5505 mFrozenDisplayId = INVALID_DISPLAY; 5506 mDisplayFrozen = false; 5507 mInputManagerCallback.thawInputDispatchingLw(); 5508 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime); 5509 StringBuilder sb = new StringBuilder(128); 5510 sb.append("Screen frozen for "); 5511 TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb); 5512 if (mLastFinishedFreezeSource != null) { 5513 sb.append(" due to "); 5514 sb.append(mLastFinishedFreezeSource); 5515 } 5516 Slog.i(TAG_WM, sb.toString()); 5517 mH.removeMessages(H.APP_FREEZE_TIMEOUT); 5518 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); 5519 if (PROFILE_ORIENTATION) { 5520 Debug.stopMethodTracing(); 5521 } 5522 5523 boolean updateRotation = false; 5524 5525 ScreenRotationAnimation screenRotationAnimation = 5526 mAnimator.getScreenRotationAnimationLocked(displayId); 5527 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null 5528 && screenRotationAnimation.hasScreenshot()) { 5529 if (DEBUG_ORIENTATION) Slog.i(TAG_WM, "**** Dismissing screen rotation animation"); 5530 DisplayInfo displayInfo = displayContent.getDisplayInfo(); 5531 // Get rotation animation again, with new top window 5532 if (!displayContent.getDisplayPolicy() 5533 .validateRotationAnimationLw(mExitAnimId, mEnterAnimId, false)) { 5534 mExitAnimId = mEnterAnimId = 0; 5535 } 5536 if (screenRotationAnimation.dismiss(mTransaction, MAX_ANIMATION_DURATION, 5537 getTransitionAnimationScaleLocked(), displayInfo.logicalWidth, 5538 displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) { 5539 mTransaction.apply(); 5540 scheduleAnimationLocked(); 5541 } else { 5542 screenRotationAnimation.kill(); 5543 mAnimator.setScreenRotationAnimationLocked(displayId, null); 5544 updateRotation = true; 5545 } 5546 } else { 5547 if (screenRotationAnimation != null) { 5548 screenRotationAnimation.kill(); 5549 mAnimator.setScreenRotationAnimationLocked(displayId, null); 5550 } 5551 updateRotation = true; 5552 } 5553 5554 boolean configChanged; 5555 5556 // While the display is frozen we don't re-compute the orientation 5557 // to avoid inconsistent states. However, something interesting 5558 // could have actually changed during that time so re-evaluate it 5559 // now to catch that. 5560 configChanged = displayContent != null && displayContent.updateOrientationFromAppTokens(); 5561 5562 // A little kludge: a lot could have happened while the 5563 // display was frozen, so now that we are coming back we 5564 // do a gc so that any remote references the system 5565 // processes holds on others can be released if they are 5566 // no longer needed. 5567 mH.removeMessages(H.FORCE_GC); 5568 mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000); 5569 5570 mScreenFrozenLock.release(); 5571 5572 if (updateRotation && displayContent != null && updateRotation) { 5573 if (DEBUG_ORIENTATION) Slog.d(TAG_WM, "Performing post-rotate rotation"); 5574 configChanged |= displayContent.updateRotationUnchecked(); 5575 } 5576 5577 if (configChanged) { 5578 displayContent.sendNewConfiguration(); 5579 } 5580 mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN); 5581 } 5582 getPropertyInt(String[] tokens, int index, int defUnits, int defDps, DisplayMetrics dm)5583 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps, 5584 DisplayMetrics dm) { 5585 if (index < tokens.length) { 5586 String str = tokens[index]; 5587 if (str != null && str.length() > 0) { 5588 try { 5589 int val = Integer.parseInt(str); 5590 return val; 5591 } catch (Exception e) { 5592 } 5593 } 5594 } 5595 if (defUnits == TypedValue.COMPLEX_UNIT_PX) { 5596 return defDps; 5597 } 5598 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm); 5599 return val; 5600 } 5601 createWatermarkInTransaction()5602 void createWatermarkInTransaction() { 5603 if (mWatermark != null) { 5604 return; 5605 } 5606 5607 File file = new File("/system/etc/setup.conf"); 5608 FileInputStream in = null; 5609 DataInputStream ind = null; 5610 try { 5611 in = new FileInputStream(file); 5612 ind = new DataInputStream(in); 5613 String line = ind.readLine(); 5614 if (line != null) { 5615 String[] toks = line.split("%"); 5616 if (toks != null && toks.length > 0) { 5617 // TODO(multi-display): Show watermarks on secondary displays. 5618 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 5619 mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics, 5620 toks); 5621 } 5622 } 5623 } catch (FileNotFoundException e) { 5624 } catch (IOException e) { 5625 } finally { 5626 if (ind != null) { 5627 try { 5628 ind.close(); 5629 } catch (IOException e) { 5630 } 5631 } else if (in != null) { 5632 try { 5633 in.close(); 5634 } catch (IOException e) { 5635 } 5636 } 5637 } 5638 } 5639 5640 @Override setRecentsVisibility(boolean visible)5641 public void setRecentsVisibility(boolean visible) { 5642 mAtmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR, 5643 "setRecentsVisibility()"); 5644 synchronized (mGlobalLock) { 5645 mPolicy.setRecentsVisibilityLw(visible); 5646 } 5647 } 5648 5649 @Override setPipVisibility(boolean visible)5650 public void setPipVisibility(boolean visible) { 5651 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) 5652 != PackageManager.PERMISSION_GRANTED) { 5653 throw new SecurityException("Caller does not hold permission " 5654 + android.Manifest.permission.STATUS_BAR); 5655 } 5656 5657 synchronized (mGlobalLock) { 5658 mPolicy.setPipVisibilityLw(visible); 5659 } 5660 } 5661 5662 @Override setShelfHeight(boolean visible, int shelfHeight)5663 public void setShelfHeight(boolean visible, int shelfHeight) { 5664 mAtmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR, 5665 "setShelfHeight()"); 5666 synchronized (mGlobalLock) { 5667 getDefaultDisplayContentLocked().getPinnedStackController().setAdjustedForShelf(visible, 5668 shelfHeight); 5669 } 5670 } 5671 5672 @Override statusBarVisibilityChanged(int displayId, int visibility)5673 public void statusBarVisibilityChanged(int displayId, int visibility) { 5674 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) 5675 != PackageManager.PERMISSION_GRANTED) { 5676 throw new SecurityException("Caller does not hold permission " 5677 + android.Manifest.permission.STATUS_BAR); 5678 } 5679 5680 synchronized (mGlobalLock) { 5681 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5682 if (displayContent != null) { 5683 displayContent.statusBarVisibilityChanged(visibility); 5684 } else { 5685 Slog.w(TAG, "statusBarVisibilityChanged with invalid displayId=" + displayId); 5686 } 5687 } 5688 } 5689 5690 @Override setForceShowSystemBars(boolean show)5691 public void setForceShowSystemBars(boolean show) { 5692 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) 5693 != PackageManager.PERMISSION_GRANTED) { 5694 throw new SecurityException("Caller does not hold permission " 5695 + android.Manifest.permission.STATUS_BAR); 5696 } 5697 synchronized (mGlobalLock) { 5698 mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer( 5699 DisplayPolicy::setForceShowSystemBars, PooledLambda.__(), show)); 5700 } 5701 } 5702 setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled)5703 public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) { 5704 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) 5705 != PackageManager.PERMISSION_GRANTED) { 5706 throw new SecurityException("Caller does not hold permission " 5707 + android.Manifest.permission.STATUS_BAR); 5708 } 5709 5710 synchronized (mGlobalLock) { 5711 mPolicy.setNavBarVirtualKeyHapticFeedbackEnabledLw(enabled); 5712 } 5713 } 5714 5715 /** 5716 * Used by ActivityManager to determine where to position an app with aspect ratio shorter then 5717 * the screen is. 5718 * @see DisplayPolicy#getNavBarPosition() 5719 */ 5720 @Override 5721 @WindowManagerPolicy.NavigationBarPosition getNavBarPosition(int displayId)5722 public int getNavBarPosition(int displayId) { 5723 synchronized (mGlobalLock) { 5724 // Perform layout if it was scheduled before to make sure that we get correct nav bar 5725 // position when doing rotations. 5726 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5727 if (displayContent == null) { 5728 Slog.w(TAG, "getNavBarPosition with invalid displayId=" + displayId 5729 + " callers=" + Debug.getCallers(3)); 5730 return NAV_BAR_INVALID; 5731 } 5732 displayContent.performLayout(false /* initial */, 5733 false /* updateInputWindows */); 5734 return displayContent.getDisplayPolicy().getNavBarPosition(); 5735 } 5736 } 5737 5738 @Override createInputConsumer(Looper looper, String name, InputEventReceiver.Factory inputEventReceiverFactory, int displayId)5739 public WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name, 5740 InputEventReceiver.Factory inputEventReceiverFactory, int displayId) { 5741 synchronized (mGlobalLock) { 5742 DisplayContent displayContent = mRoot.getDisplayContent(displayId); 5743 if (displayContent != null) { 5744 return displayContent.getInputMonitor().createInputConsumer(looper, name, 5745 inputEventReceiverFactory); 5746 } else { 5747 return null; 5748 } 5749 } 5750 } 5751 5752 @Override createInputConsumer(IBinder token, String name, int displayId, InputChannel inputChannel)5753 public void createInputConsumer(IBinder token, String name, int displayId, 5754 InputChannel inputChannel) { 5755 synchronized (mGlobalLock) { 5756 DisplayContent display = mRoot.getDisplayContent(displayId); 5757 if (display != null) { 5758 display.getInputMonitor().createInputConsumer(token, name, inputChannel, 5759 Binder.getCallingPid(), Binder.getCallingUserHandle()); 5760 } 5761 } 5762 } 5763 5764 @Override destroyInputConsumer(String name, int displayId)5765 public boolean destroyInputConsumer(String name, int displayId) { 5766 synchronized (mGlobalLock) { 5767 DisplayContent display = mRoot.getDisplayContent(displayId); 5768 if (display != null) { 5769 return display.getInputMonitor().destroyInputConsumer(name); 5770 } 5771 return false; 5772 } 5773 } 5774 5775 @Override getCurrentImeTouchRegion()5776 public Region getCurrentImeTouchRegion() { 5777 if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) { 5778 throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services"); 5779 } 5780 synchronized (mGlobalLock) { 5781 final Region r = new Region(); 5782 // TODO(b/111080190): this method is only return the recent focused IME touch region, 5783 // For Multi-Session IME, will need to add API for given display Id to 5784 // get the right IME touch region. 5785 for (int i = mRoot.mChildren.size() - 1; i >= 0; --i) { 5786 final DisplayContent displayContent = mRoot.mChildren.get(i); 5787 if (displayContent.mInputMethodWindow != null) { 5788 displayContent.mInputMethodWindow.getTouchableRegion(r); 5789 return r; 5790 } 5791 } 5792 return r; 5793 } 5794 } 5795 5796 @Override hasNavigationBar(int displayId)5797 public boolean hasNavigationBar(int displayId) { 5798 synchronized (mGlobalLock) { 5799 final DisplayContent dc = mRoot.getDisplayContent(displayId); 5800 if (dc == null) { 5801 return false; 5802 } 5803 return dc.getDisplayPolicy().hasNavigationBar(); 5804 } 5805 } 5806 5807 @Override lockNow(Bundle options)5808 public void lockNow(Bundle options) { 5809 mPolicy.lockNow(options); 5810 } 5811 showRecentApps()5812 public void showRecentApps() { 5813 mPolicy.showRecentApps(); 5814 } 5815 5816 @Override isSafeModeEnabled()5817 public boolean isSafeModeEnabled() { 5818 return mSafeMode; 5819 } 5820 5821 @Override clearWindowContentFrameStats(IBinder token)5822 public boolean clearWindowContentFrameStats(IBinder token) { 5823 if (!checkCallingPermission(Manifest.permission.FRAME_STATS, 5824 "clearWindowContentFrameStats()")) { 5825 throw new SecurityException("Requires FRAME_STATS permission"); 5826 } 5827 synchronized (mGlobalLock) { 5828 WindowState windowState = mWindowMap.get(token); 5829 if (windowState == null) { 5830 return false; 5831 } 5832 WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController; 5833 if (surfaceController == null) { 5834 return false; 5835 } 5836 return surfaceController.clearWindowContentFrameStats(); 5837 } 5838 } 5839 5840 @Override getWindowContentFrameStats(IBinder token)5841 public WindowContentFrameStats getWindowContentFrameStats(IBinder token) { 5842 if (!checkCallingPermission(Manifest.permission.FRAME_STATS, 5843 "getWindowContentFrameStats()")) { 5844 throw new SecurityException("Requires FRAME_STATS permission"); 5845 } 5846 synchronized (mGlobalLock) { 5847 WindowState windowState = mWindowMap.get(token); 5848 if (windowState == null) { 5849 return null; 5850 } 5851 WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController; 5852 if (surfaceController == null) { 5853 return null; 5854 } 5855 if (mTempWindowRenderStats == null) { 5856 mTempWindowRenderStats = new WindowContentFrameStats(); 5857 } 5858 WindowContentFrameStats stats = mTempWindowRenderStats; 5859 if (!surfaceController.getWindowContentFrameStats(stats)) { 5860 return null; 5861 } 5862 return stats; 5863 } 5864 } 5865 notifyAppRelaunching(IBinder token)5866 public void notifyAppRelaunching(IBinder token) { 5867 synchronized (mGlobalLock) { 5868 final AppWindowToken appWindow = mRoot.getAppWindowToken(token); 5869 if (appWindow != null) { 5870 appWindow.startRelaunching(); 5871 } 5872 } 5873 } 5874 notifyAppRelaunchingFinished(IBinder token)5875 public void notifyAppRelaunchingFinished(IBinder token) { 5876 synchronized (mGlobalLock) { 5877 final AppWindowToken appWindow = mRoot.getAppWindowToken(token); 5878 if (appWindow != null) { 5879 appWindow.finishRelaunching(); 5880 } 5881 } 5882 } 5883 notifyAppRelaunchesCleared(IBinder token)5884 public void notifyAppRelaunchesCleared(IBinder token) { 5885 synchronized (mGlobalLock) { 5886 final AppWindowToken appWindow = mRoot.getAppWindowToken(token); 5887 if (appWindow != null) { 5888 appWindow.clearRelaunching(); 5889 } 5890 } 5891 } 5892 notifyAppResumedFinished(IBinder token)5893 public void notifyAppResumedFinished(IBinder token) { 5894 synchronized (mGlobalLock) { 5895 final AppWindowToken appWindow = mRoot.getAppWindowToken(token); 5896 if (appWindow != null) { 5897 appWindow.getDisplayContent().mUnknownAppVisibilityController 5898 .notifyAppResumedFinished(appWindow); 5899 } 5900 } 5901 } 5902 5903 /** 5904 * Called when a task has been removed from the recent tasks list. 5905 * <p> 5906 * Note: This doesn't go through {@link TaskWindowContainerController} yet as the window 5907 * container may not exist when this happens. 5908 */ notifyTaskRemovedFromRecents(int taskId, int userId)5909 public void notifyTaskRemovedFromRecents(int taskId, int userId) { 5910 synchronized (mGlobalLock) { 5911 mTaskSnapshotController.notifyTaskRemovedFromRecents(taskId, userId); 5912 } 5913 } 5914 dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll)5915 private void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) { 5916 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)"); 5917 mPolicy.dump(" ", pw, args); 5918 } 5919 dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll)5920 private void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) { 5921 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)"); 5922 mAnimator.dumpLocked(pw, " ", dumpAll); 5923 } 5924 dumpTokensLocked(PrintWriter pw, boolean dumpAll)5925 private void dumpTokensLocked(PrintWriter pw, boolean dumpAll) { 5926 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)"); 5927 mRoot.dumpTokens(pw, dumpAll); 5928 } 5929 dumpTraceStatus(PrintWriter pw)5930 private void dumpTraceStatus(PrintWriter pw) { 5931 pw.println("WINDOW MANAGER TRACE (dumpsys window trace)"); 5932 pw.print(mWindowTracing.getStatus() + "\n"); 5933 } 5934 dumpSessionsLocked(PrintWriter pw, boolean dumpAll)5935 private void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) { 5936 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)"); 5937 for (int i=0; i<mSessions.size(); i++) { 5938 Session s = mSessions.valueAt(i); 5939 pw.print(" Session "); pw.print(s); pw.println(':'); 5940 s.dump(pw, " "); 5941 } 5942 } 5943 5944 /** 5945 * Write to a protocol buffer output stream. Protocol buffer message definition is at 5946 * {@link com.android.server.wm.WindowManagerServiceDumpProto}. 5947 * 5948 * @param proto Stream to write the WindowContainer object to. 5949 * @param logLevel Determines the amount of data to be written to the Protobuf. 5950 */ writeToProtoLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel)5951 void writeToProtoLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) { 5952 mPolicy.writeToProto(proto, POLICY); 5953 mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER, logLevel); 5954 final DisplayContent topFocusedDisplayContent = mRoot.getTopFocusedDisplayContent(); 5955 if (topFocusedDisplayContent.mCurrentFocus != null) { 5956 topFocusedDisplayContent.mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW); 5957 } 5958 if (topFocusedDisplayContent.mFocusedApp != null) { 5959 topFocusedDisplayContent.mFocusedApp.writeNameToProto(proto, FOCUSED_APP); 5960 } 5961 final WindowState imeWindow = mRoot.getCurrentInputMethodWindow(); 5962 if (imeWindow != null) { 5963 imeWindow.writeIdentifierToProto(proto, INPUT_METHOD_WINDOW); 5964 } 5965 proto.write(DISPLAY_FROZEN, mDisplayFrozen); 5966 final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked(); 5967 proto.write(ROTATION, defaultDisplayContent.getRotation()); 5968 proto.write(LAST_ORIENTATION, defaultDisplayContent.getLastOrientation()); 5969 } 5970 dumpWindowsLocked(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows)5971 private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll, 5972 ArrayList<WindowState> windows) { 5973 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)"); 5974 dumpWindowsNoHeaderLocked(pw, dumpAll, windows); 5975 } 5976 dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows)5977 private void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll, 5978 ArrayList<WindowState> windows) { 5979 mRoot.dumpWindowsNoHeader(pw, dumpAll, windows); 5980 5981 if (!mHidingNonSystemOverlayWindows.isEmpty()) { 5982 pw.println(); 5983 pw.println(" Hiding System Alert Windows:"); 5984 for (int i = mHidingNonSystemOverlayWindows.size() - 1; i >= 0; i--) { 5985 final WindowState w = mHidingNonSystemOverlayWindows.get(i); 5986 pw.print(" #"); pw.print(i); pw.print(' '); 5987 pw.print(w); 5988 if (dumpAll) { 5989 pw.println(":"); 5990 w.dump(pw, " ", true); 5991 } else { 5992 pw.println(); 5993 } 5994 } 5995 } 5996 if (mPendingRemove.size() > 0) { 5997 pw.println(); 5998 pw.println(" Remove pending for:"); 5999 for (int i=mPendingRemove.size()-1; i>=0; i--) { 6000 WindowState w = mPendingRemove.get(i); 6001 if (windows == null || windows.contains(w)) { 6002 pw.print(" Remove #"); pw.print(i); pw.print(' '); 6003 pw.print(w); 6004 if (dumpAll) { 6005 pw.println(":"); 6006 w.dump(pw, " ", true); 6007 } else { 6008 pw.println(); 6009 } 6010 } 6011 } 6012 } 6013 if (mForceRemoves != null && mForceRemoves.size() > 0) { 6014 pw.println(); 6015 pw.println(" Windows force removing:"); 6016 for (int i=mForceRemoves.size()-1; i>=0; i--) { 6017 WindowState w = mForceRemoves.get(i); 6018 pw.print(" Removing #"); pw.print(i); pw.print(' '); 6019 pw.print(w); 6020 if (dumpAll) { 6021 pw.println(":"); 6022 w.dump(pw, " ", true); 6023 } else { 6024 pw.println(); 6025 } 6026 } 6027 } 6028 if (mDestroySurface.size() > 0) { 6029 pw.println(); 6030 pw.println(" Windows waiting to destroy their surface:"); 6031 for (int i=mDestroySurface.size()-1; i>=0; i--) { 6032 WindowState w = mDestroySurface.get(i); 6033 if (windows == null || windows.contains(w)) { 6034 pw.print(" Destroy #"); pw.print(i); pw.print(' '); 6035 pw.print(w); 6036 if (dumpAll) { 6037 pw.println(":"); 6038 w.dump(pw, " ", true); 6039 } else { 6040 pw.println(); 6041 } 6042 } 6043 } 6044 } 6045 if (mResizingWindows.size() > 0) { 6046 pw.println(); 6047 pw.println(" Windows waiting to resize:"); 6048 for (int i=mResizingWindows.size()-1; i>=0; i--) { 6049 WindowState w = mResizingWindows.get(i); 6050 if (windows == null || windows.contains(w)) { 6051 pw.print(" Resizing #"); pw.print(i); pw.print(' '); 6052 pw.print(w); 6053 if (dumpAll) { 6054 pw.println(":"); 6055 w.dump(pw, " ", true); 6056 } else { 6057 pw.println(); 6058 } 6059 } 6060 } 6061 } 6062 if (mWaitingForDrawn.size() > 0) { 6063 pw.println(); 6064 pw.println(" Clients waiting for these windows to be drawn:"); 6065 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) { 6066 WindowState win = mWaitingForDrawn.get(i); 6067 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(win); 6068 } 6069 } 6070 pw.println(); 6071 pw.print(" mGlobalConfiguration="); pw.println(mRoot.getConfiguration()); 6072 pw.print(" mHasPermanentDpad="); pw.println(mHasPermanentDpad); 6073 mRoot.dumpTopFocusedDisplayId(pw); 6074 mRoot.forAllDisplays(dc -> { 6075 final WindowState inputMethodTarget = dc.mInputMethodTarget; 6076 if (inputMethodTarget != null) { 6077 pw.print(" mInputMethodTarget in display# "); pw.print(dc.getDisplayId()); 6078 pw.print(' '); pw.println(inputMethodTarget); 6079 } 6080 }); 6081 pw.print(" mInTouchMode="); pw.println(mInTouchMode); 6082 pw.print(" mLastDisplayFreezeDuration="); 6083 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw); 6084 if ( mLastFinishedFreezeSource != null) { 6085 pw.print(" due to "); 6086 pw.print(mLastFinishedFreezeSource); 6087 } 6088 pw.println(); 6089 pw.print(" mLastWakeLockHoldingWindow=");pw.print(mLastWakeLockHoldingWindow); 6090 pw.print(" mLastWakeLockObscuringWindow="); pw.print(mLastWakeLockObscuringWindow); 6091 pw.println(); 6092 6093 mInputManagerCallback.dump(pw, " "); 6094 mTaskSnapshotController.dump(pw, " "); 6095 6096 if (dumpAll) { 6097 final WindowState imeWindow = mRoot.getCurrentInputMethodWindow(); 6098 if (imeWindow != null) { 6099 pw.print(" mInputMethodWindow="); pw.println(imeWindow); 6100 } 6101 mWindowPlacerLocked.dump(pw, " "); 6102 pw.print(" mSystemBooted="); pw.print(mSystemBooted); 6103 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled); 6104 6105 mRoot.dumpLayoutNeededDisplayIds(pw); 6106 6107 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence); 6108 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen); 6109 pw.print(" windows="); pw.print(mWindowsFreezingScreen); 6110 pw.print(" client="); pw.print(mClientFreezingScreen); 6111 pw.print(" apps="); pw.print(mAppsFreezingScreen); 6112 final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked(); 6113 pw.print(" mRotation="); pw.print(defaultDisplayContent.getRotation()); 6114 pw.print(" mLastWindowForcedOrientation="); 6115 pw.print(defaultDisplayContent.getLastWindowForcedOrientation()); 6116 pw.print(" mLastOrientation="); 6117 pw.println(defaultDisplayContent.getLastOrientation()); 6118 pw.print(" waitingForConfig="); 6119 pw.println(defaultDisplayContent.mWaitingForConfig); 6120 6121 pw.print(" Animation settings: disabled="); pw.print(mAnimationsDisabled); 6122 pw.print(" window="); pw.print(mWindowAnimationScaleSetting); 6123 pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting); 6124 pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting); 6125 if (mRecentsAnimationController != null) { 6126 pw.print(" mRecentsAnimationController="); pw.println(mRecentsAnimationController); 6127 mRecentsAnimationController.dump(pw, " "); 6128 } 6129 PolicyControl.dump(" ", pw); 6130 } 6131 } 6132 dumpWindows(PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)6133 private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti, 6134 boolean dumpAll) { 6135 final ArrayList<WindowState> windows = new ArrayList(); 6136 if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) { 6137 final boolean appsOnly = name.contains("apps"); 6138 final boolean visibleOnly = name.contains("visible"); 6139 synchronized (mGlobalLock) { 6140 if (appsOnly) { 6141 mRoot.dumpDisplayContents(pw); 6142 } 6143 6144 mRoot.forAllWindows((w) -> { 6145 if ((!visibleOnly || w.mWinAnimator.getShown()) 6146 && (!appsOnly || w.mAppToken != null)) { 6147 windows.add(w); 6148 } 6149 }, true /* traverseTopToBottom */); 6150 } 6151 } else { 6152 synchronized (mGlobalLock) { 6153 mRoot.getWindowsByName(windows, name); 6154 } 6155 } 6156 6157 if (windows.size() <= 0) { 6158 return false; 6159 } 6160 6161 synchronized (mGlobalLock) { 6162 dumpWindowsLocked(pw, dumpAll, windows); 6163 } 6164 return true; 6165 } 6166 dumpLastANRLocked(PrintWriter pw)6167 private void dumpLastANRLocked(PrintWriter pw) { 6168 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)"); 6169 if (mLastANRState == null) { 6170 pw.println(" <no ANR has occurred since boot>"); 6171 } else { 6172 pw.println(mLastANRState); 6173 } 6174 } 6175 6176 /** 6177 * Saves information about the state of the window manager at 6178 * the time an ANR occurred before anything else in the system changes 6179 * in response. 6180 * 6181 * @param appWindowToken The application that ANR'd, may be null. 6182 * @param windowState The window that ANR'd, may be null. 6183 * @param reason The reason for the ANR, may be null. 6184 */ saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState, String reason)6185 void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState, String reason) { 6186 StringWriter sw = new StringWriter(); 6187 PrintWriter pw = new FastPrintWriter(sw, false, 1024); 6188 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date())); 6189 if (appWindowToken != null) { 6190 pw.println(" Application at fault: " + appWindowToken.stringName); 6191 } 6192 if (windowState != null) { 6193 pw.println(" Window at fault: " + windowState.mAttrs.getTitle()); 6194 } 6195 if (reason != null) { 6196 pw.println(" Reason: " + reason); 6197 } 6198 for (int i = mRoot.getChildCount() - 1; i >= 0; i--) { 6199 final DisplayContent dc = mRoot.getChildAt(i); 6200 final int displayId = dc.getDisplayId(); 6201 if (!dc.mWinAddedSinceNullFocus.isEmpty()) { 6202 pw.println(" Windows added in display #" + displayId + " since null focus: " 6203 + dc.mWinAddedSinceNullFocus); 6204 } 6205 if (!dc.mWinRemovedSinceNullFocus.isEmpty()) { 6206 pw.println(" Windows removed in display #" + displayId + " since null focus: " 6207 + dc.mWinRemovedSinceNullFocus); 6208 } 6209 } 6210 pw.println(); 6211 dumpWindowsNoHeaderLocked(pw, true, null); 6212 pw.println(); 6213 pw.println("Last ANR continued"); 6214 mRoot.dumpDisplayContents(pw); 6215 pw.close(); 6216 mLastANRState = sw.toString(); 6217 6218 mH.removeMessages(H.RESET_ANR_MESSAGE); 6219 mH.sendEmptyMessageDelayed(H.RESET_ANR_MESSAGE, LAST_ANR_LIFETIME_DURATION_MSECS); 6220 } 6221 6222 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)6223 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 6224 PriorityDump.dump(mPriorityDumper, fd, pw, args); 6225 } 6226 doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto)6227 private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) { 6228 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 6229 boolean dumpAll = false; 6230 6231 int opti = 0; 6232 while (opti < args.length) { 6233 String opt = args[opti]; 6234 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 6235 break; 6236 } 6237 opti++; 6238 if ("-a".equals(opt)) { 6239 dumpAll = true; 6240 } else if ("-h".equals(opt)) { 6241 pw.println("Window manager dump options:"); 6242 pw.println(" [-a] [-h] [cmd] ..."); 6243 pw.println(" cmd may be one of:"); 6244 pw.println(" l[astanr]: last ANR information"); 6245 pw.println(" p[policy]: policy state"); 6246 pw.println(" a[animator]: animator state"); 6247 pw.println(" s[essions]: active sessions"); 6248 pw.println(" surfaces: active surfaces (debugging enabled only)"); 6249 pw.println(" d[isplays]: active display contents"); 6250 pw.println(" t[okens]: token list"); 6251 pw.println(" w[indows]: window list"); 6252 pw.println(" trace: print trace status and write Winscope trace to file"); 6253 pw.println(" cmd may also be a NAME to dump windows. NAME may"); 6254 pw.println(" be a partial substring in a window name, a"); 6255 pw.println(" Window hex object identifier, or"); 6256 pw.println(" \"all\" for all windows, or"); 6257 pw.println(" \"visible\" for the visible windows."); 6258 pw.println(" \"visible-apps\" for the visible app windows."); 6259 pw.println(" -a: include all available server state."); 6260 pw.println(" --proto: output dump in protocol buffer format."); 6261 return; 6262 } else { 6263 pw.println("Unknown argument: " + opt + "; use -h for help"); 6264 } 6265 } 6266 6267 if (useProto) { 6268 final ProtoOutputStream proto = new ProtoOutputStream(fd); 6269 synchronized (mGlobalLock) { 6270 writeToProtoLocked(proto, WindowTraceLogLevel.ALL); 6271 } 6272 proto.flush(); 6273 return; 6274 } 6275 // Is the caller requesting to dump a particular piece of data? 6276 if (opti < args.length) { 6277 String cmd = args[opti]; 6278 opti++; 6279 if ("lastanr".equals(cmd) || "l".equals(cmd)) { 6280 synchronized (mGlobalLock) { 6281 dumpLastANRLocked(pw); 6282 } 6283 return; 6284 } else if ("policy".equals(cmd) || "p".equals(cmd)) { 6285 synchronized (mGlobalLock) { 6286 dumpPolicyLocked(pw, args, true); 6287 } 6288 return; 6289 } else if ("animator".equals(cmd) || "a".equals(cmd)) { 6290 synchronized (mGlobalLock) { 6291 dumpAnimatorLocked(pw, args, true); 6292 } 6293 return; 6294 } else if ("sessions".equals(cmd) || "s".equals(cmd)) { 6295 synchronized (mGlobalLock) { 6296 dumpSessionsLocked(pw, true); 6297 } 6298 return; 6299 } else if ("displays".equals(cmd) || "d".equals(cmd)) { 6300 synchronized (mGlobalLock) { 6301 mRoot.dumpDisplayContents(pw); 6302 } 6303 return; 6304 } else if ("tokens".equals(cmd) || "t".equals(cmd)) { 6305 synchronized (mGlobalLock) { 6306 dumpTokensLocked(pw, true); 6307 } 6308 return; 6309 } else if ("windows".equals(cmd) || "w".equals(cmd)) { 6310 synchronized (mGlobalLock) { 6311 dumpWindowsLocked(pw, true, null); 6312 } 6313 return; 6314 } else if ("all".equals(cmd)) { 6315 synchronized (mGlobalLock) { 6316 dumpWindowsLocked(pw, true, null); 6317 } 6318 return; 6319 } else if ("containers".equals(cmd)) { 6320 synchronized (mGlobalLock) { 6321 mRoot.dumpChildrenNames(pw, " "); 6322 pw.println(" "); 6323 mRoot.forAllWindows(w -> {pw.println(w);}, true /* traverseTopToBottom */); 6324 } 6325 return; 6326 } else if ("trace".equals(cmd)) { 6327 dumpTraceStatus(pw); 6328 return; 6329 } else { 6330 // Dumping a single name? 6331 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) { 6332 pw.println("Bad window command, or no windows match: " + cmd); 6333 pw.println("Use -h for help."); 6334 } 6335 return; 6336 } 6337 } 6338 6339 synchronized (mGlobalLock) { 6340 pw.println(); 6341 final String separator = "---------------------------------------------------------" 6342 + "----------------------"; 6343 if (dumpAll) { 6344 pw.println(separator); 6345 } 6346 dumpLastANRLocked(pw); 6347 pw.println(); 6348 if (dumpAll) { 6349 pw.println(separator); 6350 } 6351 dumpPolicyLocked(pw, args, dumpAll); 6352 pw.println(); 6353 if (dumpAll) { 6354 pw.println(separator); 6355 } 6356 dumpAnimatorLocked(pw, args, dumpAll); 6357 pw.println(); 6358 if (dumpAll) { 6359 pw.println(separator); 6360 } 6361 dumpSessionsLocked(pw, dumpAll); 6362 pw.println(); 6363 if (dumpAll) { 6364 pw.println(separator); 6365 } 6366 if (dumpAll) { 6367 pw.println(separator); 6368 } 6369 mRoot.dumpDisplayContents(pw); 6370 pw.println(); 6371 if (dumpAll) { 6372 pw.println(separator); 6373 } 6374 dumpTokensLocked(pw, dumpAll); 6375 pw.println(); 6376 if (dumpAll) { 6377 pw.println(separator); 6378 } 6379 dumpWindowsLocked(pw, dumpAll, null); 6380 if (dumpAll) { 6381 pw.println(separator); 6382 } 6383 dumpTraceStatus(pw); 6384 } 6385 } 6386 6387 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection). 6388 @Override monitor()6389 public void monitor() { 6390 synchronized (mGlobalLock) { } 6391 } 6392 6393 // There is an inherent assumption that this will never return null. 6394 // TODO(multi-display): Inspect all the call-points of this method to see if they make sense to 6395 // support non-default display. getDefaultDisplayContentLocked()6396 DisplayContent getDefaultDisplayContentLocked() { 6397 return mRoot.getDisplayContent(DEFAULT_DISPLAY); 6398 } 6399 onOverlayChanged()6400 public void onOverlayChanged() { 6401 synchronized (mGlobalLock) { 6402 mRoot.forAllDisplays(displayContent -> { 6403 displayContent.getDisplayPolicy().onOverlayChangedLw(); 6404 displayContent.updateDisplayInfo(); 6405 }); 6406 requestTraversal(); 6407 } 6408 } 6409 onDisplayChanged(int displayId)6410 public void onDisplayChanged(int displayId) { 6411 synchronized (mGlobalLock) { 6412 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 6413 if (displayContent != null) { 6414 displayContent.updateDisplayInfo(); 6415 } 6416 mWindowPlacerLocked.requestTraversal(); 6417 } 6418 } 6419 6420 @Override getWindowManagerLock()6421 public Object getWindowManagerLock() { 6422 return mGlobalLock; 6423 } 6424 6425 /** 6426 * Hint to a token that its activity will relaunch, which will trigger removal and addition of 6427 * a window. 6428 * @param token Application token for which the activity will be relaunched. 6429 */ setWillReplaceWindow(IBinder token, boolean animate)6430 public void setWillReplaceWindow(IBinder token, boolean animate) { 6431 synchronized (mGlobalLock) { 6432 final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token); 6433 if (appWindowToken == null) { 6434 Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " 6435 + token); 6436 return; 6437 } 6438 if (!appWindowToken.hasContentToDisplay()) { 6439 Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content" 6440 + token); 6441 return; 6442 } 6443 appWindowToken.setWillReplaceWindows(animate); 6444 } 6445 } 6446 6447 /** 6448 * Hint to a token that its windows will be replaced across activity relaunch. 6449 * The windows would otherwise be removed shortly following this as the 6450 * activity is torn down. 6451 * @param token Application token for which the activity will be relaunched. 6452 * @param childrenOnly Whether to mark only child windows for replacement 6453 * (for the case where main windows are being preserved/ 6454 * reused rather than replaced). 6455 * 6456 */ 6457 // TODO: The s at the end of the method name is the only difference with the name of the method 6458 // above. We should combine them or find better names. setWillReplaceWindows(IBinder token, boolean childrenOnly)6459 void setWillReplaceWindows(IBinder token, boolean childrenOnly) { 6460 synchronized (mGlobalLock) { 6461 final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token); 6462 if (appWindowToken == null) { 6463 Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " 6464 + token); 6465 return; 6466 } 6467 if (!appWindowToken.hasContentToDisplay()) { 6468 Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content" 6469 + token); 6470 return; 6471 } 6472 6473 if (childrenOnly) { 6474 appWindowToken.setWillReplaceChildWindows(); 6475 } else { 6476 appWindowToken.setWillReplaceWindows(false /* animate */); 6477 } 6478 6479 scheduleClearWillReplaceWindows(token, true /* replacing */); 6480 } 6481 } 6482 6483 /** 6484 * If we're replacing the window, schedule a timer to clear the replaced window 6485 * after a timeout, in case the replacing window is not coming. 6486 * 6487 * If we're not replacing the window, clear the replace window settings of the app. 6488 * 6489 * @param token Application token for the activity whose window might be replaced. 6490 * @param replacing Whether the window is being replaced or not. 6491 */ scheduleClearWillReplaceWindows(IBinder token, boolean replacing)6492 public void scheduleClearWillReplaceWindows(IBinder token, boolean replacing) { 6493 synchronized (mGlobalLock) { 6494 final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token); 6495 if (appWindowToken == null) { 6496 Slog.w(TAG_WM, "Attempted to reset replacing window on non-existing app token " 6497 + token); 6498 return; 6499 } 6500 if (replacing) { 6501 scheduleWindowReplacementTimeouts(appWindowToken); 6502 } else { 6503 appWindowToken.clearWillReplaceWindows(); 6504 } 6505 } 6506 } 6507 scheduleWindowReplacementTimeouts(AppWindowToken appWindowToken)6508 void scheduleWindowReplacementTimeouts(AppWindowToken appWindowToken) { 6509 if (!mWindowReplacementTimeouts.contains(appWindowToken)) { 6510 mWindowReplacementTimeouts.add(appWindowToken); 6511 } 6512 mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT); 6513 mH.sendEmptyMessageDelayed( 6514 H.WINDOW_REPLACEMENT_TIMEOUT, WINDOW_REPLACEMENT_TIMEOUT_DURATION); 6515 } 6516 6517 @Override getDockedStackSide()6518 public int getDockedStackSide() { 6519 synchronized (mGlobalLock) { 6520 final TaskStack dockedStack = getDefaultDisplayContentLocked() 6521 .getSplitScreenPrimaryStackIgnoringVisibility(); 6522 return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide(); 6523 } 6524 } 6525 setDockedStackResizing(boolean resizing)6526 public void setDockedStackResizing(boolean resizing) { 6527 synchronized (mGlobalLock) { 6528 getDefaultDisplayContentLocked().getDockedDividerController().setResizing(resizing); 6529 requestTraversal(); 6530 } 6531 } 6532 6533 @Override setDockedStackDividerTouchRegion(Rect touchRegion)6534 public void setDockedStackDividerTouchRegion(Rect touchRegion) { 6535 synchronized (mGlobalLock) { 6536 final DisplayContent dc = getDefaultDisplayContentLocked(); 6537 dc.getDockedDividerController().setTouchRegion(touchRegion); 6538 dc.updateTouchExcludeRegion(); 6539 } 6540 } 6541 6542 @Override setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha)6543 public void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) { 6544 synchronized (mGlobalLock) { 6545 getDefaultDisplayContentLocked().getDockedDividerController().setResizeDimLayer( 6546 visible, targetWindowingMode, alpha); 6547 } 6548 } 6549 setForceResizableTasks(boolean forceResizableTasks)6550 public void setForceResizableTasks(boolean forceResizableTasks) { 6551 synchronized (mGlobalLock) { 6552 mForceResizableTasks = forceResizableTasks; 6553 } 6554 } 6555 setSupportsPictureInPicture(boolean supportsPictureInPicture)6556 public void setSupportsPictureInPicture(boolean supportsPictureInPicture) { 6557 synchronized (mGlobalLock) { 6558 mSupportsPictureInPicture = supportsPictureInPicture; 6559 } 6560 } 6561 setSupportsFreeformWindowManagement(boolean supportsFreeformWindowManagement)6562 public void setSupportsFreeformWindowManagement(boolean supportsFreeformWindowManagement) { 6563 synchronized (mGlobalLock) { 6564 mSupportsFreeformWindowManagement = supportsFreeformWindowManagement; 6565 } 6566 } 6567 setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays)6568 void setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays) { 6569 synchronized (mGlobalLock) { 6570 mForceDesktopModeOnExternalDisplays = forceDesktopModeOnExternalDisplays; 6571 } 6572 } 6573 setIsPc(boolean isPc)6574 public void setIsPc(boolean isPc) { 6575 synchronized (mGlobalLock) { 6576 mIsPc = isPc; 6577 } 6578 } 6579 dipToPixel(int dip, DisplayMetrics displayMetrics)6580 static int dipToPixel(int dip, DisplayMetrics displayMetrics) { 6581 return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics); 6582 } 6583 6584 @Override registerDockedStackListener(IDockedStackListener listener)6585 public void registerDockedStackListener(IDockedStackListener listener) { 6586 mAtmInternal.enforceCallerIsRecentsOrHasPermission(REGISTER_WINDOW_MANAGER_LISTENERS, 6587 "registerDockedStackListener()"); 6588 synchronized (mGlobalLock) { 6589 // TODO(multi-display): The listener is registered on the default display only. 6590 getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener( 6591 listener); 6592 } 6593 } 6594 6595 @Override registerPinnedStackListener(int displayId, IPinnedStackListener listener)6596 public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) { 6597 if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, 6598 "registerPinnedStackListener()")) { 6599 return; 6600 } 6601 if (!mSupportsPictureInPicture) { 6602 return; 6603 } 6604 synchronized (mGlobalLock) { 6605 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 6606 displayContent.getPinnedStackController().registerPinnedStackListener(listener); 6607 } 6608 } 6609 6610 @Override requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId)6611 public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) { 6612 try { 6613 WindowState focusedWindow = getFocusedWindow(); 6614 if (focusedWindow != null && focusedWindow.mClient != null) { 6615 getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver, deviceId); 6616 } 6617 } catch (RemoteException e) { 6618 } 6619 } 6620 6621 @Override getStableInsets(int displayId, Rect outInsets)6622 public void getStableInsets(int displayId, Rect outInsets) throws RemoteException { 6623 synchronized (mGlobalLock) { 6624 getStableInsetsLocked(displayId, outInsets); 6625 } 6626 } 6627 getStableInsetsLocked(int displayId, Rect outInsets)6628 void getStableInsetsLocked(int displayId, Rect outInsets) { 6629 outInsets.setEmpty(); 6630 final DisplayContent dc = mRoot.getDisplayContent(displayId); 6631 if (dc != null) { 6632 final DisplayInfo di = dc.getDisplayInfo(); 6633 dc.getDisplayPolicy().getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, 6634 di.displayCutout, outInsets); 6635 } 6636 } 6637 6638 @Override setForwardedInsets(int displayId, Insets insets)6639 public void setForwardedInsets(int displayId, Insets insets) throws RemoteException { 6640 synchronized (mGlobalLock) { 6641 final DisplayContent dc = mRoot.getDisplayContent(displayId); 6642 if (dc == null) { 6643 return; 6644 } 6645 final int callingUid = Binder.getCallingUid(); 6646 final int displayOwnerUid = dc.getDisplay().getOwnerUid(); 6647 if (callingUid != displayOwnerUid) { 6648 throw new SecurityException( 6649 "Only owner of the display can set ForwardedInsets to it."); 6650 } 6651 dc.setForwardedInsets(insets); 6652 } 6653 } 6654 intersectDisplayInsetBounds(Rect display, Rect insets, Rect inOutBounds)6655 void intersectDisplayInsetBounds(Rect display, Rect insets, Rect inOutBounds) { 6656 mTmpRect3.set(display); 6657 mTmpRect3.inset(insets); 6658 inOutBounds.intersect(mTmpRect3); 6659 } 6660 6661 MousePositionTracker mMousePositionTracker = new MousePositionTracker(); 6662 6663 private static class MousePositionTracker implements PointerEventListener { 6664 private boolean mLatestEventWasMouse; 6665 private float mLatestMouseX; 6666 private float mLatestMouseY; 6667 updatePosition(float x, float y)6668 void updatePosition(float x, float y) { 6669 synchronized (this) { 6670 mLatestEventWasMouse = true; 6671 mLatestMouseX = x; 6672 mLatestMouseY = y; 6673 } 6674 } 6675 6676 @Override onPointerEvent(MotionEvent motionEvent)6677 public void onPointerEvent(MotionEvent motionEvent) { 6678 if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) { 6679 updatePosition(motionEvent.getRawX(), motionEvent.getRawY()); 6680 } else { 6681 synchronized (this) { 6682 mLatestEventWasMouse = false; 6683 } 6684 } 6685 } 6686 }; 6687 updatePointerIcon(IWindow client)6688 void updatePointerIcon(IWindow client) { 6689 float mouseX, mouseY; 6690 6691 synchronized(mMousePositionTracker) { 6692 if (!mMousePositionTracker.mLatestEventWasMouse) { 6693 return; 6694 } 6695 mouseX = mMousePositionTracker.mLatestMouseX; 6696 mouseY = mMousePositionTracker.mLatestMouseY; 6697 } 6698 6699 synchronized (mGlobalLock) { 6700 if (mDragDropController.dragDropActiveLocked()) { 6701 // Drag cursor overrides the app cursor. 6702 return; 6703 } 6704 WindowState callingWin = windowForClientLocked(null, client, false); 6705 if (callingWin == null) { 6706 Slog.w(TAG_WM, "Bad requesting window " + client); 6707 return; 6708 } 6709 final DisplayContent displayContent = callingWin.getDisplayContent(); 6710 if (displayContent == null) { 6711 return; 6712 } 6713 WindowState windowUnderPointer = 6714 displayContent.getTouchableWinAtPointLocked(mouseX, mouseY); 6715 if (windowUnderPointer != callingWin) { 6716 return; 6717 } 6718 try { 6719 windowUnderPointer.mClient.updatePointerIcon( 6720 windowUnderPointer.translateToWindowX(mouseX), 6721 windowUnderPointer.translateToWindowY(mouseY)); 6722 } catch (RemoteException e) { 6723 Slog.w(TAG_WM, "unable to update pointer icon"); 6724 } 6725 } 6726 } 6727 restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY)6728 void restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY) { 6729 // Mouse position tracker has not been getting updates while dragging, update it now. 6730 mMousePositionTracker.updatePosition(latestX, latestY); 6731 6732 WindowState windowUnderPointer = 6733 displayContent.getTouchableWinAtPointLocked(latestX, latestY); 6734 if (windowUnderPointer != null) { 6735 try { 6736 windowUnderPointer.mClient.updatePointerIcon( 6737 windowUnderPointer.translateToWindowX(latestX), 6738 windowUnderPointer.translateToWindowY(latestY)); 6739 } catch (RemoteException e) { 6740 Slog.w(TAG_WM, "unable to restore pointer icon"); 6741 } 6742 } else { 6743 InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_DEFAULT); 6744 } 6745 } 6746 checkCallerOwnsDisplay(int displayId)6747 private void checkCallerOwnsDisplay(int displayId) { 6748 final Display display = mDisplayManager.getDisplay(displayId); 6749 if (display == null) { 6750 throw new IllegalArgumentException( 6751 "Cannot find display for non-existent displayId: " + displayId); 6752 } 6753 6754 final int callingUid = Binder.getCallingUid(); 6755 final int displayOwnerUid = display.getOwnerUid(); 6756 if (callingUid != displayOwnerUid) { 6757 throw new SecurityException("The caller doesn't own the display."); 6758 } 6759 } 6760 6761 /** @see Session#reparentDisplayContent(IWindow, SurfaceControl, int) */ reparentDisplayContent(IWindow client, SurfaceControl sc, int displayId)6762 void reparentDisplayContent(IWindow client, SurfaceControl sc, int displayId) { 6763 checkCallerOwnsDisplay(displayId); 6764 6765 synchronized (mGlobalLock) { 6766 final long token = Binder.clearCallingIdentity(); 6767 try { 6768 final WindowState win = windowForClientLocked(null, client, false); 6769 if (win == null) { 6770 Slog.w(TAG_WM, "Bad requesting window " + client); 6771 return; 6772 } 6773 getDisplayContentOrCreate(displayId, null).reparentDisplayContent(win, sc); 6774 } finally { 6775 Binder.restoreCallingIdentity(token); 6776 } 6777 } 6778 } 6779 6780 /** @see Session#updateDisplayContentLocation(IWindow, int, int, int) */ updateDisplayContentLocation(IWindow client, int x, int y, int displayId)6781 void updateDisplayContentLocation(IWindow client, int x, int y, int displayId) { 6782 checkCallerOwnsDisplay(displayId); 6783 6784 synchronized (mGlobalLock) { 6785 final long token = Binder.clearCallingIdentity(); 6786 try { 6787 final WindowState win = windowForClientLocked(null, client, false); 6788 if (win == null) { 6789 Slog.w(TAG_WM, "Bad requesting window " + client); 6790 return; 6791 } 6792 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 6793 if (displayContent != null) { 6794 displayContent.updateLocation(win, x, y); 6795 } 6796 } finally { 6797 Binder.restoreCallingIdentity(token); 6798 } 6799 } 6800 } 6801 6802 /** 6803 * Update a tap exclude region in the window identified by the provided id. Touches down on this 6804 * region will not: 6805 * <ol> 6806 * <li>Switch focus to this window.</li> 6807 * <li>Move the display of this window to top.</li> 6808 * <li>Send the touch events to this window.</li> 6809 * </ol> 6810 * Passing an invalid region will remove the area from the exclude region of this window. 6811 */ updateTapExcludeRegion(IWindow client, int regionId, Region region)6812 void updateTapExcludeRegion(IWindow client, int regionId, Region region) { 6813 synchronized (mGlobalLock) { 6814 final WindowState callingWin = windowForClientLocked(null, client, false); 6815 if (callingWin == null) { 6816 Slog.w(TAG_WM, "Bad requesting window " + client); 6817 return; 6818 } 6819 callingWin.updateTapExcludeRegion(regionId, region); 6820 } 6821 } 6822 6823 @Override dontOverrideDisplayInfo(int displayId)6824 public void dontOverrideDisplayInfo(int displayId) { 6825 final long token = Binder.clearCallingIdentity(); 6826 try { 6827 synchronized (mGlobalLock) { 6828 final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */); 6829 if (dc == null) { 6830 throw new IllegalArgumentException( 6831 "Trying to configure a non existent display."); 6832 } 6833 // We usually set the override info in DisplayManager so that we get consistent 6834 // values when displays are changing. However, we don't do this for displays that 6835 // serve as containers for ActivityViews because we don't want letter-/pillar-boxing 6836 // during resize. 6837 dc.mShouldOverrideDisplayConfiguration = false; 6838 mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId, 6839 null /* info */); 6840 } 6841 } finally { 6842 Binder.restoreCallingIdentity(token); 6843 } 6844 } 6845 6846 @Override getWindowingMode(int displayId)6847 public int getWindowingMode(int displayId) { 6848 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getWindowingMode()")) { 6849 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 6850 } 6851 6852 synchronized (mGlobalLock) { 6853 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 6854 if (displayContent == null) { 6855 Slog.w(TAG_WM, "Attempted to get windowing mode of a display that does not exist: " 6856 + displayId); 6857 return WindowConfiguration.WINDOWING_MODE_UNDEFINED; 6858 } 6859 return mDisplayWindowSettings.getWindowingModeLocked(displayContent); 6860 } 6861 } 6862 6863 @Override setWindowingMode(int displayId, int mode)6864 public void setWindowingMode(int displayId, int mode) { 6865 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setWindowingMode()")) { 6866 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 6867 } 6868 6869 synchronized (mGlobalLock) { 6870 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); 6871 if (displayContent == null) { 6872 Slog.w(TAG_WM, "Attempted to set windowing mode to a display that does not exist: " 6873 + displayId); 6874 return; 6875 } 6876 6877 int lastWindowingMode = displayContent.getWindowingMode(); 6878 mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode); 6879 6880 reconfigureDisplayLocked(displayContent); 6881 6882 if (lastWindowingMode != displayContent.getWindowingMode()) { 6883 // reconfigure won't detect this change in isolation because the windowing mode is 6884 // already set on the display, so fire off a new config now. 6885 mH.removeMessages(H.SEND_NEW_CONFIGURATION); 6886 6887 final long origId = Binder.clearCallingIdentity(); 6888 try { 6889 // direct call since lock is shared. 6890 sendNewConfiguration(displayId); 6891 } finally { 6892 Binder.restoreCallingIdentity(origId); 6893 } 6894 // Now that all configurations are updated, execute pending transitions 6895 displayContent.executeAppTransition(); 6896 } 6897 } 6898 } 6899 6900 @Override getRemoveContentMode(int displayId)6901 public @RemoveContentMode int getRemoveContentMode(int displayId) { 6902 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getRemoveContentMode()")) { 6903 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 6904 } 6905 6906 synchronized (mGlobalLock) { 6907 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 6908 if (displayContent == null) { 6909 Slog.w(TAG_WM, "Attempted to get remove mode of a display that does not exist: " 6910 + displayId); 6911 return REMOVE_CONTENT_MODE_UNDEFINED; 6912 } 6913 return mDisplayWindowSettings.getRemoveContentModeLocked(displayContent); 6914 } 6915 } 6916 6917 @Override setRemoveContentMode(int displayId, @RemoveContentMode int mode)6918 public void setRemoveContentMode(int displayId, @RemoveContentMode int mode) { 6919 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setRemoveContentMode()")) { 6920 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 6921 } 6922 6923 synchronized (mGlobalLock) { 6924 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); 6925 if (displayContent == null) { 6926 Slog.w(TAG_WM, "Attempted to set remove mode to a display that does not exist: " 6927 + displayId); 6928 return; 6929 } 6930 6931 mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode); 6932 6933 reconfigureDisplayLocked(displayContent); 6934 } 6935 } 6936 6937 @Override shouldShowWithInsecureKeyguard(int displayId)6938 public boolean shouldShowWithInsecureKeyguard(int displayId) { 6939 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowWithInsecureKeyguard()")) { 6940 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 6941 } 6942 6943 synchronized (mGlobalLock) { 6944 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 6945 if (displayContent == null) { 6946 Slog.w(TAG_WM, "Attempted to get flag of a display that does not exist: " 6947 + displayId); 6948 return false; 6949 } 6950 return mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(displayContent); 6951 } 6952 } 6953 6954 @Override setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow)6955 public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) { 6956 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, 6957 "setShouldShowWithInsecureKeyguard()")) { 6958 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 6959 } 6960 6961 synchronized (mGlobalLock) { 6962 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); 6963 if (displayContent == null) { 6964 Slog.w(TAG_WM, "Attempted to set flag to a display that does not exist: " 6965 + displayId); 6966 return; 6967 } 6968 6969 mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(displayContent, 6970 shouldShow); 6971 6972 reconfigureDisplayLocked(displayContent); 6973 } 6974 } 6975 6976 @Override shouldShowSystemDecors(int displayId)6977 public boolean shouldShowSystemDecors(int displayId) { 6978 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowSystemDecors()")) { 6979 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 6980 } 6981 6982 synchronized (mGlobalLock) { 6983 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 6984 if (displayContent == null) { 6985 Slog.w(TAG_WM, "Attempted to get system decors flag of a display that does " 6986 + "not exist: " + displayId); 6987 return false; 6988 } 6989 if (displayContent.isUntrustedVirtualDisplay()) { 6990 return false; 6991 } 6992 return displayContent.supportsSystemDecorations(); 6993 } 6994 } 6995 6996 @Override setShouldShowSystemDecors(int displayId, boolean shouldShow)6997 public void setShouldShowSystemDecors(int displayId, boolean shouldShow) { 6998 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowSystemDecors()")) { 6999 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 7000 } 7001 7002 synchronized (mGlobalLock) { 7003 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); 7004 if (displayContent == null) { 7005 Slog.w(TAG_WM, "Attempted to set system decors flag to a display that does " 7006 + "not exist: " + displayId); 7007 return; 7008 } 7009 if (displayContent.isUntrustedVirtualDisplay()) { 7010 throw new SecurityException("Attempted to set system decors flag to an untrusted " 7011 + "virtual display: " + displayId); 7012 } 7013 7014 mDisplayWindowSettings.setShouldShowSystemDecorsLocked(displayContent, shouldShow); 7015 7016 reconfigureDisplayLocked(displayContent); 7017 } 7018 } 7019 7020 @Override shouldShowIme(int displayId)7021 public boolean shouldShowIme(int displayId) { 7022 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowIme()")) { 7023 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 7024 } 7025 7026 synchronized (mGlobalLock) { 7027 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 7028 if (displayContent == null) { 7029 Slog.w(TAG_WM, "Attempted to get IME flag of a display that does not exist: " 7030 + displayId); 7031 return false; 7032 } 7033 if (displayContent.isUntrustedVirtualDisplay()) { 7034 return false; 7035 } 7036 return mDisplayWindowSettings.shouldShowImeLocked(displayContent) 7037 || mForceDesktopModeOnExternalDisplays; 7038 } 7039 } 7040 7041 @Override setShouldShowIme(int displayId, boolean shouldShow)7042 public void setShouldShowIme(int displayId, boolean shouldShow) { 7043 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowIme()")) { 7044 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 7045 } 7046 7047 synchronized (mGlobalLock) { 7048 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); 7049 if (displayContent == null) { 7050 Slog.w(TAG_WM, "Attempted to set IME flag to a display that does not exist: " 7051 + displayId); 7052 return; 7053 } 7054 if (displayContent.isUntrustedVirtualDisplay()) { 7055 throw new SecurityException("Attempted to set IME flag to an untrusted " 7056 + "virtual display: " + displayId); 7057 } 7058 7059 mDisplayWindowSettings.setShouldShowImeLocked(displayContent, shouldShow); 7060 7061 reconfigureDisplayLocked(displayContent); 7062 } 7063 } 7064 7065 @Override registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)7066 public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver) 7067 throws RemoteException { 7068 if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) { 7069 throw new SecurityException( 7070 "Requires REGISTER_WINDOW_MANAGER_LISTENERS permission"); 7071 } 7072 mPolicy.registerShortcutKey(shortcutCode, shortcutKeyReceiver); 7073 } 7074 7075 @Override requestUserActivityNotification()7076 public void requestUserActivityNotification() { 7077 if (!checkCallingPermission(android.Manifest.permission.USER_ACTIVITY, 7078 "requestUserActivityNotification()")) { 7079 throw new SecurityException("Requires USER_ACTIVITY permission"); 7080 } 7081 mPolicy.requestUserActivityNotification(); 7082 } 7083 markForSeamlessRotation(WindowState w, boolean seamlesslyRotated)7084 void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) { 7085 if (seamlesslyRotated == w.mSeamlesslyRotated || w.mForceSeamlesslyRotate) { 7086 return; 7087 } 7088 w.mSeamlesslyRotated = seamlesslyRotated; 7089 if (seamlesslyRotated) { 7090 mSeamlessRotationCount++; 7091 } else { 7092 mSeamlessRotationCount--; 7093 } 7094 if (mSeamlessRotationCount == 0) { 7095 if (DEBUG_ORIENTATION) { 7096 Slog.i(TAG, "Performing post-rotate rotation after seamless rotation"); 7097 } 7098 finishSeamlessRotation(); 7099 7100 w.getDisplayContent().updateRotationAndSendNewConfigIfNeeded(); 7101 } 7102 } 7103 7104 private final class LocalService extends WindowManagerInternal { 7105 @Override requestTraversalFromDisplayManager()7106 public void requestTraversalFromDisplayManager() { 7107 requestTraversal(); 7108 } 7109 7110 @Override setMagnificationSpec(int displayId, MagnificationSpec spec)7111 public void setMagnificationSpec(int displayId, MagnificationSpec spec) { 7112 synchronized (mGlobalLock) { 7113 if (mAccessibilityController != null) { 7114 mAccessibilityController.setMagnificationSpecLocked(displayId, spec); 7115 } else { 7116 throw new IllegalStateException("Magnification callbacks not set!"); 7117 } 7118 } 7119 if (Binder.getCallingPid() != myPid()) { 7120 spec.recycle(); 7121 } 7122 } 7123 7124 @Override setForceShowMagnifiableBounds(int displayId, boolean show)7125 public void setForceShowMagnifiableBounds(int displayId, boolean show) { 7126 synchronized (mGlobalLock) { 7127 if (mAccessibilityController != null) { 7128 mAccessibilityController.setForceShowMagnifiableBoundsLocked(displayId, show); 7129 } else { 7130 throw new IllegalStateException("Magnification callbacks not set!"); 7131 } 7132 } 7133 } 7134 7135 @Override getMagnificationRegion(int displayId, @NonNull Region magnificationRegion)7136 public void getMagnificationRegion(int displayId, @NonNull Region magnificationRegion) { 7137 synchronized (mGlobalLock) { 7138 if (mAccessibilityController != null) { 7139 mAccessibilityController.getMagnificationRegionLocked(displayId, 7140 magnificationRegion); 7141 } else { 7142 throw new IllegalStateException("Magnification callbacks not set!"); 7143 } 7144 } 7145 } 7146 7147 @Override getCompatibleMagnificationSpecForWindow(IBinder windowToken)7148 public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) { 7149 synchronized (mGlobalLock) { 7150 WindowState windowState = mWindowMap.get(windowToken); 7151 if (windowState == null) { 7152 return null; 7153 } 7154 MagnificationSpec spec = null; 7155 if (mAccessibilityController != null) { 7156 spec = mAccessibilityController.getMagnificationSpecForWindowLocked(windowState); 7157 } 7158 if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) { 7159 return null; 7160 } 7161 spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec); 7162 spec.scale *= windowState.mGlobalScale; 7163 return spec; 7164 } 7165 } 7166 7167 @Override setMagnificationCallbacks(int displayId, @Nullable MagnificationCallbacks callbacks)7168 public boolean setMagnificationCallbacks(int displayId, 7169 @Nullable MagnificationCallbacks callbacks) { 7170 synchronized (mGlobalLock) { 7171 if (mAccessibilityController == null) { 7172 mAccessibilityController = new AccessibilityController( 7173 WindowManagerService.this); 7174 } 7175 boolean result = mAccessibilityController.setMagnificationCallbacksLocked( 7176 displayId, callbacks); 7177 if (!mAccessibilityController.hasCallbacksLocked()) { 7178 mAccessibilityController = null; 7179 } 7180 return result; 7181 } 7182 } 7183 7184 @Override setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback)7185 public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) { 7186 synchronized (mGlobalLock) { 7187 if (mAccessibilityController == null) { 7188 mAccessibilityController = new AccessibilityController( 7189 WindowManagerService.this); 7190 } 7191 mAccessibilityController.setWindowsForAccessibilityCallback(callback); 7192 if (!mAccessibilityController.hasCallbacksLocked()) { 7193 mAccessibilityController = null; 7194 } 7195 } 7196 } 7197 7198 @Override setInputFilter(IInputFilter filter)7199 public void setInputFilter(IInputFilter filter) { 7200 mInputManager.setInputFilter(filter); 7201 } 7202 7203 @Override getFocusedWindowToken()7204 public IBinder getFocusedWindowToken() { 7205 synchronized (mGlobalLock) { 7206 WindowState windowState = getFocusedWindowLocked(); 7207 if (windowState != null) { 7208 return windowState.mClient.asBinder(); 7209 } 7210 return null; 7211 } 7212 } 7213 7214 @Override isKeyguardLocked()7215 public boolean isKeyguardLocked() { 7216 return WindowManagerService.this.isKeyguardLocked(); 7217 } 7218 7219 @Override isKeyguardShowingAndNotOccluded()7220 public boolean isKeyguardShowingAndNotOccluded() { 7221 return WindowManagerService.this.isKeyguardShowingAndNotOccluded(); 7222 } 7223 7224 @Override showGlobalActions()7225 public void showGlobalActions() { 7226 WindowManagerService.this.showGlobalActions(); 7227 } 7228 7229 @Override getWindowFrame(IBinder token, Rect outBounds)7230 public void getWindowFrame(IBinder token, Rect outBounds) { 7231 synchronized (mGlobalLock) { 7232 WindowState windowState = mWindowMap.get(token); 7233 if (windowState != null) { 7234 outBounds.set(windowState.getFrameLw()); 7235 } else { 7236 outBounds.setEmpty(); 7237 } 7238 } 7239 } 7240 7241 @Override waitForAllWindowsDrawn(Runnable callback, long timeout)7242 public void waitForAllWindowsDrawn(Runnable callback, long timeout) { 7243 boolean allWindowsDrawn = false; 7244 synchronized (mGlobalLock) { 7245 mWaitingForDrawnCallback = callback; 7246 getDefaultDisplayContentLocked().waitForAllWindowsDrawn(); 7247 mWindowPlacerLocked.requestTraversal(); 7248 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT); 7249 if (mWaitingForDrawn.isEmpty()) { 7250 allWindowsDrawn = true; 7251 } else { 7252 mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout); 7253 checkDrawnWindowsLocked(); 7254 } 7255 } 7256 if (allWindowsDrawn) { 7257 callback.run(); 7258 } 7259 } 7260 7261 @Override setForcedDisplaySize(int displayId, int width, int height)7262 public void setForcedDisplaySize(int displayId, int width, int height) { 7263 WindowManagerService.this.setForcedDisplaySize(displayId, width, height); 7264 } 7265 7266 @Override clearForcedDisplaySize(int displayId)7267 public void clearForcedDisplaySize(int displayId) { 7268 WindowManagerService.this.clearForcedDisplaySize(displayId); 7269 } 7270 7271 @Override addWindowToken(IBinder token, int type, int displayId)7272 public void addWindowToken(IBinder token, int type, int displayId) { 7273 WindowManagerService.this.addWindowToken(token, type, displayId); 7274 } 7275 7276 @Override removeWindowToken(IBinder binder, boolean removeWindows, int displayId)7277 public void removeWindowToken(IBinder binder, boolean removeWindows, int displayId) { 7278 synchronized (mGlobalLock) { 7279 if (removeWindows) { 7280 final DisplayContent dc = mRoot.getDisplayContent(displayId); 7281 if (dc == null) { 7282 Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder 7283 + " for non-exiting displayId=" + displayId); 7284 return; 7285 } 7286 7287 final WindowToken token = dc.removeWindowToken(binder); 7288 if (token == null) { 7289 Slog.w(TAG_WM, "removeWindowToken: Attempted to remove non-existing token: " 7290 + binder); 7291 return; 7292 } 7293 7294 token.removeAllWindowsIfPossible(); 7295 } 7296 WindowManagerService.this.removeWindowToken(binder, displayId); 7297 } 7298 } 7299 7300 // TODO(multi-display): currently only used by PWM to notify keyguard transitions as well 7301 // forwarding it to SystemUI for synchronizing status and navigation bar animations. 7302 @Override registerAppTransitionListener(AppTransitionListener listener)7303 public void registerAppTransitionListener(AppTransitionListener listener) { 7304 synchronized (mGlobalLock) { 7305 getDefaultDisplayContentLocked().mAppTransition.registerListenerLocked(listener); 7306 } 7307 } 7308 7309 @Override reportPasswordChanged(int userId)7310 public void reportPasswordChanged(int userId) { 7311 mKeyguardDisableHandler.updateKeyguardEnabled(userId); 7312 } 7313 7314 @Override getInputMethodWindowVisibleHeight(int displayId)7315 public int getInputMethodWindowVisibleHeight(int displayId) { 7316 synchronized (mGlobalLock) { 7317 final DisplayContent dc = mRoot.getDisplayContent(displayId); 7318 return dc.mDisplayFrames.getInputMethodWindowVisibleHeight(); 7319 } 7320 } 7321 7322 @Override updateInputMethodWindowStatus(@onNull IBinder imeToken, boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed)7323 public void updateInputMethodWindowStatus(@NonNull IBinder imeToken, 7324 boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed) { 7325 mPolicy.setDismissImeOnBackKeyPressed(dismissImeOnBackKeyPressed); 7326 } 7327 7328 @Override updateInputMethodTargetWindow(@onNull IBinder imeToken, @NonNull IBinder imeTargetWindowToken)7329 public void updateInputMethodTargetWindow(@NonNull IBinder imeToken, 7330 @NonNull IBinder imeTargetWindowToken) { 7331 // TODO (b/34628091): Use this method to address the window animation issue. 7332 if (DEBUG_INPUT_METHOD) { 7333 Slog.w(TAG_WM, "updateInputMethodTargetWindow: imeToken=" + imeToken 7334 + " imeTargetWindowToken=" + imeTargetWindowToken); 7335 } 7336 } 7337 7338 @Override isHardKeyboardAvailable()7339 public boolean isHardKeyboardAvailable() { 7340 synchronized (mGlobalLock) { 7341 return mHardKeyboardAvailable; 7342 } 7343 } 7344 7345 @Override setOnHardKeyboardStatusChangeListener( OnHardKeyboardStatusChangeListener listener)7346 public void setOnHardKeyboardStatusChangeListener( 7347 OnHardKeyboardStatusChangeListener listener) { 7348 synchronized (mGlobalLock) { 7349 mHardKeyboardStatusChangeListener = listener; 7350 } 7351 } 7352 7353 @Override isStackVisibleLw(int windowingMode)7354 public boolean isStackVisibleLw(int windowingMode) { 7355 final DisplayContent dc = getDefaultDisplayContentLocked(); 7356 return dc.isStackVisible(windowingMode); 7357 } 7358 7359 @Override computeWindowsForAccessibility()7360 public void computeWindowsForAccessibility() { 7361 final AccessibilityController accessibilityController; 7362 synchronized (mGlobalLock) { 7363 accessibilityController = mAccessibilityController; 7364 } 7365 if (accessibilityController != null) { 7366 accessibilityController.performComputeChangedWindowsNotLocked(true); 7367 } 7368 } 7369 7370 @Override setVr2dDisplayId(int vr2dDisplayId)7371 public void setVr2dDisplayId(int vr2dDisplayId) { 7372 if (DEBUG_DISPLAY) { 7373 Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId); 7374 } 7375 synchronized (mGlobalLock) { 7376 mVr2dDisplayId = vr2dDisplayId; 7377 } 7378 } 7379 7380 @Override registerDragDropControllerCallback(IDragDropCallback callback)7381 public void registerDragDropControllerCallback(IDragDropCallback callback) { 7382 mDragDropController.registerCallback(callback); 7383 } 7384 7385 @Override lockNow()7386 public void lockNow() { 7387 WindowManagerService.this.lockNow(null); 7388 } 7389 7390 @Override getWindowOwnerUserId(IBinder token)7391 public int getWindowOwnerUserId(IBinder token) { 7392 synchronized (mGlobalLock) { 7393 WindowState window = mWindowMap.get(token); 7394 if (window != null) { 7395 return UserHandle.getUserId(window.mOwnerUid); 7396 } 7397 return UserHandle.USER_NULL; 7398 } 7399 } 7400 7401 @Override isUidFocused(int uid)7402 public boolean isUidFocused(int uid) { 7403 synchronized (mGlobalLock) { 7404 for (int i = mRoot.getChildCount() - 1; i >= 0; i--) { 7405 final DisplayContent displayContent = mRoot.getChildAt(i); 7406 if (displayContent.mCurrentFocus != null 7407 && uid == displayContent.mCurrentFocus.getOwningUid()) { 7408 return true; 7409 } 7410 } 7411 return false; 7412 } 7413 } 7414 7415 @Override isInputMethodClientFocus(int uid, int pid, int displayId)7416 public boolean isInputMethodClientFocus(int uid, int pid, int displayId) { 7417 if (displayId == Display.INVALID_DISPLAY) { 7418 return false; 7419 } 7420 synchronized (mGlobalLock) { 7421 final DisplayContent displayContent = mRoot.getTopFocusedDisplayContent(); 7422 if (displayContent == null 7423 || displayContent.getDisplayId() != displayId 7424 || !displayContent.hasAccess(uid)) { 7425 return false; 7426 } 7427 if (displayContent.isInputMethodClientFocus(uid, pid)) { 7428 return true; 7429 } 7430 // Okay, how about this... what is the current focus? 7431 // It seems in some cases we may not have moved the IM 7432 // target window, such as when it was in a pop-up window, 7433 // so let's also look at the current focus. (An example: 7434 // go to Gmail, start searching so the keyboard goes up, 7435 // press home. Sometimes the IME won't go down.) 7436 // Would be nice to fix this more correctly, but it's 7437 // way at the end of a release, and this should be good enough. 7438 final WindowState currentFocus = displayContent.mCurrentFocus; 7439 if (currentFocus != null && currentFocus.mSession.mUid == uid 7440 && currentFocus.mSession.mPid == pid) { 7441 return true; 7442 } 7443 } 7444 return false; 7445 } 7446 7447 @Override isUidAllowedOnDisplay(int displayId, int uid)7448 public boolean isUidAllowedOnDisplay(int displayId, int uid) { 7449 if (displayId == Display.DEFAULT_DISPLAY) { 7450 return true; 7451 } 7452 if (displayId == Display.INVALID_DISPLAY) { 7453 return false; 7454 } 7455 synchronized (mGlobalLock) { 7456 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 7457 return displayContent != null && displayContent.hasAccess(uid); 7458 } 7459 } 7460 7461 @Override getDisplayIdForWindow(IBinder windowToken)7462 public int getDisplayIdForWindow(IBinder windowToken) { 7463 synchronized (mGlobalLock) { 7464 final WindowState window = mWindowMap.get(windowToken); 7465 if (window != null) { 7466 return window.getDisplayContent().getDisplayId(); 7467 } 7468 return Display.INVALID_DISPLAY; 7469 } 7470 } 7471 7472 @Override getTopFocusedDisplayId()7473 public int getTopFocusedDisplayId() { 7474 synchronized (mGlobalLock) { 7475 return mRoot.getTopFocusedDisplayContent().getDisplayId(); 7476 } 7477 } 7478 7479 @Override shouldShowSystemDecorOnDisplay(int displayId)7480 public boolean shouldShowSystemDecorOnDisplay(int displayId) { 7481 synchronized (mGlobalLock) { 7482 return WindowManagerService.this.shouldShowSystemDecors(displayId); 7483 } 7484 } 7485 7486 @Override shouldShowIme(int displayId)7487 public boolean shouldShowIme(int displayId) { 7488 synchronized (mGlobalLock) { 7489 return WindowManagerService.this.shouldShowIme(displayId); 7490 } 7491 } 7492 7493 @Override addNonHighRefreshRatePackage(@onNull String packageName)7494 public void addNonHighRefreshRatePackage(@NonNull String packageName) { 7495 synchronized (mGlobalLock) { 7496 mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy() 7497 .addNonHighRefreshRatePackage(packageName)); 7498 } 7499 } 7500 7501 @Override removeNonHighRefreshRatePackage(@onNull String packageName)7502 public void removeNonHighRefreshRatePackage(@NonNull String packageName) { 7503 synchronized (mGlobalLock) { 7504 mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy() 7505 .removeNonHighRefreshRatePackage(packageName)); 7506 } 7507 } 7508 } 7509 registerAppFreezeListener(AppFreezeListener listener)7510 void registerAppFreezeListener(AppFreezeListener listener) { 7511 if (!mAppFreezeListeners.contains(listener)) { 7512 mAppFreezeListeners.add(listener); 7513 } 7514 } 7515 unregisterAppFreezeListener(AppFreezeListener listener)7516 void unregisterAppFreezeListener(AppFreezeListener listener) { 7517 mAppFreezeListeners.remove(listener); 7518 } 7519 7520 /** 7521 * WARNING: This interrupts surface updates, be careful! Don't 7522 * execute within the transaction for longer than you would 7523 * execute on an animation thread. 7524 * WARNING: This method contains locks known to the State of California 7525 * to cause Deadlocks and other conditions. 7526 * 7527 * Begins a surface transaction with which the AM can batch operations. 7528 * All Surface updates performed by the WindowManager following this 7529 * will not appear on screen until after the call to 7530 * closeSurfaceTransaction. 7531 * 7532 * ActivityManager can use this to ensure multiple 'commands' will all 7533 * be reflected in a single frame. For example when reparenting a window 7534 * which was previously hidden due to it's parent properties, we may 7535 * need to ensure it is hidden in the same frame that the properties 7536 * from the new parent are inherited, otherwise it could be revealed 7537 * mistakenly. 7538 * 7539 * TODO(b/36393204): We can investigate totally replacing #deferSurfaceLayout 7540 * with something like this but it seems that some existing cases of 7541 * deferSurfaceLayout may be a little too broad, in particular the total 7542 * enclosure of startActivityUnchecked which could run for quite some time. 7543 */ inSurfaceTransaction(Runnable exec)7544 void inSurfaceTransaction(Runnable exec) { 7545 SurfaceControl.openTransaction(); 7546 try { 7547 exec.run(); 7548 } finally { 7549 SurfaceControl.closeTransaction(); 7550 } 7551 } 7552 7553 /** Called to inform window manager if non-Vr UI shoul be disabled or not. */ disableNonVrUi(boolean disable)7554 public void disableNonVrUi(boolean disable) { 7555 synchronized (mGlobalLock) { 7556 // Allow alert window notifications to be shown if non-vr UI is enabled. 7557 final boolean showAlertWindowNotifications = !disable; 7558 if (showAlertWindowNotifications == mShowAlertWindowNotifications) { 7559 return; 7560 } 7561 mShowAlertWindowNotifications = showAlertWindowNotifications; 7562 7563 for (int i = mSessions.size() - 1; i >= 0; --i) { 7564 final Session s = mSessions.valueAt(i); 7565 s.setShowingAlertWindowNotificationAllowed(mShowAlertWindowNotifications); 7566 } 7567 } 7568 } 7569 hasWideColorGamutSupport()7570 boolean hasWideColorGamutSupport() { 7571 return mHasWideColorGamutSupport && 7572 SystemProperties.getInt("persist.sys.sf.native_mode", 0) != 1; 7573 } 7574 hasHdrSupport()7575 boolean hasHdrSupport() { 7576 return mHasHdrSupport && hasWideColorGamutSupport(); 7577 } 7578 updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown)7579 void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) { 7580 if (!win.hideNonSystemOverlayWindowsWhenVisible() 7581 && !mHidingNonSystemOverlayWindows.contains(win)) { 7582 return; 7583 } 7584 final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty(); 7585 if (surfaceShown) { 7586 if (!mHidingNonSystemOverlayWindows.contains(win)) { 7587 mHidingNonSystemOverlayWindows.add(win); 7588 } 7589 } else { 7590 mHidingNonSystemOverlayWindows.remove(win); 7591 } 7592 7593 final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty(); 7594 7595 if (systemAlertWindowsHidden == hideSystemAlertWindows) { 7596 return; 7597 } 7598 7599 mRoot.forAllWindows((w) -> { 7600 w.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows); 7601 }, false /* traverseTopToBottom */); 7602 } 7603 7604 /** Called from Accessibility Controller to apply magnification spec */ applyMagnificationSpecLocked(int displayId, MagnificationSpec spec)7605 public void applyMagnificationSpecLocked(int displayId, MagnificationSpec spec) { 7606 final DisplayContent displayContent = mRoot.getDisplayContent(displayId); 7607 if (displayContent != null) { 7608 displayContent.applyMagnificationSpec(spec); 7609 } 7610 } 7611 makeSurfaceBuilder(SurfaceSession s)7612 SurfaceControl.Builder makeSurfaceBuilder(SurfaceSession s) { 7613 return mSurfaceBuilderFactory.make(s); 7614 } 7615 sendSetRunningRemoteAnimation(int pid, boolean runningRemoteAnimation)7616 void sendSetRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) { 7617 mH.obtainMessage(H.SET_RUNNING_REMOTE_ANIMATION, pid, runningRemoteAnimation ? 1 : 0) 7618 .sendToTarget(); 7619 } 7620 startSeamlessRotation()7621 void startSeamlessRotation() { 7622 // We are careful to reset this in case a window was removed before it finished 7623 // seamless rotation. 7624 mSeamlessRotationCount = 0; 7625 7626 mRotatingSeamlessly = true; 7627 } 7628 isRotatingSeamlessly()7629 boolean isRotatingSeamlessly() { 7630 return mRotatingSeamlessly; 7631 } 7632 finishSeamlessRotation()7633 void finishSeamlessRotation() { 7634 mRotatingSeamlessly = false; 7635 } 7636 7637 /** 7638 * Called when the state of lock task mode changes. This should be used to disable immersive 7639 * mode confirmation. 7640 * 7641 * @param lockTaskState the new lock task mode state. One of 7642 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, 7643 * {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, 7644 * {@link ActivityManager#LOCK_TASK_MODE_PINNED}. 7645 */ onLockTaskStateChanged(int lockTaskState)7646 void onLockTaskStateChanged(int lockTaskState) { 7647 // TODO: pass in displayId to determine which display the lock task state changed 7648 synchronized (mGlobalLock) { 7649 mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer( 7650 DisplayPolicy::onLockTaskStateChangedLw, PooledLambda.__(), lockTaskState)); 7651 } 7652 } 7653 7654 /** 7655 * Updates {@link WindowManagerPolicy} with new value about whether AOD is showing. If AOD 7656 * has changed, this will trigger a {@link WindowSurfacePlacer#performSurfacePlacement} to 7657 * ensure the new value takes effect. 7658 */ setAodShowing(boolean aodShowing)7659 public void setAodShowing(boolean aodShowing) { 7660 synchronized (mGlobalLock) { 7661 if (mPolicy.setAodShowing(aodShowing)) { 7662 mWindowPlacerLocked.performSurfacePlacement(); 7663 } 7664 } 7665 } 7666 7667 @Override injectInputAfterTransactionsApplied(InputEvent ev, int mode)7668 public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode) { 7669 boolean isDown; 7670 boolean isUp; 7671 7672 if (ev instanceof KeyEvent) { 7673 KeyEvent keyEvent = (KeyEvent) ev; 7674 isDown = keyEvent.getAction() == KeyEvent.ACTION_DOWN; 7675 isUp = keyEvent.getAction() == KeyEvent.ACTION_UP; 7676 } else { 7677 MotionEvent motionEvent = (MotionEvent) ev; 7678 isDown = motionEvent.getAction() == MotionEvent.ACTION_DOWN; 7679 isUp = motionEvent.getAction() == MotionEvent.ACTION_UP; 7680 } 7681 final boolean isMouseEvent = ev.getSource() == InputDevice.SOURCE_MOUSE; 7682 7683 // For ACTION_DOWN, syncInputTransactions before injecting input. 7684 // For all mouse events, also sync before injecting. 7685 // For ACTION_UP, sync after injecting. 7686 if (isDown || isMouseEvent) { 7687 syncInputTransactions(); 7688 } 7689 final boolean result = 7690 LocalServices.getService(InputManagerInternal.class).injectInputEvent(ev, mode); 7691 if (isUp) { 7692 syncInputTransactions(); 7693 } 7694 return result; 7695 } 7696 7697 @Override syncInputTransactions()7698 public void syncInputTransactions() { 7699 waitForAnimationsToComplete(); 7700 7701 synchronized (mGlobalLock) { 7702 mWindowPlacerLocked.performSurfacePlacementIfScheduled(); 7703 mRoot.forAllDisplays(displayContent -> 7704 displayContent.getInputMonitor().updateInputWindowsImmediately()); 7705 } 7706 new SurfaceControl.Transaction().syncInputWindows().apply(true); 7707 } 7708 waitForAnimationsToComplete()7709 private void waitForAnimationsToComplete() { 7710 synchronized (mGlobalLock) { 7711 long timeoutRemaining = ANIMATION_COMPLETED_TIMEOUT_MS; 7712 while (mRoot.isSelfOrChildAnimating() && timeoutRemaining > 0) { 7713 long startTime = System.currentTimeMillis(); 7714 try { 7715 mGlobalLock.wait(timeoutRemaining); 7716 } catch (InterruptedException e) { 7717 } 7718 timeoutRemaining -= (System.currentTimeMillis() - startTime); 7719 } 7720 7721 if (mRoot.isSelfOrChildAnimating()) { 7722 Log.w(TAG, "Timed out waiting for animations to complete."); 7723 } 7724 } 7725 } 7726 onAnimationFinished()7727 void onAnimationFinished() { 7728 synchronized (mGlobalLock) { 7729 mGlobalLock.notifyAll(); 7730 } 7731 } 7732 onPointerDownOutsideFocusLocked(IBinder touchedToken)7733 private void onPointerDownOutsideFocusLocked(IBinder touchedToken) { 7734 final WindowState touchedWindow = windowForClientLocked(null, touchedToken, false); 7735 if (touchedWindow == null || !touchedWindow.canReceiveKeys()) { 7736 return; 7737 } 7738 7739 handleTaskFocusChange(touchedWindow.getTask()); 7740 handleDisplayFocusChange(touchedWindow); 7741 } 7742 handleTaskFocusChange(Task task)7743 private void handleTaskFocusChange(Task task) { 7744 if (task == null) { 7745 return; 7746 } 7747 7748 final TaskStack stack = task.mStack; 7749 // We ignore home stack since we don't want home stack to move to front when touched. 7750 // Specifically, in freeform we don't want tapping on home to cause the freeform apps to go 7751 // behind home. See b/117376413 7752 if (stack.isActivityTypeHome()) { 7753 return; 7754 } 7755 7756 try { 7757 mActivityTaskManager.setFocusedTask(task.mTaskId); 7758 } catch (RemoteException e) { 7759 } 7760 } 7761 handleDisplayFocusChange(WindowState window)7762 private void handleDisplayFocusChange(WindowState window) { 7763 final DisplayContent displayContent = window.getDisplayContent(); 7764 if (displayContent == null) { 7765 return; 7766 } 7767 7768 if (!window.canReceiveKeys()) { 7769 // If the window that received the input event cannot receive keys, don't move the 7770 // display it's on to the top since that window won't be able to get focus anyway. 7771 return; 7772 } 7773 7774 final WindowContainer parent = displayContent.getParent(); 7775 if (parent != null && parent.getTopChild() != displayContent) { 7776 parent.positionChildAt(WindowContainer.POSITION_TOP, displayContent, 7777 true /* includingParents */); 7778 // For compatibility, only the topmost activity is allowed to be resumed for pre-Q 7779 // app. Ensure the topmost activities are resumed whenever a display is moved to top. 7780 // TODO(b/123761773): Investigate whether we can move this into 7781 // RootActivityContainer#updateTopResumedActivityIfNeeded(). Currently, it is risky 7782 // to do so because it seems possible to resume activities as part of a larger 7783 // transaction and it's too early to resume based on current order when performing 7784 // updateTopResumedActivityIfNeeded(). 7785 displayContent.mAcitvityDisplay.ensureActivitiesVisible(null /* starting */, 7786 0 /* configChanges */, !PRESERVE_WINDOWS, true /* notifyClients */); 7787 } 7788 } 7789 } 7790