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