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