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