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