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