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