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