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