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