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