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