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_TASKS;
23 import static android.Manifest.permission.MANAGE_APP_TOKENS;
24 import static android.Manifest.permission.MODIFY_TOUCH_MODE_STATE;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
27 import static android.Manifest.permission.RESTRICTED_VR_ACCESS;
28 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
29 import static android.Manifest.permission.STATUS_BAR_SERVICE;
30 import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
31 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
32 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
33 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
34 import static android.app.StatusBarManager.DISABLE_MASK;
35 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
36 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
37 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
38 import static android.content.pm.PackageManager.FEATURE_PC;
39 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
40 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
41 import static android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE;
42 import static android.os.Process.SYSTEM_UID;
43 import static android.os.Process.myPid;
44 import static android.os.Process.myUid;
45 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
46 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
47 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
48 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
49 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
50 import static android.provider.Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH;
51 import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
52 import static android.view.Display.DEFAULT_DISPLAY;
53 import static android.view.Display.INVALID_DISPLAY;
54 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
55 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
56 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
57 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
58 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
59 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
60 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
61 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
62 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
63 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
64 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
65 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
66 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
67 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
68 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
69 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
70 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
71 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
72 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
73 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
74 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
75 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
76 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
77 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
78 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
79 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
80 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
81 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
82 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
83 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
84 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
85 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
86 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
87 import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
88 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
89 import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
90 import static android.view.WindowManager.TRANSIT_NONE;
91 import static android.view.WindowManager.TRANSIT_OPEN;
92 import static android.view.WindowManager.fixScale;
93 import static android.view.WindowManagerGlobal.ADD_OKAY;
94 import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
95 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
96 import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_MULTIPLIER;
97 import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
98 import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN;
99 import static android.window.WindowProviderService.isWindowProviderService;
100 
101 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
102 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM;
103 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT;
104 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
105 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
106 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
107 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
108 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
109 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
110 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
111 import static com.android.internal.protolog.ProtoLogGroup.WM_ERROR;
112 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
113 import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
114 import static com.android.server.LockGuard.INDEX_WINDOW;
115 import static com.android.server.LockGuard.installLock;
116 import static com.android.server.policy.PhoneWindowManager.TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD;
117 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
118 import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
119 import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
120 import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
121 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
122 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
123 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
124 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
125 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
126 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
127 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
128 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
129 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
130 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
131 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
132 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
133 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
134 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
135 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
136 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
137 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
138 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
139 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
140 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
141 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
142 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
143 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
144 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
145 import static com.android.server.wm.WindowManagerServiceDumpProto.BACK_NAVIGATION;
146 import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
147 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP;
148 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_DISPLAY_ID;
149 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_WINDOW;
150 import static com.android.server.wm.WindowManagerServiceDumpProto.HARD_KEYBOARD_AVAILABLE;
151 import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
152 import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY;
153 import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER;
154 import static com.android.server.wm.WindowManagerServiceDumpProto.WINDOW_FRAMES_VALID;
155 
156 import android.Manifest;
157 import android.Manifest.permission;
158 import android.animation.ValueAnimator;
159 import android.annotation.IntDef;
160 import android.annotation.IntRange;
161 import android.annotation.NonNull;
162 import android.annotation.Nullable;
163 import android.annotation.RequiresPermission;
164 import android.annotation.UserIdInt;
165 import android.app.ActivityManager;
166 import android.app.ActivityManagerInternal;
167 import android.app.ActivityThread;
168 import android.app.AppOpsManager;
169 import android.app.IActivityManager;
170 import android.app.IAssistDataReceiver;
171 import android.app.WindowConfiguration;
172 import android.content.BroadcastReceiver;
173 import android.content.ComponentName;
174 import android.content.ContentResolver;
175 import android.content.Context;
176 import android.content.Intent;
177 import android.content.IntentFilter;
178 import android.content.pm.ApplicationInfo;
179 import android.content.pm.PackageManager;
180 import android.content.pm.PackageManagerInternal;
181 import android.content.pm.TestUtilityService;
182 import android.content.res.Configuration;
183 import android.content.res.TypedArray;
184 import android.database.ContentObserver;
185 import android.graphics.Bitmap;
186 import android.graphics.Matrix;
187 import android.graphics.Point;
188 import android.graphics.Rect;
189 import android.graphics.Region;
190 import android.hardware.configstore.V1_0.OptionalBool;
191 import android.hardware.configstore.V1_1.ISurfaceFlingerConfigs;
192 import android.hardware.display.DisplayManager;
193 import android.hardware.display.DisplayManagerInternal;
194 import android.hardware.input.InputManager;
195 import android.hardware.input.InputSettings;
196 import android.net.Uri;
197 import android.os.Binder;
198 import android.os.Build;
199 import android.os.Bundle;
200 import android.os.Debug;
201 import android.os.Handler;
202 import android.os.HandlerExecutor;
203 import android.os.IBinder;
204 import android.os.IRemoteCallback;
205 import android.os.InputConfig;
206 import android.os.Looper;
207 import android.os.Message;
208 import android.os.Parcel;
209 import android.os.ParcelFileDescriptor;
210 import android.os.PowerManager;
211 import android.os.PowerManager.ServiceType;
212 import android.os.PowerManagerInternal;
213 import android.os.PowerSaveState;
214 import android.os.RemoteCallback;
215 import android.os.RemoteCallbackList;
216 import android.os.RemoteException;
217 import android.os.ResultReceiver;
218 import android.os.ServiceManager;
219 import android.os.ShellCallback;
220 import android.os.StrictMode;
221 import android.os.SystemClock;
222 import android.os.SystemProperties;
223 import android.os.SystemService;
224 import android.os.Trace;
225 import android.os.UserHandle;
226 import android.provider.DeviceConfigInterface;
227 import android.provider.Settings;
228 import android.service.vr.IVrManager;
229 import android.service.vr.IVrStateCallbacks;
230 import android.sysprop.SurfaceFlingerProperties;
231 import android.text.format.DateUtils;
232 import android.util.ArrayMap;
233 import android.util.ArraySet;
234 import android.util.DisplayMetrics;
235 import android.util.EventLog;
236 import android.util.MergedConfiguration;
237 import android.util.Pair;
238 import android.util.Slog;
239 import android.util.SparseBooleanArray;
240 import android.util.SparseIntArray;
241 import android.util.TimeUtils;
242 import android.util.TypedValue;
243 import android.util.proto.ProtoOutputStream;
244 import android.view.Choreographer;
245 import android.view.ContentRecordingSession;
246 import android.view.Display;
247 import android.view.DisplayInfo;
248 import android.view.Gravity;
249 import android.view.IAppTransitionAnimationSpecsFuture;
250 import android.view.ICrossWindowBlurEnabledListener;
251 import android.view.IDisplayChangeWindowController;
252 import android.view.IDisplayFoldListener;
253 import android.view.IDisplayWindowInsetsController;
254 import android.view.IDisplayWindowListener;
255 import android.view.IInputFilter;
256 import android.view.IOnKeyguardExitResult;
257 import android.view.IPinnedTaskListener;
258 import android.view.IRecentsAnimationRunner;
259 import android.view.IRotationWatcher;
260 import android.view.IScrollCaptureResponseListener;
261 import android.view.ISystemGestureExclusionListener;
262 import android.view.IWallpaperVisibilityListener;
263 import android.view.IWindow;
264 import android.view.IWindowId;
265 import android.view.IWindowManager;
266 import android.view.IWindowSession;
267 import android.view.IWindowSessionCallback;
268 import android.view.InputApplicationHandle;
269 import android.view.InputChannel;
270 import android.view.InputDevice;
271 import android.view.InputWindowHandle;
272 import android.view.InsetsFrameProvider;
273 import android.view.InsetsSourceControl;
274 import android.view.InsetsState;
275 import android.view.KeyEvent;
276 import android.view.MagnificationSpec;
277 import android.view.MotionEvent;
278 import android.view.PointerIcon;
279 import android.view.RemoteAnimationAdapter;
280 import android.view.ScrollCaptureResponse;
281 import android.view.Surface;
282 import android.view.SurfaceControl;
283 import android.view.SurfaceControlViewHost;
284 import android.view.SurfaceSession;
285 import android.view.TaskTransitionSpec;
286 import android.view.View;
287 import android.view.ViewDebug;
288 import android.view.WindowContentFrameStats;
289 import android.view.WindowInsets;
290 import android.view.WindowInsets.Type.InsetsType;
291 import android.view.WindowManager;
292 import android.view.WindowManager.DisplayImePolicy;
293 import android.view.WindowManager.LayoutParams;
294 import android.view.WindowManager.RemoveContentMode;
295 import android.view.WindowManagerGlobal;
296 import android.view.WindowManagerPolicyConstants.PointerEventListener;
297 import android.view.displayhash.DisplayHash;
298 import android.view.displayhash.VerifiedDisplayHash;
299 import android.view.inputmethod.ImeTracker;
300 import android.window.AddToSurfaceSyncGroupResult;
301 import android.window.ClientWindowFrames;
302 import android.window.ISurfaceSyncGroupCompletedListener;
303 import android.window.ITaskFpsCallback;
304 import android.window.ScreenCapture;
305 import android.window.TaskSnapshot;
306 import android.window.WindowContainerToken;
307 
308 import com.android.internal.R;
309 import com.android.internal.annotations.VisibleForTesting;
310 import com.android.internal.os.IResultReceiver;
311 import com.android.internal.policy.IKeyguardDismissCallback;
312 import com.android.internal.policy.IKeyguardLockedStateListener;
313 import com.android.internal.policy.IShortcutService;
314 import com.android.internal.policy.KeyInterceptionInfo;
315 import com.android.internal.protolog.ProtoLogGroup;
316 import com.android.internal.protolog.ProtoLogImpl;
317 import com.android.internal.protolog.common.ProtoLog;
318 import com.android.internal.util.DumpUtils;
319 import com.android.internal.util.FastPrintWriter;
320 import com.android.internal.util.LatencyTracker;
321 import com.android.internal.view.WindowManagerPolicyThread;
322 import com.android.server.AnimationThread;
323 import com.android.server.DisplayThread;
324 import com.android.server.FgThread;
325 import com.android.server.LocalServices;
326 import com.android.server.UiThread;
327 import com.android.server.Watchdog;
328 import com.android.server.input.InputManagerService;
329 import com.android.server.inputmethod.InputMethodManagerInternal;
330 import com.android.server.pm.UserManagerInternal;
331 import com.android.server.policy.WindowManagerPolicy;
332 import com.android.server.policy.WindowManagerPolicy.ScreenOffListener;
333 import com.android.server.power.ShutdownThread;
334 import com.android.server.utils.PriorityDump;
335 
336 import dalvik.annotation.optimization.NeverCompile;
337 
338 import java.io.BufferedWriter;
339 import java.io.DataInputStream;
340 import java.io.File;
341 import java.io.FileDescriptor;
342 import java.io.FileInputStream;
343 import java.io.FileNotFoundException;
344 import java.io.IOException;
345 import java.io.OutputStream;
346 import java.io.OutputStreamWriter;
347 import java.io.PrintWriter;
348 import java.io.StringWriter;
349 import java.lang.annotation.Retention;
350 import java.lang.annotation.RetentionPolicy;
351 import java.net.Socket;
352 import java.text.DateFormat;
353 import java.util.ArrayList;
354 import java.util.Arrays;
355 import java.util.Collections;
356 import java.util.Date;
357 import java.util.HashMap;
358 import java.util.List;
359 import java.util.Map;
360 import java.util.NoSuchElementException;
361 import java.util.Objects;
362 import java.util.Optional;
363 import java.util.concurrent.CountDownLatch;
364 import java.util.concurrent.TimeUnit;
365 import java.util.function.Function;
366 import java.util.function.Supplier;
367 
368 /** {@hide} */
369 public class WindowManagerService extends IWindowManager.Stub
370         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
371     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowManagerService" : TAG_WM;
372     private static final int TRACE_MAX_SECTION_NAME_LENGTH = 127;
373 
374     static final int LAYOUT_REPEAT_THRESHOLD = 4;
375 
376     static final boolean PROFILE_ORIENTATION = false;
377 
378     /** The maximum length we will accept for a loaded animation duration:
379      * this is 10 seconds.
380      */
381     static final int MAX_ANIMATION_DURATION = 10 * 1000;
382 
383     /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
384     static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
385 
386     /** Amount of time to allow a last ANR message to exist before freeing the memory. */
387     static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours
388 
389     // Maximum number of milliseconds to wait for input devices to be enumerated before
390     // proceding with safe mode detection.
391     private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
392 
393     private static final int SYNC_INPUT_TRANSACTIONS_TIMEOUT_MS = 5000;
394 
395     // Poll interval in milliseconds for watching boot animation finished.
396     // TODO(b/159045990) Migrate to SystemService.waitForState with dedicated thread.
397     private static final int BOOT_ANIMATION_POLL_INTERVAL = 50;
398 
399     // The name of the boot animation service in init.rc.
400     private static final String BOOT_ANIMATION_SERVICE = "bootanim";
401 
402     static final int UPDATE_FOCUS_NORMAL = 0;
403     /** Caller will assign layers */
404     static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
405     /** Caller is performing surface placement */
406     static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
407     /** Caller will performSurfacePlacement */
408     static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
409     /** Indicates we are removing the focused window when updating the focus. */
410     static final int UPDATE_FOCUS_REMOVING_FOCUS = 4;
411 
412     private static final String SYSTEM_SECURE = "ro.secure";
413     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
414 
415     private static final String DENSITY_OVERRIDE = "ro.config.density_override";
416     private static final String SIZE_OVERRIDE = "ro.config.size_override";
417 
418     private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
419 
420     static final int MY_PID = myPid();
421     static final int MY_UID = myUid();
422 
423     static final int LOGTAG_INPUT_FOCUS = 62001;
424 
425     /**
426      * Use WMShell for app transition.
427      */
428     public static final String ENABLE_SHELL_TRANSITIONS = "persist.wm.debug.shell_transit";
429 
430     /**
431      * @see #ENABLE_SHELL_TRANSITIONS
432      */
433     public static final boolean sEnableShellTransitions =
434             SystemProperties.getBoolean(ENABLE_SHELL_TRANSITIONS, true);
435 
436     /**
437      * Allows a fullscreen windowing mode activity to launch in its desired orientation directly
438      * when the display has different orientation.
439      */
440     static final boolean ENABLE_FIXED_ROTATION_TRANSFORM =
441             SystemProperties.getBoolean("persist.wm.fixed_rotation_transform", true);
442 
443     // Enums for animation scale update types.
444     @Retention(RetentionPolicy.SOURCE)
445     @IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
446     private @interface UpdateAnimationScaleMode {};
447     private static final int WINDOW_ANIMATION_SCALE = 0;
448     private static final int TRANSITION_ANIMATION_SCALE = 1;
449     private static final int ANIMATION_DURATION_SCALE = 2;
450 
451     private static final int ANIMATION_COMPLETED_TIMEOUT_MS = 5000;
452 
453     final WindowManagerConstants mConstants;
454 
455     final WindowTracing mWindowTracing;
456     final TransitionTracer mTransitionTracer;
457 
458     private final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
459 
460     final private KeyguardDisableHandler mKeyguardDisableHandler;
461 
462     private final RemoteCallbackList<IKeyguardLockedStateListener> mKeyguardLockedStateListeners =
463             new RemoteCallbackList<>();
464     private boolean mDispatchedKeyguardLockedState = false;
465 
466     // VR Vr2d Display Id.
467     int mVr2dDisplayId = INVALID_DISPLAY;
468     boolean mVrModeEnabled = false;
469 
470     /**
471      * Tracks a map of input tokens to info that is used to decide whether to intercept
472      * a key event.
473      */
474     final Map<IBinder, KeyInterceptionInfo> mKeyInterceptionInfoForToken =
475             Collections.synchronizedMap(new ArrayMap<>());
476 
477     final StartingSurfaceController mStartingSurfaceController;
478 
479     private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
480         @Override
481         public void onVrStateChanged(boolean enabled) {
482             synchronized (mGlobalLock) {
483                 mVrModeEnabled = enabled;
484                 mRoot.forAllDisplayPolicies(p -> p.onVrStateChangedLw(enabled));
485             }
486         }
487     };
488 
489     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
490         @Override
491         public void onReceive(Context context, Intent intent) {
492             switch (intent.getAction()) {
493                 case ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED:
494                     mKeyguardDisableHandler.updateKeyguardEnabled(getSendingUserId());
495                     break;
496             }
497         }
498     };
499     final WindowSurfacePlacer mWindowPlacerLocked;
500 
501     private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
502         @Override
503         public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
504                 boolean asProto) {
505             doDump(fd, pw, new String[] {"-a"}, asProto);
506         }
507 
508         @Override
509         public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
510             doDump(fd, pw, args, asProto);
511         }
512     };
513 
514     /**
515      * Current user when multi-user is enabled. Don't show windows of non-current user.
516      */
517     @UserIdInt int mCurrentUserId;
518 
519     final Context mContext;
520 
521     final boolean mHasPermanentDpad;
522     final long mDrawLockTimeoutMillis;
523     final boolean mAllowAnimationsInLowPowerMode;
524 
525     final boolean mAllowBootMessages;
526 
527     // Indicates whether the Assistant should show on top of the Dream (respectively, above
528     // everything else on screen). Otherwise, it will be put under always-on-top stacks.
529     final boolean mAssistantOnTopOfDream;
530 
531     /**
532      * If true, don't relaunch the activity upon receiving a configuration change to transition to
533      * or from the {@link UI_MODE_TYPE_DESK} uiMode, which is sent when docking. The configuration
534      * change will still be sent regardless, only the relaunch is skipped. Apps with desk resources
535      * are exempt from this and will behave like normal, since they may expect the relaunch upon the
536      * desk uiMode change.
537      */
538     @VisibleForTesting
539     boolean mSkipActivityRelaunchWhenDocking;
540 
541     final boolean mLimitedAlphaCompositing;
542     final int mMaxUiWidth;
543 
544     @VisibleForTesting
545     WindowManagerPolicy mPolicy;
546 
547     final IActivityManager mActivityManager;
548     final ActivityManagerInternal mAmInternal;
549     final UserManagerInternal mUmInternal;
550 
551     final AppOpsManager mAppOps;
552     final PackageManagerInternal mPmInternal;
553     private final TestUtilityService mTestUtilityService;
554 
555     final DisplayWindowSettingsProvider mDisplayWindowSettingsProvider;
556     final DisplayWindowSettings mDisplayWindowSettings;
557 
558     /** If the system should display notifications for apps displaying an alert window. */
559     boolean mShowAlertWindowNotifications = true;
560 
561     /**
562      * All currently active sessions with clients.
563      */
564     final ArraySet<Session> mSessions = new ArraySet<>();
565 
566     /** Mapping from an IWindow IBinder to the server's Window object. */
567     final HashMap<IBinder, WindowState> mWindowMap = new HashMap<>();
568 
569     /** Mapping from an InputWindowHandle token to the server's Window object. */
570     final HashMap<IBinder, WindowState> mInputToWindowMap = new HashMap<>();
571 
572     /** Global service lock used by the package that owns this service. */
573     final WindowManagerGlobalLock mGlobalLock;
574 
575     /**
576      * Windows that are being resized.  Used so we can tell the client about
577      * the resize after closing the transaction in which we resized the
578      * underlying surface.
579      */
580     final ArrayList<WindowState> mResizingWindows = new ArrayList<>();
581 
582     /**
583      * Mapping of displayId to {@link DisplayImePolicy}.
584      * Note that this can be accessed without holding the lock.
585      */
586     volatile Map<Integer, Integer> mDisplayImePolicyCache = Collections.unmodifiableMap(
587             new ArrayMap<>());
588 
589     /**
590      * Windows whose surface should be destroyed.
591      */
592     final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
593 
594     /**
595      * This is set when we have run out of memory, and will either be an empty
596      * list or contain windows that need to be force removed.
597      */
598     final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
599 
600     /**
601      * The callbacks to make when the windows all have been drawn for a given
602      * {@link WindowContainer}.
603      */
604     final ArrayMap<WindowContainer<?>, Message> mWaitingForDrawnCallbacks = new ArrayMap<>();
605 
606     /** List of window currently causing non-system overlay windows to be hidden. */
607     private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();
608 
609     /**
610      * In some cases (e.g. when {@link R.bool.config_reverseDefaultRotation} has value
611      * {@value true}) we need to map some orientation to others. This {@link SparseIntArray}
612      * contains the relation between the source orientation and the one to use.
613      */
614     private final SparseIntArray mOrientationMapping = new SparseIntArray();
615 
616     final AccessibilityController mAccessibilityController;
617     private RecentsAnimationController mRecentsAnimationController;
618 
619     Watermark mWatermark;
620     StrictModeFlash mStrictModeFlash;
621     EmulatorDisplayOverlay mEmulatorDisplayOverlay;
622 
623     final Rect mTmpRect = new Rect();
624 
625     boolean mDisplayReady;
626     boolean mSafeMode;
627     boolean mDisplayEnabled = false;
628     boolean mSystemBooted = false;
629     boolean mForceDisplayEnabled = false;
630     boolean mShowingBootMessages = false;
631     boolean mSystemReady = false;
632     boolean mBootAnimationStopped = false;
633     long mBootWaitForWindowsStartTime = -1;
634 
635     /** Dump of the windows and app tokens at the time of the last ANR. Cleared after
636      * LAST_ANR_LIFETIME_DURATION_MSECS */
637     String mLastANRState;
638 
639     // The root of the device window hierarchy.
640     @NonNull
641     final RootWindowContainer mRoot;
642 
643     // Whether the system should use BLAST for ViewRootImpl
644     final boolean mUseBLAST;
645     // Whether to enable BLASTSyncEngine Transaction passing.
646     static final boolean USE_BLAST_SYNC = true;
647 
648     final BLASTSyncEngine mSyncEngine;
649 
650     boolean mIsPc;
651     /**
652      * Flag that indicates that desktop mode is forced for public secondary screens.
653      *
654      * This includes several settings:
655      * - Set freeform windowing mode on external screen if it's supported and enabled.
656      * - Enable system decorations and IME on external screen.
657      * - TODO: Show mouse pointer on external screen.
658      */
659     boolean mForceDesktopModeOnExternalDisplays;
660 
661     boolean mDisableTransitionAnimation;
662 
663     final RotationWatcherController mRotationWatcherController;
664     final WallpaperVisibilityListeners mWallpaperVisibilityListeners =
665             new WallpaperVisibilityListeners();
666 
667     IDisplayChangeWindowController mDisplayChangeController = null;
668     private final DeathRecipient mDisplayChangeControllerDeath =
669             () -> mDisplayChangeController = null;
670 
671     final DisplayWindowListenerController mDisplayNotificationController;
672     final TaskSystemBarsListenerController mTaskSystemBarsListenerController;
673 
674     boolean mDisplayFrozen = false;
675     long mDisplayFreezeTime = 0;
676     int mLastDisplayFreezeDuration = 0;
677     Object mLastFinishedFreezeSource = null;
678     boolean mSwitchingUser = false;
679 
680     final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
681     final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
682     final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2;
683     int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
684 
685     /** Indicates that the system server is actively demanding the screen be frozen. */
686     boolean mClientFreezingScreen = false;
687     int mAppsFreezingScreen = 0;
688 
689     @VisibleForTesting
690     boolean mPerDisplayFocusEnabled;
691 
692     // State while inside of layoutAndPlaceSurfacesLocked().
693     boolean mFocusMayChange;
694 
695     // Number of windows whose insets state have been changed.
696     int mWindowsInsetsChanged = 0;
697 
698     // This is held as long as we have the screen frozen, to give us time to
699     // perform a rotation animation when turning off shows the lock screen which
700     // changes the orientation.
701     private final PowerManager.WakeLock mScreenFrozenLock;
702 
703     final TaskSnapshotController mTaskSnapshotController;
704     final SnapshotController mSnapshotController;
705 
706     final BlurController mBlurController;
707     final TaskFpsCallbackController mTaskFpsCallbackController;
708 
709     boolean mIsTouchDevice;
710     boolean mIsFakeTouchDevice;
711 
712     final H mH = new H();
713 
714     /**
715      * Handler for things to run that have direct impact on an animation, i.e. animation tick,
716      * layout, starting window creation, whereas {@link H} runs things that are still important, but
717      * not as critical.
718      */
719     final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper());
720 
721     /**
722      * Used during task transitions to allow SysUI and launcher to customize task transitions.
723      */
724     TaskTransitionSpec mTaskTransitionSpec;
725 
726     boolean mHardKeyboardAvailable;
727     WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
728 
729     @Nullable ImeTargetChangeListener mImeTargetChangeListener;
730 
731     SettingsObserver mSettingsObserver;
732     final EmbeddedWindowController mEmbeddedWindowController;
733     final AnrController mAnrController;
734 
735     private final DisplayHashController mDisplayHashController;
736 
737     volatile float mMaximumObscuringOpacityForTouch =
738             InputSettings.DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH;
739 
740     @VisibleForTesting
741     final WindowContextListenerController mWindowContextListenerController =
742             new WindowContextListenerController();
743 
744     private InputTarget mFocusedInputTarget;
745 
746     @VisibleForTesting
747     final ContentRecordingController mContentRecordingController = new ContentRecordingController();
748 
749     private final SurfaceSyncGroupController mSurfaceSyncGroupController =
750             new SurfaceSyncGroupController();
751 
752     @VisibleForTesting
753     final class SettingsObserver extends ContentObserver {
754         private final Uri mDisplayInversionEnabledUri =
755                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
756         private final Uri mWindowAnimationScaleUri =
757                 Settings.Global.getUriFor(Settings.Global.WINDOW_ANIMATION_SCALE);
758         private final Uri mTransitionAnimationScaleUri =
759                 Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE);
760         private final Uri mAnimationDurationScaleUri =
761                 Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE);
762         private final Uri mImmersiveModeConfirmationsUri =
763                 Settings.Secure.getUriFor(Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS);
764         private final Uri mPolicyControlUri =
765                 Settings.Global.getUriFor(Settings.Global.POLICY_CONTROL);
766         private final Uri mForceDesktopModeOnExternalDisplaysUri = Settings.Global.getUriFor(
767                         Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS);
768         private final Uri mFreeformWindowUri = Settings.Global.getUriFor(
769                 Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT);
770         private final Uri mForceResizableUri = Settings.Global.getUriFor(
771                 DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
772         private final Uri mDevEnableNonResizableMultiWindowUri = Settings.Global.getUriFor(
773                 DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW);
774         private final Uri mDisplaySettingsPathUri = Settings.Global.getUriFor(
775                 DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
776         private final Uri mMaximumObscuringOpacityForTouchUri = Settings.Global.getUriFor(
777                 Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
778 
SettingsObserver()779         public SettingsObserver() {
780             super(new Handler());
781             ContentResolver resolver = mContext.getContentResolver();
782             resolver.registerContentObserver(mDisplayInversionEnabledUri, false, this,
783                     UserHandle.USER_ALL);
784             resolver.registerContentObserver(mWindowAnimationScaleUri, false, this,
785                     UserHandle.USER_ALL);
786             resolver.registerContentObserver(mTransitionAnimationScaleUri, false, this,
787                     UserHandle.USER_ALL);
788             resolver.registerContentObserver(mAnimationDurationScaleUri, false, this,
789                     UserHandle.USER_ALL);
790             resolver.registerContentObserver(mImmersiveModeConfirmationsUri, false, this,
791                     UserHandle.USER_ALL);
792             resolver.registerContentObserver(mPolicyControlUri, false, this, UserHandle.USER_ALL);
793             resolver.registerContentObserver(mForceDesktopModeOnExternalDisplaysUri, false, this,
794                     UserHandle.USER_ALL);
795             resolver.registerContentObserver(mFreeformWindowUri, false, this, UserHandle.USER_ALL);
796             resolver.registerContentObserver(mForceResizableUri, false, this, UserHandle.USER_ALL);
797             resolver.registerContentObserver(mDevEnableNonResizableMultiWindowUri, false, this,
798                     UserHandle.USER_ALL);
799             resolver.registerContentObserver(mDisplaySettingsPathUri, false, this,
800                     UserHandle.USER_ALL);
801             resolver.registerContentObserver(mMaximumObscuringOpacityForTouchUri, false, this,
802                     UserHandle.USER_ALL);
803         }
804 
805         @Override
onChange(boolean selfChange, Uri uri)806         public void onChange(boolean selfChange, Uri uri) {
807             if (uri == null) {
808                 return;
809             }
810 
811             if (mImmersiveModeConfirmationsUri.equals(uri) || mPolicyControlUri.equals(uri)) {
812                 updateSystemUiSettings(true /* handleChange */);
813                 return;
814             }
815 
816             if (mForceDesktopModeOnExternalDisplaysUri.equals(uri)) {
817                 updateForceDesktopModeOnExternalDisplays();
818                 return;
819             }
820 
821             if (mFreeformWindowUri.equals(uri)) {
822                 updateFreeformWindowManagement();
823                 return;
824             }
825 
826             if (mForceResizableUri.equals(uri)) {
827                 updateForceResizableTasks();
828                 return;
829             }
830 
831             if (mDevEnableNonResizableMultiWindowUri.equals(uri)) {
832                 updateDevEnableNonResizableMultiWindow();
833                 return;
834             }
835 
836             if (mDisplaySettingsPathUri.equals(uri)) {
837                 updateDisplaySettingsLocation();
838                 return;
839             }
840 
841             if (mMaximumObscuringOpacityForTouchUri.equals(uri)) {
842                 updateMaximumObscuringOpacityForTouch();
843                 return;
844             }
845 
846             @UpdateAnimationScaleMode
847             final int mode;
848             if (mWindowAnimationScaleUri.equals(uri)) {
849                 mode = WINDOW_ANIMATION_SCALE;
850             } else if (mTransitionAnimationScaleUri.equals(uri)) {
851                 mode = TRANSITION_ANIMATION_SCALE;
852             } else if (mAnimationDurationScaleUri.equals(uri)) {
853                 mode = ANIMATION_DURATION_SCALE;
854             } else {
855                 // Ignoring unrecognized content changes
856                 return;
857             }
858             Message m = mH.obtainMessage(H.UPDATE_ANIMATION_SCALE, mode, 0);
859             mH.sendMessage(m);
860         }
861 
loadSettings()862         void loadSettings() {
863             updateSystemUiSettings(false /* handleChange */);
864             updateMaximumObscuringOpacityForTouch();
865         }
866 
updateMaximumObscuringOpacityForTouch()867         void updateMaximumObscuringOpacityForTouch() {
868             ContentResolver resolver = mContext.getContentResolver();
869             mMaximumObscuringOpacityForTouch = Settings.Global.getFloat(resolver,
870                     Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH,
871                     InputSettings.DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
872             if (mMaximumObscuringOpacityForTouch < 0.0f
873                     || mMaximumObscuringOpacityForTouch > 1.0f) {
874                 mMaximumObscuringOpacityForTouch =
875                         InputSettings.DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH;
876             }
877         }
878 
updateSystemUiSettings(boolean handleChange)879         void updateSystemUiSettings(boolean handleChange) {
880             synchronized (mGlobalLock) {
881                 boolean changed = false;
882                 if (handleChange) {
883                     changed = getDefaultDisplayContentLocked().getDisplayPolicy()
884                             .onSystemUiSettingsChanged();
885                 } else {
886                     ImmersiveModeConfirmation.loadSetting(mCurrentUserId, mContext);
887                 }
888                 if (changed) {
889                     mWindowPlacerLocked.requestTraversal();
890                 }
891             }
892         }
893 
updateForceDesktopModeOnExternalDisplays()894         void updateForceDesktopModeOnExternalDisplays() {
895             ContentResolver resolver = mContext.getContentResolver();
896             final boolean enableForceDesktopMode = Settings.Global.getInt(resolver,
897                     DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
898             if (mForceDesktopModeOnExternalDisplays == enableForceDesktopMode) {
899                 return;
900             }
901             setForceDesktopModeOnExternalDisplays(enableForceDesktopMode);
902         }
903 
updateFreeformWindowManagement()904         void updateFreeformWindowManagement() {
905             ContentResolver resolver = mContext.getContentResolver();
906             final boolean freeformWindowManagement = mContext.getPackageManager().hasSystemFeature(
907                     FEATURE_FREEFORM_WINDOW_MANAGEMENT) || Settings.Global.getInt(
908                     resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
909 
910             if (mAtmService.mSupportsFreeformWindowManagement != freeformWindowManagement) {
911                 mAtmService.mSupportsFreeformWindowManagement = freeformWindowManagement;
912                 synchronized (mGlobalLock) {
913                     // Notify the root window container that the display settings value may change.
914                     mRoot.onSettingsRetrieved();
915                 }
916             }
917         }
918 
updateForceResizableTasks()919         void updateForceResizableTasks() {
920             ContentResolver resolver = mContext.getContentResolver();
921             final boolean forceResizable = Settings.Global.getInt(resolver,
922                     DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
923 
924             mAtmService.mForceResizableActivities = forceResizable;
925         }
926 
updateDevEnableNonResizableMultiWindow()927         void updateDevEnableNonResizableMultiWindow() {
928             ContentResolver resolver = mContext.getContentResolver();
929             final boolean devEnableNonResizableMultiWindow = Settings.Global.getInt(resolver,
930                     DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW, 0) != 0;
931 
932             mAtmService.mDevEnableNonResizableMultiWindow = devEnableNonResizableMultiWindow;
933         }
934 
updateDisplaySettingsLocation()935         void updateDisplaySettingsLocation() {
936             final ContentResolver resolver = mContext.getContentResolver();
937             final String filePath = Settings.Global.getString(resolver,
938                     DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
939             synchronized (mGlobalLock) {
940                 mDisplayWindowSettingsProvider.setBaseSettingsFilePath(filePath);
941                 mRoot.forAllDisplays(display -> {
942                     mDisplayWindowSettings.applySettingsToDisplayLocked(display);
943                     display.reconfigureDisplayLocked();
944                 });
945             }
946         }
947     }
948 
949     PowerManager mPowerManager;
950     PowerManagerInternal mPowerManagerInternal;
951 
952     private float mWindowAnimationScaleSetting = 1.0f;
953     private float mTransitionAnimationScaleSetting = 1.0f;
954     private float mAnimatorDurationScaleSetting = 1.0f;
955     private boolean mAnimationsDisabled = false;
956     boolean mPointerLocationEnabled = false;
957 
958     final LetterboxConfiguration mLetterboxConfiguration;
959 
960     private boolean mIsIgnoreOrientationRequestDisabled;
961 
962     final InputManagerService mInputManager;
963     final DisplayManagerInternal mDisplayManagerInternal;
964     final DisplayManager mDisplayManager;
965     final ActivityTaskManagerService mAtmService;
966 
967     /** Indicates whether this device supports wide color gamut / HDR rendering */
968     private boolean mHasWideColorGamutSupport;
969     private boolean mHasHdrSupport;
970 
971     /** Whether or not a layout can cause a wake up when theater mode is enabled. */
972     boolean mAllowTheaterModeWakeFromLayout;
973 
974     final TaskPositioningController mTaskPositioningController;
975     final DragDropController mDragDropController;
976 
977     /** For frozen screen animations. */
978     private int mExitAnimId, mEnterAnimId;
979 
980     /** The display that the rotation animation is applying to. */
981     private int mFrozenDisplayId = INVALID_DISPLAY;
982 
983     /** Skip repeated ActivityRecords initialization. Note that AppWindowsToken's version of this
984      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
985     int mTransactionSequence;
986 
987     final WindowAnimator mAnimator;
988     SurfaceAnimationRunner mSurfaceAnimationRunner;
989 
990     /**
991      * Keeps track of which animations got transferred to which animators. Entries will get cleaned
992      * up when the animation finishes.
993      */
994     final ArrayMap<AnimationAdapter, SurfaceAnimator> mAnimationTransferMap = new ArrayMap<>();
995 
996     private WindowContentFrameStats mTempWindowRenderStats;
997 
998     final LatencyTracker mLatencyTracker;
999 
1000     private ViewServer mViewServer;
1001     final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
1002     boolean mWindowsChanged = false;
1003 
1004     public interface WindowChangeListener {
1005         /** Notify on windows changed */
windowsChanged()1006         void windowsChanged();
1007 
1008         /** Notify on focus changed */
focusChanged()1009         void focusChanged();
1010     }
1011 
1012     final HighRefreshRateDenylist mHighRefreshRateDenylist;
1013 
1014     // Maintainer of a collection of all possible DisplayInfo for all configurations of the
1015     // logical displays.
1016     final PossibleDisplayInfoMapper mPossibleDisplayInfoMapper;
1017 
1018     static WindowManagerThreadPriorityBooster sThreadPriorityBooster =
1019             new WindowManagerThreadPriorityBooster();
1020 
1021     Function<SurfaceSession, SurfaceControl.Builder> mSurfaceControlFactory;
1022     Supplier<SurfaceControl.Transaction> mTransactionFactory;
1023 
1024     private final SurfaceControl.Transaction mTransaction;
1025 
boostPriorityForLockedSection()1026     static void boostPriorityForLockedSection() {
1027         sThreadPriorityBooster.boost();
1028     }
1029 
resetPriorityAfterLockedSection()1030     static void resetPriorityAfterLockedSection() {
1031         sThreadPriorityBooster.reset();
1032     }
1033 
openSurfaceTransaction()1034     void openSurfaceTransaction() {
1035         try {
1036             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
1037             SurfaceControl.openTransaction();
1038         } finally {
1039             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
1040         }
1041     }
1042 
1043     /**
1044      * Closes a surface transaction.
1045      * @param where debug string indicating where the transaction originated
1046      */
closeSurfaceTransaction(String where)1047     void closeSurfaceTransaction(String where) {
1048         try {
1049             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
1050             SurfaceControl.closeTransaction();
1051             mWindowTracing.logState(where);
1052         } finally {
1053             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
1054         }
1055     }
1056 
1057     /** Listener to notify activity manager about app transitions. */
1058     final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
1059             = new WindowManagerInternal.AppTransitionListener() {
1060 
1061         @Override
1062         public void onAppTransitionCancelledLocked(boolean keyguardGoingAwayCancelled) {
1063         }
1064 
1065         @Override
1066         public void onAppTransitionFinishedLocked(IBinder token) {
1067             final ActivityRecord atoken = mRoot.getActivityRecord(token);
1068             if (atoken == null) {
1069                 return;
1070             }
1071 
1072             // While running a recents animation, this will get called early because we show the
1073             // recents animation target activity immediately when the animation starts. Defer the
1074             // mLaunchTaskBehind updates until recents animation finishes.
1075             if (atoken.mLaunchTaskBehind && !isRecentsAnimationTarget(atoken)) {
1076                 mAtmService.mTaskSupervisor.scheduleLaunchTaskBehindComplete(atoken.token);
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(atoken)) {
1083                     atoken.mEnteringAnimation = false;
1084                     if (atoken.attachedToProcess()) {
1085                         try {
1086                             atoken.app.getThread().scheduleEnterAnimationComplete(atoken.token);
1087                         } catch (RemoteException e) {
1088                         }
1089                     }
1090                 }
1091             }
1092         }
1093     };
1094 
1095     final ArrayList<AppFreezeListener> mAppFreezeListeners = new ArrayList<>();
1096 
1097     interface AppFreezeListener {
onAppFreezeTimeout()1098         void onAppFreezeTimeout();
1099     }
1100 
main(final Context context, final InputManagerService im, final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm)1101     public static WindowManagerService main(final Context context, final InputManagerService im,
1102             final boolean showBootMsgs, WindowManagerPolicy policy,
1103             ActivityTaskManagerService atm) {
1104         return main(context, im, showBootMsgs, policy, atm, new DisplayWindowSettingsProvider(),
1105                 SurfaceControl.Transaction::new, SurfaceControl.Builder::new);
1106     }
1107 
1108     /**
1109      * Creates and returns an instance of the WindowManagerService. This call allows the caller
1110      * to override factories that can be used to stub native calls during test.
1111      */
1112     @VisibleForTesting
main(final Context context, final InputManagerService im, final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory)1113     public static WindowManagerService main(final Context context, final InputManagerService im,
1114             final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,
1115             DisplayWindowSettingsProvider displayWindowSettingsProvider,
1116             Supplier<SurfaceControl.Transaction> transactionFactory,
1117             Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
1118         final WindowManagerService[] wms = new WindowManagerService[1];
1119         DisplayThread.getHandler().runWithScissors(() ->
1120                 wms[0] = new WindowManagerService(context, im, showBootMsgs, policy, atm,
1121                         displayWindowSettingsProvider, transactionFactory,
1122                         surfaceControlFactory), 0);
1123         return wms[0];
1124     }
1125 
initPolicy()1126     private void initPolicy() {
1127         UiThread.getHandler().runWithScissors(new Runnable() {
1128             @Override
1129             public void run() {
1130                 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
1131                 mPolicy.init(mContext, WindowManagerService.this);
1132             }
1133         }, 0);
1134     }
1135 
1136     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver result)1137     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
1138             String[] args, ShellCallback callback, ResultReceiver result) {
1139         new WindowManagerShellCommand(this).exec(this, in, out, err, args, callback, result);
1140     }
1141 
WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory)1142     private WindowManagerService(Context context, InputManagerService inputManager,
1143             boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,
1144             DisplayWindowSettingsProvider displayWindowSettingsProvider,
1145             Supplier<SurfaceControl.Transaction> transactionFactory,
1146             Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
1147         installLock(this, INDEX_WINDOW);
1148         mGlobalLock = atm.getGlobalLock();
1149         mAtmService = atm;
1150         mContext = context;
1151         mIsPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
1152         mAllowBootMessages = showBootMsgs;
1153         mLimitedAlphaCompositing = context.getResources().getBoolean(
1154                 com.android.internal.R.bool.config_sf_limitedAlpha);
1155         mHasPermanentDpad = context.getResources().getBoolean(
1156                 com.android.internal.R.bool.config_hasPermanentDpad);
1157         mDrawLockTimeoutMillis = context.getResources().getInteger(
1158                 com.android.internal.R.integer.config_drawLockTimeoutMillis);
1159         mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
1160                 com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
1161         mMaxUiWidth = context.getResources().getInteger(
1162                 com.android.internal.R.integer.config_maxUiWidth);
1163         mDisableTransitionAnimation = context.getResources().getBoolean(
1164                 com.android.internal.R.bool.config_disableTransitionAnimation);
1165         mPerDisplayFocusEnabled = context.getResources().getBoolean(
1166                 com.android.internal.R.bool.config_perDisplayFocusEnabled);
1167         mAssistantOnTopOfDream = context.getResources().getBoolean(
1168                 com.android.internal.R.bool.config_assistantOnTopOfDream);
1169         mSkipActivityRelaunchWhenDocking = context.getResources()
1170                 .getBoolean(R.bool.config_skipActivityRelaunchWhenDocking);
1171 
1172         mLetterboxConfiguration = new LetterboxConfiguration(
1173                 // Using SysUI context to have access to Material colors extracted from Wallpaper.
1174                 ActivityThread.currentActivityThread().getSystemUiContext());
1175 
1176         mInputManager = inputManager; // Must be before createDisplayContentLocked.
1177         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
1178         mPossibleDisplayInfoMapper = new PossibleDisplayInfoMapper(mDisplayManagerInternal);
1179 
1180         mSurfaceControlFactory = surfaceControlFactory;
1181         mTransactionFactory = transactionFactory;
1182         mTransaction = mTransactionFactory.get();
1183 
1184         mPolicy = policy;
1185         mAnimator = new WindowAnimator(this);
1186         mRoot = new RootWindowContainer(this);
1187 
1188         final ContentResolver resolver = context.getContentResolver();
1189         mUseBLAST = Settings.Global.getInt(resolver,
1190             Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR, 1) == 1;
1191 
1192         mSyncEngine = new BLASTSyncEngine(this);
1193 
1194         mWindowPlacerLocked = new WindowSurfacePlacer(this);
1195         mSnapshotController = new SnapshotController(this);
1196         mTaskSnapshotController = mSnapshotController.mTaskSnapshotController;
1197 
1198         mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
1199                 Choreographer.getInstance());
1200         mTransitionTracer = new TransitionTracer();
1201 
1202         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
1203 
1204         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
1205 
1206         mKeyguardDisableHandler = KeyguardDisableHandler.create(mContext, mPolicy, mH);
1207 
1208         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1209         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
1210 
1211         if (mPowerManagerInternal != null) {
1212             mPowerManagerInternal.registerLowPowerModeObserver(
1213                     new PowerManagerInternal.LowPowerModeListener() {
1214                 @Override
1215                 public int getServiceType() {
1216                     return ServiceType.ANIMATION;
1217                 }
1218 
1219                 @Override
1220                 public void onLowPowerModeChanged(PowerSaveState result) {
1221                     synchronized (mGlobalLock) {
1222                         final boolean enabled = result.batterySaverEnabled;
1223                         if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
1224                             mAnimationsDisabled = enabled;
1225                             dispatchNewAnimatorScaleLocked(null);
1226                         }
1227                     }
1228                 }
1229             });
1230             mAnimationsDisabled = mPowerManagerInternal
1231                     .getLowPowerState(ServiceType.ANIMATION).batterySaverEnabled;
1232         }
1233         mScreenFrozenLock = mPowerManager.newWakeLock(
1234                 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
1235         mScreenFrozenLock.setReferenceCounted(false);
1236 
1237         mRotationWatcherController = new RotationWatcherController(this);
1238         mDisplayNotificationController = new DisplayWindowListenerController(this);
1239         mTaskSystemBarsListenerController = new TaskSystemBarsListenerController();
1240 
1241         mActivityManager = ActivityManager.getService();
1242         mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
1243         mUmInternal = LocalServices.getService(UserManagerInternal.class);
1244         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
1245         AppOpsManager.OnOpChangedInternalListener opListener =
1246                 new AppOpsManager.OnOpChangedInternalListener() {
1247                     @Override public void onOpChanged(int op, String packageName) {
1248                         updateAppOpsState();
1249                     }
1250                 };
1251         mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);
1252         mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);
1253 
1254         mPmInternal = LocalServices.getService(PackageManagerInternal.class);
1255         mTestUtilityService = LocalServices.getService(TestUtilityService.class);
1256         final IntentFilter suspendPackagesFilter = new IntentFilter();
1257         suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
1258         suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
1259         context.registerReceiverAsUser(new BroadcastReceiver() {
1260             @Override
1261             public void onReceive(Context context, Intent intent) {
1262                 final String[] affectedPackages =
1263                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1264                 final boolean suspended =
1265                         Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
1266                 updateHiddenWhileSuspendedState(new ArraySet<>(Arrays.asList(affectedPackages)),
1267                         suspended);
1268             }
1269         }, UserHandle.ALL, suspendPackagesFilter, null, null);
1270 
1271         // Get persisted window scale setting
1272         mWindowAnimationScaleSetting = getWindowAnimationScaleSetting();
1273         mTransitionAnimationScaleSetting = getTransitionAnimationScaleSetting();
1274 
1275         setAnimatorDurationScale(getAnimatorDurationScaleSetting());
1276 
1277         mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
1278                 DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
1279 
1280         final String displaySettingsPath = Settings.Global.getString(resolver,
1281                 DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
1282         mDisplayWindowSettingsProvider = displayWindowSettingsProvider;
1283         if (displaySettingsPath != null) {
1284             mDisplayWindowSettingsProvider.setBaseSettingsFilePath(displaySettingsPath);
1285         }
1286         mDisplayWindowSettings = new DisplayWindowSettings(this, mDisplayWindowSettingsProvider);
1287 
1288         IntentFilter filter = new IntentFilter();
1289         // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
1290         filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1291         mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
1292 
1293         mLatencyTracker = LatencyTracker.getInstance(context);
1294 
1295         mSettingsObserver = new SettingsObserver();
1296 
1297         mSurfaceAnimationRunner = new SurfaceAnimationRunner(mTransactionFactory,
1298                 mPowerManagerInternal);
1299 
1300         mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
1301                 com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
1302 
1303         mTaskPositioningController = new TaskPositioningController(this);
1304         mDragDropController = new DragDropController(this, mH.getLooper());
1305 
1306         mHighRefreshRateDenylist = HighRefreshRateDenylist.create(context.getResources());
1307 
1308         mConstants = new WindowManagerConstants(this, DeviceConfigInterface.REAL);
1309         mConstants.start(new HandlerExecutor(mH));
1310 
1311         LocalServices.addService(WindowManagerInternal.class, new LocalService());
1312         LocalServices.addService(
1313                 ImeTargetVisibilityPolicy.class, new ImeTargetVisibilityPolicyImpl());
1314         mEmbeddedWindowController = new EmbeddedWindowController(mAtmService);
1315 
1316         mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(
1317                 mContext.getResources());
1318 
1319         mDisplayHashController = new DisplayHashController(mContext);
1320         setGlobalShadowSettings();
1321         mAnrController = new AnrController(this);
1322         mStartingSurfaceController = new StartingSurfaceController(this);
1323 
1324         mBlurController = new BlurController(mContext, mPowerManager);
1325         mTaskFpsCallbackController = new TaskFpsCallbackController(mContext);
1326         mAccessibilityController = new AccessibilityController(this);
1327     }
1328 
getDisplayAreaPolicyProvider()1329     DisplayAreaPolicy.Provider getDisplayAreaPolicyProvider() {
1330         return mDisplayAreaPolicyProvider;
1331     }
1332 
setGlobalShadowSettings()1333     private void setGlobalShadowSettings() {
1334         final TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
1335         float lightY = a.getDimension(R.styleable.Lighting_lightY, 0);
1336         float lightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
1337         float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
1338         float ambientShadowAlpha = a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0);
1339         float spotShadowAlpha = a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0);
1340         a.recycle();
1341         float[] ambientColor = {0.f, 0.f, 0.f, ambientShadowAlpha};
1342         float[] spotColor = {0.f, 0.f, 0.f, spotShadowAlpha};
1343         SurfaceControl.setGlobalShadowSettings(ambientColor, spotColor, lightY, lightZ,
1344                 lightRadius);
1345     }
1346 
getTransitionAnimationScaleSetting()1347     private float getTransitionAnimationScaleSetting() {
1348         return fixScale(Settings.Global.getFloat(mContext.getContentResolver(),
1349                 Settings.Global.TRANSITION_ANIMATION_SCALE, mContext.getResources().getFloat(
1350                                 R.dimen.config_appTransitionAnimationDurationScaleDefault)));
1351     }
1352 
getAnimatorDurationScaleSetting()1353     private float getAnimatorDurationScaleSetting() {
1354         return fixScale(Settings.Global.getFloat(mContext.getContentResolver(),
1355                 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
1356     }
1357 
getWindowAnimationScaleSetting()1358     private float getWindowAnimationScaleSetting() {
1359         return fixScale(Settings.Global.getFloat(mContext.getContentResolver(),
1360                 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting));
1361     }
1362 
1363     /**
1364      * Called after all entities (such as the {@link ActivityManagerService}) have been set up and
1365      * associated with the {@link WindowManagerService}.
1366      */
onInitReady()1367     public void onInitReady() {
1368         initPolicy();
1369 
1370         // Add ourself to the Watchdog monitors.
1371         Watchdog.getInstance().addMonitor(this);
1372         createWatermark();
1373         showEmulatorDisplayOverlayIfNeeded();
1374     }
1375 
getInputManagerCallback()1376     public InputManagerCallback getInputManagerCallback() {
1377         return mInputManagerCallback;
1378     }
1379 
1380     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)1381     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1382             throws RemoteException {
1383         try {
1384             return super.onTransact(code, data, reply, flags);
1385         } catch (RuntimeException e) {
1386             // The window manager only throws security exceptions, so let's
1387             // log all others.
1388             if (!(e instanceof SecurityException)) {
1389                 ProtoLog.wtf(WM_ERROR, "Window Manager Crash %s", e);
1390             }
1391             throw e;
1392         }
1393     }
1394 
excludeWindowTypeFromTapOutTask(int windowType)1395     static boolean excludeWindowTypeFromTapOutTask(int windowType) {
1396         switch (windowType) {
1397             case TYPE_STATUS_BAR:
1398             case TYPE_NOTIFICATION_SHADE:
1399             case TYPE_NAVIGATION_BAR:
1400             case TYPE_INPUT_METHOD_DIALOG:
1401             case TYPE_VOLUME_OVERLAY:
1402                 return true;
1403         }
1404         return false;
1405     }
1406 
addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility, int displayId, int requestUserId, @InsetsType int requestedVisibleTypes, InputChannel outInputChannel, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame, float[] outSizeCompatScale)1407     public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
1408             int displayId, int requestUserId, @InsetsType int requestedVisibleTypes,
1409             InputChannel outInputChannel, InsetsState outInsetsState,
1410             InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame,
1411             float[] outSizeCompatScale) {
1412         outActiveControls.set(null);
1413         int[] appOp = new int[1];
1414         final boolean isRoundedCornerOverlay = (attrs.privateFlags
1415                 & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
1416         int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName,
1417                 appOp);
1418         if (res != ADD_OKAY) {
1419             return res;
1420         }
1421 
1422         WindowState parentWindow = null;
1423         final int callingUid = Binder.getCallingUid();
1424         final int callingPid = Binder.getCallingPid();
1425         final long origId = Binder.clearCallingIdentity();
1426         final int type = attrs.type;
1427 
1428         synchronized (mGlobalLock) {
1429             if (!mDisplayReady) {
1430                 throw new IllegalStateException("Display has not been initialialized");
1431             }
1432 
1433             final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);
1434 
1435             if (displayContent == null) {
1436                 ProtoLog.w(WM_ERROR, "Attempted to add window to a display that does "
1437                         + "not exist: %d. Aborting.", displayId);
1438                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
1439             }
1440             if (!displayContent.hasAccess(session.mUid)) {
1441                 ProtoLog.w(WM_ERROR,
1442                         "Attempted to add window to a display for which the application "
1443                                 + "does not have access: %d.  Aborting.",
1444                         displayContent.getDisplayId());
1445                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
1446             }
1447 
1448             if (mWindowMap.containsKey(client.asBinder())) {
1449                 ProtoLog.w(WM_ERROR, "Window %s is already added", client);
1450                 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
1451             }
1452 
1453             if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
1454                 parentWindow = windowForClientLocked(null, attrs.token, false);
1455                 if (parentWindow == null) {
1456                     ProtoLog.w(WM_ERROR, "Attempted to add window with token that is not a window: "
1457                             + "%s.  Aborting.", attrs.token);
1458                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
1459                 }
1460                 if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
1461                         && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
1462                     ProtoLog.w(WM_ERROR, "Attempted to add window with token that is a sub-window: "
1463                             + "%s.  Aborting.", attrs.token);
1464                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
1465                 }
1466             }
1467 
1468             if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
1469                 ProtoLog.w(WM_ERROR,
1470                         "Attempted to add private presentation window to a non-private display.  "
1471                                 + "Aborting.");
1472                 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
1473             }
1474 
1475             if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) {
1476                 ProtoLog.w(WM_ERROR,
1477                         "Attempted to add presentation window to a non-suitable display.  "
1478                                 + "Aborting.");
1479                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
1480             }
1481 
1482             int userId = UserHandle.getUserId(session.mUid);
1483             if (requestUserId != userId) {
1484                 try {
1485                     mAmInternal.handleIncomingUser(callingPid, callingUid, requestUserId,
1486                             false /*allowAll*/, ALLOW_NON_FULL, null, null);
1487                 } catch (Exception exp) {
1488                     ProtoLog.w(WM_ERROR, "Trying to add window with invalid user=%d",
1489                             requestUserId);
1490                     return WindowManagerGlobal.ADD_INVALID_USER;
1491                 }
1492                 // It's fine to use this userId
1493                 userId = requestUserId;
1494             }
1495 
1496             ActivityRecord activity = null;
1497             final boolean hasParent = parentWindow != null;
1498             // Use existing parent window token for child windows since they go in the same token
1499             // as there parent window so we can apply the same policy on them.
1500             WindowToken token = displayContent.getWindowToken(
1501                     hasParent ? parentWindow.mAttrs.token : attrs.token);
1502             // If this is a child window, we want to apply the same type checking rules as the
1503             // parent window type.
1504             final int rootType = hasParent ? parentWindow.mAttrs.type : type;
1505 
1506             boolean addToastWindowRequiresToken = false;
1507 
1508             final IBinder windowContextToken = attrs.mWindowContextToken;
1509 
1510             if (token == null) {
1511                 if (!unprivilegedAppCanCreateTokenWith(parentWindow, callingUid, type,
1512                         rootType, attrs.token, attrs.packageName)) {
1513                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1514                 }
1515                 if (hasParent) {
1516                     // Use existing parent window token for child windows.
1517                     token = parentWindow.mToken;
1518                 } else if (mWindowContextListenerController.hasListener(windowContextToken)) {
1519                     // Respect the window context token if the user provided it.
1520                     final IBinder binder = attrs.token != null ? attrs.token : windowContextToken;
1521                     final Bundle options = mWindowContextListenerController
1522                             .getOptions(windowContextToken);
1523                     token = new WindowToken.Builder(this, binder, type)
1524                             .setDisplayContent(displayContent)
1525                             .setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow)
1526                             .setRoundedCornerOverlay(isRoundedCornerOverlay)
1527                             .setFromClientToken(true)
1528                             .setOptions(options)
1529                             .build();
1530                 } else {
1531                     final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();
1532                     token = new WindowToken.Builder(this, binder, type)
1533                             .setDisplayContent(displayContent)
1534                             .setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow)
1535                             .setRoundedCornerOverlay(isRoundedCornerOverlay)
1536                             .build();
1537                 }
1538             } else if (rootType >= FIRST_APPLICATION_WINDOW
1539                     && rootType <= LAST_APPLICATION_WINDOW) {
1540                 activity = token.asActivityRecord();
1541                 if (activity == null) {
1542                     ProtoLog.w(WM_ERROR, "Attempted to add window with non-application token "
1543                             + ".%s Aborting.", token);
1544                     return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
1545                 } else if (activity.getParent() == null) {
1546                     ProtoLog.w(WM_ERROR, "Attempted to add window with exiting application token "
1547                             + ".%s Aborting.", token);
1548                     return WindowManagerGlobal.ADD_APP_EXITING;
1549                 } else if (type == TYPE_APPLICATION_STARTING) {
1550                     if (activity.mStartingWindow != null) {
1551                         ProtoLog.w(WM_ERROR, "Attempted to add starting window to "
1552                                 + "token with already existing starting window");
1553                         return WindowManagerGlobal.ADD_DUPLICATE_ADD;
1554                     }
1555                     if (activity.mStartingData == null) {
1556                         ProtoLog.w(WM_ERROR, "Attempted to add starting window to "
1557                                 + "token but already cleaned");
1558                         return WindowManagerGlobal.ADD_DUPLICATE_ADD;
1559                     }
1560                 }
1561             } else if (rootType == TYPE_INPUT_METHOD) {
1562                 if (token.windowType != TYPE_INPUT_METHOD) {
1563                     ProtoLog.w(WM_ERROR, "Attempted to add input method window with bad token "
1564                             + "%s.  Aborting.", attrs.token);
1565                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1566                 }
1567             } else if (rootType == TYPE_VOICE_INTERACTION) {
1568                 if (token.windowType != TYPE_VOICE_INTERACTION) {
1569                     ProtoLog.w(WM_ERROR, "Attempted to add voice interaction window with bad token "
1570                             + "%s.  Aborting.", attrs.token);
1571                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1572                 }
1573             } else if (rootType == TYPE_WALLPAPER) {
1574                 if (token.windowType != TYPE_WALLPAPER) {
1575                     ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with bad token "
1576                             + "%s.  Aborting.", attrs.token);
1577                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1578                 }
1579             } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
1580                 if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
1581                     ProtoLog.w(WM_ERROR,
1582                             "Attempted to add Accessibility overlay window with bad token "
1583                                     + "%s.  Aborting.", attrs.token);
1584                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1585                 }
1586             } else if (type == TYPE_TOAST) {
1587                 // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
1588                 addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName,
1589                         callingUid, parentWindow);
1590                 if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) {
1591                     ProtoLog.w(WM_ERROR, "Attempted to add a toast window with bad token "
1592                             + "%s.  Aborting.", attrs.token);
1593                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1594                 }
1595             } else if (type == TYPE_QS_DIALOG) {
1596                 if (token.windowType != TYPE_QS_DIALOG) {
1597                     ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with bad token "
1598                             + "%s.  Aborting.", attrs.token);
1599                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
1600                 }
1601             } else if (token.asActivityRecord() != null) {
1602                 ProtoLog.w(WM_ERROR, "Non-null activity for system window of rootType=%d",
1603                         rootType);
1604                 // It is not valid to use an app token with other system types; we will
1605                 // instead make a new token for it (as if null had been passed in for the token).
1606                 attrs.token = null;
1607                 token = new WindowToken.Builder(this, client.asBinder(), type)
1608                         .setDisplayContent(displayContent)
1609                         .setOwnerCanManageAppTokens(session.mCanAddInternalSystemWindow)
1610                         .build();
1611             }
1612 
1613             final WindowState win = new WindowState(this, session, client, token, parentWindow,
1614                     appOp[0], attrs, viewVisibility, session.mUid, userId,
1615                     session.mCanAddInternalSystemWindow);
1616             if (win.mDeathRecipient == null) {
1617                 // Client has apparently died, so there is no reason to
1618                 // continue.
1619                 ProtoLog.w(WM_ERROR, "Adding window client %s"
1620                         + " that is dead, aborting.", client.asBinder());
1621                 return WindowManagerGlobal.ADD_APP_EXITING;
1622             }
1623 
1624             if (win.getDisplayContent() == null) {
1625                 ProtoLog.w(WM_ERROR, "Adding window to Display that has been removed.");
1626                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
1627             }
1628 
1629             final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
1630             displayPolicy.adjustWindowParamsLw(win, win.mAttrs);
1631             attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), callingUid, callingPid);
1632             attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), callingUid,
1633                     callingPid);
1634             win.setRequestedVisibleTypes(requestedVisibleTypes);
1635 
1636             res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);
1637             if (res != ADD_OKAY) {
1638                 return res;
1639             }
1640 
1641             final boolean openInputChannels = (outInputChannel != null
1642                     && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
1643             if  (openInputChannels) {
1644                 win.openInputChannel(outInputChannel);
1645             }
1646 
1647             // If adding a toast requires a token for this app we always schedule hiding
1648             // toast windows to make sure they don't stick around longer then necessary.
1649             // We hide instead of remove such windows as apps aren't prepared to handle
1650             // windows being removed under them.
1651             //
1652             // If the app is older it can add toasts without a token and hence overlay
1653             // other apps. To be maximally compatible with these apps we will hide the
1654             // window after the toast timeout only if the focused window is from another
1655             // UID, otherwise we allow unlimited duration. When a UID looses focus we
1656             // schedule hiding all of its toast windows.
1657             if (type == TYPE_TOAST) {
1658                 if (!displayContent.canAddToastWindowForUid(callingUid)) {
1659                     ProtoLog.w(WM_ERROR, "Adding more than one toast window for UID at a time.");
1660                     return WindowManagerGlobal.ADD_DUPLICATE_ADD;
1661                 }
1662                 // Make sure this happens before we moved focus as one can make the
1663                 // toast focusable to force it not being hidden after the timeout.
1664                 // Focusable toasts are always timed out to prevent a focused app to
1665                 // show a focusable toasts while it has focus which will be kept on
1666                 // the screen after the activity goes away.
1667                 if (addToastWindowRequiresToken
1668                         || (attrs.flags & FLAG_NOT_FOCUSABLE) == 0
1669                         || displayContent.mCurrentFocus == null
1670                         || displayContent.mCurrentFocus.mOwnerUid != callingUid) {
1671                     mH.sendMessageDelayed(
1672                             mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win),
1673                             win.mAttrs.hideTimeoutMilliseconds);
1674                 }
1675             }
1676 
1677             // Switch to listen to the {@link WindowToken token}'s configuration changes when
1678             // adding a window to the window context. Filter sub window type here because the sub
1679             // window must be attached to the parent window, which is attached to the window context
1680             // created window token.
1681             if (!win.isChildWindow()
1682                     && mWindowContextListenerController.hasListener(windowContextToken)) {
1683                 final int windowContextType = mWindowContextListenerController
1684                         .getWindowType(windowContextToken);
1685                 final Bundle options = mWindowContextListenerController
1686                         .getOptions(windowContextToken);
1687                 if (type != windowContextType) {
1688                     ProtoLog.w(WM_ERROR, "Window types in WindowContext and"
1689                             + " LayoutParams.type should match! Type from LayoutParams is %d,"
1690                             + " but type from WindowContext is %d", type, windowContextType);
1691                     // We allow WindowProviderService to add window other than windowContextType,
1692                     // but the WindowProviderService won't be associated with the window's
1693                     // WindowToken.
1694                     if (!isWindowProviderService(options)) {
1695                         return WindowManagerGlobal.ADD_INVALID_TYPE;
1696                     }
1697                 } else {
1698                     mWindowContextListenerController.registerWindowContainerListener(
1699                             windowContextToken, token, callingUid, type, options);
1700                 }
1701             }
1702 
1703             // From now on, no exceptions or errors allowed!
1704 
1705             res = ADD_OKAY;
1706 
1707             if (mUseBLAST) {
1708                 res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST;
1709             }
1710 
1711             if (displayContent.mCurrentFocus == null) {
1712                 displayContent.mWinAddedSinceNullFocus.add(win);
1713             }
1714 
1715             if (excludeWindowTypeFromTapOutTask(type)) {
1716                 displayContent.mTapExcludedWindows.add(win);
1717             }
1718 
1719             win.attach();
1720             mWindowMap.put(client.asBinder(), win);
1721             win.initAppOpsState();
1722 
1723             final boolean suspended = mPmInternal.isPackageSuspended(win.getOwningPackage(),
1724                     UserHandle.getUserId(win.getOwningUid()));
1725             win.setHiddenWhileSuspended(suspended);
1726 
1727             final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
1728             win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
1729 
1730             boolean imMayMove = true;
1731 
1732             win.mToken.addWindow(win);
1733             displayPolicy.addWindowLw(win, attrs);
1734             displayPolicy.setDropInputModePolicy(win, win.mAttrs);
1735             if (type == TYPE_APPLICATION_STARTING && activity != null) {
1736                 activity.attachStartingWindow(win);
1737                 ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s",
1738                         activity, win);
1739             } else if (type == TYPE_INPUT_METHOD
1740                     // IME window is always touchable.
1741                     // Ignore non-touchable windows e.g. Stylus InkWindow.java.
1742                     && (win.getAttrs().flags & FLAG_NOT_TOUCHABLE) == 0) {
1743                 displayContent.setInputMethodWindowLocked(win);
1744                 imMayMove = false;
1745             } else if (type == TYPE_INPUT_METHOD_DIALOG) {
1746                 displayContent.computeImeTarget(true /* updateImeTarget */);
1747                 imMayMove = false;
1748             } else {
1749                 if (type == TYPE_WALLPAPER) {
1750                     displayContent.mWallpaperController.clearLastWallpaperTimeoutTime();
1751                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1752                 } else if (win.hasWallpaper()) {
1753                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1754                 } else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) {
1755                     // If there is currently a wallpaper being shown, and
1756                     // the base layer of the new window is below the current
1757                     // layer of the target window, then adjust the wallpaper.
1758                     // This is to avoid a new window being placed between the
1759                     // wallpaper and its target.
1760                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1761                 }
1762             }
1763 
1764             final WindowStateAnimator winAnimator = win.mWinAnimator;
1765             winAnimator.mEnterAnimationPending = true;
1766             winAnimator.mEnteringAnimation = true;
1767 
1768             if (displayPolicy.areSystemBarsForcedConsumedLw()) {
1769                 res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS;
1770             }
1771             if (displayContent.isInTouchMode()) {
1772                 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
1773             }
1774             if (win.mActivityRecord == null || win.mActivityRecord.isClientVisible()) {
1775                 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
1776             }
1777 
1778             displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();
1779 
1780             boolean focusChanged = false;
1781             if (win.canReceiveKeys()) {
1782                 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
1783                         false /*updateInputWindows*/);
1784                 if (focusChanged) {
1785                     imMayMove = false;
1786                 }
1787             }
1788 
1789             if (imMayMove) {
1790                 displayContent.computeImeTarget(true /* updateImeTarget */);
1791                 if (win.isImeOverlayLayeringTarget()) {
1792                     dispatchImeTargetOverlayVisibilityChanged(client.asBinder(), win.mAttrs.type,
1793                             win.isVisibleRequestedOrAdding(), false /* removed */);
1794                 }
1795             }
1796 
1797             // Don't do layout here, the window must call
1798             // relayout to be displayed, so we'll do it there.
1799             win.getParent().assignChildLayers();
1800 
1801             if (focusChanged) {
1802                 displayContent.getInputMonitor().setInputFocusLw(displayContent.mCurrentFocus,
1803                         false /*updateInputWindows*/);
1804             }
1805             displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/);
1806 
1807             ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addWindow: New client %s"
1808                     + ": window=%s Callers=%s", client.asBinder(), win, Debug.getCallers(5));
1809 
1810             boolean needToSendNewConfiguration =
1811                     win.isVisibleRequestedOrAdding() && displayContent.updateOrientation();
1812             if (win.providesDisplayDecorInsets()) {
1813                 needToSendNewConfiguration |= displayPolicy.updateDecorInsetsInfo();
1814             }
1815             if (needToSendNewConfiguration) {
1816                 displayContent.sendNewConfiguration();
1817             }
1818 
1819             // This window doesn't have a frame yet. Don't let this window cause the insets change.
1820             displayContent.getInsetsStateController().updateAboveInsetsState(
1821                     false /* notifyInsetsChanged */);
1822 
1823             outInsetsState.set(win.getCompatInsetsState(), true /* copySources */);
1824             getInsetsSourceControls(win, outActiveControls);
1825 
1826             if (win.mLayoutAttached) {
1827                 outAttachedFrame.set(win.getParentWindow().getFrame());
1828                 if (win.mInvGlobalScale != 1f) {
1829                     outAttachedFrame.scale(win.mInvGlobalScale);
1830                 }
1831             } else {
1832                 // Make this invalid which indicates a null attached frame.
1833                 outAttachedFrame.set(0, 0, -1, -1);
1834             }
1835             outSizeCompatScale[0] = win.getCompatScaleForClient();
1836         }
1837 
1838         Binder.restoreCallingIdentity(origId);
1839 
1840         return res;
1841     }
1842 
unprivilegedAppCanCreateTokenWith(WindowState parentWindow, int callingUid, int type, int rootType, IBinder tokenForLog, String packageName)1843     private boolean unprivilegedAppCanCreateTokenWith(WindowState parentWindow,
1844             int callingUid, int type, int rootType, IBinder tokenForLog, String packageName) {
1845         if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
1846             ProtoLog.w(WM_ERROR, "Attempted to add application window with unknown token "
1847                     + "%s.  Aborting.", tokenForLog);
1848             return false;
1849         }
1850         if (rootType == TYPE_INPUT_METHOD) {
1851             ProtoLog.w(WM_ERROR, "Attempted to add input method window with unknown token "
1852                     + "%s.  Aborting.", tokenForLog);
1853             return false;
1854         }
1855         if (rootType == TYPE_VOICE_INTERACTION) {
1856             ProtoLog.w(WM_ERROR,
1857                     "Attempted to add voice interaction window with unknown token "
1858                             + "%s.  Aborting.", tokenForLog);
1859             return false;
1860         }
1861         if (rootType == TYPE_WALLPAPER) {
1862             ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with unknown token "
1863                     + "%s.  Aborting.", tokenForLog);
1864             return false;
1865         }
1866         if (rootType == TYPE_QS_DIALOG) {
1867             ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with unknown token "
1868                     + "%s.  Aborting.", tokenForLog);
1869             return false;
1870         }
1871         if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
1872             ProtoLog.w(WM_ERROR,
1873                     "Attempted to add Accessibility overlay window with unknown token "
1874                             + "%s.  Aborting.", tokenForLog);
1875             return false;
1876         }
1877         if (type == TYPE_TOAST) {
1878             // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
1879             if (doesAddToastWindowRequireToken(packageName, callingUid, parentWindow)) {
1880                 ProtoLog.w(WM_ERROR, "Attempted to add a toast window with unknown token "
1881                         + "%s.  Aborting.", tokenForLog);
1882                 return false;
1883             }
1884         }
1885         return true;
1886     }
1887 
1888     /**
1889      * Get existing {@link DisplayContent} or create a new one if the display is registered in
1890      * DisplayManager.
1891      *
1892      * NOTE: This should only be used in cases when there is a chance that a {@link DisplayContent}
1893      * that corresponds to a display just added to DisplayManager has not yet been created. This
1894      * usually means that the call of this method was initiated from outside of Activity or Window
1895      * Manager. In most cases the regular getter should be used.
1896      * @param displayId The preferred display Id.
1897      * @param token The window token associated with the window we are trying to get display for.
1898      *              if not null then the display of the window token will be returned. Set to null
1899      *              is there isn't an a token associated with the request.
1900      * @see RootWindowContainer#getDisplayContent(int)
1901      */
getDisplayContentOrCreate(int displayId, IBinder token)1902     private DisplayContent getDisplayContentOrCreate(int displayId, IBinder token) {
1903         if (token != null) {
1904             final WindowToken wToken = mRoot.getWindowToken(token);
1905             if (wToken != null) {
1906                 return wToken.getDisplayContent();
1907             }
1908         }
1909 
1910         return mRoot.getDisplayContentOrCreate(displayId);
1911     }
1912 
doesAddToastWindowRequireToken(String packageName, int callingUid, WindowState attachedWindow)1913     private boolean doesAddToastWindowRequireToken(String packageName, int callingUid,
1914             WindowState attachedWindow) {
1915         // Try using the target SDK of the root window
1916         if (attachedWindow != null) {
1917             return attachedWindow.mActivityRecord != null
1918                     && attachedWindow.mActivityRecord.mTargetSdk >= Build.VERSION_CODES.O;
1919         } else {
1920             // Otherwise, look at the package
1921             final ApplicationInfo appInfo = mPmInternal.getApplicationInfo(
1922                     packageName, 0 /* flags */, SYSTEM_UID, UserHandle.getUserId(callingUid));
1923             if (appInfo == null || appInfo.uid != callingUid) {
1924                 throw new SecurityException("Package " + packageName + " not in UID "
1925                         + callingUid);
1926             }
1927             return appInfo.targetSdkVersion >= Build.VERSION_CODES.O;
1928         }
1929     }
1930 
1931     /**
1932      * Set whether screen capture is disabled for all windows of a specific user from
1933      * the device policy cache.
1934      */
1935     @Override
refreshScreenCaptureDisabled()1936     public void refreshScreenCaptureDisabled() {
1937         int callingUid = Binder.getCallingUid();
1938         if (callingUid != SYSTEM_UID) {
1939             throw new SecurityException("Only system can call refreshScreenCaptureDisabled.");
1940         }
1941 
1942         synchronized (mGlobalLock) {
1943             // Refresh secure surface for all windows.
1944             mRoot.refreshSecureSurfaceState();
1945         }
1946     }
1947 
removeWindow(Session session, IWindow client)1948     void removeWindow(Session session, IWindow client) {
1949         synchronized (mGlobalLock) {
1950             WindowState win = windowForClientLocked(session, client, false);
1951             if (win != null) {
1952                 win.removeIfPossible();
1953                 return;
1954             }
1955 
1956             // Remove embedded window map if the token belongs to an embedded window
1957             mEmbeddedWindowController.remove(client);
1958         }
1959     }
1960 
1961     /**
1962      * Performs some centralized bookkeeping clean-up on the window that is being removed.
1963      * NOTE: Should only be called from {@link WindowState#removeImmediately()}
1964      * TODO: Maybe better handled with a method {@link WindowContainer#removeChild} if we can
1965      * figure-out a good way to have all parents of a WindowState doing the same thing without
1966      * forgetting to add the wiring when a new parent of WindowState is added.
1967      */
postWindowRemoveCleanupLocked(WindowState win)1968     void postWindowRemoveCleanupLocked(WindowState win) {
1969         ProtoLog.v(WM_DEBUG_ADD_REMOVE, "postWindowRemoveCleanupLocked: %s", win);
1970         mWindowMap.remove(win.mClient.asBinder());
1971 
1972         final DisplayContent dc = win.getDisplayContent();
1973         dc.getDisplayRotation().markForSeamlessRotation(win, false /* seamlesslyRotated */);
1974 
1975         win.resetAppOpsState();
1976 
1977         if (dc.mCurrentFocus == null) {
1978             dc.mWinRemovedSinceNullFocus.add(win);
1979         }
1980         mEmbeddedWindowController.onWindowRemoved(win);
1981         mResizingWindows.remove(win);
1982         updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */);
1983         mWindowsChanged = true;
1984         ProtoLog.v(WM_DEBUG_WINDOW_MOVEMENT, "Final remove of window: %s", win);
1985 
1986         final DisplayContent displayContent = win.getDisplayContent();
1987         if (displayContent.mInputMethodWindow == win) {
1988             displayContent.setInputMethodWindowLocked(null);
1989         }
1990 
1991         final WindowToken token = win.mToken;
1992         ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Removing %s from %s", win, token);
1993         // Window will already be removed from token before this post clean-up method is called.
1994         if (token.isEmpty() && !token.mPersistOnEmpty) {
1995             token.removeImmediately();
1996         }
1997 
1998         if (win.mActivityRecord != null) {
1999             win.mActivityRecord.postWindowRemoveStartingWindowCleanup();
2000         }
2001 
2002         if (win.mAttrs.type == TYPE_WALLPAPER) {
2003             dc.mWallpaperController.clearLastWallpaperTimeoutTime();
2004             dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2005         } else if (dc.mWallpaperController.isWallpaperTarget(win)) {
2006             dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2007         }
2008 
2009         if (dc != null && !mWindowPlacerLocked.isInLayout()) {
2010             dc.assignWindowLayers(true /* setLayoutNeeded */);
2011             mWindowPlacerLocked.performSurfacePlacement();
2012             if (win.mActivityRecord != null) {
2013                 win.mActivityRecord.updateReportedVisibilityLocked();
2014             }
2015         }
2016 
2017         dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
2018     }
2019 
updateHiddenWhileSuspendedState(ArraySet<String> packages, boolean suspended)2020     private void updateHiddenWhileSuspendedState(ArraySet<String> packages, boolean suspended) {
2021         synchronized (mGlobalLock) {
2022             mRoot.updateHiddenWhileSuspendedState(packages, suspended);
2023         }
2024     }
2025 
updateAppOpsState()2026     private void updateAppOpsState() {
2027         synchronized (mGlobalLock) {
2028             mRoot.updateAppOpsState();
2029         }
2030     }
2031 
logSurface(WindowState w, String msg, boolean withStackTrace)2032     static void logSurface(WindowState w, String msg, boolean withStackTrace) {
2033         String str = "  SURFACE " + msg + ": " + w;
2034         if (withStackTrace) {
2035             logWithStack(TAG, str);
2036         } else {
2037             Slog.i(TAG_WM, str);
2038         }
2039     }
2040 
logWithStack(String tag, String s)2041     static void logWithStack(String tag, String s) {
2042         RuntimeException e = null;
2043         if (SHOW_STACK_CRAWLS) {
2044             e = new RuntimeException();
2045             e.fillInStackTrace();
2046         }
2047         Slog.i(tag, s, e);
2048     }
2049 
clearTouchableRegion(Session session, IWindow client)2050     void clearTouchableRegion(Session session, IWindow client) {
2051         final long origId = Binder.clearCallingIdentity();
2052         try {
2053             synchronized (mGlobalLock) {
2054                 WindowState w = windowForClientLocked(session, client, false);
2055                 w.clearClientTouchableRegion();
2056             }
2057         } finally {
2058             Binder.restoreCallingIdentity(origId);
2059         }
2060     }
2061 
setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets, Rect visibleInsets, Region touchableRegion)2062     void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets,
2063             Rect visibleInsets, Region touchableRegion) {
2064         int uid = Binder.getCallingUid();
2065         final long origId = Binder.clearCallingIdentity();
2066         try {
2067             synchronized (mGlobalLock) {
2068                 WindowState w = windowForClientLocked(session, client, false);
2069                 if (DEBUG_LAYOUT) Slog.d(TAG, "setInsetsWindow " + w
2070                         + ", contentInsets=" + w.mGivenContentInsets + " -> " + contentInsets
2071                         + ", visibleInsets=" + w.mGivenVisibleInsets + " -> " + visibleInsets
2072                         + ", touchableRegion=" + w.mGivenTouchableRegion + " -> " + touchableRegion
2073                         + ", touchableInsets " + w.mTouchableInsets + " -> " + touchableInsets);
2074                 if (w != null) {
2075                     w.mGivenInsetsPending = false;
2076                     w.mGivenContentInsets.set(contentInsets);
2077                     w.mGivenVisibleInsets.set(visibleInsets);
2078                     w.mGivenTouchableRegion.set(touchableRegion);
2079                     w.mTouchableInsets = touchableInsets;
2080                     if (w.mGlobalScale != 1) {
2081                         w.mGivenContentInsets.scale(w.mGlobalScale);
2082                         w.mGivenVisibleInsets.scale(w.mGlobalScale);
2083                         w.mGivenTouchableRegion.scale(w.mGlobalScale);
2084                     }
2085                     w.setDisplayLayoutNeeded();
2086                     w.updateSourceFrame(w.getFrame());
2087                     mWindowPlacerLocked.performSurfacePlacement();
2088                     w.getDisplayContent().getInputMonitor().updateInputWindowsLw(true);
2089 
2090                     // We need to report touchable region changes to accessibility.
2091                     if (mAccessibilityController.hasCallbacks()) {
2092                         mAccessibilityController.onSomeWindowResizedOrMovedWithCallingUid(
2093                                 uid, w.getDisplayContent().getDisplayId());
2094                     }
2095                 }
2096             }
2097         } finally {
2098             Binder.restoreCallingIdentity(origId);
2099         }
2100     }
2101 
onRectangleOnScreenRequested(IBinder token, Rect rectangle)2102     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
2103         final AccessibilityController.AccessibilityControllerInternalImpl a11yControllerInternal =
2104                 AccessibilityController.getAccessibilityControllerInternal(this);
2105         synchronized (mGlobalLock) {
2106             if (a11yControllerInternal.hasWindowManagerEventDispatcher()) {
2107                 WindowState window = mWindowMap.get(token);
2108                 if (window != null) {
2109                     a11yControllerInternal.onRectangleOnScreenRequested(
2110                             window.getDisplayId(), rectangle);
2111                 }
2112             }
2113         }
2114     }
2115 
getWindowId(IBinder token)2116     public IWindowId getWindowId(IBinder token) {
2117         synchronized (mGlobalLock) {
2118             WindowState window = mWindowMap.get(token);
2119             return window != null ? window.mWindowId : null;
2120         }
2121     }
2122 
pokeDrawLock(Session session, IBinder token)2123     public void pokeDrawLock(Session session, IBinder token) {
2124         synchronized (mGlobalLock) {
2125             WindowState window = windowForClientLocked(session, token, false);
2126             if (window != null) {
2127                 window.pokeDrawLockLw(mDrawLockTimeoutMillis);
2128             }
2129         }
2130     }
2131 
hasStatusBarPermission(int pid, int uid)2132     private boolean hasStatusBarPermission(int pid, int uid) {
2133         return mContext.checkPermission(permission.STATUS_BAR, pid, uid)
2134                         == PackageManager.PERMISSION_GRANTED;
2135     }
2136 
2137     /**
2138      * Returns whether this window can proceed with drawing or needs to retry later.
2139      */
cancelDraw(Session session, IWindow client)2140     public boolean cancelDraw(Session session, IWindow client) {
2141         synchronized (mGlobalLock) {
2142             final WindowState win = windowForClientLocked(session, client, false);
2143             if (win == null) {
2144                 return false;
2145             }
2146 
2147             return win.cancelAndRedraw();
2148         }
2149     }
2150 
relayoutWindow(Session session, IWindow client, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq, int lastSyncSeqId, ClientWindowFrames outFrames, MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Bundle outSyncIdBundle)2151     public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
2152             int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
2153             int lastSyncSeqId, ClientWindowFrames outFrames,
2154             MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
2155             InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,
2156             Bundle outSyncIdBundle) {
2157         if (outActiveControls != null) {
2158             outActiveControls.set(null);
2159         }
2160         int result = 0;
2161         boolean configChanged = false;
2162         final int pid = Binder.getCallingPid();
2163         final int uid = Binder.getCallingUid();
2164         final long origId = Binder.clearCallingIdentity();
2165         synchronized (mGlobalLock) {
2166             final WindowState win = windowForClientLocked(session, client, false);
2167             if (win == null) {
2168                 return 0;
2169             }
2170             if (win.mRelayoutSeq < seq) {
2171                 win.mRelayoutSeq = seq;
2172             } else if (win.mRelayoutSeq > seq) {
2173                 return 0;
2174             }
2175 
2176             if (win.cancelAndRedraw() && win.mPrepareSyncSeqId <= lastSyncSeqId) {
2177                 // The client has reported the sync draw, but we haven't finished it yet.
2178                 // Don't let the client perform a non-sync draw at this time.
2179                 result |= RELAYOUT_RES_CANCEL_AND_REDRAW;
2180             }
2181 
2182             final DisplayContent displayContent = win.getDisplayContent();
2183             final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
2184 
2185             WindowStateAnimator winAnimator = win.mWinAnimator;
2186             if (viewVisibility != View.GONE) {
2187                 win.setRequestedSize(requestedWidth, requestedHeight);
2188             }
2189 
2190             int attrChanges = 0;
2191             int flagChanges = 0;
2192             int privateFlagChanges = 0;
2193             if (attrs != null) {
2194                 displayPolicy.adjustWindowParamsLw(win, attrs);
2195                 attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), uid, pid);
2196                 attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), uid,
2197                         pid);
2198                 int disableFlags =
2199                         (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK;
2200                 if (disableFlags != 0 && !hasStatusBarPermission(pid, uid)) {
2201                     disableFlags = 0;
2202                 }
2203                 win.mDisableFlags = disableFlags;
2204                 if (win.mAttrs.type != attrs.type) {
2205                     throw new IllegalArgumentException(
2206                             "Window type can not be changed after the window is added.");
2207                 }
2208                 if (!(win.mAttrs.providedInsets == null && attrs.providedInsets == null)) {
2209                     if (win.mAttrs.providedInsets == null || attrs.providedInsets == null
2210                             || (win.mAttrs.providedInsets.length != attrs.providedInsets.length)) {
2211                         throw new IllegalArgumentException(
2212                                 "Insets amount can not be changed after the window is added.");
2213                     } else {
2214                         final int insetsTypes = attrs.providedInsets.length;
2215                         for (int i = 0; i < insetsTypes; i++) {
2216                             if (!win.mAttrs.providedInsets[i].idEquals(attrs.providedInsets[i])) {
2217                                 throw new IllegalArgumentException(
2218                                         "Insets ID can not be changed after the window is added.");
2219                             }
2220                             final InsetsFrameProvider.InsetsSizeOverride[] overrides =
2221                                     win.mAttrs.providedInsets[i].getInsetsSizeOverrides();
2222                             final InsetsFrameProvider.InsetsSizeOverride[] newOverrides =
2223                                     attrs.providedInsets[i].getInsetsSizeOverrides();
2224                             if (!(overrides == null && newOverrides == null)) {
2225                                 if (overrides == null || newOverrides == null
2226                                         || (overrides.length != newOverrides.length)) {
2227                                     throw new IllegalArgumentException(
2228                                             "Insets override types can not be changed after the "
2229                                                     + "window is added.");
2230                                 } else {
2231                                     final int overrideTypes = overrides.length;
2232                                     for (int j = 0; j < overrideTypes; j++) {
2233                                         if (overrides[j].getWindowType()
2234                                                 != newOverrides[j].getWindowType()) {
2235                                             throw new IllegalArgumentException(
2236                                                     "Insets override types can not be changed after"
2237                                                             + " the window is added.");
2238                                         }
2239                                     }
2240                                 }
2241                             }
2242                         }
2243                     }
2244                 }
2245 
2246                 flagChanges = win.mAttrs.flags ^ attrs.flags;
2247                 privateFlagChanges = win.mAttrs.privateFlags ^ attrs.privateFlags;
2248                 attrChanges = win.mAttrs.copyFrom(attrs);
2249                 final boolean layoutChanged =
2250                         (attrChanges & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0;
2251                 if (layoutChanged || (attrChanges
2252                         & WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) {
2253                     win.mLayoutNeeded = true;
2254                 }
2255                 if (layoutChanged && win.providesDisplayDecorInsets()) {
2256                     configChanged = displayPolicy.updateDecorInsetsInfo();
2257                 }
2258                 if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
2259                         || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
2260                     win.mActivityRecord.checkKeyguardFlagsChanged();
2261                 }
2262 
2263                 if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
2264                     updateNonSystemOverlayWindowsVisibilityIfNeeded(
2265                             win, win.mWinAnimator.getShown());
2266                 }
2267                 if ((attrChanges & (WindowManager.LayoutParams.PRIVATE_FLAGS_CHANGED)) != 0) {
2268                     winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags
2269                             & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
2270                 }
2271                 // See if the DisplayWindowPolicyController wants to keep the activity on the window
2272                 if (displayContent.mDwpcHelper.hasController()
2273                         && win.mActivityRecord != null && (!win.mRelayoutCalled || flagChanges != 0
2274                         || privateFlagChanges != 0)) {
2275                     int newOrChangedFlags = !win.mRelayoutCalled ? win.mAttrs.flags : flagChanges;
2276                     int newOrChangedPrivateFlags =
2277                             !win.mRelayoutCalled ? win.mAttrs.privateFlags : privateFlagChanges;
2278 
2279                     if (!displayContent.mDwpcHelper.keepActivityOnWindowFlagsChanged(
2280                             win.mActivityRecord.info, newOrChangedFlags, newOrChangedPrivateFlags,
2281                             win.mAttrs.flags,
2282                             win.mAttrs.privateFlags)) {
2283                         mH.sendMessage(mH.obtainMessage(H.REPARENT_TASK_TO_DEFAULT_DISPLAY,
2284                                 win.mActivityRecord.getTask()));
2285                         Slog.w(TAG_WM, "Activity " + win.mActivityRecord + " window flag changed,"
2286                                 + " can't remain on display " + displayContent.getDisplayId());
2287                         return 0;
2288                     }
2289                 }
2290             }
2291 
2292             if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
2293                     + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
2294             if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2295                 winAnimator.mAlpha = attrs.alpha;
2296             }
2297             win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
2298 
2299             if (win.mAttrs.surfaceInsets.left != 0
2300                     || win.mAttrs.surfaceInsets.top != 0
2301                     || win.mAttrs.surfaceInsets.right != 0
2302                     || win.mAttrs.surfaceInsets.bottom != 0) {
2303                 winAnimator.setOpaqueLocked(false);
2304             }
2305 
2306             final int oldVisibility = win.mViewVisibility;
2307 
2308             // If the window is becoming visible, visibleOrAdding may change which may in turn
2309             // change the IME target.
2310             final boolean becameVisible =
2311                     (oldVisibility == View.INVISIBLE || oldVisibility == View.GONE)
2312                             && viewVisibility == View.VISIBLE;
2313             boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
2314                     || becameVisible;
2315             boolean focusMayChange = win.mViewVisibility != viewVisibility
2316                     || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
2317                     || (!win.mRelayoutCalled);
2318 
2319             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2320                     && win.hasWallpaper();
2321             wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
2322             if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
2323                 winAnimator.mSurfaceController.setSecure(win.isSecureLocked());
2324             }
2325 
2326             final boolean wasVisible = win.isVisible();
2327 
2328             win.mRelayoutCalled = true;
2329             win.mInRelayout = true;
2330 
2331             win.setViewVisibility(viewVisibility);
2332             ProtoLog.i(WM_DEBUG_SCREEN_ON,
2333                     "Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,
2334                             viewVisibility, new RuntimeException().fillInStackTrace());
2335 
2336             win.setDisplayLayoutNeeded();
2337             win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
2338 
2339             // We should only relayout if the view is visible, it is a starting window, or the
2340             // associated appToken is not hidden.
2341             final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
2342                     (win.mActivityRecord == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
2343                             || win.mActivityRecord.isClientVisible());
2344 
2345             // If we are not currently running the exit animation, we need to see about starting
2346             // one.
2347             // This must be called before the call to performSurfacePlacement.
2348             if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
2349                 if (DEBUG_VISIBILITY) {
2350                     Slog.i(TAG_WM,
2351                             "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
2352                 }
2353                 result |= RELAYOUT_RES_SURFACE_CHANGED;
2354                 // When FLAG_SHOW_WALLPAPER flag is removed from a window, we usually set a flag
2355                 // in DC#pendingLayoutChanges and update the wallpaper target later.
2356                 // However it's possible that FLAG_SHOW_WALLPAPER flag is removed from a window
2357                 // when the window is about to exit, so we update the wallpaper target
2358                 // immediately here. Otherwise this window will be stuck in exiting and its
2359                 // surface remains on the screen.
2360                 // TODO(b/189856716): Allow destroying surface even if it belongs to the
2361                 //  keyguard target.
2362                 if (wallpaperMayMove) {
2363                     displayContent.mWallpaperController.adjustWallpaperWindows();
2364                 }
2365                 tryStartExitingAnimation(win, winAnimator);
2366             }
2367 
2368             // Create surfaceControl before surface placement otherwise layout will be skipped
2369             // (because WS.isGoneForLayout() is true when there is no surface.
2370             if (shouldRelayout && outSurfaceControl != null) {
2371                 try {
2372                     result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
2373                 } catch (Exception e) {
2374                     displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
2375 
2376                     ProtoLog.w(WM_ERROR,
2377                             "Exception thrown when creating surface for client %s (%s). %s",
2378                             client, win.mAttrs.getTitle(), e);
2379                     Binder.restoreCallingIdentity(origId);
2380                     return 0;
2381                 }
2382             }
2383 
2384             // We may be deferring layout passes at the moment, but since the client is interested
2385             // in the new out values right now we need to force a layout.
2386             mWindowPlacerLocked.performSurfacePlacement(true /* force */);
2387 
2388             if (shouldRelayout) {
2389                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
2390 
2391                 result = win.relayoutVisibleWindow(result);
2392 
2393                 if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
2394                     focusMayChange = true;
2395                 }
2396                 if (win.mAttrs.type == TYPE_INPUT_METHOD
2397                         && displayContent.mInputMethodWindow == null) {
2398                     displayContent.setInputMethodWindowLocked(win);
2399                     imMayMove = true;
2400                 }
2401                 win.adjustStartingWindowFlags();
2402                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2403             } else {
2404                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2");
2405 
2406                 winAnimator.mEnterAnimationPending = false;
2407                 winAnimator.mEnteringAnimation = false;
2408 
2409                 if (outSurfaceControl != null) {
2410                     if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
2411                         // We already told the client to go invisible, but the message may not be
2412                         // handled yet, or it might want to draw a last frame. If we already have a
2413                         // surface, let the client use that, but don't create new surface at this
2414                         // point.
2415                         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
2416                         winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl);
2417                         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2418                     } else {
2419                         if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
2420 
2421                         try {
2422                             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
2423                                     + win.mAttrs.getTitle());
2424                             outSurfaceControl.release();
2425                         } finally {
2426                             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2427                         }
2428                     }
2429                 }
2430 
2431                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2432             }
2433 
2434             if (focusMayChange) {
2435                 if (updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/)) {
2436                     imMayMove = false;
2437                 }
2438             }
2439 
2440             // updateFocusedWindowLocked() already assigned layers so we only need to
2441             // reassign them at this point if the IM window state gets shuffled
2442             boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
2443             if (imMayMove) {
2444                 displayContent.computeImeTarget(true /* updateImeTarget */);
2445                 if (toBeDisplayed) {
2446                     // Little hack here -- we -should- be able to rely on the function to return
2447                     // true if the IME has moved and needs its layer recomputed. However, if the IME
2448                     // was hidden and isn't actually moved in the list, its layer may be out of data
2449                     // so we make sure to recompute it.
2450                     displayContent.assignWindowLayers(false /* setLayoutNeeded */);
2451                 }
2452             }
2453 
2454             if (wallpaperMayMove) {
2455                 displayContent.pendingLayoutChanges |=
2456                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
2457             }
2458 
2459             if (win.mActivityRecord != null) {
2460                 displayContent.mUnknownAppVisibilityController.notifyRelayouted(win.mActivityRecord);
2461             }
2462 
2463             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: updateOrientation");
2464             configChanged |= displayContent.updateOrientation();
2465             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2466 
2467             if (toBeDisplayed && win.mIsWallpaper) {
2468                 displayContent.mWallpaperController.updateWallpaperOffset(win, false /* sync */);
2469             }
2470             if (win.mActivityRecord != null) {
2471                 win.mActivityRecord.updateReportedVisibilityLocked();
2472             }
2473             if (displayPolicy.areSystemBarsForcedConsumedLw()) {
2474                 result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
2475             }
2476             if (!win.isGoneForLayout()) {
2477                 win.mResizedWhileGone = false;
2478             }
2479 
2480             if (outFrames != null && outMergedConfiguration != null) {
2481                 win.fillClientWindowFramesAndConfiguration(outFrames, outMergedConfiguration,
2482                         false /* useLatestConfig */, shouldRelayout);
2483 
2484                 // Set resize-handled here because the values are sent back to the client.
2485                 win.onResizeHandled();
2486             }
2487 
2488             if (outInsetsState != null) {
2489                 outInsetsState.set(win.getCompatInsetsState(), true /* copySources */);
2490             }
2491 
2492             ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b",
2493                     win, focusMayChange);
2494 
2495             if (DEBUG_LAYOUT) {
2496                 Slog.v(TAG_WM, "Relayout complete " + win + ": outFrames=" + outFrames);
2497             }
2498             win.mInRelayout = false;
2499 
2500             final boolean winVisibleChanged = win.isVisible() != wasVisible;
2501             if (win.isImeOverlayLayeringTarget() && winVisibleChanged) {
2502                 dispatchImeTargetOverlayVisibilityChanged(client.asBinder(), win.mAttrs.type,
2503                         win.isVisible(), false /* removed */);
2504             }
2505             // Notify listeners about IME input target window visibility change.
2506             final boolean isImeInputTarget = win.getDisplayContent().getImeInputTarget() == win;
2507             if (isImeInputTarget && winVisibleChanged) {
2508                 dispatchImeInputTargetVisibilityChanged(win.mClient.asBinder(),
2509                         win.isVisible() /* visible */, false /* removed */);
2510             }
2511 
2512             if (outSyncIdBundle != null) {
2513                 final int maybeSyncSeqId;
2514                 if (USE_BLAST_SYNC && win.useBLASTSync() && viewVisibility == View.VISIBLE
2515                         && win.mSyncSeqId > lastSyncSeqId) {
2516                     maybeSyncSeqId = win.shouldSyncWithBuffers() ? win.mSyncSeqId : -1;
2517                     win.markRedrawForSyncReported();
2518                 } else {
2519                     maybeSyncSeqId = -1;
2520                 }
2521                 outSyncIdBundle.putInt("seqid", maybeSyncSeqId);
2522             }
2523 
2524             if (configChanged) {
2525                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
2526                         "relayoutWindow: postNewConfigurationToHandler");
2527                 displayContent.sendNewConfiguration();
2528                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2529             }
2530             if (outActiveControls != null) {
2531                 getInsetsSourceControls(win, outActiveControls);
2532             }
2533         }
2534 
2535         Binder.restoreCallingIdentity(origId);
2536         return result;
2537     }
2538 
getInsetsSourceControls(WindowState win, InsetsSourceControl.Array outArray)2539     private void getInsetsSourceControls(WindowState win, InsetsSourceControl.Array outArray) {
2540         final InsetsSourceControl[] controls =
2541                 win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win);
2542         if (controls != null) {
2543             final int length = controls.length;
2544             final InsetsSourceControl[] outControls = new InsetsSourceControl[length];
2545             for (int i = 0; i < length; i++) {
2546                 // We will leave the critical section before returning the leash to the client,
2547                 // so we need to copy the leash to prevent others release the one that we are
2548                 // about to return.
2549                 if (controls[i] != null) {
2550                     // This source control is an extra copy if the client is not local. By setting
2551                     // PARCELABLE_WRITE_RETURN_VALUE, the leash will be released at the end of
2552                     // SurfaceControl.writeToParcel.
2553                     outControls[i] = new InsetsSourceControl(controls[i]);
2554                     outControls[i].setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE);
2555                 }
2556             }
2557             outArray.set(outControls);
2558         }
2559     }
2560 
tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator)2561     private void tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator) {
2562         // Try starting an animation; if there isn't one, we
2563         // can destroy the surface right away.
2564         int transit = WindowManagerPolicy.TRANSIT_EXIT;
2565         if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
2566             transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2567         }
2568 
2569         if (win.isVisible() && win.isDisplayed() && win.mDisplayContent.okToAnimate()) {
2570             String reason = null;
2571             if (winAnimator.applyAnimationLocked(transit, false)) {
2572                 // This is a WMCore-driven window animation.
2573                 reason = "applyAnimation";
2574             } else if (win.isSelfAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION)) {
2575                 // This is already animating via a WMCore-driven window animation.
2576                 reason = "selfAnimating";
2577             } else {
2578                 if (win.mTransitionController.isShellTransitionsEnabled()) {
2579                     // Already animating as part of a shell-transition. Currently this only handles
2580                     // activity window because other types should be WMCore-driven.
2581                     if ((win.mActivityRecord != null && win.mActivityRecord.inTransition())) {
2582                         win.mTransitionController.mAnimatingExitWindows.add(win);
2583                         reason = "inTransition";
2584                     }
2585                 } else if (win.isAnimating(PARENTS | TRANSITION,
2586                         ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)) {
2587                     // Already animating as part of a legacy app-transition.
2588                     reason = "inLegacyTransition";
2589                 }
2590             }
2591             if (reason != null) {
2592                 win.mAnimatingExit = true;
2593                 ProtoLog.d(WM_DEBUG_ANIM,
2594                         "Set animatingExit: reason=startExitingAnimation/%s win=%s", reason, win);
2595             }
2596         }
2597         if (!win.mAnimatingExit) {
2598             boolean stopped = win.mActivityRecord == null || win.mActivityRecord.mAppStopped;
2599             // We set mDestroying=true so ActivityRecord#notifyAppStopped in-to destroy surfaces
2600             // will later actually destroy the surface if we do not do so here. Normally we leave
2601             // this to the exit animation.
2602             win.mDestroying = true;
2603             win.destroySurface(false, stopped);
2604         }
2605         if (mAccessibilityController.hasCallbacks()) {
2606             mAccessibilityController.onWindowTransition(win, transit);
2607         }
2608     }
2609 
createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win, WindowStateAnimator winAnimator)2610     private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
2611             WindowState win, WindowStateAnimator winAnimator) {
2612         if (!win.mHasSurface) {
2613             result |= RELAYOUT_RES_SURFACE_CHANGED;
2614         }
2615 
2616         WindowSurfaceController surfaceController;
2617         try {
2618             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
2619             surfaceController = winAnimator.createSurfaceLocked();
2620         } finally {
2621             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2622         }
2623         if (surfaceController != null) {
2624             surfaceController.getSurfaceControl(outSurfaceControl);
2625             ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);
2626 
2627         } else {
2628             // For some reason there isn't a surface.  Clear the
2629             // caller's object so they see the same state.
2630             ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
2631             outSurfaceControl.release();
2632         }
2633 
2634         return result;
2635     }
2636 
outOfMemoryWindow(Session session, IWindow client)2637     public boolean outOfMemoryWindow(Session session, IWindow client) {
2638         final long origId = Binder.clearCallingIdentity();
2639 
2640         try {
2641             synchronized (mGlobalLock) {
2642                 WindowState win = windowForClientLocked(session, client, false);
2643                 if (win == null) {
2644                     return false;
2645                 }
2646                 return mRoot.reclaimSomeSurfaceMemory(win.mWinAnimator, "from-client", false);
2647             }
2648         } finally {
2649             Binder.restoreCallingIdentity(origId);
2650         }
2651     }
2652 
finishDrawingWindow(Session session, IWindow client, @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId)2653     void finishDrawingWindow(Session session, IWindow client,
2654             @Nullable SurfaceControl.Transaction postDrawTransaction, int seqId) {
2655         if (postDrawTransaction != null) {
2656             postDrawTransaction.sanitize(Binder.getCallingPid(), Binder.getCallingUid());
2657         }
2658 
2659         final long origId = Binder.clearCallingIdentity();
2660         try {
2661             synchronized (mGlobalLock) {
2662                 WindowState win = windowForClientLocked(session, client, false);
2663                 ProtoLog.d(WM_DEBUG_ADD_REMOVE, "finishDrawingWindow: %s mDrawState=%s",
2664                         win, (win != null ? win.mWinAnimator.drawStateToString() : "null"));
2665                 if (win != null && win.finishDrawing(postDrawTransaction, seqId)) {
2666                     if (win.hasWallpaper()) {
2667                         win.getDisplayContent().pendingLayoutChanges |=
2668                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
2669                     }
2670                     win.setDisplayLayoutNeeded();
2671                     mWindowPlacerLocked.requestTraversal();
2672                 }
2673             }
2674         } finally {
2675             Binder.restoreCallingIdentity(origId);
2676         }
2677     }
2678 
checkCallingPermission(String permission, String func)2679     boolean checkCallingPermission(String permission, String func) {
2680         return checkCallingPermission(permission, func, true /* printLog */);
2681     }
2682 
checkCallingPermission(String permission, String func, boolean printLog)2683     boolean checkCallingPermission(String permission, String func, boolean printLog) {
2684         if (Binder.getCallingPid() == MY_PID) {
2685             return true;
2686         }
2687 
2688         if (mContext.checkCallingPermission(permission)
2689                 == PackageManager.PERMISSION_GRANTED) {
2690             return true;
2691         }
2692         if (printLog) {
2693             ProtoLog.w(WM_ERROR, "Permission Denial: %s from pid=%d, uid=%d requires %s",
2694                     func, Binder.getCallingPid(), Binder.getCallingUid(), permission);
2695         }
2696         return false;
2697     }
2698 
2699     @Override
addWindowToken(@onNull IBinder binder, int type, int displayId, @Nullable Bundle options)2700     public void addWindowToken(@NonNull IBinder binder, int type, int displayId,
2701             @Nullable Bundle options) {
2702         if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
2703             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
2704         }
2705 
2706         synchronized (mGlobalLock) {
2707             final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
2708             if (dc == null) {
2709                 ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add token: %s"
2710                         + " for non-exiting displayId=%d", binder, displayId);
2711                 return;
2712             }
2713 
2714             WindowToken token = dc.getWindowToken(binder);
2715             if (token != null) {
2716                 ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add binder token: %s"
2717                         + " for already created window token: %s"
2718                         + " displayId=%d", binder, token, displayId);
2719                 return;
2720             }
2721             if (type == TYPE_WALLPAPER) {
2722                 new WallpaperWindowToken(this, binder, true, dc,
2723                         true /* ownerCanManageAppTokens */, options);
2724             } else {
2725                 new WindowToken.Builder(this, binder, type)
2726                         .setDisplayContent(dc)
2727                         .setPersistOnEmpty(true)
2728                         .setOwnerCanManageAppTokens(true)
2729                         .setOptions(options)
2730                         .build();
2731             }
2732         }
2733     }
2734 
2735     @Override
attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId, Bundle options)2736     public Configuration attachWindowContextToDisplayArea(IBinder clientToken, int
2737             type, int displayId, Bundle options) {
2738         if (clientToken == null) {
2739             throw new IllegalArgumentException("clientToken must not be null!");
2740         }
2741         final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
2742                 "attachWindowContextToDisplayArea", false /* printLog */);
2743         final int callingUid = Binder.getCallingUid();
2744         final long origId = Binder.clearCallingIdentity();
2745         try {
2746             synchronized (mGlobalLock) {
2747                 final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
2748                 if (dc == null) {
2749                     ProtoLog.w(WM_ERROR, "attachWindowContextToDisplayArea: trying to attach"
2750                             + " to a non-existing display:%d", displayId);
2751                     return null;
2752                 }
2753                 // TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
2754                 // the feature b/155340867 is completed.
2755                 final DisplayArea<?> da = dc.findAreaForWindowType(type, options,
2756                         callerCanManageAppTokens, false /* roundedCornerOverlay */);
2757                 mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
2758                         callingUid, type, options, false /* shouDispatchConfigWhenRegistering */);
2759                 return da.getConfiguration();
2760             }
2761         } finally {
2762             Binder.restoreCallingIdentity(origId);
2763         }
2764     }
2765 
2766     @Override
attachWindowContextToWindowToken(IBinder clientToken, IBinder token)2767     public void attachWindowContextToWindowToken(IBinder clientToken, IBinder token) {
2768         final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
2769                 "attachWindowContextToWindowToken", false /* printLog */);
2770         final int callingUid = Binder.getCallingUid();
2771         final long origId = Binder.clearCallingIdentity();
2772         try {
2773             synchronized (mGlobalLock) {
2774                 final WindowToken windowToken = mRoot.getWindowToken(token);
2775                 if (windowToken == null) {
2776                     ProtoLog.w(WM_ERROR, "Then token:%s is invalid. It might be "
2777                             + "removed", token);
2778                     return;
2779                 }
2780                 final int type = mWindowContextListenerController.getWindowType(clientToken);
2781                 if (type == INVALID_WINDOW_TYPE) {
2782                     throw new IllegalArgumentException("The clientToken:" + clientToken
2783                             + " should have been attached.");
2784                 }
2785                 if (type != windowToken.windowType) {
2786                     throw new IllegalArgumentException("The WindowToken's type should match"
2787                             + " the created WindowContext's type. WindowToken's type is "
2788                             + windowToken.windowType + ", while WindowContext's is " + type);
2789                 }
2790                 if (!mWindowContextListenerController.assertCallerCanModifyListener(clientToken,
2791                         callerCanManageAppTokens, callingUid)) {
2792                     return;
2793                 }
2794                 mWindowContextListenerController.registerWindowContainerListener(clientToken,
2795                         windowToken, callingUid, windowToken.windowType, windowToken.mOptions);
2796             }
2797         } finally {
2798             Binder.restoreCallingIdentity(origId);
2799         }
2800     }
2801 
2802     @Override
detachWindowContextFromWindowContainer(IBinder clientToken)2803     public void detachWindowContextFromWindowContainer(IBinder clientToken) {
2804         final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
2805                 "detachWindowContextFromWindowContainer", false /* printLog */);
2806         final int callingUid = Binder.getCallingUid();
2807         final long origId = Binder.clearCallingIdentity();
2808         try {
2809             synchronized (mGlobalLock) {
2810                 if (!mWindowContextListenerController.assertCallerCanModifyListener(clientToken,
2811                         callerCanManageAppTokens, callingUid)) {
2812                     return;
2813                 }
2814                 final WindowContainer wc = mWindowContextListenerController
2815                         .getContainer(clientToken);
2816 
2817                 mWindowContextListenerController.unregisterWindowContainerListener(clientToken);
2818 
2819                 final WindowToken token = wc.asWindowToken();
2820                 if (token != null && token.isFromClient()) {
2821                     removeWindowToken(token.token, token.getDisplayContent().getDisplayId());
2822                 }
2823             }
2824         } finally {
2825             Binder.restoreCallingIdentity(origId);
2826         }
2827     }
2828 
2829     @Override
attachToDisplayContent(IBinder clientToken, int displayId)2830     public Configuration attachToDisplayContent(IBinder clientToken, int displayId) {
2831         if (clientToken == null) {
2832             throw new IllegalArgumentException("clientToken must not be null!");
2833         }
2834         final int callingUid = Binder.getCallingUid();
2835         final long origId = Binder.clearCallingIdentity();
2836         try {
2837             synchronized (mGlobalLock) {
2838                 // We use "getDisplayContent" instead of "getDisplayContentOrCreate" because
2839                 // this method may be called in DisplayPolicy's constructor and may cause
2840                 // infinite loop. In this scenario, we early return here and switch to do the
2841                 // registration in DisplayContent#onParentChanged at DisplayContent initialization.
2842                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
2843                 if (dc == null) {
2844                     if (Binder.getCallingPid() != MY_PID) {
2845                         throw new WindowManager.InvalidDisplayException("attachToDisplayContent: "
2846                                 + "trying to attach to a non-existing display:" + displayId);
2847                     }
2848                     // Early return if this method is invoked from system process.
2849                     // See above comments for more detail.
2850                     return null;
2851                 }
2852 
2853                 mWindowContextListenerController.registerWindowContainerListener(clientToken, dc,
2854                         callingUid, INVALID_WINDOW_TYPE, null /* options */,
2855                         false /* shouDispatchConfigWhenRegistering */);
2856                 return dc.getConfiguration();
2857             }
2858         } finally {
2859             Binder.restoreCallingIdentity(origId);
2860         }
2861     }
2862 
2863     /** Returns {@code true} if this binder is a registered window token. */
2864     @Override
isWindowToken(IBinder binder)2865     public boolean isWindowToken(IBinder binder) {
2866         synchronized (mGlobalLock) {
2867             return mRoot.getWindowToken(binder) != null;
2868         }
2869 
2870     }
2871 
removeWindowToken(IBinder binder, boolean removeWindows, boolean animateExit, int displayId)2872     void removeWindowToken(IBinder binder, boolean removeWindows, boolean animateExit,
2873             int displayId) {
2874         synchronized (mGlobalLock) {
2875             final DisplayContent dc = mRoot.getDisplayContent(displayId);
2876 
2877             if (dc == null) {
2878                 ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s"
2879                         + " for non-exiting displayId=%d", binder, displayId);
2880                 return;
2881             }
2882             final WindowToken token = dc.removeWindowToken(binder, animateExit);
2883             if (token == null) {
2884                 ProtoLog.w(WM_ERROR,
2885                         "removeWindowToken: Attempted to remove non-existing token: %s",
2886                         binder);
2887                 return;
2888             }
2889 
2890             if (removeWindows) {
2891                 token.removeAllWindowsIfPossible();
2892             }
2893             dc.getInputMonitor().updateInputWindowsLw(true /* force */);
2894         }
2895     }
2896 
2897     @Override
removeWindowToken(IBinder binder, int displayId)2898     public void removeWindowToken(IBinder binder, int displayId) {
2899         if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeWindowToken()")) {
2900             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
2901         }
2902         final long origId = Binder.clearCallingIdentity();
2903         try {
2904             removeWindowToken(binder, false /* removeWindows */, true /* animateExit */, displayId);
2905         } finally {
2906             Binder.restoreCallingIdentity(origId);
2907         }
2908     }
2909 
2910     /** @see WindowManagerInternal#moveWindowTokenToDisplay(IBinder, int)  */
moveWindowTokenToDisplay(IBinder binder, int displayId)2911     public void moveWindowTokenToDisplay(IBinder binder, int displayId) {
2912         synchronized (mGlobalLock) {
2913             final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
2914             if (dc == null) {
2915                 ProtoLog.w(WM_ERROR, "moveWindowTokenToDisplay: Attempted to move token: %s"
2916                         + " to non-exiting displayId=%d", binder, displayId);
2917                 return;
2918             }
2919             final WindowToken token = mRoot.getWindowToken(binder);
2920             if (token == null) {
2921                 ProtoLog.w(WM_ERROR,
2922                         "moveWindowTokenToDisplay: Attempted to move non-existing token: %s",
2923                         binder);
2924                 return;
2925             }
2926             if (token.getDisplayContent() == dc) {
2927                 ProtoLog.w(WM_ERROR,
2928                         "moveWindowTokenToDisplay: Cannot move to the original display "
2929                                 + "for token: %s", binder);
2930                 return;
2931             }
2932             dc.reParentWindowToken(token);
2933         }
2934     }
2935 
2936     // TODO(multi-display): remove when no default display use case.
prepareAppTransitionNone()2937     void prepareAppTransitionNone() {
2938         if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
2939             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
2940         }
2941         getDefaultDisplayContentLocked().prepareAppTransition(TRANSIT_NONE);
2942     }
2943 
2944     @Override
overridePendingAppTransitionMultiThumbFuture( IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback, boolean scaleUp, int displayId)2945     public void overridePendingAppTransitionMultiThumbFuture(
2946             IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
2947             boolean scaleUp, int displayId) {
2948         synchronized (mGlobalLock) {
2949             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
2950             if (displayContent == null) {
2951                 Slog.w(TAG, "Attempted to call overridePendingAppTransitionMultiThumbFuture"
2952                         + " for the display " + displayId + " that does not exist.");
2953                 return;
2954             }
2955             displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(specsFuture,
2956                     callback, scaleUp);
2957         }
2958     }
2959 
2960     @Override
overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter, int displayId)2961     public void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter,
2962             int displayId) {
2963         if (!checkCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
2964                 "overridePendingAppTransitionRemote()")) {
2965             throw new SecurityException(
2966                     "Requires CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS permission");
2967         }
2968         synchronized (mGlobalLock) {
2969             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
2970             if (displayContent == null) {
2971                 Slog.w(TAG, "Attempted to call overridePendingAppTransitionRemote"
2972                         + " for the display " + displayId + " that does not exist.");
2973                 return;
2974             }
2975             remoteAnimationAdapter.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
2976             displayContent.mAppTransition.overridePendingAppTransitionRemote(
2977                     remoteAnimationAdapter);
2978         }
2979     }
2980 
2981     @Override
endProlongedAnimations()2982     public void endProlongedAnimations() {
2983         // TODO: Remove once clients are updated.
2984     }
2985 
2986     // TODO(multi-display): remove when no default display use case.
2987     // (i.e. KeyguardController / RecentsAnimation)
executeAppTransition()2988     public void executeAppTransition() {
2989         if (!checkCallingPermission(MANAGE_APP_TOKENS, "executeAppTransition()")) {
2990             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
2991         }
2992         getDefaultDisplayContentLocked().executeAppTransition();
2993     }
2994 
initializeRecentsAnimation(int targetActivityType, IRecentsAnimationRunner recentsAnimationRunner, RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId, SparseBooleanArray recentTaskIds, ActivityRecord targetActivity)2995     void initializeRecentsAnimation(int targetActivityType,
2996             IRecentsAnimationRunner recentsAnimationRunner,
2997             RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId,
2998             SparseBooleanArray recentTaskIds, ActivityRecord targetActivity) {
2999         mRecentsAnimationController = new RecentsAnimationController(this, recentsAnimationRunner,
3000                 callbacks, displayId);
3001         mRoot.getDisplayContent(displayId).mAppTransition.updateBooster();
3002         mRecentsAnimationController.initialize(targetActivityType, recentTaskIds, targetActivity);
3003     }
3004 
3005     @VisibleForTesting
setRecentsAnimationController(RecentsAnimationController controller)3006     void setRecentsAnimationController(RecentsAnimationController controller) {
3007         mRecentsAnimationController = controller;
3008     }
3009 
getRecentsAnimationController()3010     RecentsAnimationController getRecentsAnimationController() {
3011         return mRecentsAnimationController;
3012     }
3013 
cancelRecentsAnimation( @ecentsAnimationController.ReorderMode int reorderMode, String reason)3014     void cancelRecentsAnimation(
3015             @RecentsAnimationController.ReorderMode int reorderMode, String reason) {
3016         if (mRecentsAnimationController != null) {
3017             // This call will call through to cleanupAnimation() below after the animation is
3018             // canceled
3019             mRecentsAnimationController.cancelAnimation(reorderMode, reason);
3020         }
3021     }
3022 
3023 
cleanupRecentsAnimation(@ecentsAnimationController.ReorderMode int reorderMode)3024     void cleanupRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
3025         if (mRecentsAnimationController != null) {
3026             final RecentsAnimationController controller = mRecentsAnimationController;
3027             mRecentsAnimationController = null;
3028             controller.cleanupAnimation(reorderMode);
3029             // TODO(multi-display): currently only default display support recents animation.
3030             final DisplayContent dc = getDefaultDisplayContentLocked();
3031             if (dc.mAppTransition.isTransitionSet()) {
3032                 dc.mSkipAppTransitionAnimation = true;
3033             }
3034             dc.forAllWindowContainers((wc) -> {
3035                 if (wc.isAnimating(TRANSITION, ANIMATION_TYPE_APP_TRANSITION)) {
3036                     wc.cancelAnimation();
3037                 }
3038             });
3039         }
3040     }
3041 
isRecentsAnimationTarget(ActivityRecord r)3042     boolean isRecentsAnimationTarget(ActivityRecord r) {
3043         return mRecentsAnimationController != null && mRecentsAnimationController.isTargetApp(r);
3044     }
3045 
setWindowOpaqueLocked(IBinder token, boolean isOpaque)3046     void setWindowOpaqueLocked(IBinder token, boolean isOpaque) {
3047         final ActivityRecord wtoken = mRoot.getActivityRecord(token);
3048         if (wtoken != null) {
3049             wtoken.setMainWindowOpaque(isOpaque);
3050         }
3051     }
3052 
isValidPictureInPictureAspectRatio(DisplayContent displayContent, float aspectRatio)3053     boolean isValidPictureInPictureAspectRatio(DisplayContent displayContent, float aspectRatio) {
3054         return displayContent.getPinnedTaskController().isValidPictureInPictureAspectRatio(
3055                 aspectRatio);
3056     }
3057 
isValidExpandedPictureInPictureAspectRatio(DisplayContent displayContent, float aspectRatio)3058     boolean isValidExpandedPictureInPictureAspectRatio(DisplayContent displayContent,
3059             float aspectRatio) {
3060         return displayContent.getPinnedTaskController().isValidExpandedPictureInPictureAspectRatio(
3061                 aspectRatio);
3062     }
3063 
3064     @Override
notifyKeyguardTrustedChanged()3065     public void notifyKeyguardTrustedChanged() {
3066         synchronized (mGlobalLock) {
3067             if (mAtmService.mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
3068                 mRoot.ensureActivitiesVisible(null, 0, false /* preserveWindows */);
3069             }
3070         }
3071     }
3072 
3073     @Override
screenTurningOff(int displayId, ScreenOffListener listener)3074     public void screenTurningOff(int displayId, ScreenOffListener listener) {
3075         mTaskSnapshotController.screenTurningOff(displayId, listener);
3076     }
3077 
3078     @Override
triggerAnimationFailsafe()3079     public void triggerAnimationFailsafe() {
3080         mH.sendEmptyMessage(H.ANIMATION_FAILSAFE);
3081     }
3082 
3083     @Override
onKeyguardShowingAndNotOccludedChanged()3084     public void onKeyguardShowingAndNotOccludedChanged() {
3085         mH.sendEmptyMessage(H.RECOMPUTE_FOCUS);
3086         dispatchKeyguardLockedState();
3087     }
3088 
3089     @Override
onPowerKeyDown(boolean isScreenOn)3090     public void onPowerKeyDown(boolean isScreenOn) {
3091         mRoot.forAllDisplayPolicies(p -> p.onPowerKeyDown(isScreenOn));
3092     }
3093 
3094     @Override
onUserSwitched()3095     public void onUserSwitched() {
3096         mSettingsObserver.updateSystemUiSettings(true /* handleChange */);
3097         synchronized (mGlobalLock) {
3098             // force a re-application of focused window sysui visibility on each display.
3099             mRoot.forAllDisplayPolicies(DisplayPolicy::resetSystemBarAttributes);
3100         }
3101     }
3102 
3103     @Override
moveDisplayToTopIfAllowed(int displayId)3104     public void moveDisplayToTopIfAllowed(int displayId) {
3105         moveDisplayToTopInternal(displayId);
3106         syncInputTransactions(true /* waitForAnimations */);
3107     }
3108 
3109     /**
3110      * Moves the given display to the top. If it cannot be moved to the top this method does
3111      * nothing (e.g. if the display has the flag FLAG_STEAL_TOP_FOCUS_DISABLED set).
3112      * @param displayId The display to move to the top.
3113      */
moveDisplayToTopInternal(int displayId)3114     void moveDisplayToTopInternal(int displayId) {
3115         synchronized (mGlobalLock) {
3116             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
3117             if (displayContent != null && mRoot.getTopChild() != displayContent) {
3118                 // Check whether anything prevents us from moving the display to the top.
3119                 if (!displayContent.canStealTopFocus()) {
3120                     ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,
3121                             "Not moving display (displayId=%d) to top. Top focused displayId=%d. "
3122                                     + "Reason: FLAG_STEAL_TOP_FOCUS_DISABLED",
3123                             displayId, mRoot.getTopFocusedDisplayContent().getDisplayId());
3124                     return;
3125                 }
3126 
3127                 // Nothing prevented us from moving the display to the top. Let's do it!
3128                 displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP,
3129                         displayContent, true /* includingParents */);
3130             }
3131         }
3132     }
3133 
3134     @Override
isAppTransitionStateIdle()3135     public boolean isAppTransitionStateIdle() {
3136         return getDefaultDisplayContentLocked().mAppTransition.isIdle();
3137     }
3138 
3139 
3140     // -------------------------------------------------------------
3141     // Misc IWindowSession methods
3142     // -------------------------------------------------------------
3143 
3144     /** Freeze the screen during a user-switch event. Called by UserController. */
3145     @Override
startFreezingScreen(int exitAnim, int enterAnim)3146     public void startFreezingScreen(int exitAnim, int enterAnim) {
3147         if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
3148                 "startFreezingScreen()")) {
3149             throw new SecurityException("Requires FREEZE_SCREEN permission");
3150         }
3151 
3152         synchronized (mGlobalLock) {
3153             if (!mClientFreezingScreen) {
3154                 mClientFreezingScreen = true;
3155                 final long origId = Binder.clearCallingIdentity();
3156                 try {
3157                     startFreezingDisplay(exitAnim, enterAnim);
3158                     mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
3159                     mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
3160                 } finally {
3161                     Binder.restoreCallingIdentity(origId);
3162                 }
3163             }
3164         }
3165     }
3166 
3167     /**
3168      * No longer actively demand that the screen remain frozen.
3169      * Called by UserController after a user-switch.
3170      * This doesn't necessarily immediately unlock the screen; it just allows it if we're ready.
3171      */
3172     @Override
stopFreezingScreen()3173     public void stopFreezingScreen() {
3174         if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
3175                 "stopFreezingScreen()")) {
3176             throw new SecurityException("Requires FREEZE_SCREEN permission");
3177         }
3178 
3179         synchronized (mGlobalLock) {
3180             if (mClientFreezingScreen) {
3181                 mClientFreezingScreen = false;
3182                 mLastFinishedFreezeSource = "client";
3183                 final long origId = Binder.clearCallingIdentity();
3184                 try {
3185                     stopFreezingDisplayLocked();
3186                 } finally {
3187                     Binder.restoreCallingIdentity(origId);
3188                 }
3189             }
3190         }
3191     }
3192 
3193     @Override
disableKeyguard(IBinder token, String tag, int userId)3194     public void disableKeyguard(IBinder token, String tag, int userId) {
3195         userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3196                 userId, false /* allowAll */, ALLOW_FULL_ONLY, "disableKeyguard", null);
3197         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
3198             != PackageManager.PERMISSION_GRANTED) {
3199             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
3200         }
3201         final int callingUid = Binder.getCallingUid();
3202         final long origIdentity = Binder.clearCallingIdentity();
3203         try {
3204             mKeyguardDisableHandler.disableKeyguard(token, tag, callingUid, userId);
3205         } finally {
3206             Binder.restoreCallingIdentity(origIdentity);
3207         }
3208     }
3209 
3210     @Override
reenableKeyguard(IBinder token, int userId)3211     public void reenableKeyguard(IBinder token, int userId) {
3212         userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3213                 userId, false /* allowAll */, ALLOW_FULL_ONLY, "reenableKeyguard", null);
3214         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
3215             != PackageManager.PERMISSION_GRANTED) {
3216             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
3217         }
3218         Objects.requireNonNull(token, "token is null");
3219         final int callingUid = Binder.getCallingUid();
3220         final long origIdentity = Binder.clearCallingIdentity();
3221         try {
3222             mKeyguardDisableHandler.reenableKeyguard(token, callingUid, userId);
3223         } finally {
3224             Binder.restoreCallingIdentity(origIdentity);
3225         }
3226     }
3227 
3228     /**
3229      * @see android.app.KeyguardManager#exitKeyguardSecurely
3230      */
3231     @Override
exitKeyguardSecurely(final IOnKeyguardExitResult callback)3232     public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
3233         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
3234             != PackageManager.PERMISSION_GRANTED) {
3235             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
3236         }
3237 
3238         if (callback == null) {
3239             throw new IllegalArgumentException("callback == null");
3240         }
3241 
3242         mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
3243             @Override
3244             public void onKeyguardExitResult(boolean success) {
3245                 try {
3246                     callback.onKeyguardExitResult(success);
3247                 } catch (RemoteException e) {
3248                     // Client has died, we don't care.
3249                 }
3250             }
3251         });
3252     }
3253 
3254     @Override
isKeyguardLocked()3255     public boolean isKeyguardLocked() {
3256         return mPolicy.isKeyguardLocked();
3257     }
3258 
isKeyguardShowingAndNotOccluded()3259     public boolean isKeyguardShowingAndNotOccluded() {
3260         return mPolicy.isKeyguardShowingAndNotOccluded();
3261     }
3262 
3263     @Override
isKeyguardSecure(int userId)3264     public boolean isKeyguardSecure(int userId) {
3265         if (userId != UserHandle.getCallingUserId()
3266                 && !checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS,
3267                 "isKeyguardSecure")) {
3268             throw new SecurityException("Requires INTERACT_ACROSS_USERS permission");
3269         }
3270 
3271         final long origId = Binder.clearCallingIdentity();
3272         try {
3273             return mPolicy.isKeyguardSecure(userId);
3274         } finally {
3275             Binder.restoreCallingIdentity(origId);
3276         }
3277     }
3278 
3279     @Override
dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message)3280     public void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message) {
3281         if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) {
3282             throw new SecurityException("Requires CONTROL_KEYGUARD permission");
3283         }
3284         if (mAtmService.mKeyguardController.isShowingDream()) {
3285             mAtmService.mTaskSupervisor.wakeUp("leaveDream");
3286         }
3287         synchronized (mGlobalLock) {
3288             mPolicy.dismissKeyguardLw(callback, message);
3289         }
3290     }
3291 
3292     @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
3293     @Override
addKeyguardLockedStateListener(IKeyguardLockedStateListener listener)3294     public void addKeyguardLockedStateListener(IKeyguardLockedStateListener listener) {
3295         enforceSubscribeToKeyguardLockedStatePermission();
3296         boolean registered = mKeyguardLockedStateListeners.register(listener);
3297         if (!registered) {
3298             Slog.w(TAG, "Failed to register listener: " + listener);
3299         }
3300     }
3301 
3302     @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
3303     @Override
removeKeyguardLockedStateListener(IKeyguardLockedStateListener listener)3304     public void removeKeyguardLockedStateListener(IKeyguardLockedStateListener listener) {
3305         enforceSubscribeToKeyguardLockedStatePermission();
3306         mKeyguardLockedStateListeners.unregister(listener);
3307     }
3308 
enforceSubscribeToKeyguardLockedStatePermission()3309     private void enforceSubscribeToKeyguardLockedStatePermission() {
3310         mContext.enforceCallingOrSelfPermission(
3311                 Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE,
3312                 Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE
3313                         + " permission required to subscribe to keyguard locked state changes");
3314     }
3315 
dispatchKeyguardLockedState()3316     private void dispatchKeyguardLockedState() {
3317         mH.post(() -> {
3318             final boolean isKeyguardLocked = mPolicy.isKeyguardShowing();
3319             if (mDispatchedKeyguardLockedState == isKeyguardLocked) {
3320                 return;
3321             }
3322             final int n = mKeyguardLockedStateListeners.beginBroadcast();
3323             for (int i = 0; i < n; i++) {
3324                 try {
3325                     mKeyguardLockedStateListeners.getBroadcastItem(i).onKeyguardLockedStateChanged(
3326                             isKeyguardLocked);
3327                 } catch (RemoteException e) {
3328                     // Handled by the RemoteCallbackList.
3329                 }
3330             }
3331             mKeyguardLockedStateListeners.finishBroadcast();
3332             mDispatchedKeyguardLockedState = isKeyguardLocked;
3333         });
3334     }
3335 
dispatchImeTargetOverlayVisibilityChanged(@onNull IBinder token, @WindowManager.LayoutParams.WindowType int windowType, boolean visible, boolean removed)3336     void dispatchImeTargetOverlayVisibilityChanged(@NonNull IBinder token,
3337             @WindowManager.LayoutParams.WindowType int windowType, boolean visible,
3338             boolean removed) {
3339         if (mImeTargetChangeListener != null) {
3340             if (DEBUG_INPUT_METHOD) {
3341                 Slog.d(TAG, "onImeTargetOverlayVisibilityChanged, win=" + mWindowMap.get(token)
3342                         + ", type=" + ViewDebug.intToString(WindowManager.LayoutParams.class,
3343                         "type", windowType) + "visible=" + visible + ", removed=" + removed);
3344             }
3345             mH.post(() -> mImeTargetChangeListener.onImeTargetOverlayVisibilityChanged(token,
3346                     windowType, visible, removed));
3347         }
3348     }
3349 
dispatchImeInputTargetVisibilityChanged(@onNull IBinder token, boolean visible, boolean removed)3350     void dispatchImeInputTargetVisibilityChanged(@NonNull IBinder token, boolean visible,
3351             boolean removed) {
3352         if (mImeTargetChangeListener != null) {
3353             if (DEBUG_INPUT_METHOD) {
3354                 Slog.d(TAG, "onImeInputTargetVisibilityChanged, win=" + mWindowMap.get(token)
3355                         + "visible=" + visible + ", removed=" + removed);
3356             }
3357             mH.post(() -> mImeTargetChangeListener.onImeInputTargetVisibilityChanged(token,
3358                     visible, removed));
3359         }
3360     }
3361 
3362     @Override
setSwitchingUser(boolean switching)3363     public void setSwitchingUser(boolean switching) {
3364         if (!checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3365                 "setSwitchingUser()")) {
3366             throw new SecurityException("Requires INTERACT_ACROSS_USERS_FULL permission");
3367         }
3368         mPolicy.setSwitchingUser(switching);
3369         synchronized (mGlobalLock) {
3370             mSwitchingUser = switching;
3371         }
3372     }
3373 
3374     @RequiresPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW)
3375     @Override
showGlobalActions()3376     public void showGlobalActions() {
3377         if (!checkCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW,
3378                 "showGlobalActions()")) {
3379             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
3380         }
3381         mPolicy.showGlobalActions();
3382     }
3383 
3384     @Override
closeSystemDialogs(String reason)3385     public void closeSystemDialogs(String reason) {
3386         int callingPid = Binder.getCallingPid();
3387         int callingUid = Binder.getCallingUid();
3388         if (!mAtmService.checkCanCloseSystemDialogs(callingPid, callingUid, null)) {
3389             return;
3390         }
3391         synchronized (mGlobalLock) {
3392             mRoot.closeSystemDialogs(reason);
3393         }
3394     }
3395 
3396 
3397     @Override
setAnimationScale(int which, float scale)3398     public void setAnimationScale(int which, float scale) {
3399         if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
3400                 "setAnimationScale()")) {
3401             throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
3402         }
3403 
3404         scale = fixScale(scale);
3405         switch (which) {
3406             case 0: mWindowAnimationScaleSetting = scale; break;
3407             case 1: mTransitionAnimationScaleSetting = scale; break;
3408             case 2: mAnimatorDurationScaleSetting = scale; break;
3409         }
3410 
3411         // Persist setting
3412         mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
3413     }
3414 
3415     @Override
setAnimationScales(float[] scales)3416     public void setAnimationScales(float[] scales) {
3417         if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
3418                 "setAnimationScale()")) {
3419             throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
3420         }
3421 
3422         if (scales != null) {
3423             if (scales.length >= 1) {
3424                 mWindowAnimationScaleSetting = fixScale(scales[0]);
3425             }
3426             if (scales.length >= 2) {
3427                 mTransitionAnimationScaleSetting = fixScale(scales[1]);
3428             }
3429             if (scales.length >= 3) {
3430                 mAnimatorDurationScaleSetting = fixScale(scales[2]);
3431                 dispatchNewAnimatorScaleLocked(null);
3432             }
3433         }
3434 
3435         // Persist setting
3436         mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
3437     }
3438 
setAnimatorDurationScale(float scale)3439     private void setAnimatorDurationScale(float scale) {
3440         mAnimatorDurationScaleSetting = scale;
3441         ValueAnimator.setDurationScale(scale);
3442     }
3443 
getWindowAnimationScaleLocked()3444     public float getWindowAnimationScaleLocked() {
3445         return mAnimationsDisabled ? 0 : mWindowAnimationScaleSetting;
3446     }
3447 
getTransitionAnimationScaleLocked()3448     public float getTransitionAnimationScaleLocked() {
3449         return mAnimationsDisabled ? 0 : mTransitionAnimationScaleSetting;
3450     }
3451 
3452     @Override
getAnimationScale(int which)3453     public float getAnimationScale(int which) {
3454         switch (which) {
3455             case 0: return mWindowAnimationScaleSetting;
3456             case 1: return mTransitionAnimationScaleSetting;
3457             case 2: return mAnimatorDurationScaleSetting;
3458         }
3459         return 0;
3460     }
3461 
3462     @Override
getAnimationScales()3463     public float[] getAnimationScales() {
3464         return new float[] { mWindowAnimationScaleSetting, mTransitionAnimationScaleSetting,
3465                 mAnimatorDurationScaleSetting };
3466     }
3467 
3468     @Override
getCurrentAnimatorScale()3469     public float getCurrentAnimatorScale() {
3470         synchronized (mGlobalLock) {
3471             return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting;
3472         }
3473     }
3474 
dispatchNewAnimatorScaleLocked(Session session)3475     void dispatchNewAnimatorScaleLocked(Session session) {
3476         mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget();
3477     }
3478 
3479     @Override
registerPointerEventListener(PointerEventListener listener, int displayId)3480     public void registerPointerEventListener(PointerEventListener listener, int displayId) {
3481         synchronized (mGlobalLock) {
3482             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
3483             if (displayContent != null) {
3484                 displayContent.registerPointerEventListener(listener);
3485             }
3486         }
3487     }
3488 
3489     @Override
unregisterPointerEventListener(PointerEventListener listener, int displayId)3490     public void unregisterPointerEventListener(PointerEventListener listener, int displayId) {
3491         synchronized (mGlobalLock) {
3492             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
3493             if (displayContent != null) {
3494                 displayContent.unregisterPointerEventListener(listener);
3495             }
3496         }
3497     }
3498 
3499     // Called by window manager policy. Not exposed externally.
3500     @Override
getLidState()3501     public int getLidState() {
3502         int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
3503                 InputManagerService.SW_LID);
3504         if (sw > 0) {
3505             // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
3506             return LID_CLOSED;
3507         } else if (sw == 0) {
3508             // Switch state: AKEY_STATE_UP.
3509             return LID_OPEN;
3510         } else {
3511             // Switch state: AKEY_STATE_UNKNOWN.
3512             return LID_ABSENT;
3513         }
3514     }
3515 
3516     // Called by window manager policy. Not exposed externally.
3517     @Override
lockDeviceNow()3518     public void lockDeviceNow() {
3519         lockNow(null);
3520     }
3521 
3522     // Called by window manager policy. Not exposed externally.
3523     @Override
getCameraLensCoverState()3524     public int getCameraLensCoverState() {
3525         int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
3526                 InputManagerService.SW_CAMERA_LENS_COVER);
3527         if (sw > 0) {
3528             // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
3529             return CAMERA_LENS_COVERED;
3530         } else if (sw == 0) {
3531             // Switch state: AKEY_STATE_UP.
3532             return CAMERA_LENS_UNCOVERED;
3533         } else {
3534             // Switch state: AKEY_STATE_UNKNOWN.
3535             return CAMERA_LENS_COVER_ABSENT;
3536         }
3537     }
3538 
3539     // Called by window manager policy.  Not exposed externally.
3540     @Override
switchKeyboardLayout(int deviceId, int direction)3541     public void switchKeyboardLayout(int deviceId, int direction) {
3542         mInputManager.switchKeyboardLayout(deviceId, direction);
3543     }
3544 
3545     // Called by window manager policy.  Not exposed externally.
3546     @Override
shutdown(boolean confirm)3547     public void shutdown(boolean confirm) {
3548         // Pass in the UI context, since ShutdownThread requires it (to show UI).
3549         ShutdownThread.shutdown(ActivityThread.currentActivityThread().getSystemUiContext(),
3550                 PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
3551     }
3552 
3553     // Called by window manager policy.  Not exposed externally.
3554     @Override
reboot(boolean confirm)3555     public void reboot(boolean confirm) {
3556         // Pass in the UI context, since ShutdownThread requires it (to show UI).
3557         ShutdownThread.reboot(ActivityThread.currentActivityThread().getSystemUiContext(),
3558                 PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
3559     }
3560 
3561     // Called by window manager policy.  Not exposed externally.
3562     @Override
rebootSafeMode(boolean confirm)3563     public void rebootSafeMode(boolean confirm) {
3564         // Pass in the UI context, since ShutdownThread requires it (to show UI).
3565         ShutdownThread.rebootSafeMode(ActivityThread.currentActivityThread().getSystemUiContext(),
3566                 confirm);
3567     }
3568 
setCurrentUser(@serIdInt int newUserId)3569     public void setCurrentUser(@UserIdInt int newUserId) {
3570         synchronized (mGlobalLock) {
3571             mAtmService.getTransitionController().requestTransitionIfNeeded(TRANSIT_OPEN, null);
3572             mCurrentUserId = newUserId;
3573             mPolicy.setCurrentUserLw(newUserId);
3574             mKeyguardDisableHandler.setCurrentUser(newUserId);
3575 
3576             // Hide windows that should not be seen by the new user.
3577             mRoot.switchUser(newUserId);
3578             mWindowPlacerLocked.performSurfacePlacement();
3579 
3580             // Notify whether the root docked task exists for the current user
3581             final DisplayContent displayContent = getDefaultDisplayContentLocked();
3582 
3583             // If the display is already prepared, update the density.
3584             // Otherwise, we'll update it when it's prepared.
3585             if (mDisplayReady) {
3586                 final int forcedDensity = getForcedDisplayDensityForUserLocked(newUserId);
3587                 final int targetDensity = forcedDensity != 0
3588                         ? forcedDensity : displayContent.getInitialDisplayDensity();
3589                 displayContent.setForcedDensity(targetDensity, UserHandle.USER_CURRENT);
3590             }
3591         }
3592     }
3593 
3594     /* Called by WindowState */
isUserVisible(@serIdInt int userId)3595     boolean isUserVisible(@UserIdInt int userId) {
3596         return mUmInternal.isUserVisible(userId);
3597     }
3598 
getUserAssignedToDisplay(int displayId)3599     @UserIdInt int getUserAssignedToDisplay(int displayId) {
3600         return mUmInternal.getUserAssignedToDisplay(displayId);
3601     }
3602 
shouldPlacePrimaryHomeOnDisplay(int displayId)3603     boolean shouldPlacePrimaryHomeOnDisplay(int displayId) {
3604         int userId = mUmInternal.getUserAssignedToDisplay(displayId);
3605         return shouldPlacePrimaryHomeOnDisplay(displayId, userId);
3606     }
3607 
shouldPlacePrimaryHomeOnDisplay(int displayId, int userId)3608     boolean shouldPlacePrimaryHomeOnDisplay(int displayId, int userId) {
3609         return mUmInternal.getMainDisplayAssignedToUser(userId) == displayId;
3610     }
3611 
enableScreenAfterBoot()3612     public void enableScreenAfterBoot() {
3613         synchronized (mGlobalLock) {
3614             ProtoLog.i(WM_DEBUG_BOOT, "enableScreenAfterBoot: mDisplayEnabled=%b "
3615                             + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. "
3616                             + "%s",
3617                     mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
3618                     new RuntimeException("here").fillInStackTrace());
3619             if (mSystemBooted) {
3620                 return;
3621             }
3622             mSystemBooted = true;
3623             hideBootMessagesLocked();
3624             // If the screen still doesn't come up after 30 seconds, give
3625             // up and turn it on.
3626             mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000);
3627         }
3628 
3629         mPolicy.systemBooted();
3630 
3631         performEnableScreen();
3632     }
3633 
3634     @Override
enableScreenIfNeeded()3635     public void enableScreenIfNeeded() {
3636         synchronized (mGlobalLock) {
3637             enableScreenIfNeededLocked();
3638         }
3639     }
3640 
enableScreenIfNeededLocked()3641     void enableScreenIfNeededLocked() {
3642         ProtoLog.i(WM_DEBUG_BOOT, "enableScreenIfNeededLocked: mDisplayEnabled=%b "
3643                         + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. "
3644                         + "%s",
3645                 mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
3646                 new RuntimeException("here").fillInStackTrace());
3647         if (mDisplayEnabled) {
3648             return;
3649         }
3650         if (!mSystemBooted && !mShowingBootMessages) {
3651             return;
3652         }
3653         mH.sendEmptyMessage(H.ENABLE_SCREEN);
3654     }
3655 
performBootTimeout()3656     public void performBootTimeout() {
3657         synchronized (mGlobalLock) {
3658             if (mDisplayEnabled) {
3659                 return;
3660             }
3661             ProtoLog.w(WM_ERROR, "***** BOOT TIMEOUT: forcing display enabled");
3662             mForceDisplayEnabled = true;
3663         }
3664         performEnableScreen();
3665     }
3666 
3667     /**
3668      * Called when System UI has been started.
3669      */
onSystemUiStarted()3670     public void onSystemUiStarted() {
3671         mPolicy.onSystemUiStarted();
3672     }
3673 
performEnableScreen()3674     private void performEnableScreen() {
3675         synchronized (mGlobalLock) {
3676             ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: mDisplayEnabled=%b"
3677                             + " mForceDisplayEnabled=%b" + " mShowingBootMessages=%b"
3678                             + " mSystemBooted=%b. %s", mDisplayEnabled,
3679                     mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
3680                     new RuntimeException("here").fillInStackTrace());
3681             if (mDisplayEnabled) {
3682                 return;
3683             }
3684             if (!mSystemBooted && !mShowingBootMessages) {
3685                 return;
3686             }
3687 
3688             if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) {
3689                 return;
3690             }
3691 
3692             // Don't enable the screen until all existing windows have been drawn.
3693             if (!mForceDisplayEnabled) {
3694                 if (mBootWaitForWindowsStartTime < 0) {
3695                     // First time we will start waiting for all windows to be drawn.
3696                     mBootWaitForWindowsStartTime = SystemClock.elapsedRealtime();
3697                 }
3698                 for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
3699                     if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) {
3700                         return;
3701                     }
3702                 }
3703                 long waitTime = SystemClock.elapsedRealtime() - mBootWaitForWindowsStartTime;
3704                 mBootWaitForWindowsStartTime = -1;
3705                 if (waitTime > 10) {
3706                     ProtoLog.i(WM_DEBUG_BOOT,
3707                             "performEnableScreen: Waited %dms for all windows to be drawn",
3708                             waitTime);
3709                 }
3710             }
3711 
3712             if (!mBootAnimationStopped) {
3713                 Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
3714                 // stop boot animation
3715                 // formerly we would just kill the process, but we now ask it to exit so it
3716                 // can choose where to stop the animation.
3717                 SystemProperties.set("service.bootanim.exit", "1");
3718                 mBootAnimationStopped = true;
3719             }
3720 
3721             if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
3722                 ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete");
3723                 return;
3724             }
3725 
3726             if (!SurfaceControl.bootFinished()) {
3727                 ProtoLog.w(WM_ERROR, "performEnableScreen: bootFinished() failed.");
3728                 return;
3729             }
3730 
3731             EventLogTags.writeWmBootAnimationDone(SystemClock.uptimeMillis());
3732             Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
3733             mDisplayEnabled = true;
3734             ProtoLog.i(WM_DEBUG_SCREEN_ON, "******************** ENABLING SCREEN!");
3735 
3736             // Enable input dispatch.
3737             mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled);
3738         }
3739 
3740         try {
3741             mActivityManager.bootAnimationComplete();
3742         } catch (RemoteException e) {
3743         }
3744 
3745         mPolicy.enableScreenAfterBoot();
3746 
3747         // Make sure the last requested orientation has been applied.
3748         updateRotationUnchecked(false, false);
3749 
3750         synchronized (mGlobalLock) {
3751             mAtmService.getTransitionController().mIsWaitingForDisplayEnabled = false;
3752             ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Notified TransitionController "
3753                     + "that the display is ready.");
3754         }
3755     }
3756 
checkBootAnimationCompleteLocked()3757     private boolean checkBootAnimationCompleteLocked() {
3758         if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
3759             mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED);
3760             mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED,
3761                     BOOT_ANIMATION_POLL_INTERVAL);
3762             ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Waiting for anim complete");
3763             return false;
3764         }
3765         ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Animation complete!");
3766         return true;
3767     }
3768 
showBootMessage(final CharSequence msg, final boolean always)3769     public void showBootMessage(final CharSequence msg, final boolean always) {
3770         boolean first = false;
3771         synchronized (mGlobalLock) {
3772             ProtoLog.i(WM_DEBUG_BOOT, "showBootMessage: msg=%s always=%b"
3773                             + " mAllowBootMessages=%b mShowingBootMessages=%b"
3774                             + " mSystemBooted=%b. %s", msg, always, mAllowBootMessages,
3775                     mShowingBootMessages, mSystemBooted,
3776                     new RuntimeException("here").fillInStackTrace());
3777             if (!mAllowBootMessages) {
3778                 return;
3779             }
3780             if (!mShowingBootMessages) {
3781                 if (!always) {
3782                     return;
3783                 }
3784                 first = true;
3785             }
3786             if (mSystemBooted) {
3787                 return;
3788             }
3789             mShowingBootMessages = true;
3790             mPolicy.showBootMessage(msg, always);
3791         }
3792         if (first) {
3793             performEnableScreen();
3794         }
3795     }
3796 
hideBootMessagesLocked()3797     public void hideBootMessagesLocked() {
3798         ProtoLog.i(WM_DEBUG_BOOT, "hideBootMessagesLocked: mDisplayEnabled=%b"
3799                         + " mForceDisplayEnabled=%b mShowingBootMessages=%b"
3800                         + " mSystemBooted=%b. %s", mDisplayEnabled, mForceDisplayEnabled,
3801                 mShowingBootMessages, mSystemBooted,
3802                 new RuntimeException("here").fillInStackTrace());
3803         if (mShowingBootMessages) {
3804             mShowingBootMessages = false;
3805             mPolicy.hideBootMessages();
3806         }
3807     }
3808 
3809     /**
3810      * Sets the touch mode state.
3811      *
3812      * If {@code com.android.internal.R.bool.config_perDisplayFocusEnabled} is set to true, then
3813      * only the display represented by the {@code displayId} parameter will be requested to switch
3814      * the touch mode state. Otherwise all displays that do not maintain their own focus and touch
3815      * mode will be requested to switch their touch mode state (disregarding {@code displayId}
3816      * parameter).
3817      *
3818      * To be able to change touch mode state, the caller must either own the focused window, or must
3819      * have the {@link android.Manifest.permission#MODIFY_TOUCH_MODE_STATE} permission. Instrumented
3820      * process, sourced with {@link android.Manifest.permission#MODIFY_TOUCH_MODE_STATE}, may switch
3821      * touch mode at any time.
3822      *
3823      * @param inTouch   the touch mode to set
3824      * @param displayId the target display id
3825      */
3826     @Override // Binder call
setInTouchMode(boolean inTouch, int displayId)3827     public void setInTouchMode(boolean inTouch, int displayId) {
3828         synchronized (mGlobalLock) {
3829             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
3830             if (mPerDisplayFocusEnabled && (displayContent == null
3831                     || displayContent.isInTouchMode() == inTouch)) {
3832                 return;
3833             }
3834             final boolean displayHasOwnTouchMode =
3835                     displayContent != null && displayContent.hasOwnFocus();
3836             if (displayHasOwnTouchMode && displayContent.isInTouchMode() == inTouch) {
3837                 return;
3838             }
3839             final int pid = Binder.getCallingPid();
3840             final int uid = Binder.getCallingUid();
3841             final boolean hasPermission = hasTouchModePermission(pid);
3842             final long token = Binder.clearCallingIdentity();
3843             try {
3844                 // If mPerDisplayFocusEnabled is set or the display maintains its own touch mode,
3845                 // then just update the display pointed by displayId
3846                 if (mPerDisplayFocusEnabled || displayHasOwnTouchMode) {
3847                     if (mInputManager.setInTouchMode(inTouch, pid, uid, hasPermission, displayId)) {
3848                         displayContent.setInTouchMode(inTouch);
3849                     }
3850                 } else {  // Otherwise update all displays that do not maintain their own touch mode
3851                     final int displayCount = mRoot.mChildren.size();
3852                     for (int i = 0; i < displayCount; ++i) {
3853                         DisplayContent dc = mRoot.mChildren.get(i);
3854                         if (dc.isInTouchMode() == inTouch || dc.hasOwnFocus()) {
3855                             continue;
3856                         }
3857                         if (mInputManager.setInTouchMode(inTouch, pid, uid, hasPermission,
3858                                 dc.mDisplayId)) {
3859                             dc.setInTouchMode(inTouch);
3860                         }
3861                     }
3862                 }
3863             } finally {
3864                 Binder.restoreCallingIdentity(token);
3865             }
3866         }
3867     }
3868 
3869     /**
3870      * Sets the touch mode state forcibly on all displays (disregarding both the value of
3871      * {@code com.android.internal.R.bool.config_perDisplayFocusEnabled} and whether the display
3872      * maintains its own focus and touch mode).
3873      *
3874      * @param inTouch the touch mode to set
3875      */
3876     @Override // Binder call
setInTouchModeOnAllDisplays(boolean inTouch)3877     public void setInTouchModeOnAllDisplays(boolean inTouch) {
3878         final int pid = Binder.getCallingPid();
3879         final int uid = Binder.getCallingUid();
3880         final boolean hasPermission = hasTouchModePermission(pid);
3881         final long token = Binder.clearCallingIdentity();
3882         try {
3883             synchronized (mGlobalLock) {
3884                 for (int i = 0; i < mRoot.mChildren.size(); ++i) {
3885                     DisplayContent dc = mRoot.mChildren.get(i);
3886                     if (dc.isInTouchMode() != inTouch
3887                             && mInputManager.setInTouchMode(inTouch, pid, uid, hasPermission,
3888                             dc.mDisplayId)) {
3889                         dc.setInTouchMode(inTouch);
3890                     }
3891                 }
3892             }
3893         } finally {
3894             Binder.restoreCallingIdentity(token);
3895         }
3896     }
3897 
hasTouchModePermission(int pid)3898     private boolean hasTouchModePermission(int pid) {
3899         return mAtmService.instrumentationSourceHasPermission(pid, MODIFY_TOUCH_MODE_STATE)
3900                 || checkCallingPermission(MODIFY_TOUCH_MODE_STATE, "setInTouchMode()",
3901                 /* printlog= */ false);
3902     }
3903 
3904     /**
3905      * Returns the touch mode state for the display id passed as argument.
3906      *
3907      * This method will return the default touch mode state (represented by
3908      * {@code com.android.internal.R.bool.config_defaultInTouchMode}) if the display passed as
3909      * argument is no longer registered in {@RootWindowContainer}).
3910      */
3911     @Override  // Binder call
isInTouchMode(int displayId)3912     public boolean isInTouchMode(int displayId) {
3913         synchronized (mGlobalLock) {
3914             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
3915             if (displayContent == null) {
3916                 return mContext.getResources().getBoolean(R.bool.config_defaultInTouchMode);
3917             }
3918             return displayContent.isInTouchMode();
3919         }
3920     }
3921 
showEmulatorDisplayOverlayIfNeeded()3922     public void showEmulatorDisplayOverlayIfNeeded() {
3923         if (mContext.getResources().getBoolean(
3924                 com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay)
3925                 && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false)
3926                 && Build.IS_EMULATOR) {
3927             mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY));
3928         }
3929     }
3930 
showEmulatorDisplayOverlay()3931     public void showEmulatorDisplayOverlay() {
3932         synchronized (mGlobalLock) {
3933 
3934             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, ">>> showEmulatorDisplayOverlay");
3935             if (mEmulatorDisplayOverlay == null) {
3936                 mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(mContext,
3937                         getDefaultDisplayContentLocked(),
3938                         mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER)
3939                                 * TYPE_LAYER_MULTIPLIER + 10, mTransaction);
3940             }
3941             mEmulatorDisplayOverlay.setVisibility(true, mTransaction);
3942             mTransaction.apply();
3943         }
3944     }
3945 
3946     // TODO: more accounting of which pid(s) turned it on, keep count,
3947     // only allow disables from pids which have count on, etc.
3948     @Override
showStrictModeViolation(boolean on)3949     public void showStrictModeViolation(boolean on) {
3950         final int pid = Binder.getCallingPid();
3951         if (on) {
3952             // Show the visualization, and enqueue a second message to tear it
3953             // down if we don't hear back from the app.
3954             mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 1, pid));
3955             mH.sendMessageDelayed(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid),
3956                     DateUtils.SECOND_IN_MILLIS);
3957         } else {
3958             mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid));
3959         }
3960     }
3961 
showStrictModeViolation(int arg, int pid)3962     private void showStrictModeViolation(int arg, int pid) {
3963         final boolean on = arg != 0;
3964         synchronized (mGlobalLock) {
3965             // Ignoring requests to enable the red border from clients which aren't on screen.
3966             // (e.g. Broadcast Receivers in the background..)
3967             if (on && !mRoot.canShowStrictModeViolation(pid)) {
3968                 return;
3969             }
3970 
3971             if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM, ">>> showStrictModeViolation");
3972             // TODO: Modify this to use the surface trace once it is not going baffling.
3973             // b/31532461
3974             // TODO(multi-display): support multiple displays
3975             if (mStrictModeFlash == null) {
3976                 mStrictModeFlash = new StrictModeFlash(getDefaultDisplayContentLocked(),
3977                         mTransaction);
3978             }
3979             mStrictModeFlash.setVisibility(on, mTransaction);
3980             mTransaction.apply();
3981         }
3982     }
3983 
3984     @Override
setStrictModeVisualIndicatorPreference(String value)3985     public void setStrictModeVisualIndicatorPreference(String value) {
3986         SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
3987     }
3988 
3989     @Override
screenshotWallpaper()3990     public Bitmap screenshotWallpaper() {
3991         if (!checkCallingPermission(READ_FRAME_BUFFER, "screenshotWallpaper()")) {
3992             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
3993         }
3994         try {
3995             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
3996             synchronized (mGlobalLock) {
3997                 // TODO(b/115486823) Screenshot at secondary displays if needed.
3998                 final DisplayContent dc = mRoot.getDisplayContent(DEFAULT_DISPLAY);
3999                 return dc.mWallpaperController.screenshotWallpaperLocked();
4000             }
4001         } finally {
4002             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
4003         }
4004     }
4005 
4006     @Override
mirrorWallpaperSurface(int displayId)4007     public SurfaceControl mirrorWallpaperSurface(int displayId) {
4008         synchronized (mGlobalLock) {
4009             final DisplayContent dc = mRoot.getDisplayContent(displayId);
4010             return dc.mWallpaperController.mirrorWallpaperSurface();
4011         }
4012     }
4013 
4014     /**
4015      * Takes a snapshot of the screen.  In landscape mode this grabs the whole screen.
4016      * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
4017      * of the target image.
4018      */
4019     @Override
requestAssistScreenshot(final IAssistDataReceiver receiver)4020     public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) {
4021         if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) {
4022             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
4023         }
4024 
4025         final Bitmap bm;
4026         synchronized (mGlobalLock) {
4027             final DisplayContent displayContent = mRoot.getDisplayContent(DEFAULT_DISPLAY);
4028             if (displayContent == null) {
4029                 if (DEBUG_SCREENSHOT) {
4030                     Slog.i(TAG_WM, "Screenshot returning null. No Display for displayId="
4031                             + DEFAULT_DISPLAY);
4032                 }
4033                 bm = null;
4034             } else {
4035                 bm = displayContent.screenshotDisplayLocked();
4036             }
4037         }
4038 
4039         FgThread.getHandler().post(() -> {
4040             try {
4041                 receiver.onHandleAssistScreenshot(bm);
4042             } catch (RemoteException e) {
4043             }
4044         });
4045 
4046         return true;
4047     }
4048 
4049     /**
4050      * Retrieves a snapshot. If restoreFromDisk equals equals {@code true}, DO NOT HOLD THE WINDOW
4051      * MANAGER LOCK WHEN CALLING THIS METHOD!
4052      */
getTaskSnapshot(int taskId, int userId, boolean isLowResolution, boolean restoreFromDisk)4053     public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean isLowResolution,
4054             boolean restoreFromDisk) {
4055         return mTaskSnapshotController.getSnapshot(taskId, userId, restoreFromDisk,
4056                 isLowResolution);
4057     }
4058 
4059     /**
4060      * Generates and returns an up-to-date {@link Bitmap} for the specified taskId.
4061      *
4062      * @param taskId                  The task ID of the task for which a Bitmap is requested.
4063      * @param layerCaptureArgsBuilder A {@link ScreenCapture.LayerCaptureArgs.Builder} with
4064      *                                arguments for how to capture the Bitmap. The caller can
4065      *                                specify any arguments, but this method will ensure that the
4066      *                                specified task's SurfaceControl is used and the crop is set to
4067      *                                the bounds of that task.
4068      * @return The Bitmap, or null if no task with the specified ID can be found or the bitmap could
4069      * not be generated.
4070      */
4071     @Nullable
captureTaskBitmap(int taskId, @NonNull ScreenCapture.LayerCaptureArgs.Builder layerCaptureArgsBuilder)4072     public Bitmap captureTaskBitmap(int taskId,
4073             @NonNull ScreenCapture.LayerCaptureArgs.Builder layerCaptureArgsBuilder) {
4074         if (mTaskSnapshotController.shouldDisableSnapshots()) {
4075             return null;
4076         }
4077 
4078         synchronized (mGlobalLock) {
4079             final Task task = mRoot.anyTaskForId(taskId);
4080             if (task == null) {
4081                 return null;
4082             }
4083 
4084             // The bounds returned by the task represent the task's position on the screen. However,
4085             // we need to specify a crop relative to the task's surface control. Therefore, shift
4086             // the task's bounds to 0,0 so that we have the correct size and position within the
4087             // task's surface control.
4088             task.getBounds(mTmpRect);
4089             mTmpRect.offsetTo(0, 0);
4090 
4091             final SurfaceControl sc = task.getSurfaceControl();
4092             final ScreenCapture.ScreenshotHardwareBuffer buffer = ScreenCapture.captureLayers(
4093                     layerCaptureArgsBuilder.setLayer(sc).setSourceCrop(mTmpRect).build());
4094             if (buffer == null) {
4095                 Slog.w(TAG, "Could not get screenshot buffer for taskId: " + taskId);
4096                 return null;
4097             }
4098 
4099             return buffer.asBitmap();
4100         }
4101     }
4102 
4103     /**
4104      * In case a task write/delete operation was lost because the system crashed, this makes sure to
4105      * clean up the directory to remove obsolete files.
4106      *
4107      * @param persistentTaskIds A set of task ids that exist in our in-memory model.
4108      * @param runningUserIds The ids of the list of users that have tasks loaded in our in-memory
4109      *                       model.
4110      */
removeObsoleteTaskFiles(ArraySet<Integer> persistentTaskIds, int[] runningUserIds)4111     public void removeObsoleteTaskFiles(ArraySet<Integer> persistentTaskIds, int[] runningUserIds) {
4112         synchronized (mGlobalLock) {
4113             mTaskSnapshotController.removeObsoleteTaskFiles(persistentTaskIds, runningUserIds);
4114         }
4115     }
4116 
4117     @Override
setFixedToUserRotation(int displayId, int fixedToUserRotation)4118     public void setFixedToUserRotation(int displayId, int fixedToUserRotation) {
4119         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4120                 "setFixedToUserRotation()")) {
4121             throw new SecurityException("Requires SET_ORIENTATION permission");
4122         }
4123         final long origId = Binder.clearCallingIdentity();
4124         try {
4125             synchronized (mGlobalLock) {
4126                 final DisplayContent display = mRoot.getDisplayContent(displayId);
4127                 if (display == null) {
4128                     Slog.w(TAG, "Trying to set fixed to user rotation for a missing display.");
4129                     return;
4130                 }
4131                 display.getDisplayRotation().setFixedToUserRotation(fixedToUserRotation);
4132             }
4133         } finally {
4134             Binder.restoreCallingIdentity(origId);
4135         }
4136     }
4137 
getFixedToUserRotation(int displayId)4138     int getFixedToUserRotation(int displayId) {
4139         synchronized (mGlobalLock) {
4140             final DisplayContent display = mRoot.getDisplayContent(displayId);
4141             if (display == null) {
4142                 Slog.w(TAG, "Trying to get fixed to user rotation for a missing display.");
4143                 return -1;
4144             }
4145             return display.getDisplayRotation().getFixedToUserRotationMode();
4146         }
4147     }
4148 
4149     @Override
setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest)4150     public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
4151         if (!checkCallingPermission(
4152                 android.Manifest.permission.SET_ORIENTATION, "setIgnoreOrientationRequest()")) {
4153             throw new SecurityException("Requires SET_ORIENTATION permission");
4154         }
4155 
4156         final long origId = Binder.clearCallingIdentity();
4157         try {
4158             synchronized (mGlobalLock) {
4159                 final DisplayContent display = mRoot.getDisplayContent(displayId);
4160                 if (display == null) {
4161                     Slog.w(TAG, "Trying to setIgnoreOrientationRequest() for a missing display.");
4162                     return;
4163                 }
4164                 display.setIgnoreOrientationRequest(ignoreOrientationRequest);
4165             }
4166         } finally {
4167             Binder.restoreCallingIdentity(origId);
4168         }
4169     }
4170 
getIgnoreOrientationRequest(int displayId)4171     boolean getIgnoreOrientationRequest(int displayId) {
4172         synchronized (mGlobalLock) {
4173             final DisplayContent display = mRoot.getDisplayContent(displayId);
4174             if (display == null) {
4175                 Slog.w(TAG, "Trying to getIgnoreOrientationRequest() for a missing display.");
4176                 return false;
4177             }
4178             return display.getIgnoreOrientationRequest();
4179         }
4180     }
4181 
4182     /**
4183      * Controls whether ignore orientation request logic in {@link DisplayArea} is disabled
4184      * at runtime and how to optionally map some requested orientations to others.
4185      *
4186      * <p>Note: this assumes that {@link #mGlobalLock} is held by the caller.
4187      *
4188      * @param isIgnoreOrientationRequestDisabled when {@code true}, the system always ignores the
4189      *                   value of {@link DisplayArea#getIgnoreOrientationRequest} and app requested
4190      *                   orientation is respected.
4191      * @param fromOrientations The orientations we want to map to the correspondent orientations
4192      *                        in toOrientation.
4193      * @param toOrientations The orientations we map to the ones in fromOrientations at  the same
4194      *                       index
4195      */
setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled, @Nullable int[] fromOrientations, @Nullable int[] toOrientations)4196     void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
4197             @Nullable int[] fromOrientations, @Nullable int[] toOrientations) {
4198         mOrientationMapping.clear();
4199         if (fromOrientations != null && toOrientations != null
4200                 && fromOrientations.length == toOrientations.length) {
4201             for (int i = 0; i < fromOrientations.length; i++) {
4202                 mOrientationMapping.put(fromOrientations[i], toOrientations[i]);
4203             }
4204         }
4205         if (isIgnoreOrientationRequestDisabled == mIsIgnoreOrientationRequestDisabled) {
4206             return;
4207         }
4208         mIsIgnoreOrientationRequestDisabled = isIgnoreOrientationRequestDisabled;
4209         for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
4210             mRoot.getChildAt(i).onIsIgnoreOrientationRequestDisabledChanged();
4211         }
4212     }
4213 
4214     /**
4215      * When {@link mIsIgnoreOrientationRequestDisabled} is {@value true} this method returns the
4216      * orientation to use in place of the one in input. It returns the same requestedOrientation in
4217      * input otherwise.
4218      *
4219      * @param requestedOrientation The orientation that can be mapped.
4220      * @return The orientation to use in place of requestedOrientation.
4221      */
mapOrientationRequest(int requestedOrientation)4222     int mapOrientationRequest(int requestedOrientation) {
4223         if (!mIsIgnoreOrientationRequestDisabled) {
4224             return requestedOrientation;
4225         }
4226         return mOrientationMapping.get(requestedOrientation, requestedOrientation);
4227     }
4228 
4229     /**
4230      * Whether the system ignores the value of {@link DisplayArea#getIgnoreOrientationRequest} and
4231      * app requested orientation is respected.
4232      *
4233      * <p>Note: this assumes that {@link #mGlobalLock} is held by the caller.
4234      */
isIgnoreOrientationRequestDisabled()4235     boolean isIgnoreOrientationRequestDisabled() {
4236         return mIsIgnoreOrientationRequestDisabled
4237                 || !mLetterboxConfiguration.isIgnoreOrientationRequestAllowed();
4238     }
4239 
4240     @Override
freezeRotation(int rotation)4241     public void freezeRotation(int rotation) {
4242         freezeDisplayRotation(Display.DEFAULT_DISPLAY, rotation);
4243     }
4244 
4245     /**
4246      * Freeze rotation changes.  (Enable "rotation lock".)
4247      * Persists across reboots.
4248      * @param displayId The ID of the display to freeze.
4249      * @param rotation The desired rotation to freeze to, or -1 to use the current rotation.
4250      */
4251     @Override
freezeDisplayRotation(int displayId, int rotation)4252     public void freezeDisplayRotation(int displayId, int rotation) {
4253         // TODO(multi-display): Track which display is rotated.
4254         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4255                 "freezeRotation()")) {
4256             throw new SecurityException("Requires SET_ORIENTATION permission");
4257         }
4258         if (rotation < -1 || rotation > Surface.ROTATION_270) {
4259             throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
4260                     + "rotation constant.");
4261         }
4262 
4263         final long origId = Binder.clearCallingIdentity();
4264         try {
4265             synchronized (mGlobalLock) {
4266                 final DisplayContent display = mRoot.getDisplayContent(displayId);
4267                 if (display == null) {
4268                     Slog.w(TAG, "Trying to freeze rotation for a missing display.");
4269                     return;
4270                 }
4271                 display.getDisplayRotation().freezeRotation(rotation);
4272             }
4273         } finally {
4274             Binder.restoreCallingIdentity(origId);
4275         }
4276 
4277         updateRotationUnchecked(false, false);
4278     }
4279 
4280     @Override
thawRotation()4281     public void thawRotation() {
4282         thawDisplayRotation(Display.DEFAULT_DISPLAY);
4283     }
4284 
4285     /**
4286      * Thaw rotation changes.  (Disable "rotation lock".)
4287      * Persists across reboots.
4288      */
4289     @Override
thawDisplayRotation(int displayId)4290     public void thawDisplayRotation(int displayId) {
4291         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4292                 "thawRotation()")) {
4293             throw new SecurityException("Requires SET_ORIENTATION permission");
4294         }
4295 
4296         ProtoLog.v(WM_DEBUG_ORIENTATION, "thawRotation: mRotation=%d", getDefaultDisplayRotation());
4297 
4298         final long origId = Binder.clearCallingIdentity();
4299         try {
4300             synchronized (mGlobalLock) {
4301                 final DisplayContent display = mRoot.getDisplayContent(displayId);
4302                 if (display == null) {
4303                     Slog.w(TAG, "Trying to thaw rotation for a missing display.");
4304                     return;
4305                 }
4306                 display.getDisplayRotation().thawRotation();
4307             }
4308         } finally {
4309             Binder.restoreCallingIdentity(origId);
4310         }
4311 
4312         updateRotationUnchecked(false, false);
4313     }
4314 
4315     @Override
isRotationFrozen()4316     public boolean isRotationFrozen() {
4317         return isDisplayRotationFrozen(Display.DEFAULT_DISPLAY);
4318     }
4319 
4320     @Override
isDisplayRotationFrozen(int displayId)4321     public boolean isDisplayRotationFrozen(int displayId) {
4322         synchronized (mGlobalLock) {
4323             final DisplayContent display = mRoot.getDisplayContent(displayId);
4324             if (display == null) {
4325                 Slog.w(TAG, "Trying to check if rotation is frozen on a missing display.");
4326                 return false;
4327             }
4328             return display.getDisplayRotation().isRotationFrozen();
4329         }
4330     }
4331 
getDisplayUserRotation(int displayId)4332     int getDisplayUserRotation(int displayId) {
4333         synchronized (mGlobalLock) {
4334             final DisplayContent display = mRoot.getDisplayContent(displayId);
4335             if (display == null) {
4336                 Slog.w(TAG, "Trying to get user rotation of a missing display.");
4337                 return -1;
4338             }
4339             return display.getDisplayRotation().getUserRotation();
4340         }
4341     }
4342 
4343     /**
4344      * Recalculate the current rotation.
4345      *
4346      * Called by the window manager policy whenever the state of the system changes
4347      * such that the current rotation might need to be updated, such as when the
4348      * device is docked or rotated into a new posture.
4349      */
4350     @Override
updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout)4351     public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
4352         updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
4353     }
4354 
updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout)4355     private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
4356         ProtoLog.v(WM_DEBUG_ORIENTATION, "updateRotationUnchecked:"
4357                         + " alwaysSendConfiguration=%b forceRelayout=%b",
4358                 alwaysSendConfiguration, forceRelayout);
4359 
4360         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation");
4361 
4362         final long origId = Binder.clearCallingIdentity();
4363 
4364         try {
4365             synchronized (mGlobalLock) {
4366                 boolean layoutNeeded = false;
4367                 final int displayCount = mRoot.mChildren.size();
4368                 for (int i = 0; i < displayCount; ++i) {
4369                     final DisplayContent displayContent = mRoot.mChildren.get(i);
4370                     Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
4371                     final boolean rotationChanged = displayContent.updateRotationUnchecked();
4372                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
4373 
4374                     if (rotationChanged) {
4375                         mAtmService.getTaskChangeNotificationController()
4376                                 .notifyOnActivityRotation(displayContent.mDisplayId);
4377                     }
4378 
4379                     final boolean pendingRemoteDisplayChange = rotationChanged
4380                             && (displayContent.mRemoteDisplayChangeController
4381                                     .isWaitingForRemoteDisplayChange()
4382                             || displayContent.mTransitionController.isCollecting());
4383                     // Even if alwaysSend, we are waiting for a transition or remote to provide
4384                     // updated configuration, so we can't update configuration yet.
4385                     if (!pendingRemoteDisplayChange) {
4386                         // The layout-needed flag will be set if there is a rotation change, so
4387                         // only set it if the caller requests to force relayout.
4388                         if (forceRelayout) {
4389                             displayContent.setLayoutNeeded();
4390                             layoutNeeded = true;
4391                         }
4392                         if (rotationChanged || alwaysSendConfiguration) {
4393                             displayContent.sendNewConfiguration();
4394                         }
4395                     }
4396                 }
4397 
4398                 if (layoutNeeded) {
4399                     Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
4400                             "updateRotation: performSurfacePlacement");
4401                     mWindowPlacerLocked.performSurfacePlacement();
4402                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
4403                 }
4404             }
4405         } finally {
4406             Binder.restoreCallingIdentity(origId);
4407             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
4408         }
4409     }
4410 
4411     @Override
getDefaultDisplayRotation()4412     public int getDefaultDisplayRotation() {
4413         synchronized (mGlobalLock) {
4414             return getDefaultDisplayContentLocked().getRotation();
4415         }
4416     }
4417 
4418     @Override
setDisplayChangeWindowController(IDisplayChangeWindowController controller)4419     public void setDisplayChangeWindowController(IDisplayChangeWindowController controller) {
4420         mAtmService.enforceTaskPermission("setDisplayWindowRotationController");
4421         try {
4422             synchronized (mGlobalLock) {
4423                 if (mDisplayChangeController != null) {
4424                     mDisplayChangeController.asBinder().unlinkToDeath(
4425                             mDisplayChangeControllerDeath, 0);
4426                     mDisplayChangeController = null;
4427                 }
4428                 controller.asBinder().linkToDeath(mDisplayChangeControllerDeath, 0);
4429                 mDisplayChangeController = controller;
4430             }
4431         } catch (RemoteException e) {
4432             throw new RuntimeException("Unable to set rotation controller", e);
4433         }
4434     }
4435 
4436     @Override
addShellRoot(int displayId, IWindow client, @WindowManager.ShellRootLayer int shellRootLayer)4437     public SurfaceControl addShellRoot(int displayId, IWindow client,
4438             @WindowManager.ShellRootLayer int shellRootLayer) {
4439         if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
4440                 != PackageManager.PERMISSION_GRANTED) {
4441             throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
4442         }
4443         final long origId = Binder.clearCallingIdentity();
4444         try {
4445             synchronized (mGlobalLock) {
4446                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
4447                 if (dc == null) {
4448                     return null;
4449                 }
4450                 return dc.addShellRoot(client, shellRootLayer);
4451             }
4452         } finally {
4453             Binder.restoreCallingIdentity(origId);
4454         }
4455     }
4456 
4457     @Override
setShellRootAccessibilityWindow(int displayId, @WindowManager.ShellRootLayer int shellRootLayer, IWindow target)4458     public void setShellRootAccessibilityWindow(int displayId,
4459             @WindowManager.ShellRootLayer int shellRootLayer, IWindow target) {
4460         if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
4461                 != PackageManager.PERMISSION_GRANTED) {
4462             throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
4463         }
4464         final long origId = Binder.clearCallingIdentity();
4465         try {
4466             synchronized (mGlobalLock) {
4467                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
4468                 if (dc == null) {
4469                     return;
4470                 }
4471                 ShellRoot root = dc.mShellRoots.get(shellRootLayer);
4472                 if (root == null) {
4473                     return;
4474                 }
4475                 root.setAccessibilityWindow(target);
4476             }
4477         } finally {
4478             Binder.restoreCallingIdentity(origId);
4479         }
4480     }
4481 
4482     @Override
setDisplayWindowInsetsController( int displayId, IDisplayWindowInsetsController insetsController)4483     public void setDisplayWindowInsetsController(
4484             int displayId, IDisplayWindowInsetsController insetsController) {
4485         if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
4486                 != PackageManager.PERMISSION_GRANTED) {
4487             throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
4488         }
4489         final long origId = Binder.clearCallingIdentity();
4490         try {
4491             synchronized (mGlobalLock) {
4492                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
4493                 if (dc == null) {
4494                     return;
4495                 }
4496                 dc.setRemoteInsetsController(insetsController);
4497             }
4498         } finally {
4499             Binder.restoreCallingIdentity(origId);
4500         }
4501     }
4502 
4503     @Override
updateDisplayWindowRequestedVisibleTypes( int displayId, @InsetsType int requestedVisibleTypes)4504     public void updateDisplayWindowRequestedVisibleTypes(
4505             int displayId, @InsetsType int requestedVisibleTypes) {
4506         if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
4507                 != PackageManager.PERMISSION_GRANTED) {
4508             throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
4509         }
4510         final long origId = Binder.clearCallingIdentity();
4511         try {
4512             synchronized (mGlobalLock) {
4513                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
4514                 if (dc == null || dc.mRemoteInsetsControlTarget == null) {
4515                     return;
4516                 }
4517                 dc.mRemoteInsetsControlTarget.setRequestedVisibleTypes(requestedVisibleTypes);
4518                 dc.getInsetsStateController().onRequestedVisibleTypesChanged(
4519                         dc.mRemoteInsetsControlTarget);
4520             }
4521         } finally {
4522             Binder.restoreCallingIdentity(origId);
4523         }
4524     }
4525 
4526     @Override
watchRotation(IRotationWatcher watcher, int displayId)4527     public int watchRotation(IRotationWatcher watcher, int displayId) {
4528         final DisplayContent displayContent;
4529         synchronized (mGlobalLock) {
4530             displayContent = mRoot.getDisplayContent(displayId);
4531             if (displayContent == null) {
4532                 throw new IllegalArgumentException("Trying to register rotation event "
4533                         + "for invalid display: " + displayId);
4534             }
4535             mRotationWatcherController.registerDisplayRotationWatcher(watcher, displayId);
4536             return displayContent.getRotation();
4537         }
4538     }
4539 
4540     @Override
removeRotationWatcher(IRotationWatcher watcher)4541     public void removeRotationWatcher(IRotationWatcher watcher) {
4542         synchronized (mGlobalLock) {
4543             mRotationWatcherController.removeRotationWatcher(watcher);
4544         }
4545     }
4546 
4547     @Surface.Rotation
4548     @Override
registerProposedRotationListener(IBinder contextToken, IRotationWatcher listener)4549     public int registerProposedRotationListener(IBinder contextToken, IRotationWatcher listener) {
4550         synchronized (mGlobalLock) {
4551             final WindowContainer<?> wc =
4552                     mRotationWatcherController.getAssociatedWindowContainer(contextToken);
4553             if (wc == null) {
4554                 Slog.w(TAG, "Register rotation listener from non-existing token, uid="
4555                         + Binder.getCallingUid());
4556                 return Surface.ROTATION_0;
4557             }
4558             mRotationWatcherController.registerProposedRotationListener(listener, contextToken);
4559             final WindowOrientationListener orientationListener =
4560                     wc.mDisplayContent.getDisplayRotation().getOrientationListener();
4561             if (orientationListener != null) {
4562                 // It may be -1 if sensor is disabled.
4563                 final int rotation = orientationListener.getProposedRotation();
4564                 if (rotation >= Surface.ROTATION_0) {
4565                     return rotation;
4566                 }
4567             }
4568             return wc.getWindowConfiguration().getRotation();
4569         }
4570     }
4571 
4572     @Override
registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener, int displayId)4573     public boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
4574             int displayId) {
4575         synchronized (mGlobalLock) {
4576             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
4577             if (displayContent == null) {
4578                 throw new IllegalArgumentException("Trying to register visibility event "
4579                         + "for invalid display: " + displayId);
4580             }
4581             mWallpaperVisibilityListeners.registerWallpaperVisibilityListener(listener, displayId);
4582             return displayContent.mWallpaperController.isWallpaperVisible();
4583         }
4584     }
4585 
4586     @Override
unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener, int displayId)4587     public void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
4588             int displayId) {
4589         synchronized (mGlobalLock) {
4590             mWallpaperVisibilityListeners
4591                     .unregisterWallpaperVisibilityListener(listener, displayId);
4592         }
4593     }
4594 
4595     @Override
registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener, int displayId)4596     public void registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener,
4597             int displayId) {
4598         synchronized (mGlobalLock) {
4599             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
4600             if (displayContent == null) {
4601                 throw new IllegalArgumentException("Trying to register visibility event "
4602                         + "for invalid display: " + displayId);
4603             }
4604             displayContent.registerSystemGestureExclusionListener(listener);
4605         }
4606     }
4607 
4608     @Override
unregisterSystemGestureExclusionListener(ISystemGestureExclusionListener listener, int displayId)4609     public void unregisterSystemGestureExclusionListener(ISystemGestureExclusionListener listener,
4610             int displayId) {
4611         synchronized (mGlobalLock) {
4612             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
4613             if (displayContent == null) {
4614                 throw new IllegalArgumentException("Trying to register visibility event "
4615                         + "for invalid display: " + displayId);
4616             }
4617             displayContent.unregisterSystemGestureExclusionListener(listener);
4618         }
4619     }
4620 
reportSystemGestureExclusionChanged(Session session, IWindow window, List<Rect> exclusionRects)4621     void reportSystemGestureExclusionChanged(Session session, IWindow window,
4622             List<Rect> exclusionRects) {
4623         synchronized (mGlobalLock) {
4624             final WindowState win = windowForClientLocked(session, window, true);
4625             if (win.setSystemGestureExclusion(exclusionRects)) {
4626                 win.getDisplayContent().updateSystemGestureExclusion();
4627             }
4628         }
4629     }
4630 
reportKeepClearAreasChanged(Session session, IWindow window, List<Rect> restricted, List<Rect> unrestricted)4631     void reportKeepClearAreasChanged(Session session, IWindow window,
4632             List<Rect> restricted, List<Rect> unrestricted) {
4633         synchronized (mGlobalLock) {
4634             final WindowState win = windowForClientLocked(session, window, true);
4635             if (win.setKeepClearAreas(restricted, unrestricted)) {
4636                 win.getDisplayContent().updateKeepClearAreas();
4637             }
4638         }
4639     }
4640 
4641     @Override
registerDisplayFoldListener(IDisplayFoldListener listener)4642     public void registerDisplayFoldListener(IDisplayFoldListener listener) {
4643         mPolicy.registerDisplayFoldListener(listener);
4644     }
4645 
4646     @Override
unregisterDisplayFoldListener(IDisplayFoldListener listener)4647     public void unregisterDisplayFoldListener(IDisplayFoldListener listener) {
4648         mPolicy.unregisterDisplayFoldListener(listener);
4649     }
4650 
4651     /**
4652      * Overrides the folded area.
4653      *
4654      * @param area the overriding folded area or an empty {@code Rect} to clear the override.
4655      */
setOverrideFoldedArea(@onNull Rect area)4656     void setOverrideFoldedArea(@NonNull Rect area) {
4657         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
4658                 != PackageManager.PERMISSION_GRANTED) {
4659             throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
4660         }
4661 
4662         final long origId = Binder.clearCallingIdentity();
4663         try {
4664             synchronized (mGlobalLock) {
4665                 mPolicy.setOverrideFoldedArea(area);
4666             }
4667         } finally {
4668             Binder.restoreCallingIdentity(origId);
4669         }
4670     }
4671 
4672     /**
4673      * Get the display folded area.
4674      */
getFoldedArea()4675     @NonNull Rect getFoldedArea() {
4676         final long origId = Binder.clearCallingIdentity();
4677         try {
4678             synchronized (mGlobalLock) {
4679                 return mPolicy.getFoldedArea();
4680             }
4681         } finally {
4682             Binder.restoreCallingIdentity(origId);
4683         }
4684     }
4685 
4686     /**
4687      * Registers a hierarchy listener that gets callbacks when the hierarchy changes. The listener's
4688      * onDisplayAdded() will not be called for the displays returned.
4689      *
4690      * @return the displayIds for the existing displays
4691      */
4692     @Override
registerDisplayWindowListener(IDisplayWindowListener listener)4693     public int[] registerDisplayWindowListener(IDisplayWindowListener listener) {
4694         mAtmService.enforceTaskPermission("registerDisplayWindowListener");
4695         final long ident = Binder.clearCallingIdentity();
4696         try {
4697             return mDisplayNotificationController.registerListener(listener);
4698         } finally {
4699             Binder.restoreCallingIdentity(ident);
4700         }
4701     }
4702 
4703     /** Unregister a hierarchy listener so that it stops receiving callbacks. */
4704     @Override
unregisterDisplayWindowListener(IDisplayWindowListener listener)4705     public void unregisterDisplayWindowListener(IDisplayWindowListener listener) {
4706         mAtmService.enforceTaskPermission("unregisterDisplayWindowListener");
4707         mDisplayNotificationController.unregisterListener(listener);
4708     }
4709 
4710     @Override
getPreferredOptionsPanelGravity(int displayId)4711     public int getPreferredOptionsPanelGravity(int displayId) {
4712         synchronized (mGlobalLock) {
4713             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
4714             if (displayContent == null) {
4715                 return Gravity.CENTER | Gravity.BOTTOM;
4716             }
4717             return displayContent.getPreferredOptionsPanelGravity();
4718         }
4719     }
4720 
4721     /**
4722      * Starts the view server on the specified port.
4723      *
4724      * @param port The port to listener to.
4725      *
4726      * @return True if the server was successfully started, false otherwise.
4727      *
4728      * @see com.android.server.wm.ViewServer
4729      * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
4730      */
4731     @Override
startViewServer(int port)4732     public boolean startViewServer(int port) {
4733         if (isSystemSecure()) {
4734             return false;
4735         }
4736 
4737         if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
4738             return false;
4739         }
4740 
4741         if (port < 1024) {
4742             return false;
4743         }
4744 
4745         if (mViewServer != null) {
4746             if (!mViewServer.isRunning()) {
4747                 try {
4748                     return mViewServer.start();
4749                 } catch (IOException e) {
4750                     ProtoLog.w(WM_ERROR, "View server did not start");
4751                 }
4752             }
4753             return false;
4754         }
4755 
4756         try {
4757             mViewServer = new ViewServer(this, port);
4758             return mViewServer.start();
4759         } catch (IOException e) {
4760             ProtoLog.w(WM_ERROR, "View server did not start");
4761         }
4762         return false;
4763     }
4764 
isSystemSecure()4765     private boolean isSystemSecure() {
4766         return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
4767                 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4768     }
4769 
4770     /**
4771      * Stops the view server if it exists.
4772      *
4773      * @return True if the server stopped, false if it wasn't started or
4774      *         couldn't be stopped.
4775      *
4776      * @see com.android.server.wm.ViewServer
4777      */
4778     @Override
stopViewServer()4779     public boolean stopViewServer() {
4780         if (isSystemSecure()) {
4781             return false;
4782         }
4783 
4784         if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
4785             return false;
4786         }
4787 
4788         if (mViewServer != null) {
4789             return mViewServer.stop();
4790         }
4791         return false;
4792     }
4793 
4794     /**
4795      * Indicates whether the view server is running.
4796      *
4797      * @return True if the server is running, false otherwise.
4798      *
4799      * @see com.android.server.wm.ViewServer
4800      */
4801     @Override
isViewServerRunning()4802     public boolean isViewServerRunning() {
4803         if (isSystemSecure()) {
4804             return false;
4805         }
4806 
4807         if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
4808             return false;
4809         }
4810 
4811         return mViewServer != null && mViewServer.isRunning();
4812     }
4813 
4814     /**
4815      * Lists all available windows in the system. The listing is written in the specified Socket's
4816      * output stream with the following syntax: windowHashCodeInHexadecimal windowName
4817      * Each line of the output represents a different window.
4818      *
4819      * @param client The remote client to send the listing to.
4820      * @return false if an error occurred, true otherwise.
4821      */
viewServerListWindows(Socket client)4822     boolean viewServerListWindows(Socket client) {
4823         if (isSystemSecure()) {
4824             return false;
4825         }
4826 
4827         boolean result = true;
4828 
4829         final ArrayList<WindowState> windows = new ArrayList();
4830         synchronized (mGlobalLock) {
4831             mRoot.forAllWindows(w -> {
4832                 windows.add(w);
4833             }, false /* traverseTopToBottom */);
4834         }
4835 
4836         BufferedWriter out = null;
4837 
4838         // Any uncaught exception will crash the system process
4839         try {
4840             OutputStream clientStream = client.getOutputStream();
4841             out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4842 
4843             final int count = windows.size();
4844             for (int i = 0; i < count; i++) {
4845                 final WindowState w = windows.get(i);
4846                 out.write(Integer.toHexString(System.identityHashCode(w)));
4847                 out.write(' ');
4848                 out.append(w.mAttrs.getTitle());
4849                 out.write('\n');
4850             }
4851 
4852             out.write("DONE.\n");
4853             out.flush();
4854         } catch (Exception e) {
4855             result = false;
4856         } finally {
4857             if (out != null) {
4858                 try {
4859                     out.close();
4860                 } catch (IOException e) {
4861                     result = false;
4862                 }
4863             }
4864         }
4865 
4866         return result;
4867     }
4868 
4869     // TODO(multidisplay): Extend to multiple displays.
4870     /**
4871      * Returns the focused window in the following format:
4872      * windowHashCodeInHexadecimal windowName
4873      *
4874      * @param client The remote client to send the listing to.
4875      * @return False if an error occurred, true otherwise.
4876      */
viewServerGetFocusedWindow(Socket client)4877     boolean viewServerGetFocusedWindow(Socket client) {
4878         if (isSystemSecure()) {
4879             return false;
4880         }
4881 
4882         boolean result = true;
4883 
4884         WindowState focusedWindow = getFocusedWindow();
4885 
4886         BufferedWriter out = null;
4887 
4888         // Any uncaught exception will crash the system process
4889         try {
4890             OutputStream clientStream = client.getOutputStream();
4891             out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
4892 
4893             if(focusedWindow != null) {
4894                 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
4895                 out.write(' ');
4896                 out.append(focusedWindow.mAttrs.getTitle());
4897             }
4898             out.write('\n');
4899             out.flush();
4900         } catch (Exception e) {
4901             result = false;
4902         } finally {
4903             if (out != null) {
4904                 try {
4905                     out.close();
4906                 } catch (IOException e) {
4907                     result = false;
4908                 }
4909             }
4910         }
4911 
4912         return result;
4913     }
4914 
4915     /**
4916      * Sends a command to a target window. The result of the command, if any, will be
4917      * written in the output stream of the specified socket.
4918      *
4919      * The parameters must follow this syntax:
4920      * windowHashcode extra
4921      *
4922      * Where XX is the length in characeters of the windowTitle.
4923      *
4924      * The first parameter is the target window. The window with the specified hashcode
4925      * will be the target. If no target can be found, nothing happens. The extra parameters
4926      * will be delivered to the target window and as parameters to the command itself.
4927      *
4928      * @param client The remote client to sent the result, if any, to.
4929      * @param command The command to execute.
4930      * @param parameters The command parameters.
4931      *
4932      * @return True if the command was successfully delivered, false otherwise. This does
4933      *         not indicate whether the command itself was successful.
4934      */
viewServerWindowCommand(Socket client, String command, String parameters)4935     boolean viewServerWindowCommand(Socket client, String command, String parameters) {
4936         if (isSystemSecure()) {
4937             return false;
4938         }
4939 
4940         boolean success = true;
4941         Parcel data = null;
4942         Parcel reply = null;
4943 
4944         BufferedWriter out = null;
4945 
4946         // Any uncaught exception will crash the system process
4947         try {
4948             // Find the hashcode of the window
4949             int index = parameters.indexOf(' ');
4950             if (index == -1) {
4951                 index = parameters.length();
4952             }
4953             final String code = parameters.substring(0, index);
4954             int hashCode = (int) Long.parseLong(code, 16);
4955 
4956             // Extract the command's parameter after the window description
4957             if (index < parameters.length()) {
4958                 parameters = parameters.substring(index + 1);
4959             } else {
4960                 parameters = "";
4961             }
4962 
4963             final WindowState window = findWindow(hashCode);
4964             if (window == null) {
4965                 return false;
4966             }
4967 
4968             data = Parcel.obtain();
4969             data.writeInterfaceToken("android.view.IWindow");
4970             data.writeString(command);
4971             data.writeString(parameters);
4972             data.writeInt(1);
4973             ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
4974 
4975             reply = Parcel.obtain();
4976 
4977             final IBinder binder = window.mClient.asBinder();
4978             // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
4979             binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
4980 
4981             reply.readException();
4982 
4983             if (!client.isOutputShutdown()) {
4984                 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
4985                 out.write("DONE\n");
4986                 out.flush();
4987             }
4988 
4989         } catch (Exception e) {
4990             ProtoLog.w(WM_ERROR, "Could not send command %s with parameters %s. %s", command,
4991                     parameters, e);
4992             success = false;
4993         } finally {
4994             if (data != null) {
4995                 data.recycle();
4996             }
4997             if (reply != null) {
4998                 reply.recycle();
4999             }
5000             if (out != null) {
5001                 try {
5002                     out.close();
5003                 } catch (IOException e) {
5004 
5005                 }
5006             }
5007         }
5008 
5009         return success;
5010     }
5011 
addWindowChangeListener(WindowChangeListener listener)5012     public void addWindowChangeListener(WindowChangeListener listener) {
5013         synchronized (mGlobalLock) {
5014             mWindowChangeListeners.add(listener);
5015         }
5016     }
5017 
removeWindowChangeListener(WindowChangeListener listener)5018     public void removeWindowChangeListener(WindowChangeListener listener) {
5019         synchronized (mGlobalLock) {
5020             mWindowChangeListeners.remove(listener);
5021         }
5022     }
5023 
notifyWindowsChanged()5024     private void notifyWindowsChanged() {
5025         WindowChangeListener[] windowChangeListeners;
5026         synchronized (mGlobalLock) {
5027             if(mWindowChangeListeners.isEmpty()) {
5028                 return;
5029             }
5030             windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5031             windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5032         }
5033         int N = windowChangeListeners.length;
5034         for(int i = 0; i < N; i++) {
5035             windowChangeListeners[i].windowsChanged();
5036         }
5037     }
5038 
notifyFocusChanged()5039     private void notifyFocusChanged() {
5040         WindowChangeListener[] windowChangeListeners;
5041         synchronized (mGlobalLock) {
5042             if(mWindowChangeListeners.isEmpty()) {
5043                 return;
5044             }
5045             windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5046             windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5047         }
5048         int N = windowChangeListeners.length;
5049         for(int i = 0; i < N; i++) {
5050             windowChangeListeners[i].focusChanged();
5051         }
5052     }
5053 
findWindow(int hashCode)5054     private WindowState findWindow(int hashCode) {
5055         if (hashCode == -1) {
5056             // TODO(multidisplay): Extend to multiple displays.
5057             return getFocusedWindow();
5058         }
5059 
5060         synchronized (mGlobalLock) {
5061             return mRoot.getWindow((w) -> System.identityHashCode(w) == hashCode);
5062         }
5063     }
5064 
computeNewConfiguration(int displayId)5065     public Configuration computeNewConfiguration(int displayId) {
5066         synchronized (mGlobalLock) {
5067             return computeNewConfigurationLocked(displayId);
5068         }
5069     }
5070 
computeNewConfigurationLocked(int displayId)5071     private Configuration computeNewConfigurationLocked(int displayId) {
5072         if (!mDisplayReady) {
5073             return null;
5074         }
5075         final Configuration config = new Configuration();
5076         final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5077         displayContent.computeScreenConfiguration(config);
5078         return config;
5079     }
5080 
notifyHardKeyboardStatusChange()5081     void notifyHardKeyboardStatusChange() {
5082         final boolean available;
5083         final WindowManagerInternal.OnHardKeyboardStatusChangeListener listener;
5084         synchronized (mGlobalLock) {
5085             listener = mHardKeyboardStatusChangeListener;
5086             available = mHardKeyboardAvailable;
5087         }
5088         if (listener != null) {
5089             listener.onHardKeyboardStatusChange(available);
5090         }
5091     }
5092 
5093     // -------------------------------------------------------------
5094     // Input Events and Focus Management
5095     // -------------------------------------------------------------
5096 
5097     final InputManagerCallback mInputManagerCallback = new InputManagerCallback(this);
5098     private boolean mEventDispatchingEnabled;
5099 
5100     @Override
setEventDispatching(boolean enabled)5101     public void setEventDispatching(boolean enabled) {
5102         if (!checkCallingPermission(MANAGE_APP_TOKENS, "setEventDispatching()")) {
5103             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
5104         }
5105 
5106         synchronized (mGlobalLock) {
5107             mEventDispatchingEnabled = enabled;
5108             if (mDisplayEnabled) {
5109                 mInputManagerCallback.setEventDispatchingLw(enabled);
5110             }
5111         }
5112     }
5113 
getFocusedWindow()5114     private WindowState getFocusedWindow() {
5115         synchronized (mGlobalLock) {
5116             return getFocusedWindowLocked();
5117         }
5118     }
5119 
getFocusedWindowLocked()5120     WindowState getFocusedWindowLocked() {
5121         // Return the focused window in the focused display.
5122         return mRoot.getTopFocusedDisplayContent().mCurrentFocus;
5123     }
5124 
getImeFocusRootTaskLocked()5125     Task getImeFocusRootTaskLocked() {
5126         // Don't use mCurrentFocus.getStack() because it returns home stack for system windows.
5127         // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE
5128         // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved
5129         // to make room for IME, but the window is not the focused window that's taking input.
5130         // TODO (b/111080190): Consider the case of multiple IMEs on multi-display.
5131         final DisplayContent topFocusedDisplay = mRoot.getTopFocusedDisplayContent();
5132         final ActivityRecord focusedApp = topFocusedDisplay.mFocusedApp;
5133         return (focusedApp != null && focusedApp.getTask() != null)
5134                 ? focusedApp.getTask().getRootTask() : null;
5135     }
5136 
detectSafeMode()5137     public boolean detectSafeMode() {
5138         if (!mInputManagerCallback.waitForInputDevicesReady(
5139                 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
5140             ProtoLog.w(WM_ERROR, "Devices still not ready after waiting %d"
5141                             + " milliseconds before attempting to detect safe mode.",
5142                     INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS);
5143         }
5144 
5145         if (Settings.Global.getInt(
5146                 mContext.getContentResolver(), Settings.Global.SAFE_BOOT_DISALLOWED, 0) != 0) {
5147             return false;
5148         }
5149 
5150         int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
5151                 KeyEvent.KEYCODE_MENU);
5152         int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
5153         int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
5154                 KeyEvent.KEYCODE_DPAD_CENTER);
5155         int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
5156                 InputManagerService.BTN_MOUSE);
5157         int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
5158                 KeyEvent.KEYCODE_VOLUME_DOWN);
5159         mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
5160                 || volumeDownState > 0;
5161         try {
5162             if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0
5163                     || SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) != 0) {
5164                 mSafeMode = true;
5165                 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
5166             }
5167         } catch (IllegalArgumentException e) {
5168         }
5169         if (mSafeMode) {
5170             ProtoLog.i(WM_ERROR, "SAFE MODE ENABLED (menu=%d s=%d dpad=%d"
5171                     + " trackball=%d)", menuState, sState, dpadState, trackballState);
5172             // May already be set if (for instance) this process has crashed
5173             if (SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) == 0) {
5174                 SystemProperties.set(ShutdownThread.RO_SAFEMODE_PROPERTY, "1");
5175             }
5176         } else {
5177             ProtoLog.i(WM_ERROR, "SAFE MODE not enabled");
5178         }
5179         mPolicy.setSafeMode(mSafeMode);
5180         return mSafeMode;
5181     }
5182 
displayReady()5183     public void displayReady() {
5184         synchronized (mGlobalLock) {
5185             if (mMaxUiWidth > 0) {
5186                 mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
5187             }
5188             applyForcedPropertiesForDefaultDisplay();
5189             mAnimator.ready();
5190             mDisplayReady = true;
5191             // Reconfigure all displays to make sure that forced properties and
5192             // DisplayWindowSettings are applied.
5193             mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);
5194             mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
5195                     PackageManager.FEATURE_TOUCHSCREEN);
5196             mIsFakeTouchDevice = mContext.getPackageManager().hasSystemFeature(
5197                     PackageManager.FEATURE_FAKETOUCH);
5198         }
5199 
5200         mAtmService.updateConfiguration(null /* request to compute config */);
5201     }
5202 
systemReady()5203     public void systemReady() {
5204         mSystemReady = true;
5205         mPolicy.systemReady();
5206         mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
5207         mSnapshotController.systemReady();
5208         mHasWideColorGamutSupport = queryWideColorGamutSupport();
5209         mHasHdrSupport = queryHdrSupport();
5210         UiThread.getHandler().post(mSettingsObserver::loadSettings);
5211         IVrManager vrManager = IVrManager.Stub.asInterface(
5212                 ServiceManager.getService(Context.VR_SERVICE));
5213         if (vrManager != null) {
5214             try {
5215                 final boolean vrModeEnabled = vrManager.getVrModeState();
5216                 synchronized (mGlobalLock) {
5217                     vrManager.registerListener(mVrStateCallbacks);
5218                     if (vrModeEnabled) {
5219                         mVrModeEnabled = vrModeEnabled;
5220                         mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
5221                     }
5222                 }
5223             } catch (RemoteException e) {
5224                 // Ignore, we cannot do anything if we failed to register VR mode listener
5225             }
5226         }
5227     }
5228 
5229 
5230     // Keep logic in sync with SurfaceFlingerProperties.cpp
5231     // Consider exposing properties via ISurfaceComposer instead.
queryWideColorGamutSupport()5232     private static boolean queryWideColorGamutSupport() {
5233         boolean defaultValue = false;
5234         Optional<Boolean> hasWideColorProp = SurfaceFlingerProperties.has_wide_color_display();
5235         if (hasWideColorProp.isPresent()) {
5236             return hasWideColorProp.get();
5237         }
5238         try {
5239             ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService();
5240             OptionalBool hasWideColor = surfaceFlinger.hasWideColorDisplay();
5241             if (hasWideColor != null) {
5242                 return hasWideColor.value;
5243             }
5244         } catch (RemoteException e) {
5245             // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store
5246         } catch (NoSuchElementException e) {
5247             return defaultValue;
5248         }
5249         return false;
5250     }
5251 
queryHdrSupport()5252     private static boolean queryHdrSupport() {
5253         boolean defaultValue = false;
5254         Optional<Boolean> hasHdrProp = SurfaceFlingerProperties.has_HDR_display();
5255         if (hasHdrProp.isPresent()) {
5256             return hasHdrProp.get();
5257         }
5258         try {
5259             ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService();
5260             OptionalBool hasHdr = surfaceFlinger.hasHDRDisplay();
5261             if (hasHdr != null) {
5262                 return hasHdr.value;
5263             }
5264         } catch (RemoteException e) {
5265             // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store
5266         } catch (NoSuchElementException e) {
5267             return defaultValue;
5268         }
5269         return false;
5270     }
5271 
5272     // Returns an input target which is mapped to the given input token. This can be a WindowState
5273     // or an embedded window.
getInputTargetFromToken(IBinder inputToken)5274     @Nullable InputTarget getInputTargetFromToken(IBinder inputToken) {
5275         WindowState windowState = mInputToWindowMap.get(inputToken);
5276         if (windowState != null) {
5277             return windowState;
5278         }
5279 
5280         EmbeddedWindowController.EmbeddedWindow embeddedWindow =
5281                 mEmbeddedWindowController.get(inputToken);
5282         if (embeddedWindow != null) {
5283             return embeddedWindow;
5284         }
5285 
5286         return null;
5287     }
5288 
getInputTargetFromWindowTokenLocked(IBinder windowToken)5289     @Nullable InputTarget getInputTargetFromWindowTokenLocked(IBinder windowToken) {
5290         InputTarget window = mWindowMap.get(windowToken);
5291         if (window != null) {
5292             return window;
5293         }
5294         window = mEmbeddedWindowController.getByWindowToken(windowToken);
5295         return window;
5296     }
5297 
reportFocusChanged(IBinder oldToken, IBinder newToken)5298     void reportFocusChanged(IBinder oldToken, IBinder newToken) {
5299         InputTarget lastTarget;
5300         InputTarget newTarget;
5301         synchronized (mGlobalLock) {
5302             lastTarget = getInputTargetFromToken(oldToken);
5303             newTarget = getInputTargetFromToken(newToken);
5304             if (newTarget == null && lastTarget == null) {
5305                 Slog.v(TAG_WM, "Unknown focus tokens, dropping reportFocusChanged");
5306                 return;
5307             }
5308             mFocusedInputTarget = newTarget;
5309 
5310             mAccessibilityController.onFocusChanged(lastTarget, newTarget);
5311             ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Focus changing: %s -> %s", lastTarget, newTarget);
5312         }
5313 
5314         // Call WindowState focus change observers
5315         WindowState newFocusedWindow = newTarget != null ? newTarget.getWindowState() : null;
5316         if (newFocusedWindow != null && newFocusedWindow.mInputChannelToken == newToken) {
5317             mAnrController.onFocusChanged(newFocusedWindow);
5318             newFocusedWindow.reportFocusChangedSerialized(true);
5319             notifyFocusChanged();
5320         }
5321 
5322         WindowState lastFocusedWindow = lastTarget != null ? lastTarget.getWindowState() : null;
5323         if (lastFocusedWindow != null && lastFocusedWindow.mInputChannelToken == oldToken) {
5324             lastFocusedWindow.reportFocusChangedSerialized(false);
5325         }
5326     }
5327 
5328     // -------------------------------------------------------------
5329     // Async Handler
5330     // -------------------------------------------------------------
5331 
5332     final class H extends android.os.Handler {
5333         public static final int WINDOW_FREEZE_TIMEOUT = 11;
5334 
5335         public static final int PERSIST_ANIMATION_SCALE = 14;
5336         public static final int ENABLE_SCREEN = 16;
5337         public static final int APP_FREEZE_TIMEOUT = 17;
5338         public static final int REPORT_WINDOWS_CHANGE = 19;
5339 
5340         public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
5341         public static final int BOOT_TIMEOUT = 23;
5342         public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
5343         public static final int SHOW_STRICT_MODE_VIOLATION = 25;
5344 
5345         public static final int CLIENT_FREEZE_TIMEOUT = 30;
5346         public static final int NOTIFY_ACTIVITY_DRAWN = 32;
5347 
5348         public static final int NEW_ANIMATOR_SCALE = 34;
5349 
5350         public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36;
5351 
5352         public static final int CHECK_IF_BOOT_ANIMATION_FINISHED = 37;
5353         public static final int RESET_ANR_MESSAGE = 38;
5354         public static final int WALLPAPER_DRAW_PENDING_TIMEOUT = 39;
5355 
5356         public static final int UPDATE_MULTI_WINDOW_STACKS = 41;
5357 
5358         public static final int UPDATE_ANIMATION_SCALE = 51;
5359         public static final int WINDOW_HIDE_TIMEOUT = 52;
5360         public static final int RESTORE_POINTER_ICON = 55;
5361         public static final int SET_HAS_OVERLAY_UI = 58;
5362         public static final int ANIMATION_FAILSAFE = 60;
5363         public static final int RECOMPUTE_FOCUS = 61;
5364         public static final int ON_POINTER_DOWN_OUTSIDE_FOCUS = 62;
5365         public static final int WINDOW_STATE_BLAST_SYNC_TIMEOUT = 64;
5366         public static final int REPARENT_TASK_TO_DEFAULT_DISPLAY = 65;
5367         public static final int INSETS_CHANGED = 66;
5368 
5369         /**
5370          * Used to denote that an integer field in a message will not be used.
5371          */
5372         public static final int UNUSED = 0;
5373 
5374         @Override
handleMessage(Message msg)5375         public void handleMessage(Message msg) {
5376             if (DEBUG_WINDOW_TRACE) {
5377                 Slog.v(TAG_WM, "handleMessage: entry what=" + msg.what);
5378             }
5379             switch (msg.what) {
5380                 case WINDOW_FREEZE_TIMEOUT: {
5381                     final DisplayContent displayContent = (DisplayContent) msg.obj;
5382                     synchronized (mGlobalLock) {
5383                         displayContent.onWindowFreezeTimeout();
5384                     }
5385                     break;
5386                 }
5387 
5388                 case PERSIST_ANIMATION_SCALE: {
5389                     Settings.Global.putFloat(mContext.getContentResolver(),
5390                             Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
5391                     Settings.Global.putFloat(mContext.getContentResolver(),
5392                             Settings.Global.TRANSITION_ANIMATION_SCALE,
5393                             mTransitionAnimationScaleSetting);
5394                     Settings.Global.putFloat(mContext.getContentResolver(),
5395                             Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting);
5396                     break;
5397                 }
5398 
5399                 case UPDATE_ANIMATION_SCALE: {
5400                     @UpdateAnimationScaleMode
5401                     final int mode = msg.arg1;
5402                     switch (mode) {
5403                         case WINDOW_ANIMATION_SCALE: {
5404                             mWindowAnimationScaleSetting = getWindowAnimationScaleSetting();
5405                             break;
5406                         }
5407                         case TRANSITION_ANIMATION_SCALE: {
5408                             mTransitionAnimationScaleSetting =
5409                                     getTransitionAnimationScaleSetting();
5410                             break;
5411                         }
5412                         case ANIMATION_DURATION_SCALE: {
5413                             mAnimatorDurationScaleSetting = getAnimatorDurationScaleSetting();
5414                             dispatchNewAnimatorScaleLocked(null);
5415                             break;
5416                         }
5417                     }
5418                     break;
5419                 }
5420 
5421                 case ENABLE_SCREEN: {
5422                     performEnableScreen();
5423                     break;
5424                 }
5425 
5426                 case APP_FREEZE_TIMEOUT: {
5427                     synchronized (mGlobalLock) {
5428                         ProtoLog.w(WM_ERROR, "App freeze timeout expired.");
5429                         mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
5430                         for (int i = mAppFreezeListeners.size() - 1; i >= 0; --i) {
5431                             mAppFreezeListeners.get(i).onAppFreezeTimeout();
5432                         }
5433                     }
5434                     break;
5435                 }
5436 
5437                 case CLIENT_FREEZE_TIMEOUT: {
5438                     synchronized (mGlobalLock) {
5439                         if (mClientFreezingScreen) {
5440                             mClientFreezingScreen = false;
5441                             mLastFinishedFreezeSource = "client-timeout";
5442                             stopFreezingDisplayLocked();
5443                         }
5444                     }
5445                     break;
5446                 }
5447 
5448                 case REPORT_WINDOWS_CHANGE: {
5449                     if (mWindowsChanged) {
5450                         synchronized (mGlobalLock) {
5451                             mWindowsChanged = false;
5452                         }
5453                         notifyWindowsChanged();
5454                     }
5455                     break;
5456                 }
5457 
5458                 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
5459                     notifyHardKeyboardStatusChange();
5460                     break;
5461                 }
5462 
5463                 case BOOT_TIMEOUT: {
5464                     performBootTimeout();
5465                     break;
5466                 }
5467 
5468                 case WAITING_FOR_DRAWN_TIMEOUT: {
5469                     final Message callback;
5470                     final WindowContainer<?> container = (WindowContainer<?>) msg.obj;
5471                     synchronized (mGlobalLock) {
5472                         ProtoLog.w(WM_ERROR, "Timeout waiting for drawn: undrawn=%s",
5473                                 container.mWaitingForDrawn);
5474                         if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
5475                             for (int i = 0; i < container.mWaitingForDrawn.size(); i++) {
5476                                 traceEndWaitingForWindowDrawn(container.mWaitingForDrawn.get(i));
5477                             }
5478                         }
5479                         container.mWaitingForDrawn.clear();
5480                         callback = mWaitingForDrawnCallbacks.remove(container);
5481                     }
5482                     if (callback != null) {
5483                         callback.sendToTarget();
5484                     }
5485                     break;
5486                 }
5487 
5488                 case SHOW_STRICT_MODE_VIOLATION: {
5489                     showStrictModeViolation(msg.arg1, msg.arg2);
5490                     break;
5491                 }
5492 
5493                 case SHOW_EMULATOR_DISPLAY_OVERLAY: {
5494                     showEmulatorDisplayOverlay();
5495                     break;
5496                 }
5497 
5498                 case NOTIFY_ACTIVITY_DRAWN: {
5499                     final ActivityRecord activity = (ActivityRecord) msg.obj;
5500                     synchronized (mGlobalLock) {
5501                         if (activity.isAttached()) {
5502                             activity.getRootTask().notifyActivityDrawnLocked(activity);
5503                         }
5504                     }
5505                     break;
5506                 }
5507                 case NEW_ANIMATOR_SCALE: {
5508                     float scale = getCurrentAnimatorScale();
5509                     ValueAnimator.setDurationScale(scale);
5510                     Session session = (Session)msg.obj;
5511                     if (session != null) {
5512                         try {
5513                             session.mCallback.onAnimatorScaleChanged(scale);
5514                         } catch (RemoteException e) {
5515                         }
5516                     } else {
5517                         ArrayList<IWindowSessionCallback> callbacks
5518                                 = new ArrayList<IWindowSessionCallback>();
5519                         synchronized (mGlobalLock) {
5520                             for (int i=0; i<mSessions.size(); i++) {
5521                                 callbacks.add(mSessions.valueAt(i).mCallback);
5522                             }
5523 
5524                         }
5525                         for (int i=0; i<callbacks.size(); i++) {
5526                             try {
5527                                 callbacks.get(i).onAnimatorScaleChanged(scale);
5528                             } catch (RemoteException e) {
5529                             }
5530                         }
5531                     }
5532                     break;
5533                 }
5534                 case CHECK_IF_BOOT_ANIMATION_FINISHED: {
5535                     final boolean bootAnimationComplete;
5536                     synchronized (mGlobalLock) {
5537                         ProtoLog.i(WM_DEBUG_BOOT, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
5538                         bootAnimationComplete = checkBootAnimationCompleteLocked();
5539                     }
5540                     if (bootAnimationComplete) {
5541                         performEnableScreen();
5542                     }
5543                     break;
5544                 }
5545                 case RESET_ANR_MESSAGE: {
5546                     synchronized (mGlobalLock) {
5547                         mLastANRState = null;
5548                         mAtmService.mLastANRState = null;
5549                     }
5550                     break;
5551                 }
5552                 case WALLPAPER_DRAW_PENDING_TIMEOUT: {
5553                     synchronized (mGlobalLock) {
5554                         final WallpaperController wallpaperController =
5555                                 (WallpaperController) msg.obj;
5556                         if (wallpaperController != null
5557                                 && wallpaperController.processWallpaperDrawPendingTimeout()) {
5558                             mWindowPlacerLocked.performSurfacePlacement();
5559                         }
5560                     }
5561                     break;
5562                 }
5563                 case UPDATE_MULTI_WINDOW_STACKS: {
5564                     synchronized (mGlobalLock) {
5565                         final DisplayContent displayContent = (DisplayContent) msg.obj;
5566                         if (displayContent != null) {
5567                             displayContent.adjustForImeIfNeeded();
5568                         }
5569                     }
5570                     break;
5571                 }
5572                 case WINDOW_HIDE_TIMEOUT: {
5573                     final WindowState window = (WindowState) msg.obj;
5574                     synchronized (mGlobalLock) {
5575                         // TODO: This is all about fixing b/21693547
5576                         // where partially initialized Toasts get stuck
5577                         // around and keep the screen on. We'd like
5578                         // to just remove the toast...but this can cause clients
5579                         // who miss the timeout due to normal circumstances (e.g.
5580                         // running under debugger) to crash (b/29105388). The windows will
5581                         // eventually be removed when the client process finishes.
5582                         // The best we can do for now is remove the FLAG_KEEP_SCREEN_ON
5583                         // and prevent the symptoms of b/21693547. Since apps don't
5584                         // support windows being removed under them we hide the window
5585                         // and it will be removed when the app dies.
5586                         window.mAttrs.flags &= ~FLAG_KEEP_SCREEN_ON;
5587                         window.hidePermanentlyLw();
5588                         window.setDisplayLayoutNeeded();
5589                         mWindowPlacerLocked.performSurfacePlacement();
5590                     }
5591                     break;
5592                 }
5593                 case RESTORE_POINTER_ICON: {
5594                     synchronized (mGlobalLock) {
5595                         restorePointerIconLocked((DisplayContent)msg.obj, msg.arg1, msg.arg2);
5596                     }
5597                     break;
5598                 }
5599                 case SET_HAS_OVERLAY_UI: {
5600                     mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1);
5601                     break;
5602                 }
5603                 case ANIMATION_FAILSAFE: {
5604                     synchronized (mGlobalLock) {
5605                         if (mRecentsAnimationController != null) {
5606                             mRecentsAnimationController.scheduleFailsafe();
5607                         }
5608                     }
5609                     break;
5610                 }
5611                 case RECOMPUTE_FOCUS: {
5612                     synchronized (mGlobalLock) {
5613                         updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
5614                                 true /* updateInputWindows */);
5615                     }
5616                     break;
5617                 }
5618                 case ON_POINTER_DOWN_OUTSIDE_FOCUS: {
5619                     synchronized (mGlobalLock) {
5620                         final IBinder touchedToken = (IBinder) msg.obj;
5621                         onPointerDownOutsideFocusLocked(getInputTargetFromToken(touchedToken));
5622                     }
5623                     break;
5624                 }
5625                 case WINDOW_STATE_BLAST_SYNC_TIMEOUT: {
5626                     synchronized (mGlobalLock) {
5627                         final WindowState ws = (WindowState) msg.obj;
5628                         Slog.i(TAG, "Blast sync timeout: " + ws);
5629                         ws.immediatelyNotifyBlastSync();
5630                     }
5631                     break;
5632                 }
5633                 case REPARENT_TASK_TO_DEFAULT_DISPLAY: {
5634                     synchronized (mGlobalLock) {
5635                         Task task = (Task) msg.obj;
5636                         task.reparent(mRoot.getDefaultTaskDisplayArea(), true /* onTop */);
5637                         // Resume focusable root task after reparenting to another display area.
5638                         task.resumeNextFocusAfterReparent();
5639                     }
5640                     break;
5641                 }
5642                 case INSETS_CHANGED: {
5643                     synchronized (mGlobalLock) {
5644                         if (mWindowsInsetsChanged > 0) {
5645                             mWindowsInsetsChanged = 0;
5646                             // We need to update resizing windows and dispatch the new insets state
5647                             // to them.
5648                             mWindowPlacerLocked.performSurfacePlacement();
5649                         }
5650                     }
5651                     break;
5652                 }
5653             }
5654             if (DEBUG_WINDOW_TRACE) {
5655                 Slog.v(TAG_WM, "handleMessage: exit");
5656             }
5657         }
5658 
5659         /** Remove the previous messages with the same 'what' and 'obj' then send the new one. */
sendNewMessageDelayed(int what, Object obj, long delayMillis)5660         void sendNewMessageDelayed(int what, Object obj, long delayMillis) {
5661             removeMessages(what, obj);
5662             sendMessageDelayed(obtainMessage(what, obj), delayMillis);
5663         }
5664     }
5665 
5666     // -------------------------------------------------------------
5667     // IWindowManager API
5668     // -------------------------------------------------------------
5669 
5670     @Override
openSession(IWindowSessionCallback callback)5671     public IWindowSession openSession(IWindowSessionCallback callback) {
5672         return new Session(this, callback);
5673     }
5674 
5675     @Override
useBLAST()5676     public boolean useBLAST() {
5677         return mUseBLAST;
5678     }
5679 
useBLASTSync()5680     public boolean useBLASTSync() {
5681         return USE_BLAST_SYNC;
5682     }
5683 
5684     @Override
getInitialDisplaySize(int displayId, Point size)5685     public void getInitialDisplaySize(int displayId, Point size) {
5686         synchronized (mGlobalLock) {
5687             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5688             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
5689                 size.x = displayContent.mInitialDisplayWidth;
5690                 size.y = displayContent.mInitialDisplayHeight;
5691             }
5692         }
5693     }
5694 
5695     @Override
getBaseDisplaySize(int displayId, Point size)5696     public void getBaseDisplaySize(int displayId, Point size) {
5697         synchronized (mGlobalLock) {
5698             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5699             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
5700                 size.x = displayContent.mBaseDisplayWidth;
5701                 size.y = displayContent.mBaseDisplayHeight;
5702             }
5703         }
5704     }
5705 
5706     @Override
setForcedDisplaySize(int displayId, int width, int height)5707     public void setForcedDisplaySize(int displayId, int width, int height) {
5708         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
5709                 != PackageManager.PERMISSION_GRANTED) {
5710             throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
5711         }
5712 
5713         final long ident = Binder.clearCallingIdentity();
5714         try {
5715             synchronized (mGlobalLock) {
5716                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5717                 if (displayContent != null) {
5718                     displayContent.setForcedSize(width, height);
5719                 }
5720             }
5721         } finally {
5722             Binder.restoreCallingIdentity(ident);
5723         }
5724     }
5725 
5726     @Override
setForcedDisplayScalingMode(int displayId, int mode)5727     public void setForcedDisplayScalingMode(int displayId, int mode) {
5728         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
5729                 != PackageManager.PERMISSION_GRANTED) {
5730             throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
5731         }
5732 
5733         final long ident = Binder.clearCallingIdentity();
5734         try {
5735             synchronized (mGlobalLock) {
5736                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5737                 if (displayContent != null) {
5738                     displayContent.setForcedScalingMode(mode);
5739                 }
5740             }
5741         } finally {
5742             Binder.restoreCallingIdentity(ident);
5743         }
5744     }
5745 
setSandboxDisplayApis(int displayId, boolean sandboxDisplayApis)5746     void setSandboxDisplayApis(int displayId, boolean sandboxDisplayApis) {
5747         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
5748                 != PackageManager.PERMISSION_GRANTED) {
5749             throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
5750         }
5751 
5752         final long ident = Binder.clearCallingIdentity();
5753         try {
5754             synchronized (mGlobalLock) {
5755                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5756                 if (displayContent != null) {
5757                     displayContent.setSandboxDisplayApis(sandboxDisplayApis);
5758                 }
5759             }
5760         } finally {
5761             Binder.restoreCallingIdentity(ident);
5762         }
5763     }
5764 
5765     /** The global settings only apply to default display. */
applyForcedPropertiesForDefaultDisplay()5766     private boolean applyForcedPropertiesForDefaultDisplay() {
5767         boolean changed = false;
5768         final DisplayContent displayContent = getDefaultDisplayContentLocked();
5769         // Display size.
5770         String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
5771                 Settings.Global.DISPLAY_SIZE_FORCED);
5772         if (sizeStr == null || sizeStr.length() == 0) {
5773             sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
5774         }
5775         if (sizeStr != null && sizeStr.length() > 0) {
5776             final int pos = sizeStr.indexOf(',');
5777             if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
5778                 try {
5779                     final Point size = displayContent.getValidForcedSize(
5780                             Integer.parseInt(sizeStr.substring(0, pos)),
5781                             Integer.parseInt(sizeStr.substring(pos + 1)));
5782                     final int width = size.x;
5783                     final int height = size.y;
5784                     if (displayContent.mBaseDisplayWidth != width
5785                             || displayContent.mBaseDisplayHeight != height) {
5786                         ProtoLog.i(WM_ERROR, "FORCED DISPLAY SIZE: %dx%d", width, height);
5787                         displayContent.updateBaseDisplayMetrics(width, height,
5788                                 displayContent.mBaseDisplayDensity,
5789                                 displayContent.mBaseDisplayPhysicalXDpi,
5790                                 displayContent.mBaseDisplayPhysicalYDpi);
5791                         changed = true;
5792                     }
5793                 } catch (NumberFormatException ex) {
5794                 }
5795             }
5796         }
5797 
5798         // Display density.
5799         final int density = getForcedDisplayDensityForUserLocked(mCurrentUserId);
5800         if (density != 0 && density != displayContent.mBaseDisplayDensity) {
5801             displayContent.mBaseDisplayDensity = density;
5802             changed = true;
5803         }
5804 
5805         // Display scaling mode.
5806         int mode = Settings.Global.getInt(mContext.getContentResolver(),
5807                 Settings.Global.DISPLAY_SCALING_FORCE, 0);
5808         if (displayContent.mDisplayScalingDisabled != (mode != 0)) {
5809             ProtoLog.i(WM_ERROR, "FORCED DISPLAY SCALING DISABLED");
5810             displayContent.mDisplayScalingDisabled = true;
5811             changed = true;
5812         }
5813         return changed;
5814     }
5815 
5816     @Override
clearForcedDisplaySize(int displayId)5817     public void clearForcedDisplaySize(int displayId) {
5818         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
5819                 != PackageManager.PERMISSION_GRANTED) {
5820             throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
5821         }
5822 
5823         final long ident = Binder.clearCallingIdentity();
5824         try {
5825             synchronized (mGlobalLock) {
5826                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5827                 if (displayContent != null) {
5828                     displayContent.setForcedSize(displayContent.mInitialDisplayWidth,
5829                             displayContent.mInitialDisplayHeight,
5830                             displayContent.mInitialPhysicalXDpi,
5831                             displayContent.mInitialPhysicalXDpi);
5832                 }
5833             }
5834         } finally {
5835             Binder.restoreCallingIdentity(ident);
5836         }
5837     }
5838 
5839     @Override
getInitialDisplayDensity(int displayId)5840     public int getInitialDisplayDensity(int displayId) {
5841         synchronized (mGlobalLock) {
5842             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5843             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
5844                 return displayContent.getInitialDisplayDensity();
5845             }
5846 
5847             DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId);
5848             if (info != null && info.hasAccess(Binder.getCallingUid())) {
5849                 return info.logicalDensityDpi;
5850             }
5851         }
5852         return -1;
5853     }
5854 
5855     @Override
getBaseDisplayDensity(int displayId)5856     public int getBaseDisplayDensity(int displayId) {
5857         synchronized (mGlobalLock) {
5858             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5859             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
5860                 return displayContent.mBaseDisplayDensity;
5861             }
5862         }
5863         return -1;
5864     }
5865 
5866     /**
5867      * Return the display Id that has the given uniqueId. Unique ID is defined in
5868      * {@link DisplayInfo#uniqueId}.
5869      */
5870     @Override
getDisplayIdByUniqueId(String uniqueId)5871     public int getDisplayIdByUniqueId(String uniqueId) {
5872         synchronized (mGlobalLock) {
5873             final DisplayContent displayContent = mRoot.getDisplayContent(uniqueId);
5874             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
5875                 return displayContent.mDisplayId;
5876             }
5877         }
5878         return -1;
5879     }
5880 
5881     @Override
setForcedDisplayDensityForUser(int displayId, int density, int userId)5882     public void setForcedDisplayDensityForUser(int displayId, int density, int userId) {
5883         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
5884                 != PackageManager.PERMISSION_GRANTED) {
5885             throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
5886         }
5887 
5888         final int targetUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
5889                 Binder.getCallingUid(), userId, false, true, "setForcedDisplayDensityForUser",
5890                 null);
5891         final long ident = Binder.clearCallingIdentity();
5892         try {
5893             synchronized (mGlobalLock) {
5894                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5895                 if (displayContent != null) {
5896                     displayContent.setForcedDensity(density, targetUserId);
5897                 } else {
5898                     DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId);
5899                     if (info != null) {
5900                         mDisplayWindowSettings.setForcedDensity(info, density, userId);
5901                     }
5902                 }
5903             }
5904         } finally {
5905             Binder.restoreCallingIdentity(ident);
5906         }
5907     }
5908 
5909     @Override
clearForcedDisplayDensityForUser(int displayId, int userId)5910     public void clearForcedDisplayDensityForUser(int displayId, int userId) {
5911         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
5912                 != PackageManager.PERMISSION_GRANTED) {
5913             throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
5914         }
5915 
5916         final int callingUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
5917                 Binder.getCallingUid(), userId, false, true, "clearForcedDisplayDensityForUser",
5918                 null);
5919         final long ident = Binder.clearCallingIdentity();
5920         try {
5921             synchronized (mGlobalLock) {
5922                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
5923                 if (displayContent != null) {
5924                     displayContent.setForcedDensity(displayContent.getInitialDisplayDensity(),
5925                             callingUserId);
5926                 } else {
5927                     DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId);
5928                     if (info != null) {
5929                         mDisplayWindowSettings.setForcedDensity(info, info.logicalDensityDpi,
5930                                 userId);
5931                     }
5932                 }
5933             }
5934         } finally {
5935             Binder.restoreCallingIdentity(ident);
5936         }
5937     }
5938 
5939     /**
5940      * @param userId the ID of the user
5941      * @return the forced display density for the specified user, if set, or
5942      *         {@code 0} if not set
5943      */
getForcedDisplayDensityForUserLocked(int userId)5944     private int getForcedDisplayDensityForUserLocked(int userId) {
5945         String densityStr = Settings.Secure.getStringForUser(mContext.getContentResolver(),
5946                 Settings.Secure.DISPLAY_DENSITY_FORCED, userId);
5947         if (densityStr == null || densityStr.length() == 0) {
5948             densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
5949         }
5950         if (densityStr != null && densityStr.length() > 0) {
5951             try {
5952                 return Integer.parseInt(densityStr);
5953             } catch (NumberFormatException ex) {
5954             }
5955         }
5956         return 0;
5957     }
5958 
5959     @Override
startWindowTrace()5960     public void startWindowTrace(){
5961         mWindowTracing.startTrace(null /* printwriter */);
5962     }
5963 
5964     @Override
stopWindowTrace()5965     public void stopWindowTrace(){
5966         mWindowTracing.stopTrace(null /* printwriter */);
5967     }
5968 
5969     @Override
saveWindowTraceToFile()5970     public void saveWindowTraceToFile() {
5971         mWindowTracing.saveForBugreport(null /* printwriter */);
5972     }
5973 
5974     @Override
isWindowTraceEnabled()5975     public boolean isWindowTraceEnabled() {
5976         return mWindowTracing.isEnabled();
5977     }
5978 
5979     @Override
startTransitionTrace()5980     public void startTransitionTrace() {
5981         mTransitionTracer.startTrace(null /* printwriter */);
5982     }
5983 
5984     @Override
stopTransitionTrace()5985     public void stopTransitionTrace() {
5986         mTransitionTracer.stopTrace(null /* printwriter */);
5987     }
5988 
5989     @Override
isTransitionTraceEnabled()5990     public boolean isTransitionTraceEnabled() {
5991         return mTransitionTracer.isActiveTracingEnabled();
5992     }
5993 
5994     @Override
registerCrossWindowBlurEnabledListener( ICrossWindowBlurEnabledListener listener)5995     public boolean registerCrossWindowBlurEnabledListener(
5996                 ICrossWindowBlurEnabledListener listener) {
5997         return mBlurController.registerCrossWindowBlurEnabledListener(listener);
5998     }
5999 
6000     @Override
unregisterCrossWindowBlurEnabledListener( ICrossWindowBlurEnabledListener listener)6001     public void unregisterCrossWindowBlurEnabledListener(
6002                 ICrossWindowBlurEnabledListener listener) {
6003         mBlurController.unregisterCrossWindowBlurEnabledListener(listener);
6004     }
6005 
6006     // -------------------------------------------------------------
6007     // Internals
6008     // -------------------------------------------------------------
6009 
windowForClientLocked(Session session, IWindow client, boolean throwOnError)6010     final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) {
6011         return windowForClientLocked(session, client.asBinder(), throwOnError);
6012     }
6013 
windowForClientLocked(Session session, IBinder client, boolean throwOnError)6014     final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) {
6015         WindowState win = mWindowMap.get(client);
6016         if (DEBUG) Slog.v(TAG_WM, "Looking up client " + client + ": " + win);
6017         if (win == null) {
6018             if (throwOnError) {
6019                 throw new IllegalArgumentException(
6020                         "Requested window " + client + " does not exist");
6021             }
6022             ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
6023                     Debug.getCallers(3));
6024             return null;
6025         }
6026         if (session != null && win.mSession != session) {
6027             if (throwOnError) {
6028                 throw new IllegalArgumentException("Requested window " + client + " is in session "
6029                         + win.mSession + ", not " + session);
6030             }
6031             ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
6032                     Debug.getCallers(3));
6033             return null;
6034         }
6035 
6036         return win;
6037     }
6038 
makeWindowFreezingScreenIfNeededLocked(WindowState w)6039     void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
6040         // If the screen is currently frozen, then keep it frozen until this window draws at its
6041         // new orientation.
6042         if (mFrozenDisplayId != INVALID_DISPLAY && mFrozenDisplayId == w.getDisplayId()
6043                 && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
6044             ProtoLog.v(WM_DEBUG_ORIENTATION, "Changing surface while display frozen: %s", w);
6045             // WindowsState#reportResized won't tell invisible requested window to redraw,
6046             // so do not set it as changing orientation to avoid affecting draw state.
6047             if (w.isVisibleRequested()) {
6048                 w.setOrientationChanging(true);
6049             }
6050             if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
6051                 mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
6052                 // XXX should probably keep timeout from
6053                 // when we first froze the display.
6054                 mH.sendNewMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, w.getDisplayContent(),
6055                         WINDOW_FREEZE_TIMEOUT_DURATION);
6056             }
6057         }
6058     }
6059 
checkDrawnWindowsLocked()6060     void checkDrawnWindowsLocked() {
6061         if (mWaitingForDrawnCallbacks.isEmpty()) {
6062             return;
6063         }
6064         for (int i = mWaitingForDrawnCallbacks.size() - 1; i >= 0; i--) {
6065             final WindowContainer<?> container = mWaitingForDrawnCallbacks.keyAt(i);
6066             for (int j = container.mWaitingForDrawn.size() - 1; j >= 0; j--) {
6067                 final WindowState win = (WindowState) container.mWaitingForDrawn.get(j);
6068                 ProtoLog.i(WM_DEBUG_SCREEN_ON,
6069                         "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
6070                         win, win.mRemoved, win.isVisible(), win.mHasSurface,
6071                         win.mWinAnimator.mDrawState);
6072                 if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) {
6073                     // Window has been removed or hidden; no draw will now happen, so stop waiting.
6074                     ProtoLog.w(WM_DEBUG_SCREEN_ON, "Aborted waiting for drawn: %s", win);
6075                     container.mWaitingForDrawn.remove(win);
6076                     if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
6077                         traceEndWaitingForWindowDrawn(win);
6078                     }
6079                 } else if (win.hasDrawn()) {
6080                     // Window is now drawn (and shown).
6081                     ProtoLog.d(WM_DEBUG_SCREEN_ON, "Window drawn win=%s", win);
6082                     container.mWaitingForDrawn.remove(win);
6083                     if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
6084                         traceEndWaitingForWindowDrawn(win);
6085                     }
6086                 }
6087             }
6088             if (container.mWaitingForDrawn.isEmpty()) {
6089                 ProtoLog.d(WM_DEBUG_SCREEN_ON, "All windows drawn!");
6090                 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
6091                 mWaitingForDrawnCallbacks.removeAt(i).sendToTarget();
6092             }
6093         }
6094     }
6095 
traceStartWaitingForWindowDrawn(WindowState window)6096     private void traceStartWaitingForWindowDrawn(WindowState window) {
6097         final String traceName = TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD + "#"
6098                 + window.getWindowTag();
6099         final String shortenedTraceName = traceName.substring(0, Math.min(
6100                 TRACE_MAX_SECTION_NAME_LENGTH, traceName.length()));
6101         Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, shortenedTraceName, /* cookie= */ 0);
6102     }
6103 
traceEndWaitingForWindowDrawn(WindowState window)6104     private void traceEndWaitingForWindowDrawn(WindowState window) {
6105         final String traceName = TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD + "#"
6106                 + window.getWindowTag();
6107         final String shortenedTraceName = traceName.substring(0, Math.min(
6108                 TRACE_MAX_SECTION_NAME_LENGTH, traceName.length()));
6109         Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, shortenedTraceName, /* cookie= */ 0);
6110     }
6111 
requestTraversal()6112     void requestTraversal() {
6113         mWindowPlacerLocked.requestTraversal();
6114     }
6115 
6116     /** Note that Locked in this case is on mLayoutToAnim */
scheduleAnimationLocked()6117     void scheduleAnimationLocked() {
6118         mAnimator.scheduleAnimation();
6119     }
6120 
updateFocusedWindowLocked(int mode, boolean updateInputWindows)6121     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
6122         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
6123         boolean changed = mRoot.updateFocusedWindowLocked(mode, updateInputWindows);
6124         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
6125         return changed;
6126     }
6127 
startFreezingDisplay(int exitAnim, int enterAnim)6128     void startFreezingDisplay(int exitAnim, int enterAnim) {
6129         startFreezingDisplay(exitAnim, enterAnim, getDefaultDisplayContentLocked());
6130     }
6131 
startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent)6132     void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent) {
6133         startFreezingDisplay(exitAnim, enterAnim, displayContent,
6134                 ROTATION_UNDEFINED /* overrideOriginalRotation */);
6135     }
6136 
startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent, int overrideOriginalRotation)6137     void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent,
6138             int overrideOriginalRotation) {
6139         if (mDisplayFrozen || displayContent.getDisplayRotation().isRotatingSeamlessly()) {
6140             return;
6141         }
6142 
6143         if (!displayContent.isReady() || !displayContent.getDisplayPolicy().isScreenOnFully()
6144                 || displayContent.getDisplayInfo().state == Display.STATE_OFF
6145                 || !displayContent.okToAnimate()) {
6146             // No need to freeze the screen before the display is ready,  if the screen is off,
6147             // or we can't currently animate.
6148             return;
6149         }
6150 
6151         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.doStartFreezingDisplay");
6152         doStartFreezingDisplay(exitAnim, enterAnim, displayContent, overrideOriginalRotation);
6153         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
6154     }
6155 
doStartFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent, int overrideOriginalRotation)6156     private void doStartFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent,
6157             int overrideOriginalRotation) {
6158         ProtoLog.d(WM_DEBUG_ORIENTATION,
6159                             "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s",
6160                             exitAnim, enterAnim, Debug.getCallers(8));
6161         mScreenFrozenLock.acquire();
6162         // Apply launch power mode to reduce screen frozen time because orientation change may
6163         // relaunch activity and redraw windows. This may also help speed up user switching.
6164         mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
6165 
6166         mDisplayFrozen = true;
6167         mDisplayFreezeTime = SystemClock.elapsedRealtime();
6168         mLastFinishedFreezeSource = null;
6169 
6170         // {@link mDisplayFrozen} prevents us from freezing on multiple displays at the same time.
6171         // As a result, we only track the display that has initially froze the screen.
6172         mFrozenDisplayId = displayContent.getDisplayId();
6173 
6174         mInputManagerCallback.freezeInputDispatchingLw();
6175 
6176         if (displayContent.mAppTransition.isTransitionSet()) {
6177             displayContent.mAppTransition.freeze();
6178         }
6179 
6180         if (PROFILE_ORIENTATION) {
6181             File file = new File("/data/system/frozen");
6182             Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
6183         }
6184 
6185         mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
6186         mExitAnimId = exitAnim;
6187         mEnterAnimId = enterAnim;
6188 
6189         displayContent.updateDisplayInfo();
6190         final int originalRotation = overrideOriginalRotation != ROTATION_UNDEFINED
6191                 ? overrideOriginalRotation
6192                 : displayContent.getDisplayInfo().rotation;
6193         displayContent.setRotationAnimation(new ScreenRotationAnimation(displayContent,
6194                 originalRotation));
6195     }
6196 
stopFreezingDisplayLocked()6197     void stopFreezingDisplayLocked() {
6198         if (!mDisplayFrozen) {
6199             return;
6200         }
6201 
6202         final DisplayContent displayContent = mRoot.getDisplayContent(mFrozenDisplayId);
6203         final int numOpeningApps;
6204         final boolean waitingForConfig;
6205         final boolean waitingForRemoteDisplayChange;
6206         if (displayContent != null) {
6207             numOpeningApps = displayContent.mOpeningApps.size();
6208             waitingForConfig = displayContent.mWaitingForConfig;
6209             waitingForRemoteDisplayChange = displayContent.mRemoteDisplayChangeController
6210                     .isWaitingForRemoteDisplayChange();
6211         } else {
6212             waitingForConfig = waitingForRemoteDisplayChange = false;
6213             numOpeningApps = 0;
6214         }
6215         if (waitingForConfig || waitingForRemoteDisplayChange || mAppsFreezingScreen > 0
6216                 || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
6217                 || mClientFreezingScreen || numOpeningApps > 0) {
6218             ProtoLog.d(WM_DEBUG_ORIENTATION, "stopFreezingDisplayLocked: Returning "
6219                     + "waitingForConfig=%b, waitingForRemoteDisplayChange=%b, "
6220                     + "mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, "
6221                     + "mClientFreezingScreen=%b, mOpeningApps.size()=%d",
6222                     waitingForConfig, waitingForRemoteDisplayChange,
6223                     mAppsFreezingScreen, mWindowsFreezingScreen,
6224                     mClientFreezingScreen, numOpeningApps);
6225             return;
6226         }
6227 
6228         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.doStopFreezingDisplayLocked-"
6229                 + mLastFinishedFreezeSource);
6230         doStopFreezingDisplayLocked(displayContent);
6231         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
6232     }
6233 
doStopFreezingDisplayLocked(DisplayContent displayContent)6234     private void doStopFreezingDisplayLocked(DisplayContent displayContent) {
6235         ProtoLog.d(WM_DEBUG_ORIENTATION,
6236                     "stopFreezingDisplayLocked: Unfreezing now");
6237 
6238         // We must make a local copy of the displayId as it can be potentially overwritten later on
6239         // in this method. For example, {@link startFreezingDisplayLocked} may be called as a result
6240         // of update rotation, but we reference the frozen display after that call in this method.
6241         mFrozenDisplayId = INVALID_DISPLAY;
6242         mDisplayFrozen = false;
6243         mInputManagerCallback.thawInputDispatchingLw();
6244         mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
6245         StringBuilder sb = new StringBuilder(128);
6246         sb.append("Screen frozen for ");
6247         TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
6248         if (mLastFinishedFreezeSource != null) {
6249             sb.append(" due to ");
6250             sb.append(mLastFinishedFreezeSource);
6251         }
6252         ProtoLog.i(WM_ERROR, "%s", sb.toString());
6253         mH.removeMessages(H.APP_FREEZE_TIMEOUT);
6254         mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
6255         if (PROFILE_ORIENTATION) {
6256             Debug.stopMethodTracing();
6257         }
6258 
6259         boolean updateRotation = false;
6260 
6261         ScreenRotationAnimation screenRotationAnimation = displayContent == null ? null
6262                 : displayContent.getRotationAnimation();
6263         if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) {
6264             ProtoLog.i(WM_DEBUG_ORIENTATION, "**** Dismissing screen rotation animation");
6265             DisplayInfo displayInfo = displayContent.getDisplayInfo();
6266             // Get rotation animation again, with new top window
6267             if (!displayContent.getDisplayRotation().validateRotationAnimation(
6268                     mExitAnimId, mEnterAnimId, false /* forceDefault */)) {
6269                 mExitAnimId = mEnterAnimId = 0;
6270             }
6271             if (screenRotationAnimation.dismiss(mTransaction, MAX_ANIMATION_DURATION,
6272                     getTransitionAnimationScaleLocked(), displayInfo.logicalWidth,
6273                         displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
6274                 mTransaction.apply();
6275             } else {
6276                 screenRotationAnimation.kill();
6277                 displayContent.setRotationAnimation(null);
6278                 updateRotation = true;
6279             }
6280         } else {
6281             if (screenRotationAnimation != null) {
6282                 screenRotationAnimation.kill();
6283                 displayContent.setRotationAnimation(null);
6284             }
6285             updateRotation = true;
6286         }
6287 
6288         boolean configChanged;
6289 
6290         // While the display is frozen we don't re-compute the orientation
6291         // to avoid inconsistent states.  However, something interesting
6292         // could have actually changed during that time so re-evaluate it
6293         // now to catch that.
6294         configChanged = displayContent != null && displayContent.updateOrientation();
6295 
6296         mScreenFrozenLock.release();
6297 
6298         if (updateRotation && displayContent != null) {
6299             ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation");
6300             configChanged |= displayContent.updateRotationUnchecked();
6301         }
6302 
6303         if (configChanged) {
6304             displayContent.sendNewConfiguration();
6305         }
6306         mAtmService.endLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
6307         mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN);
6308     }
6309 
getPropertyInt(String[] tokens, int index, int defUnits, int defDps, DisplayMetrics dm)6310     static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
6311             DisplayMetrics dm) {
6312         if (index < tokens.length) {
6313             String str = tokens[index];
6314             if (str != null && str.length() > 0) {
6315                 try {
6316                     int val = Integer.parseInt(str);
6317                     return val;
6318                 } catch (Exception e) {
6319                 }
6320             }
6321         }
6322         if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
6323             return defDps;
6324         }
6325         int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
6326         return val;
6327     }
6328 
createWatermark()6329     void createWatermark() {
6330         if (mWatermark != null) {
6331             return;
6332         }
6333 
6334         File file = new File("/system/etc/setup.conf");
6335         FileInputStream in = null;
6336         DataInputStream ind = null;
6337         try {
6338             in = new FileInputStream(file);
6339             ind = new DataInputStream(in);
6340             String line = ind.readLine();
6341             if (line != null) {
6342                 String[] toks = line.split("%");
6343                 if (toks != null && toks.length > 0) {
6344                     // TODO(multi-display): Show watermarks on secondary displays.
6345                     final DisplayContent displayContent = getDefaultDisplayContentLocked();
6346                     mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics,
6347                             toks, mTransaction);
6348                     mTransaction.apply();
6349                 }
6350             }
6351         } catch (FileNotFoundException e) {
6352         } catch (IOException e) {
6353         } finally {
6354             if (ind != null) {
6355                 try {
6356                     ind.close();
6357                 } catch (IOException e) {
6358                 }
6359             } else if (in != null) {
6360                 try {
6361                     in.close();
6362                 } catch (IOException e) {
6363                 }
6364             }
6365         }
6366     }
6367 
6368     @Override
setRecentsVisibility(boolean visible)6369     public void setRecentsVisibility(boolean visible) {
6370         if (!checkCallingPermission(
6371                 android.Manifest.permission.STATUS_BAR, "setRecentsVisibility()")) {
6372             throw new SecurityException("Requires STATUS_BAR permission");
6373         }
6374         synchronized (mGlobalLock) {
6375             mPolicy.setRecentsVisibilityLw(visible);
6376         }
6377     }
6378 
6379     @Override
hideTransientBars(int displayId)6380     public void hideTransientBars(int displayId) {
6381         if (!checkCallingPermission(
6382                 android.Manifest.permission.STATUS_BAR, "hideTransientBars()")) {
6383             throw new SecurityException("Requires STATUS_BAR permission");
6384         }
6385 
6386         synchronized (mGlobalLock) {
6387             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
6388             if (displayContent != null) {
6389                 displayContent.getInsetsPolicy().hideTransient();
6390             } else {
6391                 Slog.w(TAG, "hideTransientBars with invalid displayId=" + displayId);
6392             }
6393         }
6394     }
6395 
6396     @Override
updateStaticPrivacyIndicatorBounds(int displayId, Rect[] staticBounds)6397     public void updateStaticPrivacyIndicatorBounds(int displayId,
6398             Rect[] staticBounds) {
6399         synchronized (mGlobalLock) {
6400             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
6401             if (displayContent != null) {
6402                 displayContent.updatePrivacyIndicatorBounds(staticBounds);
6403             } else {
6404                 Slog.w(TAG, "updateStaticPrivacyIndicatorBounds with invalid displayId="
6405                         + displayId);
6406             }
6407         }
6408     }
6409 
setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled)6410     public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) {
6411         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
6412                 != PackageManager.PERMISSION_GRANTED) {
6413             throw new SecurityException("Caller does not hold permission "
6414                     + android.Manifest.permission.STATUS_BAR);
6415         }
6416 
6417         synchronized (mGlobalLock) {
6418             mPolicy.setNavBarVirtualKeyHapticFeedbackEnabledLw(enabled);
6419         }
6420     }
6421 
6422     @Override
createInputConsumer(IBinder token, String name, int displayId, InputChannel inputChannel)6423     public void createInputConsumer(IBinder token, String name, int displayId,
6424             InputChannel inputChannel) {
6425         if (!mAtmService.isCallerRecents(Binder.getCallingUid())
6426                 && mContext.checkCallingOrSelfPermission(INPUT_CONSUMER) != PERMISSION_GRANTED) {
6427             throw new SecurityException("createInputConsumer requires INPUT_CONSUMER permission");
6428         }
6429 
6430         synchronized (mGlobalLock) {
6431             DisplayContent display = mRoot.getDisplayContent(displayId);
6432             if (display != null) {
6433                 display.getInputMonitor().createInputConsumer(token, name, inputChannel,
6434                         Binder.getCallingPid(), Binder.getCallingUserHandle());
6435             }
6436         }
6437     }
6438 
6439     @Override
destroyInputConsumer(String name, int displayId)6440     public boolean destroyInputConsumer(String name, int displayId) {
6441         if (!mAtmService.isCallerRecents(Binder.getCallingUid())
6442                 && mContext.checkCallingOrSelfPermission(INPUT_CONSUMER) != PERMISSION_GRANTED) {
6443             throw new SecurityException("destroyInputConsumer requires INPUT_CONSUMER permission");
6444         }
6445 
6446         synchronized (mGlobalLock) {
6447             DisplayContent display = mRoot.getDisplayContent(displayId);
6448             if (display != null) {
6449                 return display.getInputMonitor().destroyInputConsumer(name);
6450             }
6451             return false;
6452         }
6453     }
6454 
6455     @Override
getCurrentImeTouchRegion()6456     public Region getCurrentImeTouchRegion() {
6457         if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
6458             throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services");
6459         }
6460         synchronized (mGlobalLock) {
6461             final Region r = new Region();
6462             // TODO(b/111080190): this method is only return the recent focused IME touch region,
6463             // For Multi-Session IME, will need to add API for given display Id to
6464             // get the right IME touch region.
6465             for (int i = mRoot.mChildren.size() - 1; i >= 0; --i) {
6466                 final DisplayContent displayContent = mRoot.mChildren.get(i);
6467                 if (displayContent.mInputMethodWindow != null) {
6468                     displayContent.mInputMethodWindow.getTouchableRegion(r);
6469                     return r;
6470                 }
6471             }
6472             return r;
6473         }
6474     }
6475 
6476     @Override
hasNavigationBar(int displayId)6477     public boolean hasNavigationBar(int displayId) {
6478         synchronized (mGlobalLock) {
6479             final DisplayContent dc = mRoot.getDisplayContent(displayId);
6480             if (dc == null) {
6481                 return false;
6482             }
6483             return dc.getDisplayPolicy().hasNavigationBar();
6484         }
6485     }
6486 
6487     @Override
lockNow(Bundle options)6488     public void lockNow(Bundle options) {
6489         mPolicy.lockNow(options);
6490     }
6491 
showRecentApps()6492     public void showRecentApps() {
6493         mPolicy.showRecentApps();
6494     }
6495 
6496     @Override
isSafeModeEnabled()6497     public boolean isSafeModeEnabled() {
6498         return mSafeMode;
6499     }
6500 
6501     @Override
clearWindowContentFrameStats(IBinder token)6502     public boolean clearWindowContentFrameStats(IBinder token) {
6503         if (!checkCallingPermission(Manifest.permission.FRAME_STATS,
6504                 "clearWindowContentFrameStats()")) {
6505             throw new SecurityException("Requires FRAME_STATS permission");
6506         }
6507         synchronized (mGlobalLock) {
6508             WindowState windowState = mWindowMap.get(token);
6509             if (windowState == null) {
6510                 return false;
6511             }
6512             WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
6513             if (surfaceController == null) {
6514                 return false;
6515             }
6516             return surfaceController.clearWindowContentFrameStats();
6517         }
6518     }
6519 
6520     @Override
getWindowContentFrameStats(IBinder token)6521     public WindowContentFrameStats getWindowContentFrameStats(IBinder token) {
6522         if (!checkCallingPermission(Manifest.permission.FRAME_STATS,
6523                 "getWindowContentFrameStats()")) {
6524             throw new SecurityException("Requires FRAME_STATS permission");
6525         }
6526         synchronized (mGlobalLock) {
6527             WindowState windowState = mWindowMap.get(token);
6528             if (windowState == null) {
6529                 return null;
6530             }
6531             WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
6532             if (surfaceController == null) {
6533                 return null;
6534             }
6535             if (mTempWindowRenderStats == null) {
6536                 mTempWindowRenderStats = new WindowContentFrameStats();
6537             }
6538             WindowContentFrameStats stats = mTempWindowRenderStats;
6539             if (!surfaceController.getWindowContentFrameStats(stats)) {
6540                 return null;
6541             }
6542             return stats;
6543         }
6544     }
6545 
dumpPolicyLocked(PrintWriter pw, String[] args)6546     private void dumpPolicyLocked(PrintWriter pw, String[] args) {
6547         pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
6548         mPolicy.dump("    ", pw, args);
6549     }
6550 
dumpAnimatorLocked(PrintWriter pw, boolean dumpAll)6551     private void dumpAnimatorLocked(PrintWriter pw, boolean dumpAll) {
6552         pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
6553         mAnimator.dumpLocked(pw, "    ", dumpAll);
6554     }
6555 
dumpTokensLocked(PrintWriter pw, boolean dumpAll)6556     private void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
6557         pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
6558         mRoot.dumpTokens(pw, dumpAll);
6559     }
6560 
6561 
dumpHighRefreshRateBlacklist(PrintWriter pw)6562     private void dumpHighRefreshRateBlacklist(PrintWriter pw) {
6563         pw.println("WINDOW MANAGER HIGH REFRESH RATE BLACKLIST (dumpsys window refresh)");
6564         mHighRefreshRateDenylist.dump(pw);
6565     }
6566 
dumpTraceStatus(PrintWriter pw)6567     private void dumpTraceStatus(PrintWriter pw) {
6568         pw.println("WINDOW MANAGER TRACE (dumpsys window trace)");
6569         pw.print(mWindowTracing.getStatus() + "\n");
6570     }
6571 
dumpLogStatus(PrintWriter pw)6572     private void dumpLogStatus(PrintWriter pw) {
6573         pw.println("WINDOW MANAGER LOGGING (dumpsys window logging)");
6574         pw.println(ProtoLogImpl.getSingleInstance().getStatus());
6575     }
6576 
dumpSessionsLocked(PrintWriter pw)6577     private void dumpSessionsLocked(PrintWriter pw) {
6578         pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
6579         for (int i=0; i<mSessions.size(); i++) {
6580             Session s = mSessions.valueAt(i);
6581             pw.print("  Session "); pw.print(s); pw.println(':');
6582             s.dump(pw, "    ");
6583         }
6584     }
6585 
6586     /**
6587      * Write to a protocol buffer output stream. Protocol buffer message definition is at
6588      * {@link com.android.server.wm.WindowManagerServiceDumpProto}.
6589      *
6590      * @param proto     Stream to write the WindowContainer object to.
6591      * @param logLevel  Determines the amount of data to be written to the Protobuf.
6592      */
dumpDebugLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel)6593     void dumpDebugLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {
6594         mPolicy.dumpDebug(proto, POLICY);
6595         mRoot.dumpDebug(proto, ROOT_WINDOW_CONTAINER, logLevel);
6596         final DisplayContent topFocusedDisplayContent = mRoot.getTopFocusedDisplayContent();
6597         if (topFocusedDisplayContent.mCurrentFocus != null) {
6598             topFocusedDisplayContent.mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);
6599         }
6600         if (topFocusedDisplayContent.mFocusedApp != null) {
6601             topFocusedDisplayContent.mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
6602         }
6603         final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
6604         if (imeWindow != null) {
6605             imeWindow.writeIdentifierToProto(proto, INPUT_METHOD_WINDOW);
6606         }
6607         proto.write(DISPLAY_FROZEN, mDisplayFrozen);
6608         proto.write(FOCUSED_DISPLAY_ID, topFocusedDisplayContent.getDisplayId());
6609         proto.write(HARD_KEYBOARD_AVAILABLE, mHardKeyboardAvailable);
6610 
6611         // This is always true for now since we still update the window frames at the server side.
6612         // Once we move the window layout to the client side, this can be false when we are waiting
6613         // for the frames.
6614         proto.write(WINDOW_FRAMES_VALID, true);
6615 
6616         // Write the BackNavigationController's state into the protocol buffer
6617         mAtmService.mBackNavigationController.dumpDebug(proto, BACK_NAVIGATION);
6618     }
6619 
dumpWindowsLocked(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows)6620     private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
6621             ArrayList<WindowState> windows) {
6622         pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
6623         dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
6624     }
6625 
dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows)6626     private void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
6627             ArrayList<WindowState> windows) {
6628         mRoot.dumpWindowsNoHeader(pw, dumpAll, windows);
6629 
6630         if (!mHidingNonSystemOverlayWindows.isEmpty()) {
6631             pw.println();
6632             pw.println("  Hiding System Alert Windows:");
6633             for (int i = mHidingNonSystemOverlayWindows.size() - 1; i >= 0; i--) {
6634                 final WindowState w = mHidingNonSystemOverlayWindows.get(i);
6635                 pw.print("  #"); pw.print(i); pw.print(' ');
6636                 pw.print(w);
6637                 if (dumpAll) {
6638                     pw.println(":");
6639                     w.dump(pw, "    ", true);
6640                 } else {
6641                     pw.println();
6642                 }
6643             }
6644         }
6645         if (mForceRemoves != null && !mForceRemoves.isEmpty()) {
6646             pw.println();
6647             pw.println("  Windows force removing:");
6648             for (int i=mForceRemoves.size()-1; i>=0; i--) {
6649                 WindowState w = mForceRemoves.get(i);
6650                 pw.print("  Removing #"); pw.print(i); pw.print(' ');
6651                         pw.print(w);
6652                 if (dumpAll) {
6653                     pw.println(":");
6654                     w.dump(pw, "    ", true);
6655                 } else {
6656                     pw.println();
6657                 }
6658             }
6659         }
6660         if (!mDestroySurface.isEmpty()) {
6661             pw.println();
6662             pw.println("  Windows waiting to destroy their surface:");
6663             for (int i=mDestroySurface.size()-1; i>=0; i--) {
6664                 WindowState w = mDestroySurface.get(i);
6665                 if (windows == null || windows.contains(w)) {
6666                     pw.print("  Destroy #"); pw.print(i); pw.print(' ');
6667                             pw.print(w);
6668                     if (dumpAll) {
6669                         pw.println(":");
6670                         w.dump(pw, "    ", true);
6671                     } else {
6672                         pw.println();
6673                     }
6674                 }
6675             }
6676         }
6677         if (!mResizingWindows.isEmpty()) {
6678             pw.println();
6679             pw.println("  Windows waiting to resize:");
6680             for (int i=mResizingWindows.size()-1; i>=0; i--) {
6681                 WindowState w = mResizingWindows.get(i);
6682                 if (windows == null || windows.contains(w)) {
6683                     pw.print("  Resizing #"); pw.print(i); pw.print(' ');
6684                             pw.print(w);
6685                     if (dumpAll) {
6686                         pw.println(":");
6687                         w.dump(pw, "    ", true);
6688                     } else {
6689                         pw.println();
6690                     }
6691                 }
6692             }
6693         }
6694         if (!mWaitingForDrawnCallbacks.isEmpty()) {
6695             pw.println();
6696             pw.println("  Clients waiting for these windows to be drawn:");
6697             mWaitingForDrawnCallbacks.forEach((wc, callback) -> {
6698                 pw.print("  WindowContainer ");
6699                 pw.println(wc.getName());
6700                 for (int i = wc.mWaitingForDrawn.size() - 1; i >= 0; i--) {
6701                     final WindowState win = (WindowState) wc.mWaitingForDrawn.get(i);
6702                     pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(win);
6703                 }
6704             });
6705 
6706         }
6707         pw.println();
6708         pw.print("  mGlobalConfiguration="); pw.println(mRoot.getConfiguration());
6709         pw.print("  mHasPermanentDpad="); pw.println(mHasPermanentDpad);
6710         mRoot.dumpTopFocusedDisplayId(pw);
6711         mRoot.forAllDisplays(dc -> {
6712             final int displayId = dc.getDisplayId();
6713             final InsetsControlTarget imeLayeringTarget = dc.getImeTarget(IME_TARGET_LAYERING);
6714             final InputTarget imeInputTarget = dc.getImeInputTarget();
6715             final InsetsControlTarget imeControlTarget = dc.getImeTarget(IME_TARGET_CONTROL);
6716             if (imeLayeringTarget != null) {
6717                 pw.print("  imeLayeringTarget in display# "); pw.print(displayId);
6718                 pw.print(' '); pw.println(imeLayeringTarget);
6719             }
6720             if (imeInputTarget != null) {
6721                 pw.print("  imeInputTarget in display# "); pw.print(displayId);
6722                 pw.print(' '); pw.println(imeInputTarget);
6723             }
6724             if (imeControlTarget != null) {
6725                 pw.print("  imeControlTarget in display# "); pw.print(displayId);
6726                 pw.print(' '); pw.println(imeControlTarget);
6727             }
6728             pw.print("  Minimum task size of display#"); pw.print(displayId);
6729             pw.print(' '); pw.print(dc.mMinSizeOfResizeableTaskDp);
6730         });
6731         pw.print("  mBlurEnabled="); pw.println(mBlurController.getBlurEnabled());
6732         pw.print("  mLastDisplayFreezeDuration=");
6733                 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
6734                 if ( mLastFinishedFreezeSource != null) {
6735                     pw.print(" due to ");
6736                     pw.print(mLastFinishedFreezeSource);
6737                 }
6738                 pw.println();
6739 
6740         mInputManagerCallback.dump(pw, "  ");
6741         mSnapshotController.dump(pw, " ");
6742 
6743         dumpAccessibilityController(pw, /* force= */ false);
6744 
6745         if (dumpAll) {
6746             final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
6747             if (imeWindow != null) {
6748                 pw.print("  mInputMethodWindow="); pw.println(imeWindow);
6749             }
6750             mWindowPlacerLocked.dump(pw, "  ");
6751             pw.print("  mSystemBooted="); pw.print(mSystemBooted);
6752                     pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
6753 
6754             mRoot.dumpLayoutNeededDisplayIds(pw);
6755 
6756             pw.print("  mTransactionSequence="); pw.println(mTransactionSequence);
6757             pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
6758                     pw.print(" windows="); pw.print(mWindowsFreezingScreen);
6759                     pw.print(" client="); pw.print(mClientFreezingScreen);
6760                     pw.print(" apps="); pw.println(mAppsFreezingScreen);
6761             final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
6762             pw.print("  mRotation="); pw.println(defaultDisplayContent.getRotation());
6763             pw.print("  mLastOrientation=");
6764                     pw.println(defaultDisplayContent.getLastOrientation());
6765             pw.print("  mWaitingForConfig=");
6766                     pw.println(defaultDisplayContent.mWaitingForConfig);
6767             mRotationWatcherController.dump(pw);
6768 
6769             pw.print("  Animation settings: disabled="); pw.print(mAnimationsDisabled);
6770                     pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
6771                     pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
6772                     pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
6773             if (mRecentsAnimationController != null) {
6774                 pw.print("  mRecentsAnimationController="); pw.println(mRecentsAnimationController);
6775                 mRecentsAnimationController.dump(pw, "    ");
6776             }
6777         }
6778     }
6779 
dumpAccessibilityController(PrintWriter pw, boolean force)6780     private void dumpAccessibilityController(PrintWriter pw, boolean force) {
6781         boolean hasCallbacks = mAccessibilityController.hasCallbacks();
6782         if (!hasCallbacks && !force) {
6783             return;
6784         }
6785         if (!hasCallbacks) {
6786             pw.println("AccessibilityController doesn't have callbacks, but printing it anways:");
6787         } else {
6788             pw.println("AccessibilityController:");
6789         }
6790         mAccessibilityController.dump(pw, "  ");
6791     }
6792 
dumpAccessibilityLocked(PrintWriter pw)6793     private void dumpAccessibilityLocked(PrintWriter pw) {
6794         dumpAccessibilityController(pw, /* force= */ true);
6795     }
6796 
dumpWindows(PrintWriter pw, String name, boolean dumpAll)6797     private boolean dumpWindows(PrintWriter pw, String name, boolean dumpAll) {
6798         final ArrayList<WindowState> windows = new ArrayList();
6799         if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
6800             final boolean appsOnly = name.contains("apps");
6801             final boolean visibleOnly = name.contains("visible");
6802             synchronized (mGlobalLock) {
6803                 if (appsOnly) {
6804                     mRoot.dumpDisplayContents(pw);
6805                 }
6806 
6807                 mRoot.forAllWindows((w) -> {
6808                     if ((!visibleOnly || w.isVisible())
6809                             && (!appsOnly || w.mActivityRecord != null)) {
6810                         windows.add(w);
6811                     }
6812                 }, true /* traverseTopToBottom */);
6813             }
6814         } else {
6815             synchronized (mGlobalLock) {
6816                 mRoot.getWindowsByName(windows, name);
6817             }
6818         }
6819 
6820         if (windows.isEmpty()) {
6821             return false;
6822         }
6823 
6824         synchronized (mGlobalLock) {
6825             dumpWindowsLocked(pw, dumpAll, windows);
6826         }
6827         return true;
6828     }
6829 
dumpLastANRLocked(PrintWriter pw)6830     private void dumpLastANRLocked(PrintWriter pw) {
6831         pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
6832         if (mLastANRState == null) {
6833             pw.println("  <no ANR has occurred since boot>");
6834         } else {
6835             pw.println(mLastANRState);
6836         }
6837     }
6838 
6839     /**
6840      * Saves information about the state of the window manager at
6841      * the time an ANR occurred before anything else in the system changes
6842      * in response.
6843      *
6844      * @param activity The application that ANR'd, may be null.
6845      * @param windowState The window that ANR'd, may be null.
6846      * @param reason The reason for the ANR, may be null.
6847      */
saveANRStateLocked(ActivityRecord activity, WindowState windowState, String reason)6848     void saveANRStateLocked(ActivityRecord activity, WindowState windowState, String reason) {
6849         StringWriter sw = new StringWriter();
6850         PrintWriter pw = new FastPrintWriter(sw, false, 1024);
6851         pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
6852         if (activity != null) {
6853             pw.println("  Application at fault: " + activity.stringName);
6854         }
6855         if (windowState != null) {
6856             pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
6857         }
6858         if (reason != null) {
6859             pw.println("  Reason: " + reason);
6860         }
6861         for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
6862             final DisplayContent dc = mRoot.getChildAt(i);
6863             final int displayId = dc.getDisplayId();
6864             if (!dc.mWinAddedSinceNullFocus.isEmpty()) {
6865                 pw.println("  Windows added in display #" + displayId + " since null focus: "
6866                         + dc.mWinAddedSinceNullFocus);
6867             }
6868             if (!dc.mWinRemovedSinceNullFocus.isEmpty()) {
6869                 pw.println("  Windows removed in display #" + displayId + " since null focus: "
6870                         + dc.mWinRemovedSinceNullFocus);
6871             }
6872         }
6873         pw.println();
6874         dumpWindowsNoHeaderLocked(pw, true, null);
6875         pw.println();
6876         pw.println("Last ANR continued");
6877         mRoot.dumpDisplayContents(pw);
6878         pw.close();
6879         mLastANRState = sw.toString();
6880 
6881         mH.removeMessages(H.RESET_ANR_MESSAGE);
6882         mH.sendEmptyMessageDelayed(H.RESET_ANR_MESSAGE, LAST_ANR_LIFETIME_DURATION_MSECS);
6883     }
6884 
6885     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)6886     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
6887         PriorityDump.dump(mPriorityDumper, fd, pw, args);
6888     }
6889 
6890     @NeverCompile // Avoid size overhead of debugging code.
doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto)6891     private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
6892         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
6893         boolean dumpAll = false;
6894 
6895         int opti = 0;
6896         while (opti < args.length) {
6897             String opt = args[opti];
6898             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
6899                 break;
6900             }
6901             opti++;
6902             if ("-a".equals(opt)) {
6903                 dumpAll = true;
6904             } else if ("-h".equals(opt)) {
6905                 pw.println("Window manager dump options:");
6906                 pw.println("  [-a] [-h] [cmd] ...");
6907                 pw.println("  cmd may be one of:");
6908                 pw.println("    l[astanr]: last ANR information");
6909                 pw.println("    p[policy]: policy state");
6910                 pw.println("    a[animator]: animator state");
6911                 pw.println("    s[essions]: active sessions");
6912                 pw.println("    surfaces: active surfaces (debugging enabled only)");
6913                 pw.println("    d[isplays]: active display contents");
6914                 pw.println("    t[okens]: token list");
6915                 pw.println("    w[indows]: window list");
6916                 pw.println("    a11y[accessibility]: accessibility-related state");
6917                 pw.println("    package-config: installed packages having app-specific config");
6918                 pw.println("    trace: print trace status and write Winscope trace to file");
6919                 pw.println("  cmd may also be a NAME to dump windows.  NAME may");
6920                 pw.println("    be a partial substring in a window name, a");
6921                 pw.println("    Window hex object identifier, or");
6922                 pw.println("    \"all\" for all windows, or");
6923                 pw.println("    \"visible\" for the visible windows.");
6924                 pw.println("    \"visible-apps\" for the visible app windows.");
6925                 pw.println("  -a: include all available server state.");
6926                 pw.println("  --proto: output dump in protocol buffer format.");
6927                 return;
6928             } else {
6929                 pw.println("Unknown argument: " + opt + "; use -h for help");
6930             }
6931         }
6932 
6933         if (useProto) {
6934             final ProtoOutputStream proto = new ProtoOutputStream(fd);
6935             synchronized (mGlobalLock) {
6936                 dumpDebugLocked(proto, WindowTraceLogLevel.ALL);
6937             }
6938             proto.flush();
6939             return;
6940         }
6941         // Is the caller requesting to dump a particular piece of data?
6942         if (opti < args.length) {
6943             String cmd = args[opti];
6944             opti++;
6945             if ("lastanr".equals(cmd) || "l".equals(cmd)) {
6946                 synchronized (mGlobalLock) {
6947                     dumpLastANRLocked(pw);
6948                 }
6949                 return;
6950             } else if ("policy".equals(cmd) || "p".equals(cmd)) {
6951                 synchronized (mGlobalLock) {
6952                     dumpPolicyLocked(pw, args);
6953                 }
6954                 return;
6955             } else if ("animator".equals(cmd) || "a".equals(cmd)) {
6956                 synchronized (mGlobalLock) {
6957                     dumpAnimatorLocked(pw, true);
6958                 }
6959                 return;
6960             } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
6961                 synchronized (mGlobalLock) {
6962                     dumpSessionsLocked(pw);
6963                 }
6964                 return;
6965             } else if ("displays".equals(cmd) || "d".equals(cmd)) {
6966                 synchronized (mGlobalLock) {
6967                     mRoot.dumpDisplayContents(pw);
6968                 }
6969                 return;
6970             } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
6971                 synchronized (mGlobalLock) {
6972                     dumpTokensLocked(pw, true);
6973                 }
6974                 return;
6975             } else if ("windows".equals(cmd) || "w".equals(cmd)) {
6976                 synchronized (mGlobalLock) {
6977                     dumpWindowsLocked(pw, true, null);
6978                 }
6979                 return;
6980             } else if ("accessibility".equals(cmd) || "a11y".equals(cmd)) {
6981                 synchronized (mGlobalLock) {
6982                     dumpAccessibilityLocked(pw);
6983                 }
6984                 return;
6985             } else if ("all".equals(cmd)) {
6986                 synchronized (mGlobalLock) {
6987                     dumpWindowsLocked(pw, true, null);
6988                 }
6989                 return;
6990             } else if ("containers".equals(cmd)) {
6991                 synchronized (mGlobalLock) {
6992                     mRoot.dumpChildrenNames(pw, " ");
6993                     pw.println(" ");
6994                     mRoot.forAllWindows(w -> {pw.println(w);}, true /* traverseTopToBottom */);
6995                 }
6996                 return;
6997             } else if ("trace".equals(cmd)) {
6998                 dumpTraceStatus(pw);
6999                 return;
7000             } else if ("logging".equals(cmd)) {
7001                 dumpLogStatus(pw);
7002                 return;
7003             } else if ("refresh".equals(cmd)) {
7004                 dumpHighRefreshRateBlacklist(pw);
7005                 return;
7006             } else if ("constants".equals(cmd)) {
7007                 mConstants.dump(pw);
7008                 return;
7009             } else if ("package-config".equals(cmd)) {
7010                 mAtmService.dumpInstalledPackagesConfig(pw);
7011                 return;
7012             } else {
7013                 // Dumping a single name?
7014                 if (!dumpWindows(pw, cmd, dumpAll)) {
7015                     pw.println("Bad window command, or no windows match: " + cmd);
7016                     pw.println("Use -h for help.");
7017                 }
7018                 return;
7019             }
7020         }
7021 
7022         synchronized (mGlobalLock) {
7023             pw.println();
7024             final String separator = "---------------------------------------------------------"
7025                     + "----------------------";
7026             if (dumpAll) {
7027                 pw.println(separator);
7028             }
7029             dumpLastANRLocked(pw);
7030             pw.println();
7031             if (dumpAll) {
7032                 pw.println(separator);
7033             }
7034             dumpPolicyLocked(pw, args);
7035             pw.println();
7036             if (dumpAll) {
7037                 pw.println(separator);
7038             }
7039             dumpAnimatorLocked(pw, dumpAll);
7040             pw.println();
7041             if (dumpAll) {
7042                 pw.println(separator);
7043             }
7044             dumpSessionsLocked(pw);
7045             pw.println();
7046             if (dumpAll) {
7047                 pw.println(separator);
7048             }
7049             if (dumpAll) {
7050                 pw.println(separator);
7051             }
7052             mRoot.dumpDisplayContents(pw);
7053             pw.println();
7054             if (dumpAll) {
7055                 pw.println(separator);
7056             }
7057             dumpTokensLocked(pw, dumpAll);
7058             pw.println();
7059             if (dumpAll) {
7060                 pw.println(separator);
7061             }
7062             dumpWindowsLocked(pw, dumpAll, null);
7063             if (dumpAll) {
7064                 pw.println(separator);
7065             }
7066             dumpTraceStatus(pw);
7067             if (dumpAll) {
7068                 pw.println(separator);
7069             }
7070             dumpLogStatus(pw);
7071             if (dumpAll) {
7072                 pw.println(separator);
7073             }
7074             dumpHighRefreshRateBlacklist(pw);
7075             if (dumpAll) {
7076                 pw.println(separator);
7077             }
7078             mAtmService.dumpInstalledPackagesConfig(pw);
7079             if (dumpAll) {
7080                 pw.println(separator);
7081             }
7082             mConstants.dump(pw);
7083         }
7084     }
7085 
7086     // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
7087     @Override
monitor()7088     public void monitor() {
7089         synchronized (mGlobalLock) { }
7090     }
7091 
7092     // There is an inherent assumption that this will never return null.
7093     // TODO(multi-display): Inspect all the call-points of this method to see if they make sense to
7094     // support non-default display.
getDefaultDisplayContentLocked()7095     DisplayContent getDefaultDisplayContentLocked() {
7096         return mRoot.getDisplayContent(DEFAULT_DISPLAY);
7097     }
7098 
onOverlayChanged()7099     public void onOverlayChanged() {
7100         // Post to display thread so it can get the latest display info.
7101         mH.post(() -> {
7102             synchronized (mGlobalLock) {
7103                 mAtmService.deferWindowLayout();
7104                 mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().onOverlayChanged());
7105                 mAtmService.continueWindowLayout();
7106             }
7107         });
7108     }
7109 
7110     @Override
getWindowManagerLock()7111     public Object getWindowManagerLock() {
7112         return mGlobalLock;
7113     }
7114 
7115     @Override
getDockedStackSide()7116     public int getDockedStackSide() {
7117         return 0;
7118     }
7119 
setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays)7120     void setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays) {
7121         synchronized (mGlobalLock) {
7122             mForceDesktopModeOnExternalDisplays = forceDesktopModeOnExternalDisplays;
7123             mRoot.updateDisplayImePolicyCache();
7124         }
7125     }
7126 
7127     @VisibleForTesting
setIsPc(boolean isPc)7128     void setIsPc(boolean isPc) {
7129         synchronized (mGlobalLock) {
7130             mIsPc = isPc;
7131         }
7132     }
7133 
dipToPixel(int dip, DisplayMetrics displayMetrics)7134     static int dipToPixel(int dip, DisplayMetrics displayMetrics) {
7135         return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
7136     }
7137 
registerPinnedTaskListener(int displayId, IPinnedTaskListener listener)7138     public void registerPinnedTaskListener(int displayId, IPinnedTaskListener listener) {
7139         if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
7140                 "registerPinnedTaskListener()")) {
7141             return;
7142         }
7143         if (!mAtmService.mSupportsPictureInPicture) {
7144             return;
7145         }
7146         synchronized (mGlobalLock) {
7147             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
7148             displayContent.getPinnedTaskController().registerPinnedTaskListener(listener);
7149         }
7150     }
7151 
7152     @Override
requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId)7153     public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
7154         enforceRegisterWindowManagerListenersPermission("requestAppKeyboardShortcuts");
7155 
7156         WindowState focusedWindow = getFocusedWindow();
7157         if (focusedWindow == null || focusedWindow.mClient == null) {
7158             notifyReceiverWithEmptyBundle(receiver);
7159             return;
7160         }
7161         try {
7162             focusedWindow.mClient.requestAppKeyboardShortcuts(receiver, deviceId);
7163         } catch (RemoteException e) {
7164             notifyReceiverWithEmptyBundle(receiver);
7165         }
7166     }
7167 
7168     @Override
requestImeKeyboardShortcuts(IResultReceiver receiver, int deviceId)7169     public void requestImeKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
7170         enforceRegisterWindowManagerListenersPermission("requestImeKeyboardShortcuts");
7171 
7172         WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
7173         if (imeWindow == null || imeWindow.mClient == null) {
7174             notifyReceiverWithEmptyBundle(receiver);
7175             return;
7176         }
7177         try {
7178             imeWindow.mClient.requestAppKeyboardShortcuts(receiver, deviceId);
7179         } catch (RemoteException e) {
7180             notifyReceiverWithEmptyBundle(receiver);
7181         }
7182     }
7183 
enforceRegisterWindowManagerListenersPermission(String message)7184     private void enforceRegisterWindowManagerListenersPermission(String message) {
7185         mContext.enforceCallingOrSelfPermission(REGISTER_WINDOW_MANAGER_LISTENERS, message);
7186     }
7187 
notifyReceiverWithEmptyBundle(IResultReceiver receiver)7188     private static void notifyReceiverWithEmptyBundle(IResultReceiver receiver) {
7189         try {
7190             receiver.send(0, Bundle.EMPTY);
7191         } catch (RemoteException e) {
7192             ProtoLog.e(WM_ERROR, "unable to call receiver for empty keyboard shortcuts");
7193         }
7194     }
7195 
7196     @Override
getStableInsets(int displayId, Rect outInsets)7197     public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
7198         synchronized (mGlobalLock) {
7199             getStableInsetsLocked(displayId, outInsets);
7200         }
7201     }
7202 
getStableInsetsLocked(int displayId, Rect outInsets)7203     void getStableInsetsLocked(int displayId, Rect outInsets) {
7204         outInsets.setEmpty();
7205         final DisplayContent dc = mRoot.getDisplayContent(displayId);
7206         if (dc != null) {
7207             final DisplayInfo di = dc.getDisplayInfo();
7208             outInsets.set(dc.getDisplayPolicy().getDecorInsetsInfo(
7209                     di.rotation, di.logicalWidth, di.logicalHeight).mConfigInsets);
7210         }
7211     }
7212 
7213     MousePositionTracker mMousePositionTracker = new MousePositionTracker();
7214 
7215     private static class MousePositionTracker implements PointerEventListener {
7216         private boolean mLatestEventWasMouse;
7217         private float mLatestMouseX;
7218         private float mLatestMouseY;
7219 
7220         /**
7221          * The display that the pointer (mouse cursor) is currently shown on. This is updated
7222          * directly by InputManagerService when the pointer display changes.
7223          */
7224         private int mPointerDisplayId = INVALID_DISPLAY;
7225 
7226         /**
7227          * Update the mouse cursor position as a result of a mouse movement.
7228          * @return true if the position was successfully updated, false otherwise.
7229          */
updatePosition(int displayId, float x, float y)7230         boolean updatePosition(int displayId, float x, float y) {
7231             synchronized (this) {
7232                 mLatestEventWasMouse = true;
7233 
7234                 if (displayId != mPointerDisplayId) {
7235                     // The display of the position update does not match the display on which the
7236                     // mouse pointer is shown, so do not update the position.
7237                     return false;
7238                 }
7239                 mLatestMouseX = x;
7240                 mLatestMouseY = y;
7241                 return true;
7242             }
7243         }
7244 
setPointerDisplayId(int displayId)7245         void setPointerDisplayId(int displayId) {
7246             synchronized (this) {
7247                 mPointerDisplayId = displayId;
7248             }
7249         }
7250 
7251         @Override
onPointerEvent(MotionEvent motionEvent)7252         public void onPointerEvent(MotionEvent motionEvent) {
7253             if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) {
7254                 updatePosition(motionEvent.getDisplayId(), motionEvent.getRawX(),
7255                         motionEvent.getRawY());
7256             } else {
7257                 synchronized (this) {
7258                     mLatestEventWasMouse = false;
7259                 }
7260             }
7261         }
7262     };
7263 
updatePointerIcon(IWindow client)7264     void updatePointerIcon(IWindow client) {
7265         int pointerDisplayId;
7266         float mouseX, mouseY;
7267 
7268         synchronized(mMousePositionTracker) {
7269             if (!mMousePositionTracker.mLatestEventWasMouse) {
7270                 return;
7271             }
7272             mouseX = mMousePositionTracker.mLatestMouseX;
7273             mouseY = mMousePositionTracker.mLatestMouseY;
7274             pointerDisplayId = mMousePositionTracker.mPointerDisplayId;
7275         }
7276 
7277         synchronized (mGlobalLock) {
7278             if (mDragDropController.dragDropActiveLocked()) {
7279                 // Drag cursor overrides the app cursor.
7280                 return;
7281             }
7282             WindowState callingWin = windowForClientLocked(null, client, false);
7283             if (callingWin == null) {
7284                 ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
7285                 return;
7286             }
7287             final DisplayContent displayContent = callingWin.getDisplayContent();
7288             if (displayContent == null) {
7289                 return;
7290             }
7291             if (pointerDisplayId != displayContent.getDisplayId()) {
7292                 // Do not let the pointer icon be updated by a window on a different display.
7293                 return;
7294             }
7295             WindowState windowUnderPointer =
7296                     displayContent.getTouchableWinAtPointLocked(mouseX, mouseY);
7297             if (windowUnderPointer != callingWin) {
7298                 return;
7299             }
7300             try {
7301                 windowUnderPointer.mClient.updatePointerIcon(
7302                         windowUnderPointer.translateToWindowX(mouseX),
7303                         windowUnderPointer.translateToWindowY(mouseY));
7304             } catch (RemoteException e) {
7305                 ProtoLog.w(WM_ERROR, "unable to update pointer icon");
7306             }
7307         }
7308     }
7309 
restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY)7310     void restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY) {
7311         // Mouse position tracker has not been getting updates while dragging, update it now.
7312         if (!mMousePositionTracker.updatePosition(
7313                 displayContent.getDisplayId(), latestX, latestY)) {
7314             // The mouse position could not be updated, so ignore this request.
7315             return;
7316         }
7317 
7318         WindowState windowUnderPointer =
7319                 displayContent.getTouchableWinAtPointLocked(latestX, latestY);
7320         if (windowUnderPointer != null) {
7321             try {
7322                 windowUnderPointer.mClient.updatePointerIcon(
7323                         windowUnderPointer.translateToWindowX(latestX),
7324                         windowUnderPointer.translateToWindowY(latestY));
7325             } catch (RemoteException e) {
7326                 ProtoLog.w(WM_ERROR, "unable to restore pointer icon");
7327             }
7328         } else {
7329             mContext.getSystemService(InputManager.class)
7330                     .setPointerIconType(PointerIcon.TYPE_DEFAULT);
7331         }
7332     }
setMousePointerDisplayId(int displayId)7333     void setMousePointerDisplayId(int displayId) {
7334         mMousePositionTracker.setPointerDisplayId(displayId);
7335     }
7336 
7337     /**
7338      * Update a tap exclude region in the window identified by the provided id. Touches down on this
7339      * region will not:
7340      * <ol>
7341      * <li>Switch focus to this window.</li>
7342      * <li>Move the display of this window to top.</li>
7343      * <li>Send the touch events to this window.</li>
7344      * </ol>
7345      * Passing an invalid region will remove the area from the exclude region of this window.
7346      */
updateTapExcludeRegion(IWindow client, Region region)7347     void updateTapExcludeRegion(IWindow client, Region region) {
7348         synchronized (mGlobalLock) {
7349             final WindowState callingWin = windowForClientLocked(null, client, false);
7350             if (callingWin == null) {
7351                 ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
7352                 return;
7353             }
7354             callingWin.updateTapExcludeRegion(region);
7355         }
7356     }
7357 
7358     /**
7359      * Forwards a scroll capture request to the appropriate window, if available.
7360      *
7361      * @param displayId the display for the request
7362      * @param behindClient token for a window, used to filter the search to windows behind it
7363      * @param taskId specifies the id of a task the result must belong to or -1 to match any task
7364      * @param listener to receive the response
7365      */
requestScrollCapture(int displayId, @Nullable IBinder behindClient, int taskId, IScrollCaptureResponseListener listener)7366     public void requestScrollCapture(int displayId, @Nullable IBinder behindClient, int taskId,
7367             IScrollCaptureResponseListener listener) {
7368         if (!checkCallingPermission(READ_FRAME_BUFFER, "requestScrollCapture()")) {
7369             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
7370         }
7371         final long token = Binder.clearCallingIdentity();
7372         try {
7373             ScrollCaptureResponse.Builder responseBuilder = new ScrollCaptureResponse.Builder();
7374             synchronized (mGlobalLock) {
7375                 DisplayContent dc = mRoot.getDisplayContent(displayId);
7376                 if (dc == null) {
7377                     ProtoLog.e(WM_ERROR,
7378                             "Invalid displayId for requestScrollCapture: %d", displayId);
7379                     responseBuilder.setDescription(String.format("bad displayId: %d", displayId));
7380                     listener.onScrollCaptureResponse(responseBuilder.build());
7381                     return;
7382                 }
7383                 WindowState topWindow = null;
7384                 if (behindClient != null) {
7385                     topWindow = windowForClientLocked(null, behindClient, /* throwOnError*/ false);
7386                 }
7387                 WindowState targetWindow = dc.findScrollCaptureTargetWindow(topWindow, taskId);
7388                 if (targetWindow == null) {
7389                     responseBuilder.setDescription("findScrollCaptureTargetWindow returned null");
7390                     listener.onScrollCaptureResponse(responseBuilder.build());
7391                     return;
7392                 }
7393                 try {
7394                     // Forward to the window for handling, which will respond using the callback.
7395                     targetWindow.mClient.requestScrollCapture(listener);
7396                 } catch (RemoteException e) {
7397                     ProtoLog.w(WM_ERROR,
7398                             "requestScrollCapture: caught exception dispatching to window."
7399                                     + "token=%s", targetWindow.mClient.asBinder());
7400                     responseBuilder.setWindowTitle(targetWindow.getName());
7401                     responseBuilder.setPackageName(targetWindow.getOwningPackage());
7402                     responseBuilder.setDescription(String.format("caught exception: %s", e));
7403                     listener.onScrollCaptureResponse(responseBuilder.build());
7404                 }
7405             }
7406         } catch (RemoteException e) {
7407             ProtoLog.w(WM_ERROR,
7408                     "requestScrollCapture: caught exception dispatching callback: %s", e);
7409         } finally {
7410             Binder.restoreCallingIdentity(token);
7411         }
7412     }
7413 
7414     @Override
getWindowingMode(int displayId)7415     public int getWindowingMode(int displayId) {
7416         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getWindowingMode()")) {
7417             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7418         }
7419 
7420         synchronized (mGlobalLock) {
7421             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
7422             if (displayContent == null) {
7423                 ProtoLog.w(WM_ERROR,
7424                         "Attempted to get windowing mode of a display that does not exist: %d",
7425                         displayId);
7426                 return WindowConfiguration.WINDOWING_MODE_UNDEFINED;
7427             }
7428             return mDisplayWindowSettings.getWindowingModeLocked(displayContent);
7429         }
7430     }
7431 
7432     @Override
setWindowingMode(int displayId, int mode)7433     public void setWindowingMode(int displayId, int mode) {
7434         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setWindowingMode()")) {
7435             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7436         }
7437 
7438         final long origId = Binder.clearCallingIdentity();
7439         try {
7440             synchronized (mGlobalLock) {
7441                 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
7442                 if (displayContent == null) {
7443                     ProtoLog.w(WM_ERROR,
7444                             "Attempted to set windowing mode to a display that does not exist: %d",
7445                             displayId);
7446                     return;
7447                 }
7448 
7449                 int lastWindowingMode = displayContent.getWindowingMode();
7450                 mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode);
7451 
7452                 displayContent.reconfigureDisplayLocked();
7453 
7454                 if (lastWindowingMode != displayContent.getWindowingMode()) {
7455                     // reconfigure won't detect this change in isolation because the windowing mode
7456                     // is already set on the display, so fire off a new config now.
7457                     displayContent.sendNewConfiguration();
7458                     // Now that all configurations are updated, execute pending transitions.
7459                     displayContent.executeAppTransition();
7460                 }
7461             }
7462         } finally {
7463             Binder.restoreCallingIdentity(origId);
7464         }
7465     }
7466 
7467     @Override
getRemoveContentMode(int displayId)7468     public @RemoveContentMode int getRemoveContentMode(int displayId) {
7469         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getRemoveContentMode()")) {
7470             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7471         }
7472 
7473         synchronized (mGlobalLock) {
7474             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
7475             if (displayContent == null) {
7476                 ProtoLog.w(WM_ERROR,
7477                         "Attempted to get remove mode of a display that does not exist: %d",
7478                         displayId);
7479                 return REMOVE_CONTENT_MODE_UNDEFINED;
7480             }
7481             return mDisplayWindowSettings.getRemoveContentModeLocked(displayContent);
7482         }
7483     }
7484 
7485     @Override
setRemoveContentMode(int displayId, @RemoveContentMode int mode)7486     public void setRemoveContentMode(int displayId, @RemoveContentMode int mode) {
7487         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setRemoveContentMode()")) {
7488             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7489         }
7490 
7491         final long origId = Binder.clearCallingIdentity();
7492         try {
7493             synchronized (mGlobalLock) {
7494                 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
7495                 if (displayContent == null) {
7496                     ProtoLog.w(WM_ERROR,
7497                             "Attempted to set remove mode to a display that does not exist: %d",
7498                             displayId);
7499                     return;
7500                 }
7501 
7502                 mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode);
7503                 displayContent.reconfigureDisplayLocked();
7504             }
7505         } finally {
7506             Binder.restoreCallingIdentity(origId);
7507         }
7508     }
7509 
7510     @Override
shouldShowWithInsecureKeyguard(int displayId)7511     public boolean shouldShowWithInsecureKeyguard(int displayId) {
7512         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowWithInsecureKeyguard()")) {
7513             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7514         }
7515 
7516         synchronized (mGlobalLock) {
7517             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
7518             if (displayContent == null) {
7519                 ProtoLog.w(WM_ERROR, "Attempted to get flag of a display that does not exist: %d",
7520                         displayId);
7521                 return false;
7522             }
7523             return mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(displayContent);
7524         }
7525     }
7526 
7527     @Override
setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow)7528     public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
7529         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW,
7530                 "setShouldShowWithInsecureKeyguard()")) {
7531             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7532         }
7533         final long origId = Binder.clearCallingIdentity();
7534         try {
7535             synchronized (mGlobalLock) {
7536                 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
7537                 if (displayContent == null) {
7538                     ProtoLog.w(WM_ERROR, "Attempted to set flag to a display that does not exist: "
7539                             + "%d", displayId);
7540                     return;
7541                 }
7542 
7543                 mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(displayContent,
7544                         shouldShow);
7545 
7546                 displayContent.reconfigureDisplayLocked();
7547             }
7548         } finally {
7549             Binder.restoreCallingIdentity(origId);
7550         }
7551     }
7552 
7553     @Override
shouldShowSystemDecors(int displayId)7554     public boolean shouldShowSystemDecors(int displayId) {
7555         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowSystemDecors()")) {
7556             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7557         }
7558 
7559         synchronized (mGlobalLock) {
7560             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
7561             if (displayContent == null) {
7562                 ProtoLog.w(WM_ERROR, "Attempted to get system decors flag of a display that does "
7563                         + "not exist: %d", displayId);
7564                 return false;
7565             }
7566             return displayContent.supportsSystemDecorations();
7567         }
7568     }
7569 
7570     @Override
setShouldShowSystemDecors(int displayId, boolean shouldShow)7571     public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
7572         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowSystemDecors()")) {
7573             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7574         }
7575         final long origId = Binder.clearCallingIdentity();
7576         try {
7577             synchronized (mGlobalLock) {
7578                 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
7579                 if (displayContent == null) {
7580                     ProtoLog.w(WM_ERROR, "Attempted to set system decors flag to a display that "
7581                             + "does not exist: %d", displayId);
7582                     return;
7583                 }
7584                 if (!displayContent.isTrusted()) {
7585                     throw new SecurityException("Attempted to set system decors flag to an "
7586                             + "untrusted virtual display: " + displayId);
7587                 }
7588 
7589                 mDisplayWindowSettings.setShouldShowSystemDecorsLocked(displayContent, shouldShow);
7590 
7591                 displayContent.reconfigureDisplayLocked();
7592             }
7593         } finally {
7594             Binder.restoreCallingIdentity(origId);
7595         }
7596     }
7597 
7598     @Override
getDisplayImePolicy(int displayId)7599     public @DisplayImePolicy int getDisplayImePolicy(int displayId) {
7600         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getDisplayImePolicy()")) {
7601             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7602         }
7603         final Map<Integer, Integer> displayImePolicyCache = mDisplayImePolicyCache;
7604         if (!displayImePolicyCache.containsKey(displayId)) {
7605             ProtoLog.w(WM_ERROR,
7606                     "Attempted to get IME policy of a display that does not exist: %d",
7607                     displayId);
7608             return DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
7609         }
7610         return displayImePolicyCache.get(displayId);
7611     }
7612 
7613     @Override
setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy)7614     public void setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy) {
7615         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setDisplayImePolicy()")) {
7616             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
7617         }
7618         final long origId = Binder.clearCallingIdentity();
7619         try {
7620             synchronized (mGlobalLock) {
7621                 final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
7622                 if (displayContent == null) {
7623                     ProtoLog.w(WM_ERROR, "Attempted to set IME policy to a display"
7624                             + " that does not exist: %d", displayId);
7625                     return;
7626                 }
7627                 if (!displayContent.isTrusted()) {
7628                     throw new SecurityException("Attempted to set IME policy to an untrusted "
7629                             + "virtual display: " + displayId);
7630                 }
7631 
7632                 mDisplayWindowSettings.setDisplayImePolicy(displayContent, imePolicy);
7633 
7634                 displayContent.reconfigureDisplayLocked();
7635             }
7636         } finally {
7637             Binder.restoreCallingIdentity(origId);
7638         }
7639     }
7640 
7641     @Override
registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)7642     public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
7643             throws RemoteException {
7644         if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) {
7645             throw new SecurityException(
7646                     "Requires REGISTER_WINDOW_MANAGER_LISTENERS permission");
7647         }
7648         mPolicy.registerShortcutKey(shortcutCode, shortcutKeyReceiver);
7649     }
7650 
7651     private final class LocalService extends WindowManagerInternal {
7652 
7653         @Override
getAccessibilityController()7654         public AccessibilityControllerInternal getAccessibilityController() {
7655             return AccessibilityController.getAccessibilityControllerInternal(
7656                     WindowManagerService.this);
7657         }
7658 
7659         @Override
clearSnapshotCache()7660         public void clearSnapshotCache() {
7661             synchronized (mGlobalLock) {
7662                 mTaskSnapshotController.clearSnapshotCache();
7663             }
7664         }
7665 
7666         @Override
requestTraversalFromDisplayManager()7667         public void requestTraversalFromDisplayManager() {
7668             synchronized (mGlobalLock) {
7669                 requestTraversal();
7670             }
7671         }
7672 
7673         @Override
onDisplayManagerReceivedDeviceState(int deviceState)7674         public void onDisplayManagerReceivedDeviceState(int deviceState) {
7675             mH.post(() -> {
7676                 synchronized (mGlobalLock) {
7677                     mRoot.onDisplayManagerReceivedDeviceState(deviceState);
7678                 }
7679             });
7680         }
7681 
7682         @Override
setMagnificationSpec(int displayId, MagnificationSpec spec)7683         public void setMagnificationSpec(int displayId, MagnificationSpec spec) {
7684             synchronized (mGlobalLock) {
7685                 if (mAccessibilityController.hasCallbacks()) {
7686                     mAccessibilityController.setMagnificationSpec(displayId, spec);
7687                 } else {
7688                     throw new IllegalStateException("Magnification callbacks not set!");
7689                 }
7690             }
7691         }
7692 
7693         @Override
setForceShowMagnifiableBounds(int displayId, boolean show)7694         public void setForceShowMagnifiableBounds(int displayId, boolean show) {
7695             synchronized (mGlobalLock) {
7696                 if (mAccessibilityController.hasCallbacks()) {
7697                     mAccessibilityController.setForceShowMagnifiableBounds(displayId, show);
7698                 } else {
7699                     throw new IllegalStateException("Magnification callbacks not set!");
7700                 }
7701             }
7702         }
7703 
7704         @Override
getMagnificationRegion(int displayId, @NonNull Region magnificationRegion)7705         public void getMagnificationRegion(int displayId, @NonNull Region magnificationRegion) {
7706             synchronized (mGlobalLock) {
7707                 if (mAccessibilityController.hasCallbacks()) {
7708                     mAccessibilityController.getMagnificationRegion(displayId, magnificationRegion);
7709                 } else {
7710                     throw new IllegalStateException("Magnification callbacks not set!");
7711                 }
7712             }
7713         }
7714 
7715         @Override
setMagnificationCallbacks(int displayId, @Nullable MagnificationCallbacks callbacks)7716         public boolean setMagnificationCallbacks(int displayId,
7717                 @Nullable MagnificationCallbacks callbacks) {
7718             synchronized (mGlobalLock) {
7719                 return mAccessibilityController.setMagnificationCallbacks(displayId, callbacks);
7720             }
7721         }
7722 
7723         @Override
setWindowsForAccessibilityCallback(int displayId, WindowsForAccessibilityCallback callback)7724         public void setWindowsForAccessibilityCallback(int displayId,
7725                 WindowsForAccessibilityCallback callback) {
7726             synchronized (mGlobalLock) {
7727                 mAccessibilityController.setWindowsForAccessibilityCallback(displayId, callback);
7728             }
7729         }
7730 
7731         @Override
setInputFilter(IInputFilter filter)7732         public void setInputFilter(IInputFilter filter) {
7733             mInputManager.setInputFilter(filter);
7734         }
7735 
7736         @Override
getFocusedWindowToken()7737         public IBinder getFocusedWindowToken() {
7738             synchronized (mGlobalLock) {
7739                 return mAccessibilityController.getFocusedWindowToken();
7740             }
7741         }
7742 
7743         // TODO (b/229837707): Delete this method after changing the solution.
7744         @Override
getFocusedWindowTokenFromWindowStates()7745         public IBinder getFocusedWindowTokenFromWindowStates() {
7746             synchronized (mGlobalLock) {
7747                 final WindowState windowState = getFocusedWindowLocked();
7748                 if (windowState != null) {
7749                     return windowState.mClient.asBinder();
7750                 }
7751                 return null;
7752             }
7753         }
7754 
7755         @Override
moveDisplayToTopIfAllowed(int displayId)7756         public void moveDisplayToTopIfAllowed(int displayId) {
7757             WindowManagerService.this.moveDisplayToTopIfAllowed(displayId);
7758         }
7759 
7760         @Override
requestWindowFocus(IBinder windowToken)7761         public void requestWindowFocus(IBinder windowToken) {
7762             synchronized (mGlobalLock) {
7763                 final InputTarget inputTarget =
7764                         WindowManagerService.this.getInputTargetFromWindowTokenLocked(windowToken);
7765                 WindowManagerService.this.onPointerDownOutsideFocusLocked(inputTarget);
7766             }
7767         }
7768 
7769         @Override
isKeyguardLocked()7770         public boolean isKeyguardLocked() {
7771             return WindowManagerService.this.isKeyguardLocked();
7772         }
7773 
7774         @Override
isKeyguardShowingAndNotOccluded()7775         public boolean isKeyguardShowingAndNotOccluded() {
7776             return WindowManagerService.this.isKeyguardShowingAndNotOccluded();
7777         }
7778 
7779         @Override
isKeyguardSecure(@serIdInt int userId)7780         public boolean isKeyguardSecure(@UserIdInt int userId) {
7781             return mPolicy.isKeyguardSecure(userId);
7782         }
7783 
7784         @Override
showGlobalActions()7785         public void showGlobalActions() {
7786             WindowManagerService.this.showGlobalActions();
7787         }
7788 
7789         @Override
getWindowFrame(IBinder token, Rect outBounds)7790         public void getWindowFrame(IBinder token, Rect outBounds) {
7791             synchronized (mGlobalLock) {
7792                 WindowState windowState = mWindowMap.get(token);
7793                 if (windowState != null) {
7794                     outBounds.set(windowState.getFrame());
7795                 } else {
7796                     outBounds.setEmpty();
7797                 }
7798             }
7799         }
7800 
7801         @Override
getWindowTransformationMatrixAndMagnificationSpec( IBinder token)7802         public Pair<Matrix, MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec(
7803                 IBinder token) {
7804             return mAccessibilityController
7805                     .getWindowTransformationMatrixAndMagnificationSpec(token);
7806         }
7807 
7808         @Override
waitForAllWindowsDrawn(Message message, long timeout, int displayId)7809         public void waitForAllWindowsDrawn(Message message, long timeout, int displayId) {
7810             Objects.requireNonNull(message.getTarget());
7811             final WindowContainer<?> container = displayId == INVALID_DISPLAY
7812                     ? mRoot : mRoot.getDisplayContent(displayId);
7813             if (container == null) {
7814                 // The waiting container doesn't exist, no need to wait to run the callback. Run and
7815                 // return;
7816                 message.sendToTarget();
7817                 return;
7818             }
7819             boolean allWindowsDrawn = false;
7820             synchronized (mGlobalLock) {
7821                 container.waitForAllWindowsDrawn();
7822                 mWindowPlacerLocked.requestTraversal();
7823                 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
7824                 if (container.mWaitingForDrawn.isEmpty()) {
7825                     allWindowsDrawn = true;
7826                 } else {
7827                     if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
7828                         for (int i = 0; i < container.mWaitingForDrawn.size(); i++) {
7829                             traceStartWaitingForWindowDrawn(container.mWaitingForDrawn.get(i));
7830                         }
7831                     }
7832 
7833                     mWaitingForDrawnCallbacks.put(container, message);
7834                     mH.sendNewMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, container, timeout);
7835                     checkDrawnWindowsLocked();
7836                 }
7837             }
7838             if (allWindowsDrawn) {
7839                 message.sendToTarget();
7840             }
7841         }
7842 
7843         @Override
setForcedDisplaySize(int displayId, int width, int height)7844         public void setForcedDisplaySize(int displayId, int width, int height) {
7845             WindowManagerService.this.setForcedDisplaySize(displayId, width, height);
7846         }
7847 
7848         @Override
clearForcedDisplaySize(int displayId)7849         public void clearForcedDisplaySize(int displayId) {
7850             WindowManagerService.this.clearForcedDisplaySize(displayId);
7851         }
7852 
7853         @Override
addWindowToken(IBinder token, int type, int displayId, @Nullable Bundle options)7854         public void addWindowToken(IBinder token, int type, int displayId,
7855                 @Nullable Bundle options) {
7856             WindowManagerService.this.addWindowToken(token, type, displayId, options);
7857         }
7858 
7859         @Override
removeWindowToken(IBinder binder, boolean removeWindows, boolean animateExit, int displayId)7860         public void removeWindowToken(IBinder binder, boolean removeWindows, boolean animateExit,
7861                 int displayId) {
7862             WindowManagerService.this.removeWindowToken(binder, removeWindows, animateExit,
7863                     displayId);
7864         }
7865 
7866         @Override
moveWindowTokenToDisplay(IBinder binder, int displayId)7867         public void moveWindowTokenToDisplay(IBinder binder, int displayId) {
7868             WindowManagerService.this.moveWindowTokenToDisplay(binder, displayId);
7869         }
7870 
7871         // TODO(multi-display): currently only used by PWM to notify keyguard transitions as well
7872         // forwarding it to SystemUI for synchronizing status and navigation bar animations.
7873         @Override
registerAppTransitionListener(AppTransitionListener listener)7874         public void registerAppTransitionListener(AppTransitionListener listener) {
7875             synchronized (mGlobalLock) {
7876                 getDefaultDisplayContentLocked().mAppTransition.registerListenerLocked(listener);
7877                 mAtmService.getTransitionController().registerLegacyListener(listener);
7878             }
7879         }
7880 
7881         @Override
registerTaskSystemBarsListener(TaskSystemBarsListener listener)7882         public void registerTaskSystemBarsListener(TaskSystemBarsListener listener) {
7883             synchronized (mGlobalLock) {
7884                 mTaskSystemBarsListenerController.registerListener(listener);
7885             }
7886         }
7887 
7888         @Override
unregisterTaskSystemBarsListener(TaskSystemBarsListener listener)7889         public void unregisterTaskSystemBarsListener(TaskSystemBarsListener listener) {
7890             synchronized (mGlobalLock) {
7891                 mTaskSystemBarsListenerController.unregisterListener(listener);
7892             }
7893         }
7894 
7895         @Override
registerKeyguardExitAnimationStartListener( KeyguardExitAnimationStartListener listener)7896         public void registerKeyguardExitAnimationStartListener(
7897                 KeyguardExitAnimationStartListener listener) {
7898             synchronized (mGlobalLock) {
7899                 getDefaultDisplayContentLocked().mAppTransition
7900                         .registerKeygaurdExitAnimationStartListener(listener);
7901             }
7902         }
7903 
7904         @Override
reportPasswordChanged(int userId)7905         public void reportPasswordChanged(int userId) {
7906             mKeyguardDisableHandler.updateKeyguardEnabled(userId);
7907         }
7908 
7909         @Override
getInputMethodWindowVisibleHeight(int displayId)7910         public int getInputMethodWindowVisibleHeight(int displayId) {
7911             synchronized (mGlobalLock) {
7912                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
7913                 return dc.getInputMethodWindowVisibleHeight();
7914             }
7915         }
7916 
7917         @Override
setDismissImeOnBackKeyPressed(boolean dismissImeOnBackKeyPressed)7918         public void setDismissImeOnBackKeyPressed(boolean dismissImeOnBackKeyPressed) {
7919             mPolicy.setDismissImeOnBackKeyPressed(dismissImeOnBackKeyPressed);
7920         }
7921 
7922         @Override
updateInputMethodTargetWindow(@onNull IBinder imeToken, @NonNull IBinder imeTargetWindowToken)7923         public void updateInputMethodTargetWindow(@NonNull IBinder imeToken,
7924                 @NonNull IBinder imeTargetWindowToken) {
7925             // TODO (b/34628091): Use this method to address the window animation issue.
7926             if (DEBUG_INPUT_METHOD) {
7927                 Slog.w(TAG_WM, "updateInputMethodTargetWindow: imeToken=" + imeToken
7928                         + " imeTargetWindowToken=" + imeTargetWindowToken);
7929             }
7930             synchronized (mGlobalLock) {
7931                 InputTarget imeTarget =
7932                     getInputTargetFromWindowTokenLocked(imeTargetWindowToken);
7933                 if (imeTarget != null) {
7934                     imeTarget.getDisplayContent().updateImeInputAndControlTarget(imeTarget);
7935                 }
7936             }
7937         }
7938 
7939         @Override
isHardKeyboardAvailable()7940         public boolean isHardKeyboardAvailable() {
7941             synchronized (mGlobalLock) {
7942                 return mHardKeyboardAvailable;
7943             }
7944         }
7945 
7946         @Override
setOnHardKeyboardStatusChangeListener( OnHardKeyboardStatusChangeListener listener)7947         public void setOnHardKeyboardStatusChangeListener(
7948                 OnHardKeyboardStatusChangeListener listener) {
7949             synchronized (mGlobalLock) {
7950                 mHardKeyboardStatusChangeListener = listener;
7951             }
7952         }
7953 
7954         @Override
computeWindowsForAccessibility(int displayId)7955         public void computeWindowsForAccessibility(int displayId) {
7956             mAccessibilityController.performComputeChangedWindowsNot(displayId, true);
7957         }
7958 
7959         @Override
setVr2dDisplayId(int vr2dDisplayId)7960         public void setVr2dDisplayId(int vr2dDisplayId) {
7961             if (DEBUG_DISPLAY) {
7962                 Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
7963             }
7964             synchronized (mGlobalLock) {
7965                 mVr2dDisplayId = vr2dDisplayId;
7966             }
7967         }
7968 
7969         @Override
registerDragDropControllerCallback(IDragDropCallback callback)7970         public void registerDragDropControllerCallback(IDragDropCallback callback) {
7971             mDragDropController.registerCallback(callback);
7972         }
7973 
7974         @Override
lockNow()7975         public void lockNow() {
7976             WindowManagerService.this.lockNow(null);
7977         }
7978 
7979         @Override
getWindowOwnerUserId(IBinder token)7980         public int getWindowOwnerUserId(IBinder token) {
7981             synchronized (mGlobalLock) {
7982                 WindowState window = mWindowMap.get(token);
7983                 if (window != null) {
7984                     return window.mShowUserId;
7985                 }
7986                 return UserHandle.USER_NULL;
7987             }
7988         }
7989 
7990         @Override
setWallpaperShowWhenLocked(IBinder binder, boolean showWhenLocked)7991         public void setWallpaperShowWhenLocked(IBinder binder, boolean showWhenLocked) {
7992             synchronized (mGlobalLock) {
7993                 final WindowToken token = mRoot.getWindowToken(binder);
7994                 if (token == null || token.asWallpaperToken() == null) {
7995                     ProtoLog.w(WM_ERROR,
7996                             "setWallpaperShowWhenLocked: non-existent wallpaper token: %s", binder);
7997                     return;
7998                 }
7999                 token.asWallpaperToken().setShowWhenLocked(showWhenLocked);
8000             }
8001         }
8002 
8003         @Override
isUidFocused(int uid)8004         public boolean isUidFocused(int uid) {
8005             synchronized (mGlobalLock) {
8006                 for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
8007                     final DisplayContent displayContent = mRoot.getChildAt(i);
8008                     if (displayContent.mCurrentFocus != null
8009                             && uid == displayContent.mCurrentFocus.getOwningUid()) {
8010                         return true;
8011                     }
8012                 }
8013                 return false;
8014             }
8015         }
8016 
8017         @Override
hasInputMethodClientFocus(IBinder windowToken, int uid, int pid, int displayId)8018         public @ImeClientFocusResult int hasInputMethodClientFocus(IBinder windowToken,
8019                 int uid, int pid, int displayId) {
8020             if (displayId == Display.INVALID_DISPLAY) {
8021                 return ImeClientFocusResult.INVALID_DISPLAY_ID;
8022             }
8023             synchronized (mGlobalLock) {
8024                 final DisplayContent displayContent = mRoot.getTopFocusedDisplayContent();
8025                 InputTarget target = getInputTargetFromWindowTokenLocked(windowToken);
8026                 if (target == null) {
8027                     return ImeClientFocusResult.NOT_IME_TARGET_WINDOW;
8028                 }
8029                 final int tokenDisplayId = target.getDisplayContent().getDisplayId();
8030                 if (tokenDisplayId != displayId) {
8031                     Slog.e(TAG, "isInputMethodClientFocus: display ID mismatch."
8032                             + " from client: " + displayId
8033                             + " from window: " + tokenDisplayId);
8034                     return ImeClientFocusResult.DISPLAY_ID_MISMATCH;
8035                 }
8036                 if (displayContent == null
8037                         || displayContent.getDisplayId() != displayId
8038                         || !displayContent.hasAccess(uid)) {
8039                     return ImeClientFocusResult.INVALID_DISPLAY_ID;
8040                 }
8041 
8042                 if (target.isInputMethodClientFocus(uid, pid)) {
8043                     return ImeClientFocusResult.HAS_IME_FOCUS;
8044                 }
8045                 // Okay, how about this...  what is the current focus?
8046                 // It seems in some cases we may not have moved the IM
8047                 // target window, such as when it was in a pop-up window,
8048                 // so let's also look at the current focus.  (An example:
8049                 // go to Gmail, start searching so the keyboard goes up,
8050                 // press home.  Sometimes the IME won't go down.)
8051                 // Would be nice to fix this more correctly, but it's
8052                 // way at the end of a release, and this should be good enough.
8053                 final WindowState currentFocus = displayContent.mCurrentFocus;
8054                 if (currentFocus != null && currentFocus.mSession.mUid == uid
8055                         && currentFocus.mSession.mPid == pid) {
8056                     return currentFocus.canBeImeTarget() ? ImeClientFocusResult.HAS_IME_FOCUS
8057                             : ImeClientFocusResult.NOT_IME_TARGET_WINDOW;
8058                 }
8059             }
8060             return ImeClientFocusResult.NOT_IME_TARGET_WINDOW;
8061         }
8062 
8063         @Override
showImePostLayout(IBinder imeTargetWindowToken, @Nullable ImeTracker.Token statsToken)8064         public void showImePostLayout(IBinder imeTargetWindowToken,
8065                 @Nullable ImeTracker.Token statsToken) {
8066             synchronized (mGlobalLock) {
8067                 InputTarget imeTarget = getInputTargetFromWindowTokenLocked(imeTargetWindowToken);
8068                 if (imeTarget == null) {
8069                     return;
8070                 }
8071                 Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.showImePostLayout", 0);
8072                 final InsetsControlTarget controlTarget = imeTarget.getImeControlTarget();
8073                 imeTarget = controlTarget.getWindow();
8074                 // If InsetsControlTarget doesn't have a window, it's using remoteControlTarget
8075                 // which is controlled by default display
8076                 final DisplayContent dc = imeTarget != null
8077                         ? imeTarget.getDisplayContent() : getDefaultDisplayContentLocked();
8078                 dc.getInsetsStateController().getImeSourceProvider()
8079                         .scheduleShowImePostLayout(controlTarget, statsToken);
8080             }
8081         }
8082 
8083         @Override
hideIme(IBinder imeTargetWindowToken, int displayId, @Nullable ImeTracker.Token statsToken)8084         public void hideIme(IBinder imeTargetWindowToken, int displayId,
8085                 @Nullable ImeTracker.Token statsToken) {
8086             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WMS.hideIme");
8087             synchronized (mGlobalLock) {
8088                 WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
8089                 ProtoLog.d(WM_DEBUG_IME, "hideIme target: %s ", imeTarget);
8090                 DisplayContent dc = mRoot.getDisplayContent(displayId);
8091                 if (imeTarget != null) {
8092                     imeTarget = imeTarget.getImeControlTarget().getWindow();
8093                     if (imeTarget != null) {
8094                         dc = imeTarget.getDisplayContent();
8095                     }
8096                     // If there was a pending IME show(), reset it as IME has been
8097                     // requested to be hidden.
8098                     dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout();
8099                 }
8100                 if (dc != null && dc.getImeTarget(IME_TARGET_CONTROL) != null) {
8101                     ImeTracker.forLogging().onProgress(statsToken,
8102                             ImeTracker.PHASE_WM_HAS_IME_INSETS_CONTROL_TARGET);
8103                     ProtoLog.d(WM_DEBUG_IME, "hideIme Control target: %s ",
8104                             dc.getImeTarget(IME_TARGET_CONTROL));
8105                     dc.getImeTarget(IME_TARGET_CONTROL).hideInsets(WindowInsets.Type.ime(),
8106                             true /* fromIme */, statsToken);
8107                 } else {
8108                     ImeTracker.forLogging().onFailed(statsToken,
8109                             ImeTracker.PHASE_WM_HAS_IME_INSETS_CONTROL_TARGET);
8110                 }
8111                 if (dc != null) {
8112                     dc.getInsetsStateController().getImeSourceProvider().setImeShowing(false);
8113                 }
8114             }
8115             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
8116         }
8117 
8118         @Override
isUidAllowedOnDisplay(int displayId, int uid)8119         public boolean isUidAllowedOnDisplay(int displayId, int uid) {
8120             if (displayId == Display.DEFAULT_DISPLAY) {
8121                 return true;
8122             }
8123             if (displayId == Display.INVALID_DISPLAY) {
8124                 return false;
8125             }
8126             synchronized (mGlobalLock) {
8127                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
8128                 return displayContent != null && displayContent.hasAccess(uid);
8129             }
8130         }
8131 
8132         @Override
getDisplayIdForWindow(IBinder windowToken)8133         public int getDisplayIdForWindow(IBinder windowToken) {
8134             synchronized (mGlobalLock) {
8135                 final WindowState window = mWindowMap.get(windowToken);
8136                 if (window != null) {
8137                     return window.getDisplayContent().getDisplayId();
8138                 }
8139                 return Display.INVALID_DISPLAY;
8140             }
8141         }
8142 
8143         @Override
getTopFocusedDisplayId()8144         public int getTopFocusedDisplayId() {
8145             synchronized (mGlobalLock) {
8146                 return mRoot.getTopFocusedDisplayContent().getDisplayId();
8147             }
8148         }
8149 
8150         @Override
getTopFocusedDisplayUiContext()8151         public Context getTopFocusedDisplayUiContext() {
8152             synchronized (mGlobalLock) {
8153                 return mRoot.getTopFocusedDisplayContent().getDisplayUiContext();
8154             }
8155         }
8156 
8157         @Override
shouldShowSystemDecorOnDisplay(int displayId)8158         public boolean shouldShowSystemDecorOnDisplay(int displayId) {
8159             synchronized (mGlobalLock) {
8160                 return WindowManagerService.this.shouldShowSystemDecors(displayId);
8161             }
8162         }
8163 
8164         @Override
getDisplayImePolicy(int displayId)8165         public @DisplayImePolicy int getDisplayImePolicy(int displayId) {
8166             return WindowManagerService.this.getDisplayImePolicy(displayId);
8167         }
8168 
8169         @Override
addRefreshRateRangeForPackage(@onNull String packageName, float minRefreshRate, float maxRefreshRate)8170         public void addRefreshRateRangeForPackage(@NonNull String packageName,
8171                 float minRefreshRate, float maxRefreshRate) {
8172             synchronized (mGlobalLock) {
8173                 mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
8174                         .addRefreshRateRangeForPackage(
8175                                 packageName, minRefreshRate, maxRefreshRate));
8176             }
8177         }
8178 
8179         @Override
removeRefreshRateRangeForPackage(@onNull String packageName)8180         public void removeRefreshRateRangeForPackage(@NonNull String packageName) {
8181             synchronized (mGlobalLock) {
8182                 mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
8183                         .removeRefreshRateRangeForPackage(packageName));
8184             }
8185         }
8186 
8187         @Override
isTouchOrFaketouchDevice()8188         public boolean isTouchOrFaketouchDevice() {
8189             synchronized (mGlobalLock) {
8190                 if (mIsTouchDevice && !mIsFakeTouchDevice) {
8191                     throw new IllegalStateException(
8192                             "touchscreen supported device must report faketouch.");
8193                 }
8194                 return mIsFakeTouchDevice;
8195             }
8196         }
8197 
8198         @Override
getKeyInterceptionInfoFromToken(IBinder inputToken)8199         public @Nullable KeyInterceptionInfo getKeyInterceptionInfoFromToken(IBinder inputToken) {
8200             return mKeyInterceptionInfoForToken.get(inputToken);
8201         }
8202 
8203         @Override
setAccessibilityIdToSurfaceMetadata( IBinder windowToken, int accessibilityWindowId)8204         public void setAccessibilityIdToSurfaceMetadata(
8205                 IBinder windowToken, int accessibilityWindowId) {
8206             synchronized (mGlobalLock) {
8207                 final WindowState state = mWindowMap.get(windowToken);
8208                 if (state == null) {
8209                     Slog.w(TAG, "Cannot find window which accessibility connection is added to");
8210                     return;
8211                 }
8212                 mTransaction.setMetadata(state.mSurfaceControl,
8213                         SurfaceControl.METADATA_ACCESSIBILITY_ID, accessibilityWindowId).apply();
8214             }
8215         }
8216 
8217         @Override
getWindowName(@onNull IBinder binder)8218         public String getWindowName(@NonNull IBinder binder) {
8219             synchronized (mGlobalLock) {
8220                 final WindowState w = mWindowMap.get(binder);
8221                 return w != null ? w.getName() : null;
8222             }
8223         }
8224 
8225         @Override
onToggleImeRequested(boolean show, IBinder focusedToken, IBinder requestToken, int displayId)8226         public ImeTargetInfo onToggleImeRequested(boolean show, IBinder focusedToken,
8227                 IBinder requestToken, int displayId) {
8228             final String focusedWindowName;
8229             final String requestWindowName;
8230             final String imeControlTargetName;
8231             final String imeLayerTargetName;
8232             final String imeSurfaceParentName;
8233             synchronized (mGlobalLock) {
8234                 final WindowState focusedWin = mWindowMap.get(focusedToken);
8235                 focusedWindowName = focusedWin != null ? focusedWin.getName() : "null";
8236                 final WindowState requestWin = mWindowMap.get(requestToken);
8237                 requestWindowName = requestWin != null ? requestWin.getName() : "null";
8238                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
8239                 if (dc != null) {
8240                     final InsetsControlTarget controlTarget = dc.getImeTarget(IME_TARGET_CONTROL);
8241                     if (controlTarget != null) {
8242                         final WindowState w = InsetsControlTarget.asWindowOrNull(controlTarget);
8243                         imeControlTargetName = w != null ? w.getName() : controlTarget.toString();
8244                     } else {
8245                         imeControlTargetName = "null";
8246                     }
8247                     final InsetsControlTarget target = dc.getImeTarget(IME_TARGET_LAYERING);
8248                     imeLayerTargetName = target != null ? target.getWindow().getName() : "null";
8249                     final SurfaceControl imeParent = dc.mInputMethodSurfaceParent;
8250                     imeSurfaceParentName = imeParent != null ? imeParent.toString() : "null";
8251                     if (show) {
8252                         dc.onShowImeRequested();
8253                     }
8254                 } else {
8255                     imeControlTargetName = imeLayerTargetName = imeSurfaceParentName = "no-display";
8256                 }
8257             }
8258             return new ImeTargetInfo(focusedWindowName, requestWindowName, imeControlTargetName,
8259                     imeLayerTargetName, imeSurfaceParentName);
8260         }
8261 
8262         @Override
shouldRestoreImeVisibility(IBinder imeTargetWindowToken)8263         public boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) {
8264             return WindowManagerService.this.shouldRestoreImeVisibility(imeTargetWindowToken);
8265        }
8266 
8267         @Override
addTrustedTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay)8268         public void addTrustedTaskOverlay(int taskId,
8269                 SurfaceControlViewHost.SurfacePackage overlay) {
8270             if (overlay == null) {
8271                 throw new IllegalArgumentException("Invalid overlay passed in for task=" + taskId);
8272             } else if (overlay.getSurfaceControl() == null
8273                     || !overlay.getSurfaceControl().isValid()) {
8274                 throw new IllegalArgumentException(
8275                         "Invalid overlay surfacecontrol passed in for task=" + taskId);
8276             }
8277             synchronized (mGlobalLock) {
8278                 final Task task = mRoot.getRootTask(taskId);
8279                 if (task == null) {
8280                     throw new IllegalArgumentException("no task with taskId" + taskId);
8281                 }
8282                 task.addTrustedOverlay(overlay, task.getTopVisibleAppMainWindow());
8283             }
8284         }
8285 
8286         @Override
removeTrustedTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay)8287         public void removeTrustedTaskOverlay(int taskId,
8288                 SurfaceControlViewHost.SurfacePackage overlay) {
8289             if (overlay == null) {
8290                 throw new IllegalArgumentException("Invalid overlay passed in for task=" + taskId);
8291             } else if (overlay.getSurfaceControl() == null
8292                     || !overlay.getSurfaceControl().isValid()) {
8293                 throw new IllegalArgumentException(
8294                         "Invalid overlay surfacecontrol passed in for task=" + taskId);
8295             }
8296             synchronized (mGlobalLock) {
8297                 final Task task = mRoot.getRootTask(taskId);
8298                 if (task == null) {
8299                     throw new IllegalArgumentException("no task with taskId" + taskId);
8300                 }
8301                 task.removeTrustedOverlay(overlay);
8302             }
8303         }
8304 
8305         @Override
getHandwritingSurfaceForDisplay(int displayId)8306         public SurfaceControl getHandwritingSurfaceForDisplay(int displayId) {
8307             synchronized (mGlobalLock) {
8308                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
8309                 if (dc == null) {
8310                     Slog.e(TAG, "Failed to create a handwriting surface on display: "
8311                             + displayId + " - DisplayContent not found.");
8312                     return null;
8313                 }
8314                 final SurfaceControl inputOverlay = dc.getInputOverlayLayer();
8315                 if (inputOverlay == null) {
8316                     Slog.e(TAG, "Failed to create a gesture monitor on display: " + displayId
8317                             + " - Input overlay layer is not initialized.");
8318                     return null;
8319                 }
8320                 // TODO(b/210039666): Use a method like add/removeDisplayOverlay if available.
8321                 return makeSurfaceBuilder(dc.getSession())
8322                         .setContainerLayer()
8323                         .setName("IME Handwriting Surface")
8324                         .setCallsite("getHandwritingSurfaceForDisplay")
8325                         .setParent(inputOverlay)
8326                         .build();
8327             }
8328         }
8329 
8330         @Override
isPointInsideWindow(@onNull IBinder windowToken, int displayId, float displayX, float displayY)8331         public boolean isPointInsideWindow(@NonNull IBinder windowToken, int displayId,
8332                 float displayX, float displayY) {
8333             synchronized (mGlobalLock) {
8334                 final WindowState w = mWindowMap.get(windowToken);
8335                 if (w == null || w.getDisplayId() != displayId) {
8336                     return false;
8337                 }
8338 
8339                 return w.getBounds().contains((int) displayX, (int) displayY);
8340             }
8341         }
8342 
8343         @Override
setContentRecordingSession( @ullable ContentRecordingSession incomingSession)8344         public boolean setContentRecordingSession(
8345                 @Nullable ContentRecordingSession incomingSession) {
8346             synchronized (mGlobalLock) {
8347                 // Allow the controller to handle teardown of a non-task session.
8348                 if (incomingSession == null
8349                         || incomingSession.getContentToRecord() != RECORD_CONTENT_TASK) {
8350                     mContentRecordingController.setContentRecordingSessionLocked(incomingSession,
8351                             WindowManagerService.this);
8352                     return true;
8353                 }
8354                 // For a task session, find the activity identified by the launch cookie.
8355                 final WindowContainerToken wct = getTaskWindowContainerTokenForLaunchCookie(
8356                         incomingSession.getTokenToRecord());
8357                 if (wct == null) {
8358                     Slog.w(TAG, "Handling a new recording session; unable to find the "
8359                             + "WindowContainerToken");
8360                     return false;
8361                 }
8362                 // Replace the launch cookie in the session details with the task's
8363                 // WindowContainerToken.
8364                 incomingSession.setTokenToRecord(wct.asBinder());
8365                 mContentRecordingController.setContentRecordingSessionLocked(incomingSession,
8366                         WindowManagerService.this);
8367                 return true;
8368             }
8369         }
8370 
8371         @Override
getA11yOverlayLayer(int displayId)8372         public SurfaceControl getA11yOverlayLayer(int displayId) {
8373             synchronized (mGlobalLock) {
8374                 DisplayContent dc = mRoot.getDisplayContent(displayId);
8375                 if (dc != null) {
8376                     return dc.getA11yOverlayLayer();
8377                 }
8378             }
8379             return null;
8380         }
8381 
8382         @Override
hasNavigationBar(int displayId)8383         public boolean hasNavigationBar(int displayId) {
8384             return WindowManagerService.this.hasNavigationBar(displayId);
8385         }
8386 
8387         @Override
setInputMethodTargetChangeListener(@onNull ImeTargetChangeListener listener)8388         public void setInputMethodTargetChangeListener(@NonNull ImeTargetChangeListener listener) {
8389             synchronized (mGlobalLock) {
8390                 mImeTargetChangeListener = listener;
8391             }
8392         }
8393     }
8394 
8395     private final class ImeTargetVisibilityPolicyImpl extends ImeTargetVisibilityPolicy {
8396 
8397         @Override
showImeScreenshot(@onNull IBinder imeTarget, int displayId)8398         public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId) {
8399             synchronized (mGlobalLock) {
8400                 final WindowState imeTargetWindow = mWindowMap.get(imeTarget);
8401                 if (imeTargetWindow == null) {
8402                     return false;
8403                 }
8404                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
8405                 if (dc == null) {
8406                     Slog.w(TAG, "Invalid displayId:" + displayId + ", fail to show ime screenshot");
8407                     return false;
8408                 }
8409 
8410                 dc.showImeScreenshot(imeTargetWindow);
8411                 return true;
8412             }
8413         }
8414         @Override
removeImeScreenshot(int displayId)8415         public boolean removeImeScreenshot(int displayId) {
8416             synchronized (mGlobalLock) {
8417                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
8418                 if (dc == null) {
8419                     Slog.w(TAG, "Invalid displayId:" + displayId
8420                             + ", fail to remove ime screenshot");
8421                     return false;
8422                 }
8423                 dc.removeImeSurfaceImmediately();
8424             }
8425             return true;
8426         }
8427     }
8428 
registerAppFreezeListener(AppFreezeListener listener)8429     void registerAppFreezeListener(AppFreezeListener listener) {
8430         if (!mAppFreezeListeners.contains(listener)) {
8431             mAppFreezeListeners.add(listener);
8432         }
8433     }
8434 
unregisterAppFreezeListener(AppFreezeListener listener)8435     void unregisterAppFreezeListener(AppFreezeListener listener) {
8436         mAppFreezeListeners.remove(listener);
8437     }
8438 
8439     /**
8440      * WARNING: This interrupts surface updates, be careful! Don't
8441      * execute within the transaction for longer than you would
8442      * execute on an animation thread.
8443      * WARNING: This method contains locks known to the State of California
8444      * to cause Deadlocks and other conditions.
8445      *
8446      * Begins a surface transaction with which the AM can batch operations.
8447      * All Surface updates performed by the WindowManager following this
8448      * will not appear on screen until after the call to
8449      * closeSurfaceTransaction.
8450      *
8451      * ActivityManager can use this to ensure multiple 'commands' will all
8452      * be reflected in a single frame. For example when reparenting a window
8453      * which was previously hidden due to it's parent properties, we may
8454      * need to ensure it is hidden in the same frame that the properties
8455      * from the new parent are inherited, otherwise it could be revealed
8456      * mistakenly.
8457      *
8458      * TODO(b/36393204): We can investigate totally replacing #deferSurfaceLayout
8459      * with something like this but it seems that some existing cases of
8460      * deferSurfaceLayout may be a little too broad, in particular the total
8461      * enclosure of startActivityUnchecked which could run for quite some time.
8462      */
inSurfaceTransaction(Runnable exec)8463     void inSurfaceTransaction(Runnable exec) {
8464         SurfaceControl.openTransaction();
8465         try {
8466             exec.run();
8467         } finally {
8468             SurfaceControl.closeTransaction();
8469         }
8470     }
8471 
8472     /** Called to inform window manager if non-Vr UI shoul be disabled or not. */
disableNonVrUi(boolean disable)8473     public void disableNonVrUi(boolean disable) {
8474         synchronized (mGlobalLock) {
8475             // Allow alert window notifications to be shown if non-vr UI is enabled.
8476             final boolean showAlertWindowNotifications = !disable;
8477             if (showAlertWindowNotifications == mShowAlertWindowNotifications) {
8478                 return;
8479             }
8480             mShowAlertWindowNotifications = showAlertWindowNotifications;
8481 
8482             for (int i = mSessions.size() - 1; i >= 0; --i) {
8483                 final Session s = mSessions.valueAt(i);
8484                 s.setShowingAlertWindowNotificationAllowed(mShowAlertWindowNotifications);
8485             }
8486         }
8487     }
8488 
hasWideColorGamutSupport()8489     boolean hasWideColorGamutSupport() {
8490         return mHasWideColorGamutSupport &&
8491                 SystemProperties.getInt("persist.sys.sf.native_mode", 0) != 1;
8492     }
8493 
hasHdrSupport()8494     boolean hasHdrSupport() {
8495         return mHasHdrSupport && hasWideColorGamutSupport();
8496     }
8497 
updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown)8498     void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
8499         if (!win.hideNonSystemOverlayWindowsWhenVisible()
8500                 && !mHidingNonSystemOverlayWindows.contains(win)) {
8501             return;
8502         }
8503         final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty();
8504         if (surfaceShown && win.hideNonSystemOverlayWindowsWhenVisible()) {
8505             if (!mHidingNonSystemOverlayWindows.contains(win)) {
8506                 mHidingNonSystemOverlayWindows.add(win);
8507             }
8508         } else {
8509             mHidingNonSystemOverlayWindows.remove(win);
8510         }
8511 
8512         final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
8513 
8514         if (systemAlertWindowsHidden == hideSystemAlertWindows) {
8515             return;
8516         }
8517 
8518         mRoot.forAllWindows((w) -> {
8519             w.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
8520         }, false /* traverseTopToBottom */);
8521     }
8522 
8523     /** Called from Accessibility Controller to apply magnification spec */
applyMagnificationSpecLocked(int displayId, MagnificationSpec spec)8524     public void applyMagnificationSpecLocked(int displayId, MagnificationSpec spec) {
8525         final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
8526         if (displayContent != null) {
8527             displayContent.applyMagnificationSpec(spec);
8528         }
8529     }
8530 
makeSurfaceBuilder(SurfaceSession s)8531     SurfaceControl.Builder makeSurfaceBuilder(SurfaceSession s) {
8532         return mSurfaceControlFactory.apply(s);
8533     }
8534 
8535     /**
8536      * Called when the state of lock task mode changes. This should be used to disable immersive
8537      * mode confirmation.
8538      *
8539      * @param lockTaskState the new lock task mode state. One of
8540      *                      {@link ActivityManager#LOCK_TASK_MODE_NONE},
8541      *                      {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
8542      *                      {@link ActivityManager#LOCK_TASK_MODE_PINNED}.
8543      */
onLockTaskStateChanged(int lockTaskState)8544     void onLockTaskStateChanged(int lockTaskState) {
8545         // TODO: pass in displayId to determine which display the lock task state changed
8546         synchronized (mGlobalLock) {
8547             mRoot.forAllDisplayPolicies(p -> p.onLockTaskStateChangedLw(lockTaskState));
8548         }
8549     }
8550 
8551     @Override
syncInputTransactions(boolean waitForAnimations)8552     public void syncInputTransactions(boolean waitForAnimations) {
8553         final long token = Binder.clearCallingIdentity();
8554         try {
8555             if (waitForAnimations) {
8556                 waitForAnimationsToComplete();
8557             }
8558 
8559             // Collect all input transactions from all displays to make sure we could sync all input
8560             // windows at same time.
8561             final SurfaceControl.Transaction t = mTransactionFactory.get();
8562             synchronized (mGlobalLock) {
8563                 mWindowPlacerLocked.performSurfacePlacementIfScheduled();
8564                 mRoot.forAllDisplays(displayContent ->
8565                         displayContent.getInputMonitor().updateInputWindowsImmediately(t));
8566             }
8567 
8568             CountDownLatch countDownLatch = new CountDownLatch(1);
8569             t.addWindowInfosReportedListener(countDownLatch::countDown).apply();
8570             countDownLatch.await(SYNC_INPUT_TRANSACTIONS_TIMEOUT_MS, TimeUnit.MILLISECONDS);
8571         } catch (InterruptedException exception) {
8572             Slog.e(TAG_WM, "Exception thrown while waiting for window infos to be reported",
8573                     exception);
8574         } finally {
8575             Binder.restoreCallingIdentity(token);
8576         }
8577     }
8578 
8579     /**
8580      * Wait until all container animations and surface operations behalf of WindowManagerService
8581      * complete.
8582      */
waitForAnimationsToComplete()8583     private void waitForAnimationsToComplete() {
8584         synchronized (mGlobalLock) {
8585             long timeoutRemaining = ANIMATION_COMPLETED_TIMEOUT_MS;
8586             // This could prevent if there is no container animation, we still have to apply the
8587             // pending transaction and exit waiting.
8588             mAnimator.mNotifyWhenNoAnimation = true;
8589             boolean animateStarting = false;
8590             while (timeoutRemaining > 0) {
8591                 // Waiting until all starting windows has finished animating.
8592                 animateStarting = !mAtmService.getTransitionController().isShellTransitionsEnabled()
8593                         && mRoot.forAllActivities(ActivityRecord::hasStartingWindow);
8594                 boolean isAnimating = mAnimator.isAnimationScheduled()
8595                         || mRoot.isAnimating(TRANSITION | CHILDREN, ANIMATION_TYPE_ALL)
8596                         || animateStarting;
8597                 if (!isAnimating) {
8598                     // isAnimating is a legacy transition query and will be removed, so also add
8599                     // a check for whether this is in a shell-transition when not using legacy.
8600                     if (!mAtmService.getTransitionController().inTransition()) {
8601                         break;
8602                     }
8603                 }
8604                 long startTime = System.currentTimeMillis();
8605                 try {
8606                     mGlobalLock.wait(timeoutRemaining);
8607                 } catch (InterruptedException e) {
8608                 }
8609                 timeoutRemaining -= (System.currentTimeMillis() - startTime);
8610             }
8611             mAnimator.mNotifyWhenNoAnimation = false;
8612 
8613             WindowContainer animatingContainer;
8614             animatingContainer = mRoot.getAnimatingContainer(TRANSITION | CHILDREN,
8615                     ANIMATION_TYPE_ALL);
8616             if (mAnimator.isAnimationScheduled() || animatingContainer != null || animateStarting) {
8617                 Slog.w(TAG, "Timed out waiting for animations to complete,"
8618                         + " animatingContainer=" + animatingContainer
8619                         + " animationType=" + SurfaceAnimator.animationTypeToString(
8620                         animatingContainer != null
8621                                 ? animatingContainer.mSurfaceAnimator.getAnimationType()
8622                                 : SurfaceAnimator.ANIMATION_TYPE_NONE)
8623                         + " animateStarting=" + animateStarting);
8624             }
8625         }
8626     }
8627 
onAnimationFinished()8628     void onAnimationFinished() {
8629         synchronized (mGlobalLock) {
8630             mGlobalLock.notifyAll();
8631         }
8632     }
8633 
onPointerDownOutsideFocusLocked(InputTarget t)8634     private void onPointerDownOutsideFocusLocked(InputTarget t) {
8635         if (t == null || !t.receiveFocusFromTapOutside()) {
8636             // If the window that received the input event cannot receive keys, don't move the
8637             // display it's on to the top since that window won't be able to get focus anyway.
8638             return;
8639         }
8640         if (mRecentsAnimationController != null
8641             && mRecentsAnimationController.getTargetAppMainWindow() == t) {
8642             // If there is an active recents animation and touched window is the target, then ignore
8643             // the touch. The target already handles touches using its own input monitor and we
8644             // don't want to trigger any lifecycle changes from focusing another window.
8645             // TODO(b/186770026): We should remove this once we support multiple resumed activities
8646             //                    while in overview
8647             return;
8648         }
8649         final WindowState w = t.getWindowState();
8650         if (w != null) {
8651             final Task task = w.getTask();
8652             if (task != null && w.mTransitionController.isTransientHide(task)) {
8653                 // Don't disturb transient animation by accident touch.
8654                 return;
8655             }
8656         }
8657 
8658         ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "onPointerDownOutsideFocusLocked called on %s",
8659                 t);
8660         if (mFocusedInputTarget != t && mFocusedInputTarget != null) {
8661             mFocusedInputTarget.handleTapOutsideFocusOutsideSelf();
8662         }
8663         // Trigger Activity#onUserLeaveHint() if the order change of task pauses any activities.
8664         mAtmService.mTaskSupervisor.mUserLeaving = true;
8665         t.handleTapOutsideFocusInsideSelf();
8666         mAtmService.mTaskSupervisor.mUserLeaving = false;
8667     }
8668 
8669     @VisibleForTesting
handleTaskFocusChange(Task task, ActivityRecord touchedActivity)8670     void handleTaskFocusChange(Task task, ActivityRecord touchedActivity) {
8671         if (task == null) {
8672             return;
8673         }
8674 
8675         // We ignore root home task since we don't want root home task to move to front when
8676         // touched. Specifically, in freeform we don't want tapping on home to cause the freeform
8677         // apps to go behind home. See b/117376413
8678         if (task.isActivityTypeHome()) {
8679             // Only ignore root home task if the requested focus home Task is in the same
8680             // TaskDisplayArea as the current focus Task.
8681             TaskDisplayArea homeTda = task.getDisplayArea();
8682             WindowState curFocusedWindow = getFocusedWindow();
8683             if (curFocusedWindow != null && homeTda != null
8684                     && curFocusedWindow.isDescendantOf(homeTda)) {
8685                 return;
8686             }
8687         }
8688 
8689         mAtmService.setFocusedTask(task.mTaskId, touchedActivity);
8690     }
8691 
8692     /**
8693      * Retrieve the {@link WindowContainerToken} of the task that contains the activity started
8694      * with the given launch cookie.
8695      *
8696      * @param launchCookie the launch cookie set on the {@link ActivityOptions} when starting an
8697      *                     activity
8698      * @return a token representing the task containing the activity started with the given launch
8699      * cookie, or {@code null} if the token couldn't be found.
8700      */
8701     @VisibleForTesting
8702     @Nullable
getTaskWindowContainerTokenForLaunchCookie(@onNull IBinder launchCookie)8703     WindowContainerToken getTaskWindowContainerTokenForLaunchCookie(@NonNull IBinder launchCookie) {
8704         // Find the activity identified by the launch cookie.
8705         final ActivityRecord targetActivity = mRoot.getActivity(
8706                 activity -> activity.mLaunchCookie == launchCookie);
8707         if (targetActivity == null) {
8708             Slog.w(TAG, "Unable to find the activity for this launch cookie");
8709             return null;
8710         }
8711         if (targetActivity.getTask() == null) {
8712             Slog.w(TAG, "Unable to find the task for this launch cookie");
8713             return null;
8714         }
8715         WindowContainerToken taskWindowContainerToken =
8716                 targetActivity.getTask().mRemoteToken.toWindowContainerToken();
8717         if (taskWindowContainerToken == null) {
8718             Slog.w(TAG, "Unable to find the WindowContainerToken for " + targetActivity.getName());
8719             return null;
8720         }
8721         return taskWindowContainerToken;
8722     }
8723 
8724     /**
8725      * You need ALLOW_SLIPPERY_TOUCHES permission to be able to set FLAG_SLIPPERY.
8726      */
sanitizeFlagSlippery(int flags, String windowName, int callingUid, int callingPid)8727     private int sanitizeFlagSlippery(int flags, String windowName, int callingUid, int callingPid) {
8728         if ((flags & FLAG_SLIPPERY) == 0) {
8729             return flags;
8730         }
8731         final int permissionResult = mContext.checkPermission(
8732                     android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES, callingPid, callingUid);
8733         if (permissionResult != PackageManager.PERMISSION_GRANTED) {
8734             Slog.w(TAG, "Removing FLAG_SLIPPERY from '" + windowName
8735                     + "' because it doesn't have ALLOW_SLIPPERY_TOUCHES permission");
8736             return flags & ~FLAG_SLIPPERY;
8737         }
8738         return flags;
8739     }
8740 
8741     /**
8742      * You need MONITOR_INPUT permission to be able to set INPUT_FEATURE_SPY.
8743      */
sanitizeSpyWindow(int inputFeatures, String windowName, int callingUid, int callingPid)8744     private int sanitizeSpyWindow(int inputFeatures, String windowName, int callingUid,
8745             int callingPid) {
8746         if ((inputFeatures & INPUT_FEATURE_SPY) == 0) {
8747             return inputFeatures;
8748         }
8749         final int permissionResult = mContext.checkPermission(
8750                 permission.MONITOR_INPUT, callingPid, callingUid);
8751         if (permissionResult != PackageManager.PERMISSION_GRANTED) {
8752             throw new IllegalArgumentException("Cannot use INPUT_FEATURE_SPY from '" + windowName
8753                     + "' because it doesn't the have MONITOR_INPUT permission");
8754         }
8755         return inputFeatures;
8756     }
8757 
8758     /**
8759      * Assigns an InputChannel to a SurfaceControl and configures it to receive
8760      * touch input according to it's on-screen geometry.
8761      *
8762      * Used by WindowlessWindowManager to enable input on SurfaceControl embedded
8763      * views.
8764      */
grantInputChannel(Session session, int callingUid, int callingPid, int displayId, SurfaceControl surface, IWindow window, IBinder hostInputToken, int flags, int privateFlags, int inputFeatures, int type, IBinder windowToken, IBinder focusGrantToken, String inputHandleName, InputChannel outInputChannel)8765     void grantInputChannel(Session session, int callingUid, int callingPid, int displayId,
8766             SurfaceControl surface, IWindow window, IBinder hostInputToken,
8767             int flags, int privateFlags, int inputFeatures, int type, IBinder windowToken,
8768             IBinder focusGrantToken, String inputHandleName, InputChannel outInputChannel) {
8769         final int sanitizedType = sanitizeWindowType(session, displayId, windowToken, type);
8770         final InputApplicationHandle applicationHandle;
8771         final String name;
8772         Objects.requireNonNull(outInputChannel);
8773         synchronized (mGlobalLock) {
8774             EmbeddedWindowController.EmbeddedWindow win =
8775                     new EmbeddedWindowController.EmbeddedWindow(session, this, window,
8776                             mInputToWindowMap.get(hostInputToken), callingUid, callingPid,
8777                             sanitizedType, displayId, focusGrantToken, inputHandleName,
8778                             (flags & FLAG_NOT_FOCUSABLE) == 0);
8779             win.openInputChannel(outInputChannel);
8780             mEmbeddedWindowController.add(outInputChannel.getToken(), win);
8781             applicationHandle = win.getApplicationHandle();
8782             name = win.toString();
8783         }
8784 
8785         updateInputChannel(outInputChannel.getToken(), callingUid, callingPid, displayId, surface,
8786                 name, applicationHandle, flags, privateFlags, inputFeatures, sanitizedType,
8787                 null /* region */, window);
8788     }
8789 
transferEmbeddedTouchFocusToHost(IWindow embeddedWindow)8790     boolean transferEmbeddedTouchFocusToHost(IWindow embeddedWindow) {
8791         final IBinder windowBinder = embeddedWindow.asBinder();
8792         final IBinder hostInputChannel, embeddedInputChannel;
8793         synchronized (mGlobalLock) {
8794             final EmbeddedWindowController.EmbeddedWindow ew =
8795                 mEmbeddedWindowController.getByWindowToken(windowBinder);
8796             if (ew == null) {
8797                 Slog.w(TAG, "Attempt to transfer touch focus from non-existent embedded window");
8798                 return false;
8799             }
8800             final WindowState hostWindowState = ew.getWindowState();
8801             if (hostWindowState == null) {
8802                 Slog.w(TAG, "Attempt to transfer touch focus from embedded window with no" +
8803                     " associated host");
8804                 return false;
8805             }
8806             embeddedInputChannel = ew.getInputChannelToken();
8807             if (embeddedInputChannel == null) {
8808                 Slog.w(TAG, "Attempt to transfer touch focus from embedded window with no input" +
8809                     " channel");
8810                 return false;
8811             }
8812             hostInputChannel = hostWindowState.mInputChannelToken;
8813             if (hostInputChannel == null) {
8814                 Slog.w(TAG, "Attempt to transfer touch focus to a host window with no" +
8815                     " input channel");
8816                 return false;
8817             }
8818             return mInputManager.transferTouchFocus(embeddedInputChannel, hostInputChannel);
8819         }
8820     }
8821 
updateInputChannel(IBinder channelToken, int callingUid, int callingPid, int displayId, SurfaceControl surface, String name, InputApplicationHandle applicationHandle, int flags, int privateFlags, int inputFeatures, int type, Region region, IWindow window)8822     private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
8823             int displayId, SurfaceControl surface, String name,
8824             InputApplicationHandle applicationHandle, int flags,
8825             int privateFlags, int inputFeatures, int type, Region region, IWindow window) {
8826         final InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
8827         h.token = channelToken;
8828         h.setWindowToken(window);
8829         h.name = name;
8830 
8831         flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
8832         inputFeatures = sanitizeSpyWindow(inputFeatures, name, callingUid, callingPid);
8833 
8834         final int sanitizedLpFlags =
8835                 (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
8836                 | LayoutParams.FLAG_NOT_TOUCH_MODAL;
8837         h.layoutParamsType = type;
8838         h.layoutParamsFlags = sanitizedLpFlags;
8839 
8840         // Do not allow any input features to be set without sanitizing them first.
8841         h.inputConfig = InputConfigAdapter.getInputConfigFromWindowParams(
8842                         type, sanitizedLpFlags, inputFeatures);
8843 
8844 
8845         if ((flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
8846             h.inputConfig |= InputConfig.NOT_FOCUSABLE;
8847         }
8848 
8849         //  Check private trusted overlay flag to set trustedOverlay field of input window handle.
8850         if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) {
8851             h.inputConfig |= InputConfig.TRUSTED_OVERLAY;
8852         }
8853 
8854         h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
8855         h.ownerUid = callingUid;
8856         h.ownerPid = callingPid;
8857 
8858         if (region == null) {
8859             h.replaceTouchableRegionWithCrop(null);
8860         } else {
8861             h.touchableRegion.set(region);
8862             h.replaceTouchableRegionWithCrop = false;
8863 
8864             // Task managers may need to receive input events around task layers to resize tasks.
8865             final int permissionResult = mContext.checkPermission(
8866                     permission.MANAGE_ACTIVITY_TASKS, callingPid, callingUid);
8867             if (permissionResult != PackageManager.PERMISSION_GRANTED) {
8868                 h.setTouchableRegionCrop(surface);
8869             }
8870         }
8871 
8872         final SurfaceControl.Transaction t = mTransactionFactory.get();
8873         t.setInputWindowInfo(surface, h);
8874         t.apply();
8875         t.close();
8876         surface.release();
8877     }
8878 
8879     /**
8880      * Updates the flags on an existing surface's input channel. This assumes the surface provided
8881      * is the one associated with the provided input-channel. If this isn't the case, behavior
8882      * is undefined.
8883      */
updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface, int flags, int privateFlags, int inputFeatures, Region region)8884     void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
8885             int flags, int privateFlags, int inputFeatures, Region region) {
8886         final InputApplicationHandle applicationHandle;
8887         final String name;
8888         final EmbeddedWindowController.EmbeddedWindow win;
8889         synchronized (mGlobalLock) {
8890             win = mEmbeddedWindowController.get(channelToken);
8891             if (win == null) {
8892                 Slog.e(TAG, "Couldn't find window for provided channelToken.");
8893                 return;
8894             }
8895             name = win.toString();
8896             applicationHandle = win.getApplicationHandle();
8897             win.setIsFocusable((flags & FLAG_NOT_FOCUSABLE) == 0);
8898         }
8899 
8900         updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
8901                 applicationHandle, flags, privateFlags, inputFeatures, win.mWindowType, region,
8902                 win.mClient);
8903     }
8904 
8905     /** Return whether layer tracing is enabled */
isLayerTracing()8906     public boolean isLayerTracing() {
8907         if (!checkCallingPermission(
8908                 android.Manifest.permission.DUMP, "isLayerTracing()")) {
8909             throw new SecurityException("Requires DUMP permission");
8910         }
8911 
8912         final long token = Binder.clearCallingIdentity();
8913         try {
8914             Parcel data = null;
8915             Parcel reply = null;
8916             try {
8917                 IBinder sf = ServiceManager.getService("SurfaceFlinger");
8918                 if (sf != null) {
8919                     reply = Parcel.obtain();
8920                     data = Parcel.obtain();
8921                     data.writeInterfaceToken("android.ui.ISurfaceComposer");
8922                     sf.transact(/* LAYER_TRACE_STATUS_CODE */ 1026, data, reply, 0 /* flags */);
8923                     return reply.readBoolean();
8924                 }
8925             } catch (RemoteException e) {
8926                 Slog.e(TAG, "Failed to get layer tracing");
8927             } finally {
8928                 if (data != null) {
8929                     data.recycle();
8930                 }
8931                 if (reply != null) {
8932                     reply.recycle();
8933                 }
8934             }
8935         } finally {
8936             Binder.restoreCallingIdentity(token);
8937         }
8938         return false;
8939     }
8940 
8941     /** Enable or disable layer tracing */
setLayerTracing(boolean enabled)8942     public void setLayerTracing(boolean enabled) {
8943         if (!checkCallingPermission(
8944                 android.Manifest.permission.DUMP, "setLayerTracing()")) {
8945             throw new SecurityException("Requires DUMP permission");
8946         }
8947 
8948         final long token = Binder.clearCallingIdentity();
8949         try {
8950             Parcel data = null;
8951             try {
8952                 IBinder sf = ServiceManager.getService("SurfaceFlinger");
8953                 if (sf != null) {
8954                     data = Parcel.obtain();
8955                     data.writeInterfaceToken("android.ui.ISurfaceComposer");
8956                     data.writeInt(enabled ? 1 : 0);
8957                     sf.transact(/* LAYER_TRACE_CONTROL_CODE */ 1025, data, null, 0 /* flags */);
8958                 }
8959             } catch (RemoteException e) {
8960                 Slog.e(TAG, "Failed to set layer tracing");
8961             } finally {
8962                 if (data != null) {
8963                     data.recycle();
8964                 }
8965             }
8966         } finally {
8967             Binder.restoreCallingIdentity(token);
8968         }
8969     }
8970 
8971     /** Set layer tracing flags. */
setLayerTracingFlags(int flags)8972     public void setLayerTracingFlags(int flags) {
8973         if (!checkCallingPermission(
8974                 android.Manifest.permission.DUMP, "setLayerTracingFlags")) {
8975             throw new SecurityException("Requires DUMP permission");
8976         }
8977 
8978         final long token = Binder.clearCallingIdentity();
8979         try {
8980             Parcel data = null;
8981             try {
8982                 IBinder sf = ServiceManager.getService("SurfaceFlinger");
8983                 if (sf != null) {
8984                     data = Parcel.obtain();
8985                     data.writeInterfaceToken("android.ui.ISurfaceComposer");
8986                     data.writeInt(flags);
8987                     sf.transact(1033 /* LAYER_TRACE_FLAGS_CODE */, data, null, 0 /* flags */);
8988                 }
8989             } catch (RemoteException e) {
8990                 Slog.e(TAG, "Failed to set layer tracing flags");
8991             } finally {
8992                 if (data != null) {
8993                     data.recycle();
8994                 }
8995             }
8996         } finally {
8997             Binder.restoreCallingIdentity(token);
8998         }
8999     }
9000 
9001     /**
9002      * Toggle active transaction tracing.
9003      * Setting to true increases the buffer size for active debugging.
9004      * Setting to false resets the buffer size and dumps the trace to file.
9005      */
setActiveTransactionTracing(boolean active)9006     public void setActiveTransactionTracing(boolean active) {
9007         if (!checkCallingPermission(
9008                 android.Manifest.permission.DUMP, "setActiveTransactionTracing()")) {
9009             throw new SecurityException("Requires DUMP permission");
9010         }
9011 
9012         final long token = Binder.clearCallingIdentity();
9013         try {
9014             Parcel data = null;
9015             try {
9016                 IBinder sf = ServiceManager.getService("SurfaceFlinger");
9017                 if (sf != null) {
9018                     data = Parcel.obtain();
9019                     data.writeInterfaceToken("android.ui.ISurfaceComposer");
9020                     data.writeInt(active ? 1 : 0);
9021                     sf.transact(/* TRANSACTION_TRACE_CONTROL_CODE */ 1041, data,
9022                             null, 0 /* flags */);
9023                 }
9024             } catch (RemoteException e) {
9025                 Slog.e(TAG, "Failed to set transaction tracing");
9026             } finally {
9027                 if (data != null) {
9028                     data.recycle();
9029                 }
9030             }
9031         } finally {
9032             Binder.restoreCallingIdentity(token);
9033         }
9034     }
9035 
9036     @Override
mirrorDisplay(int displayId, SurfaceControl outSurfaceControl)9037     public boolean mirrorDisplay(int displayId, SurfaceControl outSurfaceControl) {
9038         if (!checkCallingPermission(READ_FRAME_BUFFER, "mirrorDisplay()")) {
9039             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
9040         }
9041 
9042         final SurfaceControl displaySc;
9043         synchronized (mGlobalLock) {
9044             DisplayContent displayContent = mRoot.getDisplayContent(displayId);
9045             if (displayContent == null) {
9046                 Slog.e(TAG, "Invalid displayId " + displayId + " for mirrorDisplay");
9047                 return false;
9048             }
9049 
9050             displaySc = displayContent.getWindowingLayer();
9051         }
9052 
9053         final SurfaceControl mirror = SurfaceControl.mirrorSurface(displaySc);
9054         outSurfaceControl.copyFrom(mirror, "WMS.mirrorDisplay");
9055         mirror.release();
9056         return true;
9057     }
9058 
9059     @Override
getWindowInsets(int displayId, IBinder token, InsetsState outInsetsState)9060     public boolean getWindowInsets(int displayId, IBinder token, InsetsState outInsetsState) {
9061         final long origId = Binder.clearCallingIdentity();
9062         try {
9063             synchronized (mGlobalLock) {
9064                 final DisplayContent dc = getDisplayContentOrCreate(displayId, token);
9065                 if (dc == null) {
9066                     throw new WindowManager.InvalidDisplayException("Display#" + displayId
9067                             + "could not be found!");
9068                 }
9069                 final WindowToken winToken = dc.getWindowToken(token);
9070                 dc.getInsetsPolicy().getInsetsForWindowMetrics(winToken, outInsetsState);
9071                 return dc.getDisplayPolicy().areSystemBarsForcedConsumedLw();
9072             }
9073         } finally {
9074             Binder.restoreCallingIdentity(origId);
9075         }
9076     }
9077 
9078     @Override
getPossibleDisplayInfo(int displayId)9079     public List<DisplayInfo> getPossibleDisplayInfo(int displayId) {
9080         final int callingUid = Binder.getCallingUid();
9081         final long origId = Binder.clearCallingIdentity();
9082         try {
9083             synchronized (mGlobalLock) {
9084                 if (!mAtmService.isCallerRecents(callingUid)) {
9085                     Slog.e(TAG, "Unable to verify uid for getPossibleDisplayInfo"
9086                             + " on uid " + callingUid);
9087                     return new ArrayList<>();
9088                 }
9089 
9090                 // Retrieve the DisplayInfo across all possible display layouts.
9091                 return mPossibleDisplayInfoMapper.getPossibleDisplayInfos(displayId);
9092             }
9093         } finally {
9094             Binder.restoreCallingIdentity(origId);
9095         }
9096     }
9097 
getPossibleDisplayInfoLocked(int displayId)9098     List<DisplayInfo> getPossibleDisplayInfoLocked(int displayId) {
9099         // Retrieve the DisplayInfo for all possible rotations across all possible display
9100         // layouts.
9101         return mPossibleDisplayInfoMapper.getPossibleDisplayInfos(displayId);
9102     }
9103 
grantEmbeddedWindowFocus(Session session, IBinder focusToken, boolean grantFocus)9104     void grantEmbeddedWindowFocus(Session session, IBinder focusToken, boolean grantFocus) {
9105         synchronized (mGlobalLock) {
9106             final EmbeddedWindowController.EmbeddedWindow embeddedWindow =
9107                     mEmbeddedWindowController.getByFocusToken(focusToken);
9108             if (embeddedWindow == null) {
9109                 Slog.e(TAG, "Embedded window not found");
9110                 return;
9111             }
9112             if (embeddedWindow.mSession != session) {
9113                 Slog.e(TAG, "Window not in session:" + session);
9114                 return;
9115             }
9116             IBinder inputToken = embeddedWindow.getInputChannelToken();
9117             if (inputToken == null) {
9118                 Slog.e(TAG, "Focus token found but input channel token not found");
9119                 return;
9120             }
9121             SurfaceControl.Transaction t = mTransactionFactory.get();
9122             final int displayId = embeddedWindow.mDisplayId;
9123             if (grantFocus) {
9124                 t.setFocusedWindow(inputToken, embeddedWindow.toString(), displayId).apply();
9125                 EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
9126                         "Focus request " + embeddedWindow, "reason=grantEmbeddedWindowFocus(true)");
9127             } else {
9128                 // Search for a new focus target
9129                 DisplayContent displayContent = mRoot.getDisplayContent(displayId);
9130                 WindowState newFocusTarget =  displayContent == null
9131                         ? null : displayContent.findFocusedWindow();
9132                 if (newFocusTarget == null) {
9133                     t.setFocusedWindow(null, null, displayId).apply();
9134                     ProtoLog.v(WM_DEBUG_FOCUS, "grantEmbeddedWindowFocus win=%s"
9135                                     + " dropped focus so setting focus to null since no candidate"
9136                                     + " was found",
9137                             embeddedWindow);
9138                     return;
9139                 }
9140                 t.setFocusedWindow(newFocusTarget.mInputChannelToken, newFocusTarget.getName(),
9141                         displayId).apply();
9142 
9143                 EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
9144                         "Focus request " + newFocusTarget,
9145                         "reason=grantEmbeddedWindowFocus(false)");
9146             }
9147             ProtoLog.v(WM_DEBUG_FOCUS, "grantEmbeddedWindowFocus win=%s grantFocus=%s",
9148                     embeddedWindow, grantFocus);
9149         }
9150     }
9151 
grantEmbeddedWindowFocus(Session session, IWindow callingWindow, IBinder targetFocusToken, boolean grantFocus)9152     void grantEmbeddedWindowFocus(Session session, IWindow callingWindow, IBinder targetFocusToken,
9153                                   boolean grantFocus) {
9154         synchronized (mGlobalLock) {
9155             final WindowState hostWindow =
9156                     windowForClientLocked(session, callingWindow, false /* throwOnError*/);
9157             if (hostWindow == null) {
9158                 Slog.e(TAG, "Host window not found");
9159                 return;
9160             }
9161             if (hostWindow.mInputChannel == null) {
9162                 Slog.e(TAG, "Host window does not have an input channel");
9163                 return;
9164             }
9165             final EmbeddedWindowController.EmbeddedWindow embeddedWindow =
9166                     mEmbeddedWindowController.getByFocusToken(targetFocusToken);
9167             if (embeddedWindow == null) {
9168                 Slog.e(TAG, "Embedded window not found");
9169                 return;
9170             }
9171             if (embeddedWindow.mHostWindowState != hostWindow) {
9172                 Slog.e(TAG, "Embedded window does not belong to the host");
9173                 return;
9174             }
9175             if (grantFocus) {
9176                 hostWindow.mInputWindowHandle.setFocusTransferTarget(
9177                         embeddedWindow.getInputChannelToken());
9178                 EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
9179                         "Transfer focus request " + embeddedWindow,
9180                         "reason=grantEmbeddedWindowFocus(true)");
9181             } else {
9182                 hostWindow.mInputWindowHandle.setFocusTransferTarget(null);
9183                 EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
9184                         "Transfer focus request " + hostWindow,
9185                         "reason=grantEmbeddedWindowFocus(false)");
9186             }
9187             DisplayContent dc = mRoot.getDisplayContent(hostWindow.getDisplayId());
9188             if (dc != null) {
9189                 dc.getInputMonitor().updateInputWindowsLw(true);
9190             }
9191 
9192             ProtoLog.v(WM_DEBUG_FOCUS, "grantEmbeddedWindowFocus win=%s grantFocus=%s",
9193                     embeddedWindow, grantFocus);
9194         }
9195     }
9196 
9197     @Override
holdLock(IBinder token, int durationMs)9198     public void holdLock(IBinder token, int durationMs) {
9199         mTestUtilityService.verifyHoldLockToken(token);
9200 
9201         synchronized (mGlobalLock) {
9202             SystemClock.sleep(durationMs);
9203         }
9204     }
9205 
9206     @Override
getSupportedDisplayHashAlgorithms()9207     public String[] getSupportedDisplayHashAlgorithms() {
9208         return mDisplayHashController.getSupportedHashAlgorithms();
9209     }
9210 
9211     @Override
verifyDisplayHash(DisplayHash displayHash)9212     public VerifiedDisplayHash verifyDisplayHash(DisplayHash displayHash) {
9213         return mDisplayHashController.verifyDisplayHash(displayHash);
9214     }
9215 
9216     @Override
setDisplayHashThrottlingEnabled(boolean enable)9217     public void setDisplayHashThrottlingEnabled(boolean enable) {
9218         if (!checkCallingPermission(READ_FRAME_BUFFER, "setDisplayHashThrottle()")) {
9219             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
9220         }
9221         mDisplayHashController.setDisplayHashThrottlingEnabled(enable);
9222     }
9223 
9224     @Override
isTaskSnapshotSupported()9225     public boolean isTaskSnapshotSupported() {
9226         synchronized (mGlobalLock) {
9227             return !mTaskSnapshotController.shouldDisableSnapshots();
9228         }
9229     }
9230 
generateDisplayHash(Session session, IWindow window, Rect boundsInWindow, String hashAlgorithm, RemoteCallback callback)9231     void generateDisplayHash(Session session, IWindow window, Rect boundsInWindow,
9232             String hashAlgorithm, RemoteCallback callback) {
9233         final SurfaceControl displaySurfaceControl;
9234         final Rect boundsInDisplay = new Rect(boundsInWindow);
9235         synchronized (mGlobalLock) {
9236             final WindowState win = windowForClientLocked(session, window, false);
9237             if (win == null) {
9238                 Slog.w(TAG, "Failed to generate DisplayHash. Invalid window");
9239                 mDisplayHashController.sendDisplayHashError(callback,
9240                         DISPLAY_HASH_ERROR_MISSING_WINDOW);
9241                 return;
9242             }
9243 
9244             if (win.mActivityRecord == null || !win.mActivityRecord.isState(
9245                     ActivityRecord.State.RESUMED)) {
9246                 mDisplayHashController.sendDisplayHashError(callback,
9247                         DISPLAY_HASH_ERROR_MISSING_WINDOW);
9248                 return;
9249             }
9250 
9251             DisplayContent displayContent = win.getDisplayContent();
9252             if (displayContent == null) {
9253                 Slog.w(TAG, "Failed to generate DisplayHash. Window is not on a display");
9254                 mDisplayHashController.sendDisplayHashError(callback,
9255                         DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN);
9256                 return;
9257             }
9258 
9259             displaySurfaceControl = displayContent.getSurfaceControl();
9260             mDisplayHashController.calculateDisplayHashBoundsLocked(win, boundsInWindow,
9261                     boundsInDisplay);
9262 
9263             if (boundsInDisplay.isEmpty()) {
9264                 Slog.w(TAG, "Failed to generate DisplayHash. Bounds are not on screen");
9265                 mDisplayHashController.sendDisplayHashError(callback,
9266                         DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN);
9267                 return;
9268             }
9269         }
9270 
9271         // A screenshot of the entire display is taken rather than just the window. This is
9272         // because if we take a screenshot of the window, it will not include content that might
9273         // be covering it with the same uid. We want to make sure we include content that's
9274         // covering to ensure we get as close as possible to what the user sees
9275         final int uid = session.mUid;
9276         ScreenCapture.LayerCaptureArgs.Builder args =
9277                 new ScreenCapture.LayerCaptureArgs.Builder(displaySurfaceControl)
9278                         .setUid(uid)
9279                         .setSourceCrop(boundsInDisplay);
9280 
9281         mDisplayHashController.generateDisplayHash(args, boundsInWindow, hashAlgorithm, uid,
9282                 callback);
9283     }
9284 
shouldRestoreImeVisibility(IBinder imeTargetWindowToken)9285     boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) {
9286         final Task imeTargetWindowTask;
9287         synchronized (mGlobalLock) {
9288             final WindowState imeTargetWindow = mWindowMap.get(imeTargetWindowToken);
9289             if (imeTargetWindow == null) {
9290                 return false;
9291             }
9292             imeTargetWindowTask = imeTargetWindow.getTask();
9293             if (imeTargetWindowTask == null) {
9294                 return false;
9295             }
9296             if (imeTargetWindow.mActivityRecord != null
9297                     && imeTargetWindow.mActivityRecord.mLastImeShown) {
9298                 return true;
9299             }
9300         }
9301         final TaskSnapshot snapshot = getTaskSnapshot(imeTargetWindowTask.mTaskId,
9302                 imeTargetWindowTask.mUserId, false /* isLowResolution */,
9303                 false /* restoreFromDisk */);
9304         return snapshot != null && snapshot.hasImeSurface();
9305     }
9306 
9307     @Override
getImeDisplayId()9308     public int getImeDisplayId() {
9309         // TODO(b/189805422): Add a toast to notify users that IMS may get extra
9310         //  onConfigurationChanged callback when perDisplayFocus is enabled.
9311         //  Enabling perDisplayFocus means that we track focus on each display, so we don't have
9312         //  the "top focus" display and getTopFocusedDisplayContent returns the default display
9313         //  as the fallback. It leads to InputMethodService receives an extra onConfiguration
9314         //  callback when InputMethodService move from a secondary display to another display
9315         //  with the same display metrics because InputMethodService will always associate with
9316         //  the ImeContainer on the default display in onCreate and receive a configuration update
9317         //  to match default display ImeContainer and then receive another configuration update
9318         //  from attachToWindowToken.
9319         synchronized (mGlobalLock) {
9320             final DisplayContent dc = mRoot.getTopFocusedDisplayContent();
9321             return dc.getImePolicy() == DISPLAY_IME_POLICY_LOCAL ? dc.getDisplayId()
9322                     : DEFAULT_DISPLAY;
9323         }
9324     }
9325 
9326     @Override
setTaskSnapshotEnabled(boolean enabled)9327     public void setTaskSnapshotEnabled(boolean enabled) {
9328         mTaskSnapshotController.setSnapshotEnabled(enabled);
9329     }
9330 
9331     @Override
setTaskTransitionSpec(TaskTransitionSpec spec)9332     public void setTaskTransitionSpec(TaskTransitionSpec spec) {
9333         if (!checkCallingPermission(MANAGE_ACTIVITY_TASKS, "setTaskTransitionSpec()")) {
9334             throw new SecurityException("Requires MANAGE_ACTIVITY_TASKS permission");
9335         }
9336 
9337         mTaskTransitionSpec = spec;
9338     }
9339 
9340     @Override
clearTaskTransitionSpec()9341     public void clearTaskTransitionSpec() {
9342         if (!checkCallingPermission(MANAGE_ACTIVITY_TASKS, "clearTaskTransitionSpec()")) {
9343             throw new SecurityException("Requires MANAGE_ACTIVITY_TASKS permission");
9344         }
9345 
9346         mTaskTransitionSpec = null;
9347     }
9348 
9349     @Override
9350     @RequiresPermission(Manifest.permission.ACCESS_FPS_COUNTER)
registerTaskFpsCallback(@ntRangefrom = 0) int taskId, ITaskFpsCallback callback)9351     public void registerTaskFpsCallback(@IntRange(from = 0) int taskId,
9352             ITaskFpsCallback callback) {
9353         if (mContext.checkCallingOrSelfPermission(Manifest.permission.ACCESS_FPS_COUNTER)
9354                 != PackageManager.PERMISSION_GRANTED) {
9355             final int pid = Binder.getCallingPid();
9356             throw new SecurityException("Access denied to process: " + pid
9357                     + ", must have permission " + Manifest.permission.ACCESS_FPS_COUNTER);
9358         }
9359 
9360         if (mRoot.anyTaskForId(taskId) == null) {
9361             throw new IllegalArgumentException("no task with taskId: " + taskId);
9362         }
9363 
9364         mTaskFpsCallbackController.registerListener(taskId, callback);
9365     }
9366 
9367     @Override
9368     @RequiresPermission(Manifest.permission.ACCESS_FPS_COUNTER)
unregisterTaskFpsCallback(ITaskFpsCallback callback)9369     public void unregisterTaskFpsCallback(ITaskFpsCallback callback) {
9370         if (mContext.checkCallingOrSelfPermission(Manifest.permission.ACCESS_FPS_COUNTER)
9371                 != PackageManager.PERMISSION_GRANTED) {
9372             final int pid = Binder.getCallingPid();
9373             throw new SecurityException("Access denied to process: " + pid
9374                     + ", must have permission " + Manifest.permission.ACCESS_FPS_COUNTER);
9375         }
9376 
9377         mTaskFpsCallbackController.unregisterListener(callback);
9378     }
9379 
9380     @Override
snapshotTaskForRecents(int taskId)9381     public Bitmap snapshotTaskForRecents(int taskId) {
9382         if (!checkCallingPermission(READ_FRAME_BUFFER, "snapshotTaskForRecents()")) {
9383             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
9384         }
9385 
9386         TaskSnapshot taskSnapshot;
9387         final long token = Binder.clearCallingIdentity();
9388         try {
9389             synchronized (mGlobalLock) {
9390                 Task task = mRoot.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
9391                 if (task == null) {
9392                     throw new IllegalArgumentException(
9393                             "Failed to find matching task for taskId=" + taskId);
9394                 }
9395                 taskSnapshot = mTaskSnapshotController.captureSnapshot(task, false);
9396             }
9397         } finally {
9398             Binder.restoreCallingIdentity(token);
9399         }
9400 
9401         if (taskSnapshot == null || taskSnapshot.getHardwareBuffer() == null) {
9402             return null;
9403         }
9404         return Bitmap.wrapHardwareBuffer(taskSnapshot.getHardwareBuffer(),
9405                 taskSnapshot.getColorSpace());
9406     }
9407 
9408     @Override
setRecentsAppBehindSystemBars(boolean behindSystemBars)9409     public void setRecentsAppBehindSystemBars(boolean behindSystemBars) {
9410         if (!checkCallingPermission(START_TASKS_FROM_RECENTS, "setRecentsAppBehindSystemBars()")) {
9411             throw new SecurityException("Requires START_TASKS_FROM_RECENTS permission");
9412         }
9413         final long token = Binder.clearCallingIdentity();
9414         try {
9415             synchronized (mGlobalLock) {
9416                 final Task recentsApp = mRoot.getTask(task -> task.isActivityTypeHomeOrRecents()
9417                         && task.getTopVisibleActivity() != null);
9418                 if (recentsApp != null) {
9419                     recentsApp.getTask().setCanAffectSystemUiFlags(behindSystemBars);
9420                     mWindowPlacerLocked.requestTraversal();
9421                 }
9422                 InputMethodManagerInternal.get().maybeFinishStylusHandwriting();
9423             }
9424         } finally {
9425             Binder.restoreCallingIdentity(token);
9426         }
9427     }
9428 
9429     /**
9430      * Gets the background color of the letterbox. Considered invalid if the background has
9431      * multiple colors {@link #isLetterboxBackgroundMultiColored}
9432      */
9433     @Override
getLetterboxBackgroundColorInArgb()9434     public int getLetterboxBackgroundColorInArgb() {
9435         return mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb();
9436     }
9437 
9438     /**
9439      *  Whether the outer area of the letterbox has multiple colors (e.g. blurred background).
9440      */
9441     @Override
isLetterboxBackgroundMultiColored()9442     public boolean isLetterboxBackgroundMultiColored() {
9443         @LetterboxConfiguration.LetterboxBackgroundType int letterboxBackgroundType =
9444                 mLetterboxConfiguration.getLetterboxBackgroundType();
9445         switch (letterboxBackgroundType) {
9446             case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
9447             case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
9448             case LETTERBOX_BACKGROUND_WALLPAPER:
9449                 return true;
9450             case LETTERBOX_BACKGROUND_SOLID_COLOR:
9451                 return false;
9452             default:
9453                 throw new AssertionError(
9454                         "Unexpected letterbox background type: " + letterboxBackgroundType);
9455         }
9456     }
9457 
9458     @Override
captureDisplay(int displayId, @Nullable ScreenCapture.CaptureArgs captureArgs, ScreenCapture.ScreenCaptureListener listener)9459     public void captureDisplay(int displayId, @Nullable ScreenCapture.CaptureArgs captureArgs,
9460             ScreenCapture.ScreenCaptureListener listener) {
9461         Slog.d(TAG, "captureDisplay");
9462         if (!checkCallingPermission(READ_FRAME_BUFFER, "captureDisplay()")) {
9463             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
9464         }
9465 
9466         ScreenCapture.LayerCaptureArgs layerCaptureArgs = getCaptureArgs(displayId, captureArgs);
9467         ScreenCapture.captureLayers(layerCaptureArgs, listener);
9468 
9469         if (Binder.getCallingUid() != SYSTEM_UID) {
9470             // Release the SurfaceControl objects only if the caller is not in system server as no
9471             // parcelling occurs in this case.
9472             layerCaptureArgs.release();
9473         }
9474     }
9475 
9476     @VisibleForTesting
getCaptureArgs(int displayId, @Nullable ScreenCapture.CaptureArgs captureArgs)9477     ScreenCapture.LayerCaptureArgs getCaptureArgs(int displayId,
9478             @Nullable ScreenCapture.CaptureArgs captureArgs) {
9479         final SurfaceControl displaySurfaceControl;
9480         synchronized (mGlobalLock) {
9481             DisplayContent displayContent = mRoot.getDisplayContent(displayId);
9482             if (displayContent == null) {
9483                 throw new IllegalArgumentException("Trying to screenshot and invalid display: "
9484                         + displayId);
9485             }
9486 
9487             displaySurfaceControl = displayContent.getSurfaceControl();
9488 
9489             if (captureArgs == null) {
9490                 captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
9491                         .build();
9492             }
9493 
9494             if (captureArgs.mSourceCrop.isEmpty()) {
9495                 displayContent.getBounds(mTmpRect);
9496                 mTmpRect.offsetTo(0, 0);
9497             } else {
9498                 mTmpRect.set(captureArgs.mSourceCrop);
9499             }
9500         }
9501 
9502         return new ScreenCapture.LayerCaptureArgs.Builder(displaySurfaceControl, captureArgs)
9503                         .setSourceCrop(mTmpRect)
9504                         .build();
9505     }
9506 
9507     @Override
isGlobalKey(int keyCode)9508     public boolean isGlobalKey(int keyCode) {
9509         return mPolicy.isGlobalKey(keyCode);
9510     }
9511 
sanitizeWindowType(Session session, int displayId, IBinder windowToken, int type)9512     private int sanitizeWindowType(Session session, int displayId, IBinder windowToken, int type) {
9513         // Determine whether this window type is valid for this process.
9514         final boolean isTypeValid;
9515         if (type == TYPE_ACCESSIBILITY_OVERLAY && windowToken != null) {
9516             // Only accessibility services can add accessibility overlays.
9517             // Accessibility services will have a WindowToken with type
9518             // TYPE_ACCESSIBILITY_OVERLAY.
9519             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
9520             final WindowToken token = displayContent.getWindowToken(windowToken);
9521             if (token == null) {
9522                 isTypeValid = false;
9523             } else if (type == token.getWindowType()) {
9524                 isTypeValid = true;
9525             } else {
9526                 isTypeValid = false;
9527             }
9528         } else if (!session.mCanAddInternalSystemWindow && type != 0) {
9529             Slog.w(
9530                     TAG_WM,
9531                     "Requires INTERNAL_SYSTEM_WINDOW permission if assign type to"
9532                             + " input. New type will be 0.");
9533             isTypeValid = false;
9534         } else {
9535             isTypeValid = true;
9536         }
9537 
9538         if (!isTypeValid) {
9539             return 0;
9540         }
9541         return type;
9542     }
9543     @Override
addToSurfaceSyncGroup(IBinder syncGroupToken, boolean parentSyncGroupMerge, @Nullable ISurfaceSyncGroupCompletedListener completedListener, AddToSurfaceSyncGroupResult outAddToSyncGroupResult)9544     public boolean addToSurfaceSyncGroup(IBinder syncGroupToken, boolean parentSyncGroupMerge,
9545             @Nullable ISurfaceSyncGroupCompletedListener completedListener,
9546             AddToSurfaceSyncGroupResult outAddToSyncGroupResult) {
9547         return mSurfaceSyncGroupController.addToSyncGroup(syncGroupToken, parentSyncGroupMerge,
9548                 completedListener, outAddToSyncGroupResult);
9549     }
9550 
9551     @Override
markSurfaceSyncGroupReady(IBinder syncGroupToken)9552     public void markSurfaceSyncGroupReady(IBinder syncGroupToken) {
9553         mSurfaceSyncGroupController.markSyncGroupReady(syncGroupToken);
9554     }
9555 
9556 
9557     /**
9558      * Must be called when a screenshot is taken via hardware chord.
9559      *
9560      * Notifies all registered visible activities that have registered for screencapture callback,
9561      * Returns a list of visible apps component names.
9562      */
9563     @Override
notifyScreenshotListeners(int displayId)9564     public List<ComponentName> notifyScreenshotListeners(int displayId) {
9565         // make sure caller is SysUI.
9566         if (!checkCallingPermission(STATUS_BAR_SERVICE,
9567                 "notifyScreenshotListeners()")) {
9568             throw new SecurityException("Requires STATUS_BAR_SERVICE permission");
9569         }
9570         synchronized (mGlobalLock) {
9571             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
9572             if (displayContent == null) {
9573                 return new ArrayList<>();
9574             }
9575             ArraySet<ComponentName> notifiedApps = new ArraySet<>();
9576             displayContent.forAllActivities(
9577                     (ar) -> {
9578                         if (!notifiedApps.contains(ar.mActivityComponent) && ar.isVisible()
9579                                 && ar.isRegisteredForScreenCaptureCallback()) {
9580                             ar.reportScreenCaptured();
9581                             notifiedApps.add(ar.mActivityComponent);
9582                         }
9583                     },
9584                     true /* traverseTopToBottom */);
9585             return List.copyOf(notifiedApps);
9586         }
9587     }
9588 }
9589