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