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