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