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