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