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