• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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.policy;
18 
19 import static android.Manifest.permission.CREATE_VIRTUAL_DEVICE;
20 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
21 import static android.Manifest.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW;
22 import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
23 import static android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY;
24 import static android.app.AppOpsManager.OP_CREATE_ACCESSIBILITY_OVERLAY;
25 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
26 import static android.app.AppOpsManager.OP_TOAST_WINDOW;
27 import static android.content.PermissionChecker.PID_UNKNOWN;
28 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
29 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
30 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
31 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
32 import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
33 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
34 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
35 import static android.content.pm.PackageManager.FEATURE_WATCH;
36 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
37 import static android.os.Build.VERSION_CODES.M;
38 import static android.os.Build.VERSION_CODES.O;
39 import static android.os.IInputConstants.INVALID_INPUT_DEVICE_ID;
40 import static android.os.UserManager.isVisibleBackgroundUsersEnabled;
41 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
42 import static android.view.Display.DEFAULT_DISPLAY;
43 import static android.view.Display.INVALID_DISPLAY;
44 import static android.view.Display.STATE_OFF;
45 import static android.view.KeyEvent.KEYCODE_BACK;
46 import static android.view.KeyEvent.KEYCODE_DPAD_CENTER;
47 import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
48 import static android.view.KeyEvent.KEYCODE_HOME;
49 import static android.view.KeyEvent.KEYCODE_POWER;
50 import static android.view.KeyEvent.KEYCODE_STEM_PRIMARY;
51 import static android.view.KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL;
52 import static android.view.KeyEvent.KEYCODE_UNKNOWN;
53 import static android.view.KeyEvent.KEYCODE_VOLUME_DOWN;
54 import static android.view.KeyEvent.KEYCODE_VOLUME_UP;
55 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
56 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
57 import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
58 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
59 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
60 import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
61 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
62 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
63 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
64 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
65 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
66 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
67 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
68 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
69 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
70 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
71 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
72 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
73 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
74 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
75 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
76 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
77 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
78 import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
79 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD;
80 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER;
81 import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
82 import static android.view.WindowManagerGlobal.ADD_OKAY;
83 import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
84 import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
85 
86 import static com.android.hardware.input.Flags.enableNew25q2Keycodes;
87 import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
88 import static com.android.hardware.input.Flags.enableVoiceAccessKeyGestures;
89 import static com.android.hardware.input.Flags.fixSearchModifierFallbacks;
90 import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
91 import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
92 import static com.android.hardware.input.Flags.modifierShortcutDump;
93 import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
94 import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
95 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
96 import static com.android.server.GestureLauncherService.DOUBLE_POWER_TAP_COUNT_THRESHOLD;
97 import static com.android.server.flags.Flags.modifierShortcutManagerMultiuser;
98 import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
99 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
100 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
101 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
102 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_BEHAVIOR_LOCK;
103 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_BEHAVIOR_NONE;
104 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_BEHAVIOR_SLEEP;
105 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
106 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
107 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_DELEGATE;
108 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_DRAW_COMPLETE;
109 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED;
110 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED_CHANGED;
111 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED_PENDING;
112 import static com.android.server.wm.WindowManagerPolicyProto.ORIENTATION;
113 import static com.android.server.wm.WindowManagerPolicyProto.ROTATION;
114 import static com.android.server.wm.WindowManagerPolicyProto.ROTATION_MODE;
115 import static com.android.server.wm.WindowManagerPolicyProto.SCREEN_ON_FULLY;
116 import static com.android.server.wm.WindowManagerPolicyProto.WINDOW_MANAGER_DRAW_COMPLETE;
117 import static com.android.systemui.shared.Flags.enableLppSqueezeEffect;
118 
119 import android.accessibilityservice.AccessibilityService;
120 import android.annotation.Nullable;
121 import android.annotation.SuppressLint;
122 import android.app.ActivityManager;
123 import android.app.ActivityManager.RecentTaskInfo;
124 import android.app.ActivityManagerInternal;
125 import android.app.ActivityTaskManager;
126 import android.app.ActivityTaskManager.RootTaskInfo;
127 import android.app.AppOpsManager;
128 import android.app.IActivityManager;
129 import android.app.IUiModeManager;
130 import android.app.NotificationManager;
131 import android.app.ProgressDialog;
132 import android.app.SearchManager;
133 import android.app.UiModeManager;
134 import android.content.ActivityNotFoundException;
135 import android.content.BroadcastReceiver;
136 import android.content.ComponentName;
137 import android.content.ContentResolver;
138 import android.content.Context;
139 import android.content.Intent;
140 import android.content.IntentFilter;
141 import android.content.PermissionChecker;
142 import android.content.pm.ActivityInfo;
143 import android.content.pm.ApplicationInfo;
144 import android.content.pm.PackageManager;
145 import android.content.pm.ResolveInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Rect;
150 import android.hardware.SensorPrivacyManager;
151 import android.hardware.display.DisplayManager;
152 import android.hardware.display.DisplayManagerInternal;
153 import android.hardware.hdmi.HdmiAudioSystemClient;
154 import android.hardware.hdmi.HdmiControlManager;
155 import android.hardware.hdmi.HdmiPlaybackClient;
156 import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
157 import android.hardware.input.AppLaunchData;
158 import android.hardware.input.InputManager;
159 import android.hardware.input.InputSettings;
160 import android.hardware.input.KeyGestureEvent;
161 import android.media.AudioManager;
162 import android.media.AudioManagerInternal;
163 import android.media.AudioSystem;
164 import android.media.IAudioService;
165 import android.media.session.MediaSessionLegacyHelper;
166 import android.os.Binder;
167 import android.os.Bundle;
168 import android.os.DeviceIdleManager;
169 import android.os.FactoryTest;
170 import android.os.Handler;
171 import android.os.IBinder;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.PowerManager;
175 import android.os.PowerManager.WakeReason;
176 import android.os.PowerManagerInternal;
177 import android.os.Process;
178 import android.os.RemoteException;
179 import android.os.ServiceManager;
180 import android.os.StrictMode;
181 import android.os.SystemClock;
182 import android.os.SystemProperties;
183 import android.os.Trace;
184 import android.os.UEventObserver;
185 import android.os.UserHandle;
186 import android.os.Vibrator;
187 import android.provider.DeviceConfig;
188 import android.provider.MediaStore;
189 import android.provider.Settings;
190 import android.provider.Settings.Secure;
191 import android.service.SensorPrivacyToggleSourceProto;
192 import android.service.dreams.DreamManagerInternal;
193 import android.service.dreams.DreamService;
194 import android.service.dreams.IDreamManager;
195 import android.service.vr.IPersistentVrStateCallbacks;
196 import android.speech.RecognizerIntent;
197 import android.telecom.TelecomManager;
198 import android.text.TextUtils;
199 import android.util.Log;
200 import android.util.MathUtils;
201 import android.util.MutableBoolean;
202 import android.util.PrintWriterPrinter;
203 import android.util.Slog;
204 import android.util.SparseArray;
205 import android.util.proto.ProtoOutputStream;
206 import android.view.Display;
207 import android.view.HapticFeedbackConstants;
208 import android.view.IDisplayFoldListener;
209 import android.view.InputDevice;
210 import android.view.KeyCharacterMap;
211 import android.view.KeyEvent;
212 import android.view.KeyboardShortcutGroup;
213 import android.view.MotionEvent;
214 import android.view.ViewConfiguration;
215 import android.view.WindowManager;
216 import android.view.WindowManagerGlobal;
217 import android.view.WindowManagerPolicyConstants;
218 import android.view.accessibility.AccessibilityEvent;
219 import android.view.accessibility.AccessibilityManager;
220 import android.view.animation.Animation;
221 import android.view.animation.AnimationUtils;
222 import android.view.autofill.AutofillManagerInternal;
223 import android.widget.Toast;
224 
225 import com.android.internal.R;
226 import com.android.internal.accessibility.AccessibilityShortcutController;
227 import com.android.internal.annotations.VisibleForTesting;
228 import com.android.internal.app.AssistUtils;
229 import com.android.internal.display.BrightnessUtils;
230 import com.android.internal.inputmethod.SoftInputShowHideReason;
231 import com.android.internal.logging.MetricsLogger;
232 import com.android.internal.logging.nano.MetricsProto;
233 import com.android.internal.os.RoSystemProperties;
234 import com.android.internal.policy.IKeyguardDismissCallback;
235 import com.android.internal.policy.IKeyguardService;
236 import com.android.internal.policy.IShortcutService;
237 import com.android.internal.policy.KeyInterceptionInfo;
238 import com.android.internal.policy.LogDecelerateInterpolator;
239 import com.android.internal.policy.PhoneWindow;
240 import com.android.internal.policy.TransitionAnimation;
241 import com.android.internal.statusbar.IStatusBarService;
242 import com.android.internal.widget.LockPatternUtils;
243 import com.android.server.AccessibilityManagerInternal;
244 import com.android.server.DockObserverInternal;
245 import com.android.server.ExtconStateObserver;
246 import com.android.server.ExtconUEventObserver;
247 import com.android.server.GestureLauncherService;
248 import com.android.server.LocalServices;
249 import com.android.server.SystemServiceManager;
250 import com.android.server.UiThread;
251 import com.android.server.input.InputManagerInternal;
252 import com.android.server.inputmethod.InputMethodManagerInternal;
253 import com.android.server.pm.UserManagerInternal;
254 import com.android.server.policy.KeyCombinationManager.TwoKeysCombinationRule;
255 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
256 import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
257 import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback;
258 import com.android.server.statusbar.StatusBarManagerInternal;
259 import com.android.server.vr.VrManagerInternal;
260 import com.android.server.wallpaper.WallpaperManagerInternal;
261 import com.android.server.wm.ActivityTaskManagerInternal;
262 import com.android.server.wm.DisplayPolicy;
263 import com.android.server.wm.DisplayRotation;
264 import com.android.server.wm.WindowManagerInternal;
265 import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
266 
267 import java.io.File;
268 import java.io.FileNotFoundException;
269 import java.io.FileReader;
270 import java.io.IOException;
271 import java.io.PrintWriter;
272 import java.util.ArrayList;
273 import java.util.Arrays;
274 import java.util.HashSet;
275 import java.util.List;
276 import java.util.Set;
277 import java.util.function.Supplier;
278 
279 /**
280  * WindowManagerPolicy implementation for the Android phone UI.  This
281  * introduces a new method suffix, Lp, for an internal lock of the
282  * PhoneWindowManager.  This is used to protect some internal state, and
283  * can be acquired with either the Lw and Li lock held, so has the restrictions
284  * of both of those when held.
285  */
286 public class PhoneWindowManager implements WindowManagerPolicy {
287     static final String TAG = "WindowManager";
288     static final boolean localLOGV = false;
289     static final boolean DEBUG_INPUT = false;
290     static final boolean DEBUG_KEYGUARD = false;
291     static final boolean DEBUG_WAKEUP = false;
292 
293     // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
294     // No longer recommended for desk docks;
295     static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
296 
297     // Whether to allow devices placed in vr headset viewers to have an alternative Home intent.
298     static final boolean ENABLE_VR_HEADSET_HOME_CAPTURE = true;
299 
300     // --------- Key behavior definitions below. ---------
301     // NOTE: When updating the valid range of any of these behaviors, and if that behavior has a
302     // Settings key associated to it for dynamic update, update its valid Settings value range in
303     // android.provider.settings.validators.GlobalSettingsValidators.
304 
305     // must match: config_shortPressOnPowerBehavior in config.xml
306     // The config value can be overridden using Settings.Global.POWER_BUTTON_SHORT_PRESS
307     static final int SHORT_PRESS_POWER_NOTHING = 0;
308     static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1;
309     static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2;
310     static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3;
311     static final int SHORT_PRESS_POWER_GO_HOME = 4;
312     static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5;
313     static final int SHORT_PRESS_POWER_LOCK_OR_SLEEP = 6;
314     static final int SHORT_PRESS_POWER_DREAM_OR_SLEEP = 7;
315     static final int SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP = 8;
316     static final int SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP = 9;
317 
318     // must match: config_LongPressOnPowerBehavior in config.xml
319     // The config value can be overridden using Settings.Global.POWER_BUTTON_LONG_PRESS
320     static final int LONG_PRESS_POWER_NOTHING = 0;
321     static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
322     static final int LONG_PRESS_POWER_SHUT_OFF = 2;
323     static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
324     static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4;
325     static final int LONG_PRESS_POWER_ASSISTANT = 5; // Settings.Secure.ASSISTANT
326 
327     // must match: config_veryLongPresOnPowerBehavior in config.xml
328     // The config value can be overridden using Settings.Global.POWER_BUTTON_VERY_LONG_PRESS
329     static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
330     static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
331 
332     // must match: config_keyChordPowerVolumeUp in config.xml
333     static final int POWER_VOLUME_UP_BEHAVIOR_NOTHING = 0;
334     static final int POWER_VOLUME_UP_BEHAVIOR_MUTE = 1;
335     static final int POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS = 2;
336 
337     // must match: config_doublePressOnPowerBehavior in config.xml
338     // The config value can be overridden using Settings.Global.POWER_BUTTON_DOUBLE_PRESS and/or
339     // Settings.Global.POWER_BUTTON_TRIPLE_PRESS
340     static final int MULTI_PRESS_POWER_NOTHING = 0;
341     static final int MULTI_PRESS_POWER_THEATER_MODE = 1;
342     static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2;
343     static final int MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY = 3;
344 
345     // must match: config_longPressOnBackBehavior in config.xml
346     static final int LONG_PRESS_BACK_NOTHING = 0;
347     static final int LONG_PRESS_BACK_GO_TO_VOICE_ASSIST = 1;
348 
349     // must match: config_longPressOnHomeBehavior in config.xml
350     static final int LONG_PRESS_HOME_NOTHING = 0;
351     static final int LONG_PRESS_HOME_ALL_APPS = 1;
352     static final int LONG_PRESS_HOME_ASSIST = 2;
353     static final int LONG_PRESS_HOME_NOTIFICATION_PANEL = 3;
354     static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_NOTIFICATION_PANEL;
355 
356     // must match: config_doubleTapOnHomeBehavior in config.xml
357     static final int DOUBLE_TAP_HOME_NOTHING = 0;
358     static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1;
359     static final int DOUBLE_TAP_HOME_PIP_MENU = 2;
360 
361     static final int SHORT_PRESS_WINDOW_NOTHING = 0;
362     static final int SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE = 1;
363 
364     static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0;
365     static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1;
366 
367     // must match: config_settingsKeyBehavior in config.xml
368     static final int SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY = 0;
369     static final int SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL = 1;
370     static final int SETTINGS_KEY_BEHAVIOR_NOTHING = 2;
371     static final int LAST_SETTINGS_KEY_BEHAVIOR = SETTINGS_KEY_BEHAVIOR_NOTHING;
372 
373     static final int PENDING_KEY_NULL = -1;
374 
375     // Must match: config_shortPressOnStemPrimaryBehavior in config.xml
376     // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS
377     static final int SHORT_PRESS_PRIMARY_NOTHING = 0;
378     static final int SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS = 1;
379     static final int SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY = 2;
380 
381     // Must match: config_longPressOnStemPrimaryBehavior in config.xml
382     // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS
383     static final int LONG_PRESS_PRIMARY_NOTHING = 0;
384     static final int LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT = 1;
385 
386     // Must match: config_doublePressOnStemPrimaryBehavior in config.xml
387     //The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_DOUBLE_PRESS
388     static final int DOUBLE_PRESS_PRIMARY_NOTHING = 0;
389     static final int DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP = 1;
390     static final int DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP = 2;
391 
392     // Must match: config_triplePressOnStemPrimaryBehavior in config.xml
393     // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_TRIPLE_PRESS
394     static final int TRIPLE_PRESS_PRIMARY_NOTHING = 0;
395     static final int TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY = 1;
396 
397     // Must match: config_searchKeyBehavior in config.xml
398     static final int SEARCH_KEY_BEHAVIOR_DEFAULT_SEARCH = 0;
399     static final int SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY = 1;
400 
401     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
402     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
403     static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
404     static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
405     static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
406     static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
407     static public final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
408 
409     public static final String TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD = "waitForAllWindowsDrawn";
410 
411     /**
412      * String extra key passed in the bundle of {@link IKeyguardService#doKeyguardTimeout(Bundle)}
413      * if the value is {@code true}, indicates to keyguard that the device should show the
414      * glanceable hub upon locking. If the hub is already visible, the device should go to sleep.
415      */
416     public static final String EXTRA_TRIGGER_HUB = "extra_trigger_hub";
417 
418     private static final int POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS = 800;
419 
420     /**
421      * Keyguard stuff
422      */
423     private boolean mKeyguardDrawnOnce;
424 
425     /** Amount of time (in milliseconds) to wait for windows drawn before powering on. */
426     static final int WAITING_FOR_DRAWN_TIMEOUT = 1000;
427 
428     /**
429       * Extra time for additional SystemUI animations.
430       * <p>Since legacy apps can add Toast windows directly instead of using Toast APIs,
431       * {@link DisplayPolicy} ensures that the window manager removes toast windows after
432       * TOAST_WINDOW_TIMEOUT. We increase this timeout by TOAST_WINDOW_ANIM_BUFFER to account for
433       * SystemUI's in/out toast animations, so that the toast text is still shown for a minimum
434       * of 3.5 seconds and the animations are finished before window manager removes the window.
435       */
436     public static final int TOAST_WINDOW_ANIM_BUFFER = 600;
437 
438     /**
439       * Amount of time (in milliseconds) a toast window can be shown before it's automatically
440       * removed by window manager.
441       */
442     public static final int TOAST_WINDOW_TIMEOUT = 3500 + TOAST_WINDOW_ANIM_BUFFER;
443 
444     /**
445      * Action for launching assistant in retail mode
446      */
447     private static final String ACTION_VOICE_ASSIST_RETAIL =
448             "android.intent.action.VOICE_ASSIST_RETAIL";
449 
450     /**
451      * Maximum amount of time in milliseconds between consecutive power onKeyDown events to be
452      * considered a multi-press, only used for the power button.
453      * Note: To maintain backwards compatibility for the power button, we are measuring the times
454      * between consecutive down events instead of the first tap's up event and the second tap's
455      * down event.
456      */
457     @VisibleForTesting public static final int POWER_MULTI_PRESS_TIMEOUT_MILLIS =
458             ViewConfiguration.getMultiPressTimeout();
459 
460     /**
461      * Lock protecting internal state.  Must not call out into window
462      * manager with lock held.  (This lock will be acquired in places
463      * where the window manager is calling in with its own lock held.)
464      */
465     private final Object mLock = new Object();
466 
467     /** List of {@link ScreenOnListener}s which do not belong to the default display. */
468     private final SparseArray<ScreenOnListener> mScreenOnListeners = new SparseArray<>();
469 
470     Context mContext;
471     WindowManagerFuncs mWindowManagerFuncs;
472     WindowManagerInternal mWindowManagerInternal;
473     PowerManager mPowerManager;
474     ActivityManagerInternal mActivityManagerInternal;
475     IActivityManager mActivityManagerService;
476     ActivityTaskManagerInternal mActivityTaskManagerInternal;
477     AutofillManagerInternal mAutofillManagerInternal;
478     InputManager mInputManager;
479     InputManagerInternal mInputManagerInternal;
480     DreamManagerInternal mDreamManagerInternal;
481     PowerManagerInternal mPowerManagerInternal;
482     IStatusBarService mStatusBarService;
483     StatusBarManagerInternal mStatusBarManagerInternal;
484     AudioManagerInternal mAudioManagerInternal;
485     SensorPrivacyManager mSensorPrivacyManager;
486     DisplayManager mDisplayManager;
487     DisplayManagerInternal mDisplayManagerInternal;
488     UserManagerInternal mUserManagerInternal;
489     DockObserverInternal mDockObserverInternal;
490 
491     private WallpaperManagerInternal mWallpaperManagerInternal;
492 
493     boolean mPreloadedRecentApps;
494     final Object mServiceAcquireLock = new Object();
495     Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
496     AccessibilityManager mAccessibilityManager;
497     AccessibilityManagerInternal mAccessibilityManagerInternal;
498     BurnInProtectionHelper mBurnInProtectionHelper;
499     private DisplayFoldController mDisplayFoldController;
500     AppOpsManager mAppOpsManager;
501     PackageManager mPackageManager;
502     SideFpsEventHandler mSideFpsEventHandler;
503     LockPatternUtils mLockPatternUtils;
504     private boolean mHasFeatureAuto;
505     private boolean mHasFeatureWatch;
506     private boolean mHasFeatureLeanback;
507     private boolean mHasFeatureHdmiCec;
508 
509     // Assigned on main thread, accessed on UI thread
510     volatile VrManagerInternal mVrManagerInternal;
511 
512     /** If true, can use a keyboard shortcut to trigger a bugreport. */
513     boolean mEnableBugReportKeyboardShortcut = false;
514 
515     /** Controller that supports enabling an AccessibilityService by holding down the volume keys */
516     private AccessibilityShortcutController mAccessibilityShortcutController;
517 
518     private TalkbackShortcutController mTalkbackShortcutController;
519 
520     private VoiceAccessShortcutController mVoiceAccessShortcutController;
521 
522     private WindowWakeUpPolicy mWindowWakeUpPolicy;
523 
524     boolean mSafeMode;
525 
526     // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
527     // This is for car dock and this is updated from resource.
528     private boolean mEnableCarDockHomeCapture = true;
529 
530     boolean mBootMessageNeedsHiding;
531     volatile boolean mBootAnimationDismissable;
532     @VisibleForTesting KeyguardServiceDelegate mKeyguardDelegate;
533     private boolean mKeyguardBound;
534     final DrawnListener mKeyguardDrawnCallback = new DrawnListener() {
535         @Override
536         public void onDrawn() {
537             if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn.");
538             mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
539         }
540     };
541 
542     private Supplier<GlobalActions> mGlobalActionsFactory;
543     private GlobalActions mGlobalActions;
544     private Handler mHandler;
545 
546     // FIXME This state is shared between the input reader and handler thread.
547     // Technically it's broken and buggy but it has been like this for many years
548     // and we have not yet seen any problems.  Someday we'll rewrite this logic
549     // so that only one thread is involved in handling input policy.  Unfortunately
550     // it's on a critical path for power management so we can't just post the work to the
551     // handler thread.  We'll need to resolve this someday by teaching the input dispatcher
552     // to hold wakelocks during dispatch and eliminating the critical path.
553     volatile boolean mPowerKeyHandled;
554     volatile boolean mBackKeyHandled;
555     volatile boolean mEndCallKeyHandled;
556     volatile boolean mPowerButtonLaunchGestureTriggered;
557     volatile boolean mPowerButtonLaunchGestureTriggeredDuringGoingToSleep;
558 
559     /**
560      * {@code true} if the device is entering a low-power state; {@code false otherwise}.
561      *
562      * <p>This differs from {@link #mRequestedOrSleepingDefaultDisplay} which tracks the power state
563      * of the {@link #mDefaultDisplay default display} versus the power state of the entire device.
564      */
565     volatile boolean mDeviceGoingToSleep;
566 
567     /**
568      * {@code true} if the {@link #mDefaultDisplay default display} is entering or was requested to
569      * enter a low-power state; {@code false otherwise}.
570      *
571      * <p>This differs from {@link #mDeviceGoingToSleep} which tracks the power state of the entire
572      * device versus the power state of the {@link #mDefaultDisplay default display}.
573      */
574     // TODO(b/178103325): Track sleep/requested sleep for every display.
575     volatile boolean mRequestedOrSleepingDefaultDisplay;
576 
577     /**
578      * This is used to check whether to acquire screen-off sleep token when screen is
579      * turned off. E.g. if it is false when screen is turned off and the display is swapping, it
580      * is expected that the screen will be on in a short time. Then it is unnecessary to acquire
581      * screen-off-sleep-token, so it can avoid intermediate visibility or lifecycle changes.
582      */
583     volatile boolean mIsGoingToSleepDefaultDisplay;
584 
585     volatile boolean mRecentsVisible;
586     volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled = true;
587     volatile boolean mPictureInPictureVisible;
588     volatile private boolean mDismissImeOnBackKeyPressed;
589 
590     // Used to hold the last user key used to wake the device.  This helps us prevent up events
591     // from being passed to the foregrounded app without a corresponding down event
592     volatile int mPendingWakeKey = PENDING_KEY_NULL;
593 
594     int mRecentAppsHeldModifiers;
595 
596     int mCameraLensCoverState = CAMERA_LENS_COVER_ABSENT;
597     boolean mHaveBuiltInKeyboard;
598 
599     boolean mSystemReady;
600     boolean mSystemBooted;
601     HdmiControl mHdmiControl;
602     IUiModeManager mUiModeManager;
603     int mUiMode;
604 
605     boolean mWakeGestureEnabledSetting;
606     MyWakeGestureListener mWakeGestureListener;
607 
608     int mLidKeyboardAccessibility;
609     int mLidNavigationAccessibility;
610     int mShortPressOnPowerBehavior;
611     private boolean mShouldEarlyShortPressOnPower;
612     boolean mShouldEarlyShortPressOnStemPrimary;
613     int mLongPressOnPowerBehavior;
614     long mLongPressOnPowerAssistantTimeoutMs;
615     int mVeryLongPressOnPowerBehavior;
616     int mDoublePressOnPowerBehavior;
617     ComponentName mPowerDoublePressTargetActivity;
618     int mTriplePressOnPowerBehavior;
619     int mLongPressOnBackBehavior;
620     int mShortPressOnSleepBehavior;
621     int mShortPressOnWindowBehavior;
622     int mPowerVolUpBehavior;
623     boolean mStylusButtonsEnabled = true;
624     boolean mKidsModeEnabled;
625     boolean mHasSoftInput = false;
626     boolean mUseTvRouting;
627     boolean mAllowStartActivityForLongPressOnPowerDuringSetup;
628     MetricsLogger mLogger;
629     boolean mWakeOnDpadKeyPress;
630     boolean mWakeOnAssistKeyPress;
631     boolean mWakeOnBackKeyPress;
632     boolean mSilenceRingerOnSleepKey;
633     long mWakeUpToLastStateTimeout;
634     int mSearchKeyBehavior;
635     ComponentName mSearchKeyTargetActivity;
636 
637     // Key Behavior - Stem Primary
638     private int mShortPressOnStemPrimaryBehavior;
639     private int mDoublePressOnStemPrimaryBehavior;
640     private int mTriplePressOnStemPrimaryBehavior;
641     private int mLongPressOnStemPrimaryBehavior;
642     private RecentTaskInfo mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp;
643 
644     // The focused task at the time when the first STEM_PRIMARY key was released. This can only
645     // be accessed from the looper thread.
646     private RootTaskInfo mFocusedTaskInfoOnStemPrimarySingleKeyUp;
647 
648     private boolean mHandleVolumeKeysInWM;
649 
650     private boolean mPendingKeyguardOccluded;
651     private boolean mKeyguardOccludedChanged;
652 
653     Intent mHomeIntent;
654     Intent mCarDockIntent;
655     Intent mDeskDockIntent;
656     Intent mVrHeadsetHomeIntent;
657     boolean mPendingMetaAction;
658     boolean mPendingCapsLockToggle;
659 
660     // support for activating the lock screen while the screen is on
661     private HashSet<Integer> mAllowLockscreenWhenOnDisplays = new HashSet<>();
662     int mLockScreenTimeout;
663     boolean mLockScreenTimerActive;
664 
665     // Behavior of ENDCALL Button.  (See Settings.System.END_BUTTON_BEHAVIOR.)
666     int mEndcallBehavior;
667 
668     // Behavior of POWER button while in-call and screen on.
669     // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.)
670     int mIncallPowerBehavior;
671 
672     // Behavior of Back button while in-call and screen on
673     int mIncallBackBehavior;
674 
675     // Whether system navigation keys are enabled
676     boolean mSystemNavigationKeysEnabled;
677 
678     // TODO(b/111361251): Remove default when the dependencies are multi-display ready.
679     Display mDefaultDisplay;
680     DisplayRotation mDefaultDisplayRotation;
681     DisplayPolicy mDefaultDisplayPolicy;
682 
683     // What we do when the user long presses on home
684     int mLongPressOnHomeBehavior;
685 
686     // What we do when the user double-taps on home
687     int mDoubleTapOnHomeBehavior;
688 
689     // What we do when the user presses the settings key
690     int mSettingsKeyBehavior;
691 
692     // Must match config_primaryShortPressTargetActivity in config.xml
693     ComponentName mPrimaryShortPressTargetActivity;
694 
695     // Whether to lock the device after the next dreaming transition has finished.
696     private boolean mLockAfterDreamingTransitionFinished;
697 
698     // If true, the power button long press behavior will be invoked even if the default display is
699     // non-interactive. If false, the power button long press behavior will be skipped if the
700     // default display is non-interactive.
701     private boolean mSupportLongPressPowerWhenNonInteractive;
702 
703     // If true, the power button short press behavior will be always invoked as long as the default
704     // display is on, even if the display is not interactive. If false, the power button short press
705     // behavior will be skipped if the default display is non-interactive.
706     private boolean mSupportShortPressPowerWhenDefaultDisplayOn;
707 
708     // Whether to go to sleep entering theater mode from power button
709     private boolean mGoToSleepOnButtonPressTheaterMode;
710 
711     // Screenshot trigger states
712     // Increase the chord delay when taking a screenshot from the keyguard
713     private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f;
714 
715     // Ringer toggle should reuse timing and triggering from screenshot power and a11y vol up
716     int mRingerToggleChord = VOLUME_HUSH_OFF;
717 
718     private static final long BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS = 1000;
719 
720     /* The number of steps between min and max brightness */
721     private static final int BRIGHTNESS_STEPS = 10;
722 
723     SettingsObserver mSettingsObserver;
724     ModifierShortcutManager mModifierShortcutManager;
725     /** Currently fully consumed key codes per device */
726     private final SparseArray<Set<Integer>> mConsumedKeysForDevice = new SparseArray<>();
727     PowerManager.WakeLock mBroadcastWakeLock;
728     PowerManager.WakeLock mPowerKeyWakeLock;
729     boolean mHavePendingMediaKeyRepeatWithWakeLock;
730 
731     private int mCurrentUserId;
732 
733     // Maps global key codes to the components that will handle them.
734     private GlobalKeyManager mGlobalKeyManager;
735 
736     private final com.android.internal.policy.LogDecelerateInterpolator mLogDecelerateInterpolator
737             = new LogDecelerateInterpolator(100, 0);
738     private final DeferredKeyActionExecutor mDeferredKeyActionExecutor =
739             new DeferredKeyActionExecutor();
740 
741     private volatile int mTopFocusedDisplayId = INVALID_DISPLAY;
742 
743     private int mPowerButtonSuppressionDelayMillis = POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS;
744 
745     private KeyCombinationManager mKeyCombinationManager;
746     private SingleKeyGestureDetector mSingleKeyGestureDetector;
747     private GestureLauncherService mGestureLauncherService;
748     private ButtonOverridePermissionChecker mButtonOverridePermissionChecker;
749 
750     private boolean mLockNowPending = false;
751 
752     // Timeout for showing the keyguard after the screen is on, in case no "ready" is received.
753     private int mKeyguardDrawnTimeout = 1000;
754 
755     private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();
756 
757     private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
758     private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
759     private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
760     private static final int MSG_KEYGUARD_DRAWN_TIMEOUT = 6;
761     private static final int MSG_WINDOW_MANAGER_DRAWN_COMPLETE = 7;
762     private static final int MSG_DISPATCH_SHOW_RECENTS = 9;
763     private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10;
764     private static final int MSG_HIDE_BOOT_MESSAGE = 11;
765     private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12;
766     private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 15;
767     private static final int MSG_SCREENSHOT_CHORD = 16;
768     private static final int MSG_ACCESSIBILITY_SHORTCUT = 17;
769     private static final int MSG_BUGREPORT_TV = 18;
770     private static final int MSG_ACCESSIBILITY_TV = 19;
771     private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 20;
772     private static final int MSG_SYSTEM_KEY_PRESS = 21;
773     private static final int MSG_HANDLE_ALL_APPS = 22;
774     private static final int MSG_LAUNCH_ASSIST = 23;
775     private static final int MSG_RINGER_TOGGLE_CHORD = 24;
776     private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 25;
777     private static final int MSG_SET_DEFERRED_KEY_ACTIONS_EXECUTABLE = 27;
778 
779     private class PolicyHandler extends Handler {
780 
PolicyHandler(Looper looper)781         private PolicyHandler(Looper looper) {
782             super(looper);
783         }
784 
785         @Override
handleMessage(Message msg)786         public void handleMessage(Message msg) {
787             switch (msg.what) {
788                 case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK:
789                     dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj);
790                     break;
791                 case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
792                     dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
793                     break;
794                 case MSG_DISPATCH_SHOW_RECENTS:
795                     showRecentApps(false);
796                     break;
797                 case MSG_DISPATCH_SHOW_GLOBAL_ACTIONS:
798                     showGlobalActionsInternal();
799                     break;
800                 case MSG_KEYGUARD_DRAWN_COMPLETE:
801                     if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
802                     finishKeyguardDrawn();
803                     break;
804                 case MSG_KEYGUARD_DRAWN_TIMEOUT:
805                     Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
806                     finishKeyguardDrawn();
807                     break;
808                 case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
809                     final int displayId = msg.arg1;
810                     if (DEBUG_WAKEUP) Slog.w(TAG, "All windows drawn on display " + displayId);
811                     Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER,
812                             TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD, displayId /* cookie */);
813                     finishWindowsDrawn(displayId);
814                     break;
815                 case MSG_HIDE_BOOT_MESSAGE:
816                     handleHideBootMessage();
817                     break;
818                 case MSG_LAUNCH_ASSIST:
819                     final int deviceId = msg.arg1;
820                     final Long eventTime = (Long) msg.obj;
821                     launchAssistAction(null /* hint */, deviceId, eventTime,
822                             AssistUtils.INVOCATION_TYPE_ASSIST_BUTTON);
823                     break;
824                 case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK:
825                     launchVoiceAssistWithWakeLock();
826                     break;
827                 case MSG_SHOW_PICTURE_IN_PICTURE_MENU:
828                     showPictureInPictureMenuInternal();
829                     break;
830                 case MSG_ACCESSIBILITY_SHORTCUT:
831                     accessibilityShortcutActivated();
832                     break;
833                 case MSG_BUGREPORT_TV:
834                     requestBugreportForTv();
835                     break;
836                 case MSG_ACCESSIBILITY_TV:
837                     if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false)) {
838                         accessibilityShortcutActivated();
839                     }
840                     break;
841                 case MSG_DISPATCH_BACK_KEY_TO_AUTOFILL:
842                     mAutofillManagerInternal.onBackKeyPressed();
843                     break;
844                 case MSG_SYSTEM_KEY_PRESS:
845                     KeyEvent event = (KeyEvent) msg.obj;
846                     sendSystemKeyToStatusBar(event);
847                     event.recycle();
848                     break;
849                 case MSG_HANDLE_ALL_APPS:
850                     KeyEvent keyEvent = (KeyEvent) msg.obj;
851                     if (isKeyEventForCurrentUser(keyEvent.getDisplayId(), keyEvent.getKeyCode(),
852                             "launchAllAppsViaA11y")) {
853                         launchAllAppsAction();
854                     }
855                     break;
856                 case MSG_RINGER_TOGGLE_CHORD:
857                     handleRingerChordGesture();
858                     break;
859                 case MSG_SCREENSHOT_CHORD:
860                     handleScreenShot(msg.arg1);
861                     break;
862                 case MSG_SWITCH_KEYBOARD_LAYOUT:
863                     SwitchKeyboardLayoutMessageObject object =
864                             (SwitchKeyboardLayoutMessageObject) msg.obj;
865                     handleSwitchKeyboardLayout(object.displayId, object.direction,
866                             object.focusedToken);
867                     break;
868                 case MSG_SET_DEFERRED_KEY_ACTIONS_EXECUTABLE:
869                     final int keyCode = msg.arg1;
870                     final long downTime = (Long) msg.obj;
871                     mDeferredKeyActionExecutor.setActionsExecutable(keyCode, downTime);
872                     break;
873             }
874         }
875     }
876 
877     private UEventObserver mHDMIObserver = new UEventObserver() {
878         @Override
879         public void onUEvent(UEventObserver.UEvent event) {
880             mDefaultDisplayPolicy.setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
881         }
882     };
883 
884     class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler)885         SettingsObserver(Handler handler) {
886             super(handler);
887         }
888 
observe()889         void observe() {
890             // Observe all users' changes
891             ContentResolver resolver = mContext.getContentResolver();
892             resolver.registerContentObserver(Settings.System.getUriFor(
893                     Settings.System.END_BUTTON_BEHAVIOR), false, this,
894                     UserHandle.USER_ALL);
895             resolver.registerContentObserver(Settings.Secure.getUriFor(
896                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this,
897                     UserHandle.USER_ALL);
898             resolver.registerContentObserver(Settings.Secure.getUriFor(
899                     Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR), false, this,
900                     UserHandle.USER_ALL);
901             resolver.registerContentObserver(Settings.Secure.getUriFor(
902                     Settings.Secure.WAKE_GESTURE_ENABLED), false, this,
903                     UserHandle.USER_ALL);
904             resolver.registerContentObserver(Settings.System.getUriFor(
905                     Settings.System.SCREEN_OFF_TIMEOUT), false, this,
906                     UserHandle.USER_ALL);
907             resolver.registerContentObserver(Settings.Secure.getUriFor(
908                     Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
909                     UserHandle.USER_ALL);
910             resolver.registerContentObserver(Settings.Secure.getUriFor(
911                     Settings.Secure.VOLUME_HUSH_GESTURE), false, this,
912                     UserHandle.USER_ALL);
913             resolver.registerContentObserver(Settings.Secure.getUriFor(
914                     Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED), false, this,
915                     UserHandle.USER_ALL);
916             resolver.registerContentObserver(Settings.Global.getUriFor(
917                     Settings.Global.POWER_BUTTON_SHORT_PRESS), false, this,
918                     UserHandle.USER_ALL);
919             resolver.registerContentObserver(Settings.Global.getUriFor(
920                     Settings.Global.POWER_BUTTON_DOUBLE_PRESS), false, this,
921                     UserHandle.USER_ALL);
922             resolver.registerContentObserver(Settings.Global.getUriFor(
923                     Settings.Global.POWER_BUTTON_TRIPLE_PRESS), false, this,
924                     UserHandle.USER_ALL);
925             resolver.registerContentObserver(Settings.Global.getUriFor(
926                     Settings.Global.POWER_BUTTON_LONG_PRESS), false, this,
927                     UserHandle.USER_ALL);
928             resolver.registerContentObserver(Settings.Global.getUriFor(
929                     Settings.Global.POWER_BUTTON_LONG_PRESS_DURATION_MS), false, this,
930                     UserHandle.USER_ALL);
931             resolver.registerContentObserver(Settings.Global.getUriFor(
932                     Settings.Global.POWER_BUTTON_VERY_LONG_PRESS), false, this,
933                     UserHandle.USER_ALL);
934             resolver.registerContentObserver(Settings.Global.getUriFor(
935                     Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS), false, this,
936                     UserHandle.USER_ALL);
937             resolver.registerContentObserver(Settings.Global.getUriFor(
938                     Settings.Global.STEM_PRIMARY_BUTTON_DOUBLE_PRESS), false, this,
939                     UserHandle.USER_ALL);
940             resolver.registerContentObserver(Settings.Global.getUriFor(
941                     Settings.Global.STEM_PRIMARY_BUTTON_TRIPLE_PRESS), false, this,
942                     UserHandle.USER_ALL);
943             resolver.registerContentObserver(Settings.Global.getUriFor(
944                     Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS), false, this,
945                     UserHandle.USER_ALL);
946             resolver.registerContentObserver(Settings.Global.getUriFor(
947                     Settings.Global.KEY_CHORD_POWER_VOLUME_UP), false, this,
948                     UserHandle.USER_ALL);
949             resolver.registerContentObserver(Settings.Global.getUriFor(
950                     Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE), false, this,
951                     UserHandle.USER_ALL);
952             resolver.registerContentObserver(Settings.Secure.getUriFor(
953                     Settings.Secure.STYLUS_BUTTONS_ENABLED), false, this,
954                     UserHandle.USER_ALL);
955             resolver.registerContentObserver(Settings.Secure.getUriFor(
956                     Settings.Secure.NAV_BAR_KIDS_MODE), false, this,
957                     UserHandle.USER_ALL);
958             updateSettings();
959         }
960 
onChange(boolean selfChange)961         @Override public void onChange(boolean selfChange) {
962             updateSettings();
963         }
964     }
965 
966     class MyWakeGestureListener extends WakeGestureListener {
MyWakeGestureListener(Context context, Handler handler)967         MyWakeGestureListener(Context context, Handler handler) {
968             super(context, handler);
969         }
970 
971         @Override
onWakeUp()972         public void onWakeUp() {
973             synchronized (mLock) {
974                 if (shouldEnableWakeGestureLp()) {
975                     performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, "Wake Up");
976                     mWindowWakeUpPolicy.wakeUpFromWakeGesture();
977                 }
978             }
979         }
980     }
981 
SwitchKeyboardLayoutMessageObject(int displayId, IBinder focusedToken, int direction)982     private record SwitchKeyboardLayoutMessageObject(int displayId, IBinder focusedToken,
983                                                      int direction) {
984     }
985 
986     final IPersistentVrStateCallbacks mPersistentVrModeListener =
987             new IPersistentVrStateCallbacks.Stub() {
988         @Override
989         public void onPersistentVrStateChanged(boolean enabled) {
990             mDefaultDisplayPolicy.setPersistentVrModeEnabled(enabled);
991         }
992     };
993 
handleRingerChordGesture()994     private void handleRingerChordGesture() {
995         if (mRingerToggleChord == VOLUME_HUSH_OFF) {
996             return;
997         }
998         getAudioManagerInternal();
999         mAudioManagerInternal.silenceRingerModeInternal("volume_hush");
1000         Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.HUSH_GESTURE_USED, 1);
1001         mLogger.action(MetricsProto.MetricsEvent.ACTION_HUSH_GESTURE, mRingerToggleChord);
1002     }
1003 
getStatusBarService()1004     IStatusBarService getStatusBarService() {
1005         synchronized (mServiceAcquireLock) {
1006             if (mStatusBarService == null) {
1007                 mStatusBarService = IStatusBarService.Stub.asInterface(
1008                         ServiceManager.getService("statusbar"));
1009             }
1010             return mStatusBarService;
1011         }
1012     }
1013 
getStatusBarManagerInternal()1014     StatusBarManagerInternal getStatusBarManagerInternal() {
1015         synchronized (mServiceAcquireLock) {
1016             if (mStatusBarManagerInternal == null) {
1017                 mStatusBarManagerInternal =
1018                         LocalServices.getService(StatusBarManagerInternal.class);
1019             }
1020             return mStatusBarManagerInternal;
1021         }
1022     }
1023 
getAudioManagerInternal()1024     AudioManagerInternal getAudioManagerInternal() {
1025         synchronized (mServiceAcquireLock) {
1026             if (mAudioManagerInternal == null) {
1027                 mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
1028             }
1029             return mAudioManagerInternal;
1030         }
1031     }
1032 
getAccessibilityManagerInternal()1033     AccessibilityManagerInternal getAccessibilityManagerInternal() {
1034         synchronized (mServiceAcquireLock) {
1035             if (mAccessibilityManagerInternal == null) {
1036                 mAccessibilityManagerInternal =
1037                         LocalServices.getService(AccessibilityManagerInternal.class);
1038             }
1039             return mAccessibilityManagerInternal;
1040         }
1041     }
1042 
1043     // returns true if the key was handled and should not be passed to the user
backKeyPress()1044     private boolean backKeyPress() {
1045         mLogger.count("key_back_press", 1);
1046         // Cache handled state
1047         boolean handled = mBackKeyHandled;
1048 
1049         if (mHasFeatureWatch) {
1050             TelecomManager telecomManager = getTelecommService();
1051 
1052             if (telecomManager != null) {
1053                 if (telecomManager.isRinging()) {
1054                     // Pressing back while there's a ringing incoming
1055                     // call should silence the ringer.
1056                     telecomManager.silenceRinger();
1057 
1058                     // It should not prevent navigating away
1059                     return false;
1060                 } else if (
1061                     (mIncallBackBehavior & Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_HANGUP) != 0
1062                         && telecomManager.isInCall()) {
1063                     // Otherwise, if "Back button ends call" is enabled,
1064                     // the Back button will hang up any current active call.
1065                     return telecomManager.endCall();
1066                 }
1067             }
1068         }
1069 
1070         if (mAutofillManagerInternal != null) {
1071             mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_BACK_KEY_TO_AUTOFILL));
1072         }
1073         return handled;
1074     }
1075 
interceptPowerKeyDown(KeyEvent event, boolean interactive, boolean isKeyGestureTriggered)1076     private void interceptPowerKeyDown(KeyEvent event, boolean interactive,
1077             boolean isKeyGestureTriggered) {
1078         // Hold a wake lock until the power key is released.
1079         if (!mPowerKeyWakeLock.isHeld()) {
1080             mPowerKeyWakeLock.acquire();
1081         }
1082 
1083         mWindowManagerFuncs.onPowerKeyDown(interactive);
1084 
1085         // Stop ringing or end call if configured to do so when power is pressed.
1086         TelecomManager telecomManager = getTelecommService();
1087         boolean hungUp = false;
1088         if (telecomManager != null) {
1089             if (telecomManager.isRinging()) {
1090                 // Pressing Power while there's a ringing incoming
1091                 // call should silence the ringer.
1092                 telecomManager.silenceRinger();
1093             } else if ((mIncallPowerBehavior
1094                     & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
1095                     && telecomManager.isInCall() && interactive) {
1096                 // Otherwise, if "Power button ends call" is enabled,
1097                 // the Power button will hang up any current active call.
1098                 hungUp = telecomManager.endCall();
1099             }
1100         }
1101 
1102         final boolean handledByPowerManager = mPowerManagerInternal.interceptPowerKeyDown(event);
1103 
1104         // Inform the StatusBar; but do not allow it to consume the event.
1105         sendSystemKeyToStatusBarAsync(event);
1106 
1107         // If the power key has still not yet been handled, then detect short
1108         // press, long press, or multi press and decide what to do.
1109         mPowerKeyHandled = mPowerKeyHandled || hungUp
1110                 || handledByPowerManager || isKeyGestureTriggered
1111                 || mKeyCombinationManager.isPowerKeyIntercepted();
1112 
1113         if (!mPowerKeyHandled) {
1114             if (!interactive) {
1115                 wakeUpFromWakeKey(event);
1116             }
1117         } else {
1118             // handled by another power key policy.
1119             if (mSingleKeyGestureDetector.isKeyIntercepted(KEYCODE_POWER)) {
1120                 Slog.d(TAG, "Skip power key gesture for other policy has handled it.");
1121                 mSingleKeyGestureDetector.reset();
1122             }
1123         }
1124     }
1125 
interceptPowerKeyUp(KeyEvent event, boolean canceled)1126     private void interceptPowerKeyUp(KeyEvent event, boolean canceled) {
1127         // Inform the StatusBar; but do not allow it to consume the event.
1128         sendSystemKeyToStatusBarAsync(event);
1129         finishPowerKeyPress();
1130     }
1131 
finishPowerKeyPress()1132     private void finishPowerKeyPress() {
1133         mPowerKeyHandled = false;
1134         if (mPowerKeyWakeLock.isHeld()) {
1135             mPowerKeyWakeLock.release();
1136         }
1137     }
1138 
1139     @VisibleForTesting
powerPress(long eventTime, int count, int displayId)1140     void powerPress(long eventTime, int count, int displayId) {
1141         // SideFPS still needs to know about suppressed power buttons, in case it needs to block
1142         // an auth attempt.
1143         if (count == 1) {
1144             mSideFpsEventHandler.notifyPowerPressed();
1145         }
1146         if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
1147             Slog.i(TAG, "Suppressed redundant power key press while "
1148                     + "already in the process of turning the screen on.");
1149             return;
1150         }
1151 
1152         final boolean interactive = mDefaultDisplayPolicy.isAwake();
1153 
1154         Slog.d(
1155                 TAG,
1156                 "powerPress: eventTime="
1157                         + eventTime
1158                         + " interactive="
1159                         + interactive
1160                         + " count="
1161                         + count
1162                         + " mShortPressOnPowerBehavior="
1163                         + mShortPressOnPowerBehavior);
1164 
1165         if (count == 2) {
1166             powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
1167         } else if (count == 3) {
1168             powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
1169         } else if (count > 3 && count <= getMaxMultiPressPowerCount()) {
1170             Slog.d(TAG, "No behavior defined for power press count " + count);
1171         } else if (count == 1 && shouldHandleShortPressPowerAction(interactive, eventTime)) {
1172             switch (mShortPressOnPowerBehavior) {
1173                 case SHORT_PRESS_POWER_NOTHING:
1174                     break;
1175                 case SHORT_PRESS_POWER_GO_TO_SLEEP:
1176                     sleepDefaultDisplayFromPowerButton(eventTime, 0);
1177                     break;
1178                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
1179                     sleepDefaultDisplayFromPowerButton(eventTime,
1180                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
1181                     break;
1182                 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
1183                     if (sleepDefaultDisplayFromPowerButton(eventTime,
1184                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE)) {
1185                         launchHomeFromHotKey(DEFAULT_DISPLAY);
1186                     }
1187                     break;
1188                 case SHORT_PRESS_POWER_GO_HOME:
1189                     shortPressPowerGoHome();
1190                     break;
1191                 case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: {
1192                     if (mDismissImeOnBackKeyPressed) {
1193                         InputMethodManagerInternal.get().hideInputMethod(
1194                                 SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, displayId);
1195                     } else {
1196                         shortPressPowerGoHome();
1197                     }
1198                     break;
1199                 }
1200                 case SHORT_PRESS_POWER_LOCK_OR_SLEEP: {
1201                     if (mKeyguardDelegate == null || !mKeyguardDelegate.hasKeyguard()
1202                             || !mKeyguardDelegate.isSecure(mCurrentUserId) || keyguardOn()) {
1203                         sleepDefaultDisplayFromPowerButton(eventTime, 0);
1204                     } else {
1205                         lockNow(null /*options*/);
1206                     }
1207                     break;
1208                 }
1209                 case SHORT_PRESS_POWER_DREAM_OR_SLEEP: {
1210                     attemptToDreamOrAwakeFromShortPowerButtonPress(
1211                             /* isScreenOn */ true,
1212                             /* awakeWhenDream */ false,
1213                             /* noDreamAction */
1214                             () -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
1215                     break;
1216                 }
1217                 case SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP: {
1218                     // With this power button behavior, the following behavior is expected from each
1219                     // system space on a power button short press:
1220                     // - Unlocked: go to hub if available, dream if not, screen off if neither
1221                     // - Lock screen, hub, or dream: go to screen off
1222                     // - Screen off: go to hub if available, dream if not, lock screen if enabled,
1223                     //               unlocked if lockscreen is disabled
1224                     // TODO(b/394657933): consolidate policy into SysUI
1225                     final boolean hubEnabled = Settings.Secure.getIntForUser(
1226                             mContext.getContentResolver(), Settings.Secure.GLANCEABLE_HUB_ENABLED,
1227                             1, mCurrentUserId) == 1;
1228 
1229                     final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
1230                     if (dreamManagerInternal == null) {
1231                         break;
1232                     }
1233 
1234                     if (dreamManagerInternal.isDreaming() || isKeyguardShowing()) {
1235                         // If the device is already dreaming or on keyguard, go to sleep.
1236                         sleepDefaultDisplayFromPowerButton(eventTime, 0);
1237                         break;
1238                     }
1239 
1240                     // Check isLockScreenDisabled to exclude NONE lock screen option, which cannot
1241                     // show hub.
1242                     boolean keyguardAvailable = !mLockPatternUtils.isLockScreenDisabled(
1243                             mCurrentUserId);
1244                     if (mUserManagerInternal.isUserUnlocked(mCurrentUserId) && hubEnabled
1245                             && keyguardAvailable && dreamManagerInternal.dreamConditionActive()) {
1246                         // If the hub can be launched, send a message to keyguard.
1247                         Bundle options = new Bundle();
1248                         options.putBoolean(EXTRA_TRIGGER_HUB, true);
1249                         lockNow(options);
1250                     } else {
1251                         // If the hub cannot be run, attempt to dream instead.
1252                         attemptToDreamOrAwakeFromShortPowerButtonPress(
1253                                 /* isScreenOn */ true,
1254                                 /* awakeWhenDream */ false,
1255                                 /* noDreamAction */
1256                                 () -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
1257                     }
1258                     break;
1259                 }
1260                 case SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP: {
1261                     attemptToDreamOrAwakeFromShortPowerButtonPress(
1262                             /* isScreenOn */ true,
1263                             /* awakeWhenDream */ true,
1264                             /* noDreamAction */
1265                             () -> sleepDefaultDisplayFromPowerButton(eventTime, 0));
1266                     break;
1267                 }
1268             }
1269         }
1270     }
1271 
shouldHandleShortPressPowerAction(boolean interactive, long eventTime)1272     private boolean shouldHandleShortPressPowerAction(boolean interactive, long eventTime) {
1273         if (mSupportShortPressPowerWhenDefaultDisplayOn) {
1274             final boolean defaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
1275             final boolean beganFromDefaultDisplayOn =
1276                     mSingleKeyGestureDetector.beganFromDefaultDisplayOn();
1277             if (!defaultDisplayOn || !beganFromDefaultDisplayOn) {
1278                 Slog.v(
1279                         TAG,
1280                         "Ignoring short press of power button because the default display is not"
1281                                 + " on. defaultDisplayOn="
1282                                 + defaultDisplayOn
1283                                 + ", beganFromDefaultDisplayOn="
1284                                 + beganFromDefaultDisplayOn);
1285                 return false;
1286             }
1287             return true;
1288         }
1289         final boolean beganFromNonInteractive = mSingleKeyGestureDetector.beganFromNonInteractive();
1290         if (!interactive || beganFromNonInteractive) {
1291             Slog.v(
1292                     TAG,
1293                     "Ignoring short press of power button because the device is not interactive."
1294                             + " interactive="
1295                             + interactive
1296                             + ", beganFromNonInteractive="
1297                             + beganFromNonInteractive);
1298             return false;
1299         }
1300         if (mSideFpsEventHandler.shouldConsumeSinglePress(eventTime)) {
1301             Slog.i(
1302                     TAG,
1303                     "Suppressing power key because the user is interacting with the "
1304                             + "fingerprint sensor");
1305             return false;
1306         }
1307         return true;
1308     }
1309 
1310     /**
1311      * Attempt to dream, awake or sleep from a power button press.
1312      *
1313      * @param isScreenOn Whether the screen is currently on.
1314      * @param awakeWhenDream When it's set to {@code true}, awake the device from dreaming.
1315      *        Otherwise, go to sleep.
1316      * @param noDreamAction The action to perform if dreaming is not possible.
1317      */
attemptToDreamOrAwakeFromShortPowerButtonPress( boolean isScreenOn, boolean awakeWhenDream, Runnable noDreamAction)1318     private void attemptToDreamOrAwakeFromShortPowerButtonPress(
1319             boolean isScreenOn, boolean awakeWhenDream, Runnable noDreamAction) {
1320         if (mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_SLEEP
1321                 && mShortPressOnPowerBehavior != SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP
1322                 && mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP) {
1323             // If the power button behavior isn't one that should be able to trigger the dream, give
1324             // up.
1325             noDreamAction.run();
1326             return;
1327         }
1328 
1329         final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
1330         if (dreamManagerInternal == null) {
1331             Slog.d(TAG,
1332                     "Can't access dream manager dreaming when attempting to start or stop dream "
1333                     + "from short power press (isScreenOn="
1334                             + isScreenOn + ", awakeWhenDream=" + awakeWhenDream + ")");
1335             noDreamAction.run();
1336             return;
1337         }
1338 
1339         if (!dreamManagerInternal.canStartDreaming(isScreenOn)) {
1340             if (awakeWhenDream && dreamManagerInternal.isDreaming()) {
1341                 dreamManagerInternal.stopDream(false /*immediate*/, "short press power" /*reason*/);
1342                 return;
1343             }
1344             Slog.d(TAG,
1345                     "Can't start dreaming and the device is not dreaming when attempting to start "
1346                     + "or stop dream from short power press (isScreenOn="
1347                             + isScreenOn + ", awakeWhenDream=" + awakeWhenDream + ")");
1348             noDreamAction.run();
1349             return;
1350         }
1351 
1352         synchronized (mLock) {
1353             // If the setting to lock instantly on power button press is true, then set the flag to
1354             // lock after the dream transition has finished.
1355             mLockAfterDreamingTransitionFinished =
1356                     mLockPatternUtils.getPowerButtonInstantlyLocks(mCurrentUserId);
1357         }
1358 
1359         dreamManagerInternal.requestDream();
1360     }
1361 
1362     /**
1363      * Sends the default display to sleep as a result of a power button press.
1364      *
1365      * @return {@code true} if the device was sent to sleep, {@code false} if the device did not
1366      * sleep.
1367      */
sleepDefaultDisplayFromPowerButton(long eventTime, int flags)1368     private boolean sleepDefaultDisplayFromPowerButton(long eventTime, int flags) {
1369         // Before we actually go to sleep, we check the last wakeup reason.
1370         // If the device very recently woke up from a gesture (like user lifting their device)
1371         // then ignore the sleep instruction. This is because users have developed
1372         // a tendency to hit the power button immediately when they pick up their device, and we
1373         // don't want to put the device back to sleep in those cases.
1374         final PowerManager.WakeData lastWakeUp = mPowerManagerInternal.getLastWakeup();
1375         if (lastWakeUp != null && (lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE
1376                 || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_LIFT
1377                 || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_BIOMETRIC)) {
1378             final long now = SystemClock.uptimeMillis();
1379             if (mPowerButtonSuppressionDelayMillis > 0
1380                     && (now < lastWakeUp.wakeTime + mPowerButtonSuppressionDelayMillis)) {
1381                 Slog.i(TAG, "Sleep from power button suppressed. Time since gesture: "
1382                         + (now - lastWakeUp.wakeTime) + "ms");
1383                 return false;
1384             }
1385         }
1386 
1387         sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags);
1388         return true;
1389     }
1390 
sleepDefaultDisplay(long eventTime, int reason, int flags)1391     private void sleepDefaultDisplay(long eventTime, int reason, int flags) {
1392         mRequestedOrSleepingDefaultDisplay = true;
1393         mPowerManager.goToSleep(eventTime, reason, flags);
1394     }
1395 
shortPressPowerGoHome()1396     private void shortPressPowerGoHome() {
1397         launchHomeFromHotKey(DEFAULT_DISPLAY, true /* awakenFromDreams */,
1398                 false /*respectKeyguard*/);
1399         if (isKeyguardShowingAndNotOccluded()) {
1400             // Notify keyguard so it can do any special handling for the power button since the
1401             // device will not power off and only launch home.
1402             mKeyguardDelegate.onShortPowerPressedGoHome();
1403         }
1404     }
1405 
powerMultiPressAction(long eventTime, boolean interactive, int behavior)1406     private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) {
1407         switch (behavior) {
1408             case MULTI_PRESS_POWER_NOTHING:
1409                 break;
1410             case MULTI_PRESS_POWER_THEATER_MODE:
1411                 if (!isUserSetupComplete()) {
1412                     Slog.i(TAG, "Ignoring toggling theater mode - device not setup.");
1413                     break;
1414                 }
1415 
1416                 if (isTheaterModeEnabled()) {
1417                     Slog.i(TAG, "Toggling theater mode off.");
1418                     Settings.Global.putInt(mContext.getContentResolver(),
1419                             Settings.Global.THEATER_MODE_ON, 0);
1420                     if (!interactive) {
1421                         wakeUpFromWakeKey(eventTime, KEYCODE_POWER, /* isDown= */ false);
1422                     }
1423                 } else {
1424                     Slog.i(TAG, "Toggling theater mode on.");
1425                     Settings.Global.putInt(mContext.getContentResolver(),
1426                             Settings.Global.THEATER_MODE_ON, 1);
1427 
1428                     if (mGoToSleepOnButtonPressTheaterMode && interactive) {
1429                         sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
1430                                 0);
1431                     }
1432                 }
1433                 break;
1434             case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
1435                 Slog.i(TAG, "Starting brightness boost.");
1436                 if (!interactive) {
1437                     wakeUpFromWakeKey(eventTime, KEYCODE_POWER, /* isDown= */ false);
1438                 }
1439                 mPowerManager.boostScreenBrightness(eventTime);
1440                 break;
1441             case MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY:
1442                 launchTargetActivityOnMultiPressPower();
1443                 break;
1444         }
1445     }
1446 
launchTargetActivityOnMultiPressPower()1447     private void launchTargetActivityOnMultiPressPower() {
1448         if (DEBUG_INPUT) {
1449             Slog.d(TAG, "Executing the double press power action.");
1450         }
1451         if (mPowerDoublePressTargetActivity != null) {
1452             Intent intent = new Intent();
1453             intent.setComponent(mPowerDoublePressTargetActivity);
1454             ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(
1455                     intent, /* flags= */0);
1456             if (resolveInfo != null) {
1457                 final boolean keyguardActive =
1458                         mKeyguardDelegate != null && mKeyguardDelegate.isShowing();
1459                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
1460                         | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
1461                 if (!keyguardActive) {
1462                     startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
1463                 } else {
1464                     mKeyguardDelegate.dismissKeyguardToLaunch(intent);
1465                 }
1466             } else {
1467                 Slog.e(TAG, "Could not resolve activity with : "
1468                         + mPowerDoublePressTargetActivity.flattenToString()
1469                         + " name.");
1470             }
1471         }
1472     }
1473 
getLidBehavior()1474     private int getLidBehavior() {
1475         return Settings.Global.getInt(mContext.getContentResolver(),
1476                 Settings.Global.LID_BEHAVIOR, LID_BEHAVIOR_NONE);
1477     }
1478 
getMaxMultiPressPowerCount()1479     private int getMaxMultiPressPowerCount() {
1480         // The actual max power button press count is 5
1481         // (EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD), which is coming from
1482         // GestureLauncherService.
1483         // To speed up the handling of single-press of power button inside SingleKeyGestureDetector,
1484         // however, we limit the max count to the number of button presses actually handled by the
1485         // SingleKeyGestureDetector except for wearable devices, where we want to de-dup the double
1486         // press gesture with the emergency gesture.
1487         if (mHasFeatureWatch
1488                 && GestureLauncherService.isEmergencyGestureSettingEnabled(
1489                         mContext, ActivityManager.getCurrentUser())) {
1490             return 5;
1491         }
1492         if (mTriplePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
1493             return 3;
1494         }
1495         if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
1496             return 2;
1497         }
1498         return 1;
1499     }
1500 
powerLongPress(long eventTime)1501     private void powerLongPress(long eventTime) {
1502         final int behavior = getResolvedLongPressOnPowerBehavior();
1503         Slog.d(TAG, "powerLongPress: eventTime=" + eventTime
1504                 + " mLongPressOnPowerBehavior=" + mLongPressOnPowerBehavior);
1505 
1506         // Sending a synthetic KeyEvent to StatusBar service with flag FLAG_LONG_PRESS set, when
1507         // power button is long pressed
1508         if (enableLppSqueezeEffect()) {
1509             // Long press is detected in a callback, so there's no explicit hardware KeyEvent
1510             // available here. Instead, we create a synthetic power key event that has properties
1511             // similar to the original one.
1512             final KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KEYCODE_POWER);
1513             event.setFlags(KeyEvent.FLAG_LONG_PRESS);
1514             // setting both downTime and eventTime as same as downTime is sent as eventTime for long
1515             // press event in SingleKeyGestureDetector's handler
1516             event.setTime(eventTime, eventTime);
1517             sendSystemKeyToStatusBarAsync(event);
1518         }
1519 
1520         switch (behavior) {
1521             case LONG_PRESS_POWER_NOTHING:
1522                 break;
1523             case LONG_PRESS_POWER_GLOBAL_ACTIONS:
1524                 mPowerKeyHandled = true;
1525                 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
1526                         "Power - Long Press - Global Actions");
1527                 showGlobalActions();
1528                 break;
1529             case LONG_PRESS_POWER_SHUT_OFF:
1530             case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
1531                 mPowerKeyHandled = true;
1532                 // don't actually trigger the shutdown if we are running stability
1533                 // tests via monkey
1534                 if (ActivityManager.isUserAMonkey()) {
1535                     break;
1536                 }
1537                 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
1538                         "Power - Long Press - Shut Off");
1539                 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
1540                 mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
1541                 break;
1542             case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
1543                 mPowerKeyHandled = true;
1544                 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
1545                         "Power - Long Press - Go To Voice Assist");
1546                 // Some devices allow the voice assistant intent during setup (and use that intent
1547                 // to launch something else, like Settings). So we explicitly allow that via the
1548                 // config_allowStartActivityForLongPressOnPowerInSetup resource in config.xml.
1549                 launchVoiceAssist(mAllowStartActivityForLongPressOnPowerDuringSetup);
1550                 break;
1551             case LONG_PRESS_POWER_ASSISTANT:
1552                 mPowerKeyHandled = true;
1553                 performHapticFeedback(HapticFeedbackConstants.ASSISTANT_BUTTON,
1554                         "Power - Long Press - Go To Assistant");
1555                 final int powerKeyDeviceId = INVALID_INPUT_DEVICE_ID;
1556                 launchAssistAction(null, powerKeyDeviceId, eventTime,
1557                         AssistUtils.INVOCATION_TYPE_POWER_BUTTON_LONG_PRESS);
1558                 break;
1559         }
1560     }
1561 
powerVeryLongPress()1562     private void powerVeryLongPress() {
1563         switch (mVeryLongPressOnPowerBehavior) {
1564             case VERY_LONG_PRESS_POWER_NOTHING:
1565                 break;
1566             case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS:
1567                 mPowerKeyHandled = true;
1568                 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
1569                         "Power - Very Long Press - Show Global Actions");
1570                 showGlobalActions();
1571                 break;
1572         }
1573     }
1574 
backLongPress()1575     private void backLongPress() {
1576         mBackKeyHandled = true;
1577 
1578         switch (mLongPressOnBackBehavior) {
1579             case LONG_PRESS_BACK_NOTHING:
1580                 break;
1581             case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST:
1582                 launchVoiceAssist(false /* allowDuringSetup */);
1583                 break;
1584         }
1585     }
1586 
accessibilityShortcutActivated()1587     private void accessibilityShortcutActivated() {
1588         mAccessibilityShortcutController.performAccessibilityShortcut();
1589     }
1590 
sleepPress()1591     private void sleepPress() {
1592         if (mShortPressOnSleepBehavior == SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME) {
1593             launchHomeFromHotKey(DEFAULT_DISPLAY, false /* awakenDreams */,
1594                     true /*respectKeyguard*/);
1595         }
1596     }
1597 
sleepRelease(long eventTime)1598     private void sleepRelease(long eventTime) {
1599         if (mSilenceRingerOnSleepKey) {
1600             TelecomManager telecomManager = getTelecommService();
1601             if (telecomManager != null && telecomManager.isRinging()) {
1602                 telecomManager.silenceRinger();
1603                 Slog.i(TAG, "sleepRelease() silence ringer");
1604                 return;
1605             }
1606         }
1607 
1608         switch (mShortPressOnSleepBehavior) {
1609             case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
1610             case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
1611                 Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)");
1612                 sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0);
1613                 break;
1614         }
1615     }
1616 
getResolvedLongPressOnPowerBehavior()1617     private int getResolvedLongPressOnPowerBehavior() {
1618         if (FactoryTest.isLongPressOnPowerOffEnabled()) {
1619             return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
1620         }
1621 
1622         // If the config indicates the assistant behavior but the device isn't yet provisioned, show
1623         // global actions instead.
1624         if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_ASSISTANT && !isDeviceProvisioned()) {
1625             return LONG_PRESS_POWER_GLOBAL_ACTIONS;
1626         }
1627 
1628         // If long press to launch assistant is disabled in settings, do nothing.
1629         if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_GO_TO_VOICE_ASSIST
1630                 && !isLongPressToAssistantEnabled(mContext)) {
1631             return LONG_PRESS_POWER_NOTHING;
1632         }
1633 
1634         return mLongPressOnPowerBehavior;
1635     }
1636 
stemPrimaryPress(int count)1637     private void stemPrimaryPress(int count) {
1638         Slog.d(TAG, "stemPrimaryPress: " + count);
1639         if (count == 3) {
1640             stemPrimaryTriplePressAction(mTriplePressOnStemPrimaryBehavior);
1641         } else if (count == 2) {
1642             stemPrimaryDoublePressAction(mDoublePressOnStemPrimaryBehavior);
1643         } else if (count == 1) {
1644             stemPrimarySinglePressAction(mShortPressOnStemPrimaryBehavior);
1645         }
1646     }
1647 
stemPrimarySinglePressAction(int behavior)1648     private void stemPrimarySinglePressAction(int behavior) {
1649         Slog.d(TAG, "stemPrimarySinglePressAction: behavior=" + behavior);
1650         if (behavior == SHORT_PRESS_PRIMARY_NOTHING) return;
1651 
1652         final boolean keyguardActive = mKeyguardDelegate != null && mKeyguardDelegate.isShowing();
1653         if (keyguardActive) {
1654             // If keyguarded then notify the keyguard.
1655             mKeyguardDelegate.onSystemKeyPressed(KeyEvent.KEYCODE_STEM_PRIMARY);
1656             Slog.d(TAG, "stemPrimarySinglePressAction: skip due to keyguard");
1657             return;
1658         }
1659         switch (behavior) {
1660             case SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS:
1661                 Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS);
1662                 allAppsIntent.addFlags(
1663                         Intent.FLAG_ACTIVITY_NEW_TASK
1664                                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
1665                 startActivityAsUser(allAppsIntent, UserHandle.CURRENT_OR_SELF);
1666                 break;
1667             case SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY:
1668                 if (mPrimaryShortPressTargetActivity != null) {
1669                     Intent targetActivityIntent = new Intent();
1670                     targetActivityIntent.setComponent(mPrimaryShortPressTargetActivity);
1671                     ResolveInfo resolveInfo =
1672                             mContext.getPackageManager()
1673                                     .resolveActivity(targetActivityIntent, /* flags= */ 0);
1674                     if (resolveInfo != null) {
1675                         targetActivityIntent.addFlags(
1676                                 Intent.FLAG_ACTIVITY_NEW_TASK
1677                                         | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
1678                                         | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
1679                         startActivityAsUser(targetActivityIntent, UserHandle.CURRENT_OR_SELF);
1680                     } else {
1681                         Slog.wtf(
1682                                 TAG,
1683                                 "Could not resolve activity with : "
1684                                         + mPrimaryShortPressTargetActivity.flattenToString()
1685                                         + " name.");
1686                     }
1687                 } else {
1688                     Slog.wtf(
1689                             TAG,
1690                             "mPrimaryShortPressTargetActivity must not be null and correctly"
1691                                 + " specified");
1692                 }
1693                 break;
1694         }
1695     }
1696 
stemPrimaryDoublePressAction(int behavior)1697     private void stemPrimaryDoublePressAction(int behavior) {
1698         Slog.d(TAG, "stemPrimaryDoublePressAction: " + behavior);
1699         switch (behavior) {
1700             case DOUBLE_PRESS_PRIMARY_NOTHING:
1701                 break;
1702             case DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP:
1703                 final boolean keyguardActive = mKeyguardDelegate == null
1704                         ? false
1705                         : mKeyguardDelegate.isShowing();
1706                 if (!keyguardActive) {
1707                     performStemPrimaryDoublePressSwitchToRecentTask();
1708                 }
1709                 break;
1710             case DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP:
1711                 final int stemPrimaryKeyDeviceId = INVALID_INPUT_DEVICE_ID;
1712                 handleKeyGestureInKeyGestureController(
1713                         KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS,
1714                         stemPrimaryKeyDeviceId, KEYCODE_STEM_PRIMARY, /* metaState= */ 0);
1715                 break;
1716         }
1717     }
1718 
stemPrimaryTriplePressAction(int behavior)1719     private void stemPrimaryTriplePressAction(int behavior) {
1720         Slog.d(TAG, "stemPrimaryTriplePressAction: " + behavior);
1721         switch (behavior) {
1722             case TRIPLE_PRESS_PRIMARY_NOTHING:
1723                 break;
1724             case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY:
1725                 mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
1726                         TalkbackShortcutController.ShortcutSource.GESTURE);
1727                 if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) {
1728                     performHapticFeedback(HapticFeedbackConstants.CONFIRM,
1729                             "Stem primary - Triple Press - Toggle Accessibility");
1730                 }
1731                 break;
1732         }
1733     }
1734 
stemPrimaryLongPress(long eventTime)1735     private void stemPrimaryLongPress(long eventTime) {
1736         Slog.d(TAG, "stemPrimaryLongPress: "  + mLongPressOnStemPrimaryBehavior);
1737 
1738         switch (mLongPressOnStemPrimaryBehavior) {
1739             case LONG_PRESS_PRIMARY_NOTHING:
1740                 break;
1741             case LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT:
1742                 final int stemPrimaryKeyDeviceId = INVALID_INPUT_DEVICE_ID;
1743                 launchAssistAction(
1744                         null,
1745                         stemPrimaryKeyDeviceId,
1746                         eventTime,
1747                         AssistUtils.INVOCATION_TYPE_UNKNOWN);
1748                 break;
1749         }
1750     }
1751 
1752     /**
1753      * Load most recent task (expect current task) and bring it to the front.
1754      */
performStemPrimaryDoublePressSwitchToRecentTask()1755     void performStemPrimaryDoublePressSwitchToRecentTask() {
1756         RecentTaskInfo targetTask = mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp;
1757         if (targetTask == null) {
1758             if (DEBUG_INPUT) {
1759                 Slog.w(TAG, "No recent task available! Show wallpaper.");
1760             }
1761             goHome();
1762             return;
1763         }
1764 
1765         if (DEBUG_INPUT) {
1766             Slog.d(
1767                     TAG,
1768                     "Starting task from recents. id="
1769                             + targetTask.id
1770                             + ", persistentId="
1771                             + targetTask.persistentId
1772                             + ", topActivity="
1773                             + targetTask.topActivity
1774                             + ", baseIntent="
1775                             + targetTask.baseIntent);
1776         }
1777         try {
1778             mActivityManagerService.startActivityFromRecents(targetTask.persistentId, null);
1779         } catch (RemoteException | IllegalArgumentException e) {
1780             Slog.e(TAG, "Failed to start task " + targetTask.persistentId + " from recents", e);
1781         }
1782     }
1783 
getMaxMultiPressStemPrimaryCount()1784     private int getMaxMultiPressStemPrimaryCount() {
1785         switch (mTriplePressOnStemPrimaryBehavior) {
1786             case TRIPLE_PRESS_PRIMARY_NOTHING:
1787                 break;
1788             case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY:
1789                 if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) {
1790                     return 3;
1791                 }
1792                 break;
1793         }
1794         if (mDoublePressOnStemPrimaryBehavior != DOUBLE_PRESS_PRIMARY_NOTHING) {
1795             return 2;
1796         }
1797         return 1;
1798     }
1799 
hasLongPressOnPowerBehavior()1800     private boolean hasLongPressOnPowerBehavior() {
1801         return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING;
1802     }
1803 
hasVeryLongPressOnPowerBehavior()1804     private boolean hasVeryLongPressOnPowerBehavior() {
1805         return mVeryLongPressOnPowerBehavior != VERY_LONG_PRESS_POWER_NOTHING;
1806     }
1807 
hasLongPressOnBackBehavior()1808     private boolean hasLongPressOnBackBehavior() {
1809         return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING;
1810     }
1811 
hasLongPressOnStemPrimaryBehavior()1812     private boolean hasLongPressOnStemPrimaryBehavior() {
1813         return mLongPressOnStemPrimaryBehavior != LONG_PRESS_PRIMARY_NOTHING;
1814     }
1815 
1816     /** Determine whether the device has any stem primary behaviors. */
hasStemPrimaryBehavior()1817     private boolean hasStemPrimaryBehavior() {
1818         // Read the default stem behaviors from the XML config to determine whether stem primary
1819         // behaviors are supported in this build. If they are supported, then the behaviors may be
1820         // overridden at runtime through their respective Settings overrides. If they are not
1821         // supported, the Settings overrides will not apply.
1822         final int defaultShortPressOnStemPrimaryBehavior = mContext.getResources().getInteger(
1823                 com.android.internal.R.integer.config_shortPressOnStemPrimaryBehavior);
1824         final int defaultLongPressOnStemPrimaryBehavior = mContext.getResources().getInteger(
1825                 com.android.internal.R.integer.config_longPressOnStemPrimaryBehavior);
1826         return getMaxMultiPressStemPrimaryCount() > 1
1827                 || defaultLongPressOnStemPrimaryBehavior != LONG_PRESS_PRIMARY_NOTHING
1828                 || defaultShortPressOnStemPrimaryBehavior != SHORT_PRESS_PRIMARY_NOTHING;
1829     }
1830 
interceptScreenshotChord(int source, long pressDelay)1831     private void interceptScreenshotChord(int source, long pressDelay) {
1832         mHandler.removeMessages(MSG_SCREENSHOT_CHORD);
1833         // arg2 is unused, but necessary to insure we call the correct method signature
1834         // since the screenshot source is read from message.arg1
1835         mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SCREENSHOT_CHORD, source, 0),
1836                 pressDelay);
1837     }
1838 
interceptAccessibilityShortcutChord()1839     private void interceptAccessibilityShortcutChord() {
1840         mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT);
1841         mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT),
1842                 getAccessibilityShortcutTimeout());
1843     }
1844 
interceptRingerToggleChord()1845     private void interceptRingerToggleChord() {
1846         mHandler.removeMessages(MSG_RINGER_TOGGLE_CHORD);
1847         mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RINGER_TOGGLE_CHORD),
1848                 getRingerToggleChordDelay());
1849     }
1850 
getAccessibilityShortcutTimeout()1851     private long getAccessibilityShortcutTimeout() {
1852         final ViewConfiguration config = ViewConfiguration.get(mContext);
1853         final boolean hasDialogShown = Settings.Secure.getIntForUser(mContext.getContentResolver(),
1854                 Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0, mCurrentUserId) != 0;
1855         final boolean skipTimeoutRestriction =
1856                 Settings.Secure.getIntForUser(mContext.getContentResolver(),
1857                         Settings.Secure.SKIP_ACCESSIBILITY_SHORTCUT_DIALOG_TIMEOUT_RESTRICTION, 0,
1858                         mCurrentUserId) != 0;
1859 
1860         // If users manually set the volume key shortcut for any accessibility service, the
1861         // system would bypass the timeout restriction of the shortcut dialog.
1862         return hasDialogShown || skipTimeoutRestriction
1863                 ? config.getAccessibilityShortcutKeyTimeoutAfterConfirmation()
1864                 : config.getAccessibilityShortcutKeyTimeout();
1865     }
1866 
getScreenshotChordLongPressDelay()1867     private long getScreenshotChordLongPressDelay() {
1868         long delayMs = DeviceConfig.getLong(
1869                 DeviceConfig.NAMESPACE_SYSTEMUI, SCREENSHOT_KEYCHORD_DELAY,
1870                 ViewConfiguration.get(mContext).getScreenshotChordKeyTimeout());
1871         if (mKeyguardDelegate.isShowing()) {
1872             // Double the time it takes to take a screenshot from the keyguard
1873             return (long) (KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER * delayMs);
1874         }
1875         return delayMs;
1876     }
1877 
getRingerToggleChordDelay()1878     private long getRingerToggleChordDelay() {
1879         // Always timeout like a tap
1880         return ViewConfiguration.getTapTimeout();
1881     }
1882 
cancelPendingScreenshotChordAction()1883     private void cancelPendingScreenshotChordAction() {
1884         mHandler.removeMessages(MSG_SCREENSHOT_CHORD);
1885     }
1886 
cancelPendingAccessibilityShortcutAction()1887     private void cancelPendingAccessibilityShortcutAction() {
1888         mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT);
1889     }
1890 
cancelPendingRingerToggleChordAction()1891     private void cancelPendingRingerToggleChordAction() {
1892         mHandler.removeMessages(MSG_RINGER_TOGGLE_CHORD);
1893     }
1894 
1895     private final Runnable mEndCallLongPress = new Runnable() {
1896         @Override
1897         public void run() {
1898             mEndCallKeyHandled = true;
1899             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
1900                     "End Call - Long Press - Show Global Actions");
1901             showGlobalActionsInternal();
1902         }
1903     };
1904 
handleScreenShot(@indowManager.ScreenshotSource int source)1905     private void handleScreenShot(@WindowManager.ScreenshotSource int source) {
1906         mDefaultDisplayPolicy.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, source);
1907     }
1908 
1909     @Override
showGlobalActions()1910     public void showGlobalActions() {
1911         mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
1912         mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
1913     }
1914 
showGlobalActionsInternal()1915     void showGlobalActionsInternal() {
1916         if (mGlobalActions == null) {
1917             mGlobalActions = mGlobalActionsFactory.get();
1918         }
1919         final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
1920         mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
1921         // since it took two seconds of long press to bring this up,
1922         // poke the wake lock so they have some time to see the dialog.
1923         mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
1924     }
1925 
cancelGlobalActionsAction()1926     private void cancelGlobalActionsAction() {
1927         mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
1928     }
1929 
isDeviceProvisioned()1930     boolean isDeviceProvisioned() {
1931         return Settings.Global.getInt(
1932                 mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1933     }
1934 
1935     @Override
isUserSetupComplete()1936     public boolean isUserSetupComplete() {
1937         boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
1938                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
1939         if (mHasFeatureLeanback) {
1940             isSetupComplete &= isTvUserSetupComplete();
1941         } else if (mHasFeatureAuto) {
1942             isSetupComplete &= isAutoUserSetupComplete();
1943         }
1944         return isSetupComplete;
1945     }
1946 
isAutoUserSetupComplete()1947     private boolean isAutoUserSetupComplete() {
1948         return Settings.Secure.getIntForUser(mContext.getContentResolver(),
1949                 "android.car.SETUP_WIZARD_IN_PROGRESS", 0, UserHandle.USER_CURRENT) == 0;
1950     }
1951 
isTvUserSetupComplete()1952     private boolean isTvUserSetupComplete() {
1953         return Settings.Secure.getIntForUser(mContext.getContentResolver(),
1954                 Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
1955     }
1956 
handleShortPressOnHome(int displayId)1957     private void handleShortPressOnHome(int displayId) {
1958         // Turn on the connected TV and switch HDMI input if we're a HDMI playback device.
1959         final HdmiControl hdmiControl = getHdmiControl();
1960         if (hdmiControl != null) {
1961             hdmiControl.turnOnTv();
1962         }
1963 
1964         // If there's a dream running then use home to escape the dream
1965         // but don't actually go home.
1966         final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
1967         if (dreamManagerInternal != null && dreamManagerInternal.isDreaming()) {
1968             dreamManagerInternal.stopDream(false /*immediate*/, "short press on home" /*reason*/);
1969             return;
1970         }
1971 
1972         // Go home!
1973         launchHomeFromHotKey(displayId);
1974     }
1975 
1976     /**
1977      * Creates an accessor to HDMI control service that performs the operation of
1978      * turning on TV (optional) and switching input to us. If HDMI control service
1979      * is not available or we're not a HDMI playback device, the operation is no-op.
1980      * @return {@link HdmiControl} instance if available, null otherwise.
1981      */
getHdmiControl()1982     private HdmiControl getHdmiControl() {
1983         if (null == mHdmiControl) {
1984             if (!mHasFeatureHdmiCec) {
1985                 return null;
1986             }
1987             HdmiControlManager manager = (HdmiControlManager) mContext.getSystemService(
1988                         Context.HDMI_CONTROL_SERVICE);
1989             HdmiPlaybackClient client = null;
1990             if (manager != null) {
1991                 client = manager.getPlaybackClient();
1992             }
1993             mHdmiControl = new HdmiControl(client);
1994         }
1995         return mHdmiControl;
1996     }
1997 
1998     private static class HdmiControl {
1999         private final HdmiPlaybackClient mClient;
2000 
HdmiControl(HdmiPlaybackClient client)2001         private HdmiControl(HdmiPlaybackClient client) {
2002             mClient = client;
2003         }
2004 
turnOnTv()2005         public void turnOnTv() {
2006             if (mClient == null) {
2007                 return;
2008             }
2009             mClient.oneTouchPlay(new OneTouchPlayCallback() {
2010                 @Override
2011                 public void onComplete(int result) {
2012                     if (result != HdmiControlManager.RESULT_SUCCESS) {
2013                         Log.w(TAG, "One touch play failed: " + result);
2014                     }
2015                 }
2016             });
2017         }
2018     }
2019 
launchAllAppsAction()2020     private void launchAllAppsAction() {
2021         if (mHasFeatureLeanback || mHasFeatureWatch) {
2022             // TV and watch support the all apps intent
2023             Intent intent = new Intent(Intent.ACTION_ALL_APPS);
2024             if (mHasFeatureLeanback) {
2025                 Intent intentLauncher = new Intent(Intent.ACTION_MAIN);
2026                 intentLauncher.addCategory(Intent.CATEGORY_HOME);
2027                 ResolveInfo resolveInfo = mPackageManager.resolveActivityAsUser(intentLauncher,
2028                         PackageManager.MATCH_SYSTEM_ONLY,
2029                         mCurrentUserId);
2030                 if (resolveInfo != null) {
2031                     intent.setPackage(resolveInfo.activityInfo.packageName);
2032                 }
2033             }
2034             startActivityAsUser(intent, UserHandle.CURRENT);
2035         } else {
2036             AccessibilityManagerInternal accessibilityManager = getAccessibilityManagerInternal();
2037             if (accessibilityManager != null) {
2038                 accessibilityManager.performSystemAction(
2039                         AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
2040             }
2041         }
2042         dismissKeyboardShortcutsMenu();
2043     }
2044 
toggleNotificationPanel()2045     private void toggleNotificationPanel() {
2046         IStatusBarService statusBarService = getStatusBarService();
2047         if (isUserSetupComplete() && statusBarService != null) {
2048             try {
2049                 statusBarService.togglePanel();
2050             } catch (RemoteException e) {
2051                 // do nothing.
2052             }
2053         }
2054     }
2055 
showSystemSettings()2056     private void showSystemSettings() {
2057         startActivityAsUser(new Intent(android.provider.Settings.ACTION_SETTINGS),
2058                 UserHandle.CURRENT_OR_SELF);
2059     }
2060 
showPictureInPictureMenu(KeyEvent event)2061     private void showPictureInPictureMenu(KeyEvent event) {
2062         if (DEBUG_INPUT) Log.d(TAG, "showPictureInPictureMenu event=" + event);
2063         mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU);
2064         Message msg = mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU);
2065         msg.setAsynchronous(true);
2066         msg.sendToTarget();
2067     }
2068 
showPictureInPictureMenuInternal()2069     private void showPictureInPictureMenuInternal() {
2070         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
2071         if (statusbar != null) {
2072             statusbar.showPictureInPictureMenu();
2073         }
2074     }
2075 
2076     /** A handler to handle home keys per display */
2077     private class DisplayHomeButtonHandler {
2078 
2079         private final int mDisplayId;
2080         private boolean mHomePressed;
2081         private boolean mHomeConsumed;
2082         private KeyEvent mPendingHomeKeyEvent;
2083         private final Runnable mHomeDoubleTapTimeoutRunnable = new Runnable() {
2084             @Override
2085             public void run() {
2086                 if (mPendingHomeKeyEvent != null) {
2087                     notifyKeyGestureCompleted(mPendingHomeKeyEvent,
2088                             KeyGestureEvent.KEY_GESTURE_TYPE_HOME);
2089                     handleShortPressOnHome(mPendingHomeKeyEvent.getDisplayId());
2090                     mPendingHomeKeyEvent = null;
2091                 }
2092             }
2093         };
2094 
DisplayHomeButtonHandler(int displayId)2095         DisplayHomeButtonHandler(int displayId) {
2096             mDisplayId = displayId;
2097         }
2098 
handleHomeButton(IBinder focusedToken, KeyEvent event)2099         boolean handleHomeButton(IBinder focusedToken, KeyEvent event) {
2100             final boolean keyguardOn = keyguardOn();
2101             final int repeatCount = event.getRepeatCount();
2102             final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
2103             final boolean canceled = event.isCanceled();
2104 
2105             if (DEBUG_INPUT) {
2106                 Log.d(TAG, String.format("handleHomeButton in display#%d mHomePressed = %b",
2107                         mDisplayId, mHomePressed));
2108             }
2109 
2110             // If we have released the home key, and didn't do anything else
2111             // while it was pressed, then it is time to go home!
2112             if (!down) {
2113                 if (mDisplayId == DEFAULT_DISPLAY) {
2114                     cancelPreloadRecentApps();
2115                 }
2116 
2117                 mHomePressed = false;
2118                 if (mHomeConsumed) {
2119                     mHomeConsumed = false;
2120                     return true;
2121                 }
2122 
2123                 if (canceled) {
2124                     Log.i(TAG, "Ignoring HOME; event canceled.");
2125                     return true;
2126                 }
2127 
2128                 // Delay handling home if a double-tap is possible.
2129                 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {
2130                     // For the picture-in-picture menu, only add the delay if a pip is there.
2131                     if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_PIP_MENU
2132                             || mPictureInPictureVisible) {
2133                         mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
2134                         mPendingHomeKeyEvent = event;
2135                         mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
2136                                 ViewConfiguration.getDoubleTapTimeout());
2137                         return true;
2138                     }
2139                 }
2140 
2141                 // Post to main thread to avoid blocking input pipeline.
2142                 mHandler.post(() -> {
2143                     notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_HOME);
2144                     handleShortPressOnHome(event.getDisplayId());
2145                 });
2146                 return true;
2147             }
2148 
2149             final KeyInterceptionInfo info =
2150                     mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);
2151             if (info != null) {
2152                 // If a system window has focus, then it doesn't make sense
2153                 // right now to interact with applications.
2154                 if (info.layoutParamsType == TYPE_KEYGUARD_DIALOG
2155                         || (info.layoutParamsType == TYPE_NOTIFICATION_SHADE
2156                         && isKeyguardShowing())) {
2157                     // the "app" is keyguard, so give it the key
2158                     return false;
2159                 }
2160                 for (int t : WINDOW_TYPES_WHERE_HOME_DOESNT_WORK) {
2161                     if (info.layoutParamsType == t) {
2162                         // don't do anything, but also don't pass it to the app
2163                         return true;
2164                     }
2165                 }
2166             }
2167 
2168             // Remember that home is pressed and handle special actions.
2169             if (repeatCount == 0) {
2170                 mHomePressed = true;
2171                 if (mPendingHomeKeyEvent != null) {
2172                     mPendingHomeKeyEvent = null;
2173                     mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);
2174                     mHandler.post(() -> handleDoubleTapOnHome(event));
2175                 // TODO(multi-display): Remove display id check once we support recents on
2176                 // multi-display
2177                 } else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI
2178                         && mDisplayId == DEFAULT_DISPLAY) {
2179                     preloadRecentApps();
2180                 }
2181             } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
2182                 if (!keyguardOn) {
2183                     // Post to main thread to avoid blocking input pipeline.
2184                     mHandler.post(() -> handleLongPressOnHome(event));
2185                 }
2186             }
2187             return true;
2188         }
2189 
handleDoubleTapOnHome(KeyEvent event)2190         private void handleDoubleTapOnHome(KeyEvent event) {
2191             if (mHomeConsumed) {
2192                 return;
2193             }
2194             switch (mDoubleTapOnHomeBehavior) {
2195                 case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI:
2196                     if (!isKeyEventForCurrentUser(
2197                             event.getDisplayId(), event.getKeyCode(), "toggleRecentApps")) {
2198                         break;
2199                     }
2200                     notifyKeyGestureCompleted(event,
2201                             KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH);
2202                     mHomeConsumed = true;
2203                     toggleRecentApps();
2204                     break;
2205                 case DOUBLE_TAP_HOME_PIP_MENU:
2206                     if (!isKeyEventForCurrentUser(
2207                             event.getDisplayId(), event.getKeyCode(),
2208                             "showPictureInPictureMenu")) {
2209                         break;
2210                     }
2211                     mHomeConsumed = true;
2212                     showPictureInPictureMenuInternal();
2213                     break;
2214                 default:
2215                     Log.w(TAG, "No action or undefined behavior for double tap home: "
2216                             + mDoubleTapOnHomeBehavior);
2217                     break;
2218             }
2219         }
2220 
handleLongPressOnHome(KeyEvent event)2221         private void handleLongPressOnHome(KeyEvent event) {
2222             if (mHomeConsumed) {
2223                 return;
2224             }
2225             if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_NOTHING) {
2226                 return;
2227             }
2228             mHomeConsumed = true;
2229             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, "Home - Long Press");
2230             switch (mLongPressOnHomeBehavior) {
2231                 case LONG_PRESS_HOME_ALL_APPS:
2232                     notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
2233                     if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
2234                             "launchAllAppsViaA11y")) {
2235                         launchAllAppsAction();
2236                     }
2237                     break;
2238                 case LONG_PRESS_HOME_ASSIST:
2239                     if (!isKeyEventForCurrentUser(
2240                             event.getDisplayId(), event.getKeyCode(), "launchAssistAction")) {
2241                         break;
2242                     }
2243                     notifyKeyGestureCompleted(event,
2244                             KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
2245                     launchAssistAction(null, event.getDeviceId(), event.getEventTime(),
2246                             AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
2247                     break;
2248                 case LONG_PRESS_HOME_NOTIFICATION_PANEL:
2249                     if (!isKeyEventForCurrentUser(
2250                             event.getDisplayId(), event.getKeyCode(), "toggleNotificationPanel")) {
2251                         break;
2252                     }
2253                     notifyKeyGestureCompleted(event,
2254                             KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
2255                     toggleNotificationPanel();
2256                     break;
2257                 default:
2258                     Log.w(TAG, "Undefined long press on home behavior: "
2259                             + mLongPressOnHomeBehavior);
2260                     break;
2261             }
2262         }
2263 
2264         @Override
toString()2265         public String toString() {
2266             return String.format("mDisplayId = %d, mHomePressed = %b", mDisplayId, mHomePressed);
2267         }
2268     }
2269 
2270     /** A DisplayHomeButtonHandler map indexed by display id */
2271     private final SparseArray<DisplayHomeButtonHandler> mDisplayHomeButtonHandlers =
2272             new SparseArray<>();
2273 
isRoundWindow()2274     private boolean isRoundWindow() {
2275         return mContext.getResources().getConfiguration().isScreenRound();
2276     }
2277 
2278     @Override
setDefaultDisplay(DisplayContentInfo displayContentInfo)2279     public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
2280         mDefaultDisplay = displayContentInfo.getDisplay();
2281         mDefaultDisplayRotation = displayContentInfo.getDisplayRotation();
2282         mDefaultDisplayPolicy = mDefaultDisplayRotation.getDisplayPolicy();
2283     }
2284 
2285     /** Point of injection for test dependencies. */
2286     @VisibleForTesting
2287     static class Injector {
2288         private final Context mContext;
2289         private final WindowManagerFuncs mWindowManagerFuncs;
2290 
Injector(Context context, WindowManagerFuncs funcs)2291         Injector(Context context, WindowManagerFuncs funcs) {
2292             mContext = context;
2293             mWindowManagerFuncs = funcs;
2294         }
2295 
getContext()2296         Context getContext() {
2297             return mContext;
2298         }
2299 
getWindowManagerFuncs()2300         WindowManagerFuncs getWindowManagerFuncs() {
2301             return mWindowManagerFuncs;
2302         }
2303 
getLooper()2304         Looper getLooper() {
2305             return Looper.myLooper();
2306         }
2307 
getAccessibilityShortcutController( Context context, Handler handler, int initialUserId)2308         AccessibilityShortcutController getAccessibilityShortcutController(
2309                 Context context, Handler handler, int initialUserId) {
2310             return new AccessibilityShortcutController(context, handler, initialUserId);
2311         }
2312 
getGlobalActionsFactory()2313         Supplier<GlobalActions> getGlobalActionsFactory() {
2314             return () -> new GlobalActions(mContext, mWindowManagerFuncs);
2315         }
2316 
getKeyguardServiceDelegate()2317         KeyguardServiceDelegate getKeyguardServiceDelegate() {
2318             return new KeyguardServiceDelegate(mContext,
2319                     new StateCallback() {
2320                         @Override
2321                         public void onTrustedChanged() {
2322                             mWindowManagerFuncs.notifyKeyguardTrustedChanged();
2323                         }
2324 
2325                         @Override
2326                         public void onShowingChanged() {
2327                             mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
2328                         }
2329                     });
2330         }
2331 
getActivityManagerService()2332         IActivityManager getActivityManagerService() {
2333             return ActivityManager.getService();
2334         }
2335 
getLockPatternUtils()2336         LockPatternUtils getLockPatternUtils() {
2337             return new LockPatternUtils(mContext);
2338         }
2339 
getButtonOverridePermissionChecker()2340         ButtonOverridePermissionChecker getButtonOverridePermissionChecker() {
2341             return new ButtonOverridePermissionChecker();
2342         }
2343 
getTalkbackShortcutController()2344         TalkbackShortcutController getTalkbackShortcutController() {
2345             return new TalkbackShortcutController(mContext);
2346         }
2347 
getVoiceAccessShortcutController()2348         VoiceAccessShortcutController getVoiceAccessShortcutController() {
2349             return new VoiceAccessShortcutController(mContext);
2350         }
2351 
getWindowWakeUpPolicy()2352         WindowWakeUpPolicy getWindowWakeUpPolicy() {
2353             return new WindowWakeUpPolicy(mContext);
2354         }
2355     }
2356 
2357     /** {@inheritDoc} */
2358     @Override
2359     public void init(Context context, WindowManagerFuncs funcs) {
2360         init(new Injector(context, funcs));
2361     }
2362 
2363     @VisibleForTesting
2364     void init(Injector injector) {
2365         mContext = injector.getContext();
2366         mWindowManagerFuncs = injector.getWindowManagerFuncs();
2367         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
2368         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
2369         mActivityManagerService = injector.getActivityManagerService();
2370         mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
2371         mInputManager = mContext.getSystemService(InputManager.class);
2372         mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
2373         mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
2374         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
2375         mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
2376         mSensorPrivacyManager = mContext.getSystemService(SensorPrivacyManager.class);
2377         mDisplayManager = mContext.getSystemService(DisplayManager.class);
2378         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
2379         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
2380         mPackageManager = mContext.getPackageManager();
2381         mHasFeatureWatch = mPackageManager.hasSystemFeature(FEATURE_WATCH);
2382         mHasFeatureLeanback = mPackageManager.hasSystemFeature(FEATURE_LEANBACK);
2383         mHasFeatureAuto = mPackageManager.hasSystemFeature(FEATURE_AUTOMOTIVE);
2384         mHasFeatureHdmiCec = mPackageManager.hasSystemFeature(FEATURE_HDMI_CEC);
2385         mAccessibilityShortcutController = injector.getAccessibilityShortcutController(
2386                 mContext, new Handler(), mCurrentUserId);
2387         mGlobalActionsFactory = injector.getGlobalActionsFactory();
2388         mLockPatternUtils = injector.getLockPatternUtils();
2389         mLogger = new MetricsLogger();
2390 
2391         Resources res = mContext.getResources();
2392         mWakeOnDpadKeyPress =
2393                 res.getBoolean(com.android.internal.R.bool.config_wakeOnDpadKeyPress);
2394         mWakeOnAssistKeyPress =
2395                 res.getBoolean(com.android.internal.R.bool.config_wakeOnAssistKeyPress);
2396         mWakeOnBackKeyPress =
2397                 res.getBoolean(com.android.internal.R.bool.config_wakeOnBackKeyPress);
2398 
2399         // Init display burn-in protection
2400         boolean burnInProtectionEnabled = mContext.getResources().getBoolean(
2401                 com.android.internal.R.bool.config_enableBurnInProtection);
2402         // Allow a system property to override this. Used by developer settings.
2403         boolean burnInProtectionDevMode =
2404                 SystemProperties.getBoolean("persist.debug.force_burn_in", false);
2405         if (burnInProtectionEnabled || burnInProtectionDevMode) {
2406             final int minHorizontal;
2407             final int maxHorizontal;
2408             final int minVertical;
2409             final int maxVertical;
2410             final int maxRadius;
2411             if (burnInProtectionDevMode) {
2412                 minHorizontal = -8;
2413                 maxHorizontal = 8;
2414                 minVertical = -8;
2415                 maxVertical = -4;
2416                 maxRadius = (isRoundWindow()) ? 6 : -1;
2417             } else {
2418                 Resources resources = mContext.getResources();
2419                 minHorizontal = resources.getInteger(
2420                         com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset);
2421                 maxHorizontal = resources.getInteger(
2422                         com.android.internal.R.integer.config_burnInProtectionMaxHorizontalOffset);
2423                 minVertical = resources.getInteger(
2424                         com.android.internal.R.integer.config_burnInProtectionMinVerticalOffset);
2425                 maxVertical = resources.getInteger(
2426                         com.android.internal.R.integer.config_burnInProtectionMaxVerticalOffset);
2427                 maxRadius = resources.getInteger(
2428                         com.android.internal.R.integer.config_burnInProtectionMaxRadius);
2429             }
2430             mBurnInProtectionHelper = new BurnInProtectionHelper(
2431                     mContext, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
2432         }
2433 
2434         mHandler = new PolicyHandler(injector.getLooper());
2435         mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
2436         mSettingsObserver = new SettingsObserver(mHandler);
2437         mSettingsObserver.observe();
2438         mModifierShortcutManager = new ModifierShortcutManager(
2439                 mContext, mHandler, UserHandle.of(mCurrentUserId));
2440         mUiMode = mContext.getResources().getInteger(
2441                 com.android.internal.R.integer.config_defaultUiModeType);
2442         mHomeIntent =  new Intent(Intent.ACTION_MAIN, null);
2443         mHomeIntent.addCategory(Intent.CATEGORY_HOME);
2444         mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2445                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
2446         mEnableCarDockHomeCapture = mContext.getResources().getBoolean(
2447                 com.android.internal.R.bool.config_enableCarDockHomeLaunch);
2448         mCarDockIntent =  new Intent(Intent.ACTION_MAIN, null);
2449         mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
2450         mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2451                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
2452         mDeskDockIntent =  new Intent(Intent.ACTION_MAIN, null);
2453         mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK);
2454         mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2455                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
2456         mVrHeadsetHomeIntent =  new Intent(Intent.ACTION_MAIN, null);
2457         mVrHeadsetHomeIntent.addCategory(Intent.CATEGORY_VR_HOME);
2458         mVrHeadsetHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2459                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
2460 
2461         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
2462         mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
2463                 "PhoneWindowManager.mBroadcastWakeLock");
2464         mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
2465                 "PhoneWindowManager.mPowerKeyWakeLock");
2466         mEnableBugReportKeyboardShortcut = "1".equals(SystemProperties.get("ro.debuggable"));
2467         mLidKeyboardAccessibility = mContext.getResources().getInteger(
2468                 com.android.internal.R.integer.config_lidKeyboardAccessibility);
2469         mLidNavigationAccessibility = mContext.getResources().getInteger(
2470                 com.android.internal.R.integer.config_lidNavigationAccessibility);
2471 
2472         mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean(
2473                 com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode);
2474 
2475         mSupportLongPressPowerWhenNonInteractive = mContext.getResources().getBoolean(
2476                 com.android.internal.R.bool.config_supportLongPressPowerWhenNonInteractive);
2477         mSupportShortPressPowerWhenDefaultDisplayOn =
2478                 mContext.getResources()
2479                         .getBoolean(
2480                                 com.android.internal.R.bool
2481                                         .config_supportShortPressPowerWhenDefaultDisplayOn);
2482 
2483         mLongPressOnBackBehavior = mContext.getResources().getInteger(
2484                 com.android.internal.R.integer.config_longPressOnBackBehavior);
2485 
2486         mLongPressOnPowerBehavior = mContext.getResources().getInteger(
2487                 com.android.internal.R.integer.config_longPressOnPowerBehavior);
2488         mLongPressOnPowerAssistantTimeoutMs = mContext.getResources().getInteger(
2489                 com.android.internal.R.integer.config_longPressOnPowerDurationMs);
2490         mVeryLongPressOnPowerBehavior = mContext.getResources().getInteger(
2491                 com.android.internal.R.integer.config_veryLongPressOnPowerBehavior);
2492         mPowerDoublePressTargetActivity = ComponentName.unflattenFromString(
2493             mContext.getResources().getString(
2494                 com.android.internal.R.string.config_doublePressOnPowerTargetActivity));
2495         mPrimaryShortPressTargetActivity = ComponentName.unflattenFromString(
2496             mContext.getResources().getString(
2497                 com.android.internal.R.string.config_primaryShortPressTargetActivity));
2498         mShortPressOnSleepBehavior = mContext.getResources().getInteger(
2499                 com.android.internal.R.integer.config_shortPressOnSleepBehavior);
2500         mSilenceRingerOnSleepKey = mContext.getResources().getBoolean(
2501                 com.android.internal.R.bool.config_silenceRingerOnSleepKey);
2502         mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean(
2503                 com.android.internal.R.bool.config_allowStartActivityForLongPressOnPowerInSetup);
2504 
2505         mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
2506 
2507         mHandleVolumeKeysInWM = mContext.getResources().getBoolean(
2508                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager);
2509 
2510         mWakeUpToLastStateTimeout = mContext.getResources().getInteger(
2511                 com.android.internal.R.integer.config_wakeUpToLastStateTimeoutMillis);
2512 
2513         mSearchKeyBehavior = mContext.getResources().getInteger(
2514                 com.android.internal.R.integer.config_searchKeyBehavior);
2515 
2516         mSearchKeyTargetActivity = ComponentName.unflattenFromString(
2517             mContext.getResources().getString(
2518                 com.android.internal.R.string.config_searchKeyTargetActivity));
2519         readConfigurationDependentBehaviors();
2520 
2521         mDisplayFoldController = DisplayFoldController.create(mContext, DEFAULT_DISPLAY);
2522 
2523         mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
2524 
2525         // register for dock events
2526         IntentFilter filter = new IntentFilter();
2527         filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
2528         filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
2529         filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE);
2530         filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE);
2531         filter.addAction(Intent.ACTION_DOCK_EVENT);
2532         mContext.registerReceiver(mDockReceiver, filter);
2533 
2534         // register for multiuser-relevant broadcasts
2535         filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
2536         mContext.registerReceiver(mMultiuserReceiver, filter);
2537 
2538         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
2539 
2540         mGlobalKeyManager = new GlobalKeyManager(mContext);
2541 
2542         // Controls rotation and the like.
2543         initializeHdmiState();
2544 
2545         // Match current screen state.
2546         if (!mPowerManager.isInteractive()) {
2547             startedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
2548                     PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
2549             finishedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
2550                     PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
2551         }
2552 
2553         final var transitionListener = new AppTransitionListener(DEFAULT_DISPLAY) {
2554             @Override
2555             public int onAppTransitionStartingLocked(long statusBarAnimationStartTime,
2556                     long statusBarAnimationDuration) {
2557                 return handleTransitionForKeyguardLw(false /* startKeyguardExitAnimation */,
2558                         false /* notifyOccluded */);
2559             }
2560 
2561             @Override
2562             public void onAppTransitionCancelledLocked(boolean keyguardGoingAwayCancelled) {
2563                 // When KEYGUARD_GOING_AWAY app transition is canceled, we need to trigger relevant
2564                 // IKeyguardService calls to sync keyguard status in WindowManagerService and SysUI.
2565                 handleTransitionForKeyguardLw(
2566                         keyguardGoingAwayCancelled /* startKeyguardExitAnimation */,
2567                         true /* notifyOccluded */);
2568 
2569                 synchronized (mLock) {
2570                     mLockAfterDreamingTransitionFinished = false;
2571                 }
2572             }
2573 
2574             @Override
2575             public void onAppTransitionFinishedLocked(IBinder token) {
2576                 synchronized (mLock) {
2577                     final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
2578                     // check both isDreaming and mLockAfterDreamingTransitionFinished before lockNow
2579                     // so it won't relock after dreaming has stopped
2580                     if (dreamManagerInternal != null && dreamManagerInternal.isDreaming()
2581                             && mLockAfterDreamingTransitionFinished) {
2582                         lockNow(null);
2583                     }
2584                     mLockAfterDreamingTransitionFinished = false;
2585                 }
2586             }
2587         };
2588         mWindowManagerInternal.registerAppTransitionListener(transitionListener);
2589 
2590         mKeyguardDrawnTimeout = mContext.getResources().getInteger(
2591                 com.android.internal.R.integer.config_keyguardDrawnTimeout);
2592         mKeyguardDelegate = injector.getKeyguardServiceDelegate();
2593         mTalkbackShortcutController = injector.getTalkbackShortcutController();
2594         mVoiceAccessShortcutController = injector.getVoiceAccessShortcutController();
2595         mWindowWakeUpPolicy = injector.getWindowWakeUpPolicy();
2596         initKeyCombinationRules();
2597         initSingleKeyGestureRules(injector.getLooper());
2598         initKeyGestures();
2599         mButtonOverridePermissionChecker = injector.getButtonOverridePermissionChecker();
2600         mSideFpsEventHandler = new SideFpsEventHandler(mContext, mHandler, mPowerManager);
2601     }
2602 
2603     private void initKeyCombinationRules() {
2604         mKeyCombinationManager = new KeyCombinationManager(mHandler);
2605         if (InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures()) {
2606             return;
2607         }
2608         final boolean screenshotChordEnabled = mContext.getResources().getBoolean(
2609                 com.android.internal.R.bool.config_enableScreenshotChord);
2610 
2611         if (screenshotChordEnabled) {
2612             mKeyCombinationManager.addRule(
2613                     new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_POWER) {
2614                         @Override
2615                         public void execute() {
2616                             mPowerKeyHandled = true;
2617                             interceptScreenshotChord(
2618                                     SCREENSHOT_KEY_CHORD, getScreenshotChordLongPressDelay());
2619                         }
2620                         @Override
2621                         public void cancel() {
2622                             cancelPendingScreenshotChordAction();
2623                         }
2624                     });
2625 
2626             if (mHasFeatureWatch) {
2627                 mKeyCombinationManager.addRule(
2628                         new TwoKeysCombinationRule(KEYCODE_POWER, KEYCODE_STEM_PRIMARY) {
2629                             @Override
2630                             public void execute() {
2631                                 mPowerKeyHandled = true;
2632                                 interceptScreenshotChord(SCREENSHOT_KEY_CHORD,
2633                                         getScreenshotChordLongPressDelay());
2634                             }
2635                             @Override
2636                             public void cancel() {
2637                                 cancelPendingScreenshotChordAction();
2638                             }
2639                         });
2640             }
2641         }
2642 
2643         mKeyCombinationManager.addRule(
2644                 new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_VOLUME_UP) {
2645                     @Override
2646                     public boolean preCondition() {
2647                         return mAccessibilityShortcutController
2648                                 .isAccessibilityShortcutAvailable(isKeyguardLocked());
2649                     }
2650                     @Override
2651                     public void execute() {
2652                         interceptAccessibilityShortcutChord();
2653                     }
2654                     @Override
2655                     public void cancel() {
2656                         cancelPendingAccessibilityShortcutAction();
2657                     }
2658                 });
2659 
2660         // Volume up + power can either be the "ringer toggle chord" or as another way to
2661         // launch GlobalActions. This behavior can change at runtime so we must check behavior
2662         // inside the TwoKeysCombinationRule.
2663         mKeyCombinationManager.addRule(
2664                 new TwoKeysCombinationRule(KEYCODE_VOLUME_UP, KEYCODE_POWER) {
2665                     @Override
2666                     public boolean preCondition() {
2667                         switch (mPowerVolUpBehavior) {
2668                             case POWER_VOLUME_UP_BEHAVIOR_MUTE:
2669                                 return mRingerToggleChord != VOLUME_HUSH_OFF;
2670                             default:
2671                                 return true;
2672                         }
2673                     }
2674                     @Override
2675                     public void execute() {
2676                         switch (mPowerVolUpBehavior) {
2677                             case POWER_VOLUME_UP_BEHAVIOR_MUTE:
2678                                 // no haptic feedback here since
2679                                 interceptRingerToggleChord();
2680                                 mPowerKeyHandled = true;
2681                                 break;
2682                             case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
2683                                 performHapticFeedback(
2684                                         HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
2685                                         "Power + Volume Up - Global Actions");
2686                                 showGlobalActions();
2687                                 mPowerKeyHandled = true;
2688                                 break;
2689                             default:
2690                                 break;
2691                         }
2692                     }
2693                     @Override
2694                     public void cancel() {
2695                         switch (mPowerVolUpBehavior) {
2696                             case POWER_VOLUME_UP_BEHAVIOR_MUTE:
2697                                 cancelPendingRingerToggleChordAction();
2698                                 break;
2699                             case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
2700                                 cancelGlobalActionsAction();
2701                                 break;
2702                         }
2703                     }
2704                 });
2705 
2706         if (mHasFeatureLeanback) {
2707             mKeyCombinationManager.addRule(
2708                     new TwoKeysCombinationRule(KEYCODE_BACK, KEYCODE_DPAD_DOWN) {
2709                         @Override
2710                         public void execute() {
2711                             mBackKeyHandled = true;
2712                             interceptAccessibilityGestureTv();
2713                         }
2714                         @Override
2715                         public void cancel() {
2716                             cancelAccessibilityGestureTv();
2717                         }
2718                         @Override
2719                         public long getKeyInterceptDelayMs() {
2720                             // Use a timeout of 0 to prevent additional latency in processing of
2721                             // this key. This will potentially cause some unwanted UI actions if the
2722                             // user does end up triggering the key combination later, but in most
2723                             // cases, the user will simply hit a single key, and this will allow us
2724                             // to process it without first waiting to see if the combination is
2725                             // going to be triggered.
2726                             return 0;
2727                         }
2728                     });
2729 
2730             mKeyCombinationManager.addRule(
2731                     new TwoKeysCombinationRule(KEYCODE_DPAD_CENTER, KEYCODE_BACK) {
2732                         @Override
2733                         public void execute() {
2734                             mBackKeyHandled = true;
2735                             interceptBugreportGestureTv();
2736                         }
2737                         @Override
2738                         public void cancel() {
2739                             cancelBugreportGestureTv();
2740                         }
2741                         @Override
2742                         public long getKeyInterceptDelayMs() {
2743                             return 0;
2744                         }
2745                     });
2746         }
2747     }
2748 
2749     /**
2750      * Rule for single power key gesture.
2751      */
2752     private final class PowerKeyRule extends SingleKeyGestureDetector.SingleKeyRule {
2753         PowerKeyRule() {
2754             super(KEYCODE_POWER);
2755         }
2756 
2757         @Override
2758         boolean supportLongPress() {
2759             return hasLongPressOnPowerBehavior();
2760         }
2761 
2762         @Override
2763         boolean supportVeryLongPress() {
2764             return hasVeryLongPressOnPowerBehavior();
2765         }
2766 
2767 
2768         @Override
2769         int getMaxMultiPressCount() {
2770             return getMaxMultiPressPowerCount();
2771         }
2772 
2773         @Override
2774         void onPress(long downTime, int displayId) {
2775             if (mShouldEarlyShortPressOnPower) {
2776                 return;
2777             }
2778             powerPress(downTime, 1 /*count*/, displayId);
2779         }
2780 
2781         @Override
2782         long getLongPressTimeoutMs() {
2783             if (getResolvedLongPressOnPowerBehavior() == LONG_PRESS_POWER_ASSISTANT) {
2784                 return mLongPressOnPowerAssistantTimeoutMs;
2785             } else {
2786                 return super.getLongPressTimeoutMs();
2787             }
2788         }
2789 
2790         @Override
2791         void onLongPress(long eventTime) {
2792             if (mSingleKeyGestureDetector.beganFromNonInteractive()
2793                     && !mSupportLongPressPowerWhenNonInteractive) {
2794                 Slog.v(TAG, "Not support long press power when device is not interactive.");
2795                 return;
2796             }
2797 
2798             powerLongPress(eventTime);
2799         }
2800 
2801         @Override
2802         void onVeryLongPress(long eventTime) {
2803             mActivityManagerInternal.prepareForPossibleShutdown();
2804             powerVeryLongPress();
2805         }
2806 
2807         @Override
2808         void onMultiPress(long downTime, int count, int displayId) {
2809             powerPress(downTime, count, displayId);
2810         }
2811 
2812         @Override
2813         void onKeyUp(long eventTime, int count, int displayId, int deviceId, int metaState) {
2814             if (mShouldEarlyShortPressOnPower && count == 1) {
2815                 powerPress(eventTime, 1 /*pressCount*/, displayId);
2816             }
2817         }
2818     }
2819 
2820     /**
2821      * Rule for single back key gesture.
2822      */
2823     private final class BackKeyRule extends SingleKeyGestureDetector.SingleKeyRule {
2824         BackKeyRule() {
2825             super(KEYCODE_BACK);
2826         }
2827 
2828         @Override
2829         boolean supportLongPress() {
2830             return hasLongPressOnBackBehavior();
2831         }
2832 
2833         @Override
2834         int getMaxMultiPressCount() {
2835             return 1;
2836         }
2837 
2838         @Override
2839         void onPress(long downTime, int unusedDisplayId) {
2840             mBackKeyHandled |= backKeyPress();
2841         }
2842 
2843         @Override
2844         void onLongPress(long downTime) {
2845             backLongPress();
2846         }
2847     }
2848 
2849     /**
2850      * Rule for single stem primary key gesture.
2851      */
2852     private final class StemPrimaryKeyRule extends SingleKeyGestureDetector.SingleKeyRule {
2853         StemPrimaryKeyRule() {
2854             super(KeyEvent.KEYCODE_STEM_PRIMARY);
2855         }
2856 
2857         @Override
2858         boolean supportLongPress() {
2859             return hasLongPressOnStemPrimaryBehavior();
2860         }
2861 
2862         @Override
2863         int getMaxMultiPressCount() {
2864             return getMaxMultiPressStemPrimaryCount();
2865         }
2866 
2867         @Override
2868         void onPress(long downTime, int unusedDisplayId) {
2869             if (shouldHandleStemPrimaryEarlyShortPress()) {
2870                 return;
2871             }
2872             // Short-press should be triggered only if app doesn't handle it.
2873             mDeferredKeyActionExecutor.queueKeyAction(
2874                     KeyEvent.KEYCODE_STEM_PRIMARY, downTime, () -> stemPrimaryPress(1 /*count*/));
2875         }
2876 
2877         @Override
2878         void onLongPress(long eventTime) {
2879             if (mLongPressOnStemPrimaryBehavior == LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT) {
2880                 // Long-press to assistant gesture is not overridable by apps.
2881                 stemPrimaryLongPress(eventTime);
2882             } else {
2883                 // Other long-press actions should be triggered only if app doesn't handle it.
2884                 mDeferredKeyActionExecutor.queueKeyAction(
2885                         KeyEvent.KEYCODE_STEM_PRIMARY,
2886                         eventTime,
2887                         () -> stemPrimaryLongPress(eventTime));
2888             }
2889         }
2890 
2891         @Override
2892         void onMultiPress(long downTime, int count, int unusedDisplayId) {
2893             // Triple-press stem to toggle accessibility gesture should always be triggered
2894             // regardless of if app handles it.
2895             if (count == 3
2896                     && mTriplePressOnStemPrimaryBehavior
2897                     == TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY) {
2898                 // Cancel any queued actions for current key code to prevent them from being
2899                 // launched after a11y layer enabled. If the action happens early,
2900                 // undoEarlySinglePress will make sure the correct task is on top.
2901                 mDeferredKeyActionExecutor.cancelQueuedAction(KeyEvent.KEYCODE_STEM_PRIMARY);
2902                 undoEarlySinglePress();
2903                 stemPrimaryPress(count);
2904             } else {
2905                 // Other multi-press gestures should be triggered only if app doesn't handle it.
2906                 mDeferredKeyActionExecutor.queueKeyAction(
2907                         KeyEvent.KEYCODE_STEM_PRIMARY, downTime, () -> stemPrimaryPress(count));
2908             }
2909         }
2910 
2911         /**
2912          * This method undo the previously launched early-single-press action by bringing the
2913          * focused task before launching early-single-press back to top.
2914          */
2915         private void undoEarlySinglePress() {
2916             if (shouldHandleStemPrimaryEarlyShortPress()
2917                     && mFocusedTaskInfoOnStemPrimarySingleKeyUp != null) {
2918                 try {
2919                     mActivityManagerService.startActivityFromRecents(
2920                             mFocusedTaskInfoOnStemPrimarySingleKeyUp.taskId, null);
2921                 } catch (RemoteException | IllegalArgumentException e) {
2922                     Slog.e(
2923                             TAG,
2924                             "Failed to start task "
2925                                     + mFocusedTaskInfoOnStemPrimarySingleKeyUp.taskId
2926                                     + " from recents",
2927                             e);
2928                 }
2929             }
2930         }
2931 
2932         @Override
2933         void onKeyUp(long eventTime, int count, int displayId, int deviceId, int metaState) {
2934             if (count == 1) {
2935                 // Save info about the most recent task on the first press of the stem key. This
2936                 // may be used later to switch to the most recent app using double press gesture.
2937                 // It is possible that we may navigate away from this task before the double
2938                 // press is detected, as a result of the first press, so we save the  current
2939                 // most recent task before that happens.
2940                 // TODO(b/311497918): guard this with DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP
2941                 mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp =
2942                         mActivityTaskManagerInternal.getMostRecentTaskFromBackground();
2943 
2944                 mFocusedTaskInfoOnStemPrimarySingleKeyUp = null;
2945 
2946                 if (shouldHandleStemPrimaryEarlyShortPress()) {
2947                     // Key-up gesture should be triggered only if app doesn't handle it.
2948                     mDeferredKeyActionExecutor.queueKeyAction(
2949                             KeyEvent.KEYCODE_STEM_PRIMARY,
2950                             eventTime,
2951                             () -> {
2952                                 Slog.d(TAG, "StemPrimaryKeyRule: executing deferred onKeyUp");
2953                                 // Save the info of the focused task on screen. This may be used
2954                                 // later to bring the current focused task back to top. For
2955                                 // example, stem primary triple press enables the A11y interface
2956                                 // on top of the current focused task. When early single press is
2957                                 // enabled for stem primary, the focused task could change to
2958                                 // something else upon first key up event. In that case, we will
2959                                 // bring the task recorded by this variable back to top. Then, start
2960                                 // A11y interface.
2961                                 try {
2962                                     mFocusedTaskInfoOnStemPrimarySingleKeyUp =
2963                                             mActivityManagerService.getFocusedRootTaskInfo();
2964                                 } catch (RemoteException e) {
2965                                     Slog.e(
2966                                             TAG,
2967                                             "StemPrimaryKeyRule: onKeyUp: error while getting "
2968                                                     + "focused task "
2969                                                     + "info.",
2970                                             e);
2971                                 }
2972 
2973                                 stemPrimaryPress(1);
2974                             });
2975                 }
2976             }
2977         }
2978 
2979         // TODO(b/311497918): make a shouldHandlePowerEarlyShortPress for power button.
2980         private boolean shouldHandleStemPrimaryEarlyShortPress() {
2981             return mShouldEarlyShortPressOnStemPrimary
2982                     && mShortPressOnStemPrimaryBehavior == SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS;
2983         }
2984     }
2985 
2986     // TODO(b/358569822): Move to KeyGestureController.
2987     private final class StylusTailButtonRule extends SingleKeyGestureDetector.SingleKeyRule {
2988         StylusTailButtonRule() {
2989             super(KEYCODE_STYLUS_BUTTON_TAIL);
2990         }
2991 
2992         @Override
2993         int getMaxMultiPressCount() {
2994             return 2;
2995         }
2996 
2997         @Override
2998         void onPress(long downTime, int displayId) {
2999 
3000         }
3001 
3002         @Override
3003         void onKeyUp(long eventTime, int pressCount, int displayId, int deviceId, int metaState) {
3004             if (pressCount != 1) {
3005                 return;
3006             }
3007             // Single press on tail button triggers the open notes gesture.
3008             handleKeyGestureInKeyGestureController(KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_NOTES,
3009                     deviceId, KEYCODE_STYLUS_BUTTON_TAIL, metaState);
3010         }
3011     }
3012 
3013     private void initSingleKeyGestureRules(Looper looper) {
3014         mSingleKeyGestureDetector = SingleKeyGestureDetector.get(mContext, looper);
3015         mSingleKeyGestureDetector.addRule(new PowerKeyRule());
3016         if (hasLongPressOnBackBehavior()) {
3017             mSingleKeyGestureDetector.addRule(new BackKeyRule());
3018         }
3019         if (hasStemPrimaryBehavior()) {
3020             mSingleKeyGestureDetector.addRule(new StemPrimaryKeyRule());
3021         }
3022         mSingleKeyGestureDetector.addRule(new StylusTailButtonRule());
3023     }
3024 
3025     /**
3026      * Read values from config.xml that may be overridden depending on
3027      * the configuration of the device.
3028      * eg. Disable long press on home goes to recents on sw600dp.
3029      */
3030     private void readConfigurationDependentBehaviors() {
3031         final Resources res = mContext.getResources();
3032 
3033         mLongPressOnHomeBehavior = res.getInteger(
3034                 com.android.internal.R.integer.config_longPressOnHomeBehavior);
3035         if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
3036                 mLongPressOnHomeBehavior > LAST_LONG_PRESS_HOME_BEHAVIOR) {
3037             mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
3038         }
3039 
3040         mDoubleTapOnHomeBehavior = res.getInteger(
3041                 com.android.internal.R.integer.config_doubleTapOnHomeBehavior);
3042         if (mDoubleTapOnHomeBehavior < DOUBLE_TAP_HOME_NOTHING ||
3043                 mDoubleTapOnHomeBehavior > DOUBLE_TAP_HOME_PIP_MENU) {
3044             mDoubleTapOnHomeBehavior = DOUBLE_TAP_HOME_NOTHING;
3045         }
3046 
3047         mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_NOTHING;
3048         if (mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
3049             mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE;
3050         }
3051 
3052         mSettingsKeyBehavior = res.getInteger(
3053                 com.android.internal.R.integer.config_settingsKeyBehavior);
3054         if (mSettingsKeyBehavior < SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY
3055                 || mSettingsKeyBehavior > LAST_SETTINGS_KEY_BEHAVIOR) {
3056             mSettingsKeyBehavior = SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY;
3057         }
3058     }
3059 
3060     private void updateSettings() {
3061         updateSettings(null);
3062     }
3063 
3064     /**
3065      * Update provider Setting values on a given {@code handler}, or synchronously if {@code null}
3066      * is passed for handler.
3067      */
3068     void updateSettings(Handler handler) {
3069         if (handler != null) {
3070             handler.post(() -> updateSettings(null));
3071             return;
3072         }
3073         ContentResolver resolver = mContext.getContentResolver();
3074         boolean updateRotation = false;
3075         boolean updateKidsModeSettings = false;
3076         final boolean kidsModeEnabled;
3077         synchronized (mLock) {
3078             mEndcallBehavior = Settings.System.getIntForUser(resolver,
3079                     Settings.System.END_BUTTON_BEHAVIOR,
3080                     Settings.System.END_BUTTON_BEHAVIOR_DEFAULT,
3081                     UserHandle.USER_CURRENT);
3082             mIncallPowerBehavior = Settings.Secure.getIntForUser(resolver,
3083                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
3084                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT,
3085                     UserHandle.USER_CURRENT);
3086             mIncallBackBehavior = Settings.Secure.getIntForUser(resolver,
3087                     Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR,
3088                     Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_DEFAULT,
3089                     UserHandle.USER_CURRENT);
3090             mSystemNavigationKeysEnabled = Settings.Secure.getIntForUser(resolver,
3091                     Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
3092                     0, UserHandle.USER_CURRENT) == 1;
3093             mRingerToggleChord = Settings.Secure.getIntForUser(resolver,
3094                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
3095                     UserHandle.USER_CURRENT);
3096             mPowerButtonSuppressionDelayMillis = Settings.Global.getInt(resolver,
3097                     Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE,
3098                     POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS);
3099             if (!mContext.getResources()
3100                     .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
3101                 mRingerToggleChord = VOLUME_HUSH_OFF;
3102             }
3103 
3104             // Configure wake gesture.
3105             boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
3106                     Settings.Secure.WAKE_GESTURE_ENABLED, 0,
3107                     UserHandle.USER_CURRENT) != 0;
3108             if (mWakeGestureEnabledSetting != wakeGestureEnabledSetting) {
3109                 mWakeGestureEnabledSetting = wakeGestureEnabledSetting;
3110                 updateWakeGestureListenerLp();
3111             }
3112 
3113             // use screen off timeout setting as the timeout for the lockscreen
3114             mLockScreenTimeout = Settings.System.getIntForUser(resolver,
3115                     Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT);
3116             String imId = Settings.Secure.getStringForUser(resolver,
3117                     Settings.Secure.DEFAULT_INPUT_METHOD, UserHandle.USER_CURRENT);
3118             boolean hasSoftInput = imId != null && imId.length() > 0;
3119             if (mHasSoftInput != hasSoftInput) {
3120                 mHasSoftInput = hasSoftInput;
3121                 updateRotation = true;
3122             }
3123 
3124             mShortPressOnPowerBehavior = Settings.Global.getInt(resolver,
3125                     Settings.Global.POWER_BUTTON_SHORT_PRESS,
3126                     mContext.getResources().getInteger(
3127                             com.android.internal.R.integer.config_shortPressOnPowerBehavior));
3128             mDoublePressOnPowerBehavior = Settings.Global.getInt(resolver,
3129                     Settings.Global.POWER_BUTTON_DOUBLE_PRESS,
3130                     mContext.getResources().getInteger(
3131                             com.android.internal.R.integer.config_doublePressOnPowerBehavior));
3132             mTriplePressOnPowerBehavior = Settings.Global.getInt(resolver,
3133                     Settings.Global.POWER_BUTTON_TRIPLE_PRESS,
3134                     mContext.getResources().getInteger(
3135                             com.android.internal.R.integer.config_triplePressOnPowerBehavior));
3136 
3137             final int longPressOnPowerBehavior = Settings.Global.getInt(resolver,
3138                     Settings.Global.POWER_BUTTON_LONG_PRESS,
3139                     mContext.getResources().getInteger(
3140                             com.android.internal.R.integer.config_longPressOnPowerBehavior));
3141             final int veryLongPressOnPowerBehavior = Settings.Global.getInt(resolver,
3142                     Settings.Global.POWER_BUTTON_VERY_LONG_PRESS,
3143                     mContext.getResources().getInteger(
3144                             com.android.internal.R.integer.config_veryLongPressOnPowerBehavior));
3145             if (mLongPressOnPowerBehavior != longPressOnPowerBehavior
3146                     || mVeryLongPressOnPowerBehavior != veryLongPressOnPowerBehavior) {
3147                 mLongPressOnPowerBehavior = longPressOnPowerBehavior;
3148                 mVeryLongPressOnPowerBehavior = veryLongPressOnPowerBehavior;
3149             }
3150 
3151             mLongPressOnPowerAssistantTimeoutMs = Settings.Global.getLong(
3152                     mContext.getContentResolver(),
3153                     Settings.Global.POWER_BUTTON_LONG_PRESS_DURATION_MS,
3154                     mContext.getResources().getInteger(
3155                             com.android.internal.R.integer.config_longPressOnPowerDurationMs));
3156 
3157             mPowerVolUpBehavior = Settings.Global.getInt(resolver,
3158                     Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
3159                     mContext.getResources().getInteger(
3160                             com.android.internal.R.integer.config_keyChordPowerVolumeUp));
3161 
3162             mShortPressOnStemPrimaryBehavior = Settings.Global.getInt(resolver,
3163                     Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS,
3164                     mContext.getResources().getInteger(
3165                             com.android.internal.R.integer.config_shortPressOnStemPrimaryBehavior));
3166             mDoublePressOnStemPrimaryBehavior = Settings.Global.getInt(resolver,
3167                     Settings.Global.STEM_PRIMARY_BUTTON_DOUBLE_PRESS,
3168                     mContext.getResources().getInteger(
3169                             com.android.internal.R.integer
3170                                     .config_doublePressOnStemPrimaryBehavior));
3171             mTriplePressOnStemPrimaryBehavior = Settings.Global.getInt(resolver,
3172                     Settings.Global.STEM_PRIMARY_BUTTON_TRIPLE_PRESS,
3173                     mContext.getResources().getInteger(
3174                             com.android.internal.R.integer
3175                                     .config_triplePressOnStemPrimaryBehavior));
3176             mLongPressOnStemPrimaryBehavior = Settings.Global.getInt(resolver,
3177                     Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS,
3178                     mContext.getResources().getInteger(
3179                             com.android.internal.R.integer.config_longPressOnStemPrimaryBehavior));
3180             mShouldEarlyShortPressOnPower =
3181                     mContext.getResources()
3182                             .getBoolean(com.android.internal.R.bool.config_shortPressEarlyOnPower);
3183             mShouldEarlyShortPressOnStemPrimary = mContext.getResources().getBoolean(
3184                     com.android.internal.R.bool.config_shortPressEarlyOnStemPrimary);
3185 
3186             mStylusButtonsEnabled = Settings.Secure.getIntForUser(resolver,
3187                     Secure.STYLUS_BUTTONS_ENABLED, 1, UserHandle.USER_CURRENT) == 1;
3188             mInputManagerInternal.setStylusButtonMotionEventsEnabled(mStylusButtonsEnabled);
3189 
3190             kidsModeEnabled = Settings.Secure.getIntForUser(resolver,
3191                     Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1;
3192             if (mKidsModeEnabled != kidsModeEnabled) {
3193                 mKidsModeEnabled = kidsModeEnabled;
3194                 updateKidsModeSettings = true;
3195             }
3196         }
3197         if (updateKidsModeSettings) {
3198             updateKidsModeSettings(kidsModeEnabled);
3199         }
3200         if (updateRotation) {
3201             updateRotation(true);
3202         }
3203     }
3204 
3205     private void updateKidsModeSettings(boolean kidsModeEnabled) {
3206         if (kidsModeEnabled) {
3207             // Needed since many Kids apps aren't optimised to support both orientations and it
3208             // will be hard for kids to understand the app compat mode.
3209             // TODO(229961548): Remove ignoreOrientationRequest exception for Kids Mode once
3210             //                  possible.
3211             if (mContext.getResources().getBoolean(R.bool.config_reverseDefaultRotation)) {
3212                 mWindowManagerInternal.setOrientationRequestPolicy(
3213                         true /* isIgnoreOrientationRequestDisabled */,
3214                         new int[]{SCREEN_ORIENTATION_LANDSCAPE,
3215                                 SCREEN_ORIENTATION_REVERSE_LANDSCAPE},
3216                         new int[]{SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
3217                                 SCREEN_ORIENTATION_SENSOR_LANDSCAPE});
3218             } else {
3219                 mWindowManagerInternal.setOrientationRequestPolicy(
3220                         true /* isIgnoreOrientationRequestDisabled */,
3221                         null /* fromOrientations */, null /* toOrientations */);
3222             }
3223         } else {
3224             mWindowManagerInternal.setOrientationRequestPolicy(
3225                     false /* isIgnoreOrientationRequestDisabled */,
3226                     null /* fromOrientations */, null /* toOrientations */);
3227         }
3228     }
3229 
3230     private DreamManagerInternal getDreamManagerInternal() {
3231         if (mDreamManagerInternal == null) {
3232             // If mDreamManagerInternal is null, attempt to re-fetch it.
3233             mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
3234         }
3235 
3236         return mDreamManagerInternal;
3237     }
3238 
3239     private void updateWakeGestureListenerLp() {
3240         if (shouldEnableWakeGestureLp()) {
3241             mWakeGestureListener.requestWakeUpTrigger();
3242         } else {
3243             mWakeGestureListener.cancelWakeUpTrigger();
3244         }
3245     }
3246 
3247     private boolean shouldEnableWakeGestureLp() {
3248         return mWakeGestureEnabledSetting && !mDefaultDisplayPolicy.isAwake()
3249                 && (getLidBehavior() != LID_BEHAVIOR_SLEEP
3250                 || mDefaultDisplayPolicy.getLidState() != LID_CLOSED)
3251                 && mWakeGestureListener.isSupported();
3252     }
3253 
3254     /** {@inheritDoc} */
3255     @Override
3256     public int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName,
3257             int[] outAppOp, int displayId) {
3258         if (isRoundedCornerOverlay && mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
3259                 != PERMISSION_GRANTED) {
3260             return ADD_PERMISSION_DENIED;
3261         }
3262 
3263         outAppOp[0] = AppOpsManager.OP_NONE;
3264 
3265         if (!((type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW)
3266                 || (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW)
3267                 || (type >= FIRST_SYSTEM_WINDOW && type <= LAST_SYSTEM_WINDOW))) {
3268             return WindowManagerGlobal.ADD_INVALID_TYPE;
3269         }
3270 
3271         if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) {
3272             // Window manager will make sure these are okay.
3273             return ADD_OKAY;
3274         }
3275 
3276         if (!isSystemAlertWindowType(type)) {
3277             switch (type) {
3278                 case TYPE_TOAST:
3279                     // Only apps that target older than O SDK can add window without a token, after
3280                     // that we require a token so apps cannot add toasts directly as the token is
3281                     // added by the notification system.
3282                     // Window manager does the checking for this.
3283                     outAppOp[0] = OP_TOAST_WINDOW;
3284                     return ADD_OKAY;
3285                 case TYPE_ACCESSIBILITY_OVERLAY:
3286                     if (createAccessibilityOverlayAppOpEnabled()) {
3287                         outAppOp[0] = OP_CREATE_ACCESSIBILITY_OVERLAY;
3288                         return ADD_OKAY;
3289                     }
3290                 case TYPE_INPUT_METHOD:
3291                 case TYPE_WALLPAPER:
3292                 case TYPE_PRESENTATION:
3293                 case TYPE_PRIVATE_PRESENTATION:
3294                 case TYPE_VOICE_INTERACTION:
3295                 case TYPE_QS_DIALOG:
3296                 case TYPE_NAVIGATION_BAR_PANEL:
3297                 case TYPE_STATUS_BAR:
3298                 case TYPE_NOTIFICATION_SHADE:
3299                 case TYPE_NAVIGATION_BAR:
3300                 case TYPE_STATUS_BAR_ADDITIONAL:
3301                 case TYPE_STATUS_BAR_SUB_PANEL:
3302                 case TYPE_VOICE_INTERACTION_STARTING:
3303                     // The window manager will check these.
3304                     return ADD_OKAY;
3305             }
3306 
3307             return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
3308                     == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
3309         }
3310 
3311         // Things get a little more interesting for alert windows...
3312         outAppOp[0] = OP_SYSTEM_ALERT_WINDOW;
3313 
3314         final int callingUid = Binder.getCallingUid();
3315         // system processes will be automatically granted privilege to draw
3316         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
3317             return ADD_OKAY;
3318         }
3319 
3320         ApplicationInfo appInfo;
3321         try {
3322             appInfo = mPackageManager.getApplicationInfoAsUser(
3323                             packageName,
3324                             0 /* flags */,
3325                             UserHandle.getUserId(callingUid));
3326         } catch (PackageManager.NameNotFoundException e) {
3327             appInfo = null;
3328         }
3329 
3330         if (appInfo == null || (type != TYPE_APPLICATION_OVERLAY && appInfo.targetSdkVersion >= O)) {
3331             /**
3332              * Apps targeting >= {@link Build.VERSION_CODES#O} are required to hold
3333              * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} (system signature apps)
3334              * permission to add alert windows that aren't
3335              * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}.
3336              */
3337             return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
3338                     == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
3339         }
3340 
3341         if (mContext.checkCallingOrSelfPermission(SYSTEM_APPLICATION_OVERLAY)
3342                 == PERMISSION_GRANTED) {
3343             return ADD_OKAY;
3344         }
3345 
3346         // Allow virtual device owners to add overlays on the trusted displays they own.
3347         if (mWindowManagerFuncs.isCallerVirtualDeviceOwner(displayId, callingUid)
3348                 && mWindowManagerFuncs.isDisplayTrusted(displayId)
3349                 && mContext.checkCallingOrSelfPermission(CREATE_VIRTUAL_DEVICE)
3350                 == PERMISSION_GRANTED) {
3351             return ADD_OKAY;
3352         }
3353 
3354         // check if user has enabled this operation. SecurityException will be thrown if this app
3355         // has not been allowed by the user. The reason to use "noteOp" (instead of checkOp) is to
3356         // make sure the usage is logged.
3357         final int mode = mAppOpsManager.noteOpNoThrow(outAppOp[0], callingUid, packageName,
3358                 null /* featureId */, "check-add");
3359         switch (mode) {
3360             case AppOpsManager.MODE_ALLOWED:
3361             case AppOpsManager.MODE_IGNORED:
3362                 // although we return ADD_OKAY for MODE_IGNORED, the added window will
3363                 // actually be hidden in WindowManagerService
3364                 return ADD_OKAY;
3365             case AppOpsManager.MODE_ERRORED:
3366                 // Don't crash legacy apps
3367                 if (appInfo.targetSdkVersion < M) {
3368                     return ADD_OKAY;
3369                 }
3370                 return ADD_PERMISSION_DENIED;
3371             default:
3372                 // in the default mode, we will make a decision here based on
3373                 // checkCallingPermission()
3374                 return (mContext.checkCallingOrSelfPermission(SYSTEM_ALERT_WINDOW)
3375                         == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
3376         }
3377     }
3378 
3379     void readLidState() {
3380         mDefaultDisplayPolicy.setLidState(mWindowManagerFuncs.getLidState());
3381     }
3382 
3383     private void readCameraLensCoverState() {
3384         mCameraLensCoverState = mWindowManagerFuncs.getCameraLensCoverState();
3385     }
3386 
3387     private boolean isHidden(int accessibilityMode) {
3388         final int lidState = mDefaultDisplayPolicy.getLidState();
3389         switch (accessibilityMode) {
3390             case 1:
3391                 return lidState == LID_CLOSED;
3392             case 2:
3393                 return lidState == LID_OPEN;
3394             default:
3395                 return false;
3396         }
3397     }
3398 
3399     /** {@inheritDoc} */
3400     @Override
3401     public void adjustConfigurationLw(Configuration config, int keyboardPresence,
3402             int navigationPresence) {
3403         mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0;
3404 
3405         readConfigurationDependentBehaviors();
3406         readLidState();
3407 
3408         if (config.keyboard == Configuration.KEYBOARD_NOKEYS
3409                 || (keyboardPresence == PRESENCE_INTERNAL
3410                         && isHidden(mLidKeyboardAccessibility))) {
3411             config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
3412             if (!mHasSoftInput) {
3413                 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
3414             }
3415         }
3416 
3417         if (config.navigation == Configuration.NAVIGATION_NONAV
3418                 || (navigationPresence == PRESENCE_INTERNAL
3419                         && isHidden(mLidNavigationAccessibility))) {
3420             config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES;
3421         }
3422     }
3423 
3424     @Override
3425     public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
3426         return attrs.type == TYPE_NOTIFICATION_SHADE;
3427     }
3428 
3429     @Override
3430     public Animation createHiddenByKeyguardExit(boolean onWallpaper,
3431             boolean goingToNotificationShade, boolean subtleAnimation) {
3432         return TransitionAnimation.createHiddenByKeyguardExit(mContext,
3433                 mLogDecelerateInterpolator, onWallpaper, goingToNotificationShade, subtleAnimation);
3434     }
3435 
3436 
3437     @Override
3438     public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) {
3439         if (goingToNotificationShade) {
3440             return null;
3441         } else {
3442             return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit);
3443         }
3444     }
3445 
3446     private static void awakenDreams() {
3447         IDreamManager dreamManager = getDreamManager();
3448         if (dreamManager != null) {
3449             try {
3450                 dreamManager.awaken();
3451             } catch (RemoteException e) {
3452                 // fine, stay asleep then
3453             }
3454         }
3455     }
3456 
3457     static IDreamManager getDreamManager() {
3458         return IDreamManager.Stub.asInterface(
3459                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
3460     }
3461 
3462     TelecomManager getTelecommService() {
3463         return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
3464     }
3465 
3466     NotificationManager getNotificationService() {
3467         return mContext.getSystemService(NotificationManager.class);
3468     }
3469 
3470     static IAudioService getAudioService() {
3471         IAudioService audioService = IAudioService.Stub.asInterface(
3472                 ServiceManager.checkService(Context.AUDIO_SERVICE));
3473         if (audioService == null) {
3474             Log.w(TAG, "Unable to find IAudioService interface.");
3475         }
3476         return audioService;
3477     }
3478 
3479     boolean keyguardOn() {
3480         return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode();
3481     }
3482 
3483     private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
3484             WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
3485             WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
3486         };
3487 
3488     private void notifyKeyGestureCompletedOnActionUp(KeyEvent event,
3489             @KeyGestureEvent.KeyGestureType int gestureType) {
3490         if (event.getAction() != KeyEvent.ACTION_UP) {
3491             return;
3492         }
3493         notifyKeyGestureCompleted(event, gestureType);
3494     }
3495 
3496     private void notifyKeyGestureCompletedOnActionDown(KeyEvent event,
3497             @KeyGestureEvent.KeyGestureType int gestureType) {
3498         if (event.getAction() != KeyEvent.ACTION_DOWN) {
3499             return;
3500         }
3501         notifyKeyGestureCompleted(event, gestureType);
3502     }
3503 
3504     private void notifyKeyGestureCompleted(KeyEvent event,
3505             @KeyGestureEvent.KeyGestureType int gestureType) {
3506         if (gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED) {
3507             return;
3508         }
3509         mInputManagerInternal.notifyKeyGestureCompleted(event.getDeviceId(),
3510                 new int[]{event.getKeyCode()}, event.getMetaState(), gestureType);
3511     }
3512 
3513     private void handleKeyGestureInKeyGestureController(
3514             @KeyGestureEvent.KeyGestureType int gestureType, int deviceId, int keyCode,
3515             int metaState) {
3516         if (gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED) {
3517             return;
3518         }
3519         mInputManagerInternal.handleKeyGestureInKeyGestureController(deviceId, new int[]{keyCode},
3520                 metaState, gestureType);
3521     }
3522 
3523     @Override
3524     public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) {
3525         if (useKeyGestureEventHandler()) {
3526             return mModifierShortcutManager.getApplicationLaunchKeyboardShortcuts(deviceId,
3527                     mInputManager.getAppLaunchBookmarks());
3528         }
3529         return mModifierShortcutManager.getApplicationLaunchKeyboardShortcuts(deviceId);
3530     }
3531 
3532     // TODO(b/117479243): handle it in InputPolicy
3533     // TODO (b/283241997): Add the remaining keyboard shortcut logging after refactoring
3534     /** {@inheritDoc} */
3535     @Override
3536     public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
3537             int policyFlags) {
3538         final int keyCode = event.getKeyCode();
3539         final int flags = event.getFlags();
3540         final long keyConsumed = -1;
3541         final long keyNotConsumed = 0;
3542         final int deviceId = event.getDeviceId();
3543 
3544         if (DEBUG_INPUT) {
3545             Log.d(TAG,
3546                     "interceptKeyTi keyCode=" + keyCode + " action=" + event.getAction()
3547                             + " repeatCount=" + event.getRepeatCount() + " keyguardOn="
3548                             + keyguardOn() + " canceled=" + event.isCanceled());
3549         }
3550 
3551         if (!InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures()) {
3552             if (mKeyCombinationManager.isKeyConsumed(event)) {
3553                 return keyConsumed;
3554             }
3555 
3556             if ((flags & KeyEvent.FLAG_FALLBACK) == 0) {
3557                 final long now = SystemClock.uptimeMillis();
3558                 final long interceptTimeout = mKeyCombinationManager.getKeyInterceptTimeout(
3559                         keyCode);
3560                 if (now < interceptTimeout) {
3561                     return interceptTimeout - now;
3562                 }
3563             }
3564         }
3565 
3566         Set<Integer> consumedKeys = mConsumedKeysForDevice.get(deviceId);
3567         if (consumedKeys == null) {
3568             consumedKeys = new HashSet<>();
3569             mConsumedKeysForDevice.put(deviceId, consumedKeys);
3570         }
3571 
3572         if (interceptSystemKeysAndShortcuts(focusedToken, event)
3573                 && event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
3574             consumedKeys.add(keyCode);
3575             return keyConsumed;
3576         }
3577 
3578         boolean needToConsumeKey = consumedKeys.contains(keyCode);
3579         if (event.getAction() == KeyEvent.ACTION_UP || event.isCanceled()) {
3580             consumedKeys.remove(keyCode);
3581             if (consumedKeys.isEmpty()) {
3582                 mConsumedKeysForDevice.remove(deviceId);
3583             }
3584         }
3585 
3586         return needToConsumeKey ? keyConsumed : keyNotConsumed;
3587     }
3588 
3589     // You can only start consuming the key gesture if ACTION_DOWN and repeat count
3590     // is 0. If you start intercepting the key halfway, then key will not be consumed
3591     // and will be sent to apps for processing too.
3592     // e.g. If a certain combination is only handled on ACTION_UP (i.e.
3593     // interceptShortcut() returns true only for ACTION_UP), then since we already
3594     // sent the ACTION_DOWN events to the application, we MUST also send the
3595     // ACTION_UP to the application.
3596     // So, to ensure that your intercept logic works properly, and we don't send any
3597     // conflicting events to application, make sure to consume the event on
3598     // ACTION_DOWN even if you want to do something on ACTION_UP. This is essential
3599     // to maintain event parity and to not have incomplete key gestures.
3600     //
3601     // NOTE: Please try not to add new Shortcut combinations here and instead use KeyGestureEvents.
3602     // Add shortcut trigger logic in {@code KeyGestureController} and add handling logic in
3603     // {@link handleKeyGesture()}
3604     private boolean interceptSystemKeysAndShortcuts(IBinder focusedToken, KeyEvent event) {
3605         if (useKeyGestureEventHandler()) {
3606             return interceptSystemKeysAndShortcutsNew(focusedToken, event);
3607         } else {
3608             return interceptSystemKeysAndShortcutsOld(focusedToken, event);
3609         }
3610     }
3611 
3612     @SuppressLint("MissingPermission")
3613     private boolean interceptSystemKeysAndShortcutsOld(IBinder focusedToken, KeyEvent event) {
3614         final boolean keyguardOn = keyguardOn();
3615         final int keyCode = event.getKeyCode();
3616         final int repeatCount = event.getRepeatCount();
3617         final int metaState = event.getMetaState();
3618         final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
3619         final boolean canceled = event.isCanceled();
3620         final int displayId = event.getDisplayId();
3621         final int deviceId = event.getDeviceId();
3622         final boolean firstDown = down && repeatCount == 0;
3623 
3624         // Cancel any pending meta actions if we see any other keys being pressed between the
3625         // down of the meta key and its corresponding up.
3626         if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) {
3627             mPendingMetaAction = false;
3628         }
3629         // Any key that is not Alt or Meta cancels Caps Lock combo tracking.
3630         if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) {
3631             mPendingCapsLockToggle = false;
3632         }
3633 
3634         if (isUserSetupComplete() && !keyguardOn) {
3635             if (mModifierShortcutManager.interceptKey(event)) {
3636                 if (isKeyEventForCurrentUser(
3637                         event.getDisplayId(), event.getKeyCode(),
3638                         "dismissKeyboardShortcutsMenu")) {
3639                     dismissKeyboardShortcutsMenu();
3640                 }
3641                 mPendingMetaAction = false;
3642                 mPendingCapsLockToggle = false;
3643                 return true;
3644             }
3645         }
3646 
3647         switch (keyCode) {
3648             case KeyEvent.KEYCODE_HOME:
3649                 return handleHomeShortcuts(focusedToken, event);
3650             case KeyEvent.KEYCODE_RECENT_APPS:
3651                 if (firstDown) {
3652                     showRecentApps(false /* triggeredFromAltTab */);
3653                     notifyKeyGestureCompleted(event,
3654                             KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS);
3655                 }
3656                 return true;
3657             case KeyEvent.KEYCODE_APP_SWITCH:
3658                 if (!keyguardOn) {
3659                     if (firstDown) {
3660                         preloadRecentApps();
3661                     } else if (!down) {
3662                         toggleRecentApps();
3663                         notifyKeyGestureCompleted(event,
3664                                 KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH);
3665                     }
3666                 }
3667                 return true;
3668             case KeyEvent.KEYCODE_A:
3669                 if (firstDown && event.isMetaPressed()) {
3670                     launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD,
3671                             deviceId, event.getEventTime(),
3672                             AssistUtils.INVOCATION_TYPE_UNKNOWN);
3673                     notifyKeyGestureCompleted(event,
3674                             KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
3675                     return true;
3676                 }
3677                 break;
3678             case KeyEvent.KEYCODE_H:
3679             case KeyEvent.KEYCODE_ENTER:
3680                 if (event.isMetaPressed()) {
3681                     return handleHomeShortcuts(focusedToken, event);
3682                 }
3683                 break;
3684             case KeyEvent.KEYCODE_I:
3685                 if (firstDown && event.isMetaPressed() && isUserSetupComplete() && !keyguardOn) {
3686                     showSystemSettings();
3687                     notifyKeyGestureCompleted(event,
3688                             KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS);
3689                     return true;
3690                 }
3691                 break;
3692             case KeyEvent.KEYCODE_L:
3693                 if (firstDown && event.isMetaPressed()) {
3694                     lockNow(null /* options */);
3695                     notifyKeyGestureCompleted(event,
3696                             KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN);
3697                     return true;
3698                 }
3699                 break;
3700             case KeyEvent.KEYCODE_N:
3701                 if (firstDown && event.isMetaPressed()) {
3702                     toggleNotificationPanel();
3703                     notifyKeyGestureCompleted(event,
3704                             KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
3705                     return true;
3706                 }
3707                 break;
3708             case KeyEvent.KEYCODE_S:
3709                 if (firstDown && event.isMetaPressed()) {
3710                     interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
3711                     notifyKeyGestureCompleted(event,
3712                             KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT);
3713                     return true;
3714                 }
3715                 break;
3716             case KeyEvent.KEYCODE_T:
3717                 if (enableTalkbackAndMagnifierKeyGestures()) {
3718                     if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
3719                         mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
3720                                 TalkbackShortcutController.ShortcutSource.KEYBOARD);
3721                         notifyKeyGestureCompleted(event,
3722                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
3723                         return true;
3724                     }
3725                 }
3726                 break;
3727             case KeyEvent.KEYCODE_3:
3728                 if (keyboardA11yShortcutControl()) {
3729                     if (firstDown && event.isMetaPressed()
3730                             && event.isAltPressed()) {
3731                         final boolean bounceKeysEnabled =
3732                                 InputSettings.isAccessibilityBounceKeysEnabled(
3733                                         mContext);
3734                         InputSettings.setAccessibilityBounceKeysThreshold(mContext,
3735                                 bounceKeysEnabled ? 0
3736                                         : InputSettings.DEFAULT_BOUNCE_KEYS_THRESHOLD_MILLIS);
3737                         notifyKeyGestureCompleted(event,
3738                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS);
3739                         return true;
3740                     }
3741                 }
3742                 break;
3743             case KeyEvent.KEYCODE_4:
3744                 if (InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled()
3745                         && keyboardA11yShortcutControl()) {
3746                     if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
3747                         final boolean mouseKeysEnabled =
3748                                 InputSettings.isAccessibilityMouseKeysEnabled(
3749                                         mContext);
3750                         InputSettings.setAccessibilityMouseKeysEnabled(mContext,
3751                                 !mouseKeysEnabled);
3752                         notifyKeyGestureCompleted(event,
3753                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS);
3754                         return true;
3755                     }
3756                 }
3757                 break;
3758             case KeyEvent.KEYCODE_5:
3759                 if (keyboardA11yShortcutControl()) {
3760                     if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
3761                         final boolean stickyKeysEnabled =
3762                                 InputSettings.isAccessibilityStickyKeysEnabled(
3763                                         mContext);
3764                         InputSettings.setAccessibilityStickyKeysEnabled(mContext,
3765                                 !stickyKeysEnabled);
3766                         notifyKeyGestureCompleted(event,
3767                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS);
3768                         return true;
3769                     }
3770                 }
3771                 break;
3772             case KeyEvent.KEYCODE_6:
3773                 if (keyboardA11yShortcutControl()) {
3774                     if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
3775                         final boolean slowKeysEnabled =
3776                                 InputSettings.isAccessibilitySlowKeysEnabled(mContext);
3777                         InputSettings.setAccessibilitySlowKeysThreshold(mContext,
3778                                 slowKeysEnabled ? 0
3779                                         : InputSettings.DEFAULT_SLOW_KEYS_THRESHOLD_MILLIS);
3780                         notifyKeyGestureCompleted(event,
3781                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS);
3782                         return true;
3783                     }
3784                 }
3785                 break;
3786             case KeyEvent.KEYCODE_DEL:
3787                 if (newBugreportKeyboardShortcut()) {
3788                     if (mEnableBugReportKeyboardShortcut && firstDown
3789                             && event.isMetaPressed() && event.isCtrlPressed()) {
3790                         try {
3791                             if (!mActivityManagerService.launchBugReportHandlerApp()) {
3792                                 mActivityManagerService.requestInteractiveBugReport();
3793                             }
3794                         } catch (RemoteException e) {
3795                             Slog.d(TAG, "Error taking bugreport", e);
3796                         }
3797                         notifyKeyGestureCompleted(event,
3798                                 KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT);
3799                         return true;
3800                     }
3801                 }
3802                 break;
3803             case KeyEvent.KEYCODE_ESCAPE:
3804                 if (firstDown && event.isMetaPressed()) {
3805                     notifyKeyGestureCompleted(event,
3806                             KeyGestureEvent.KEY_GESTURE_TYPE_BACK);
3807                     injectBackGesture(event.getDownTime());
3808                     return true;
3809                 }
3810                 break;
3811             case KeyEvent.KEYCODE_DPAD_UP:
3812                 if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) {
3813                     StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
3814                     if (statusbar != null) {
3815                         statusbar.moveFocusedTaskToFullscreen(getTargetDisplayIdForKeyEvent(event));
3816                         notifyKeyGestureCompleted(event,
3817                                 KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION);
3818                         return true;
3819                     }
3820                 }
3821                 break;
3822             case KeyEvent.KEYCODE_DPAD_DOWN:
3823                 if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) {
3824                     StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
3825                     if (statusbar != null) {
3826                         statusbar.moveFocusedTaskToDesktop(getTargetDisplayIdForKeyEvent(event));
3827                         notifyKeyGestureCompleted(event,
3828                                 KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE);
3829                         return true;
3830                     }
3831                 }
3832                 break;
3833             case KeyEvent.KEYCODE_DPAD_LEFT:
3834                 if (firstDown && event.isMetaPressed()) {
3835                     if (event.isCtrlPressed()) {
3836                         moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyEvent(event),
3837                                 true /* leftOrTop */);
3838                         notifyKeyGestureCompleted(event,
3839                                 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT);
3840                     } else {
3841                         notifyKeyGestureCompleted(event,
3842                                 KeyGestureEvent.KEY_GESTURE_TYPE_BACK);
3843                         injectBackGesture(event.getDownTime());
3844                     }
3845                     return true;
3846                 }
3847                 break;
3848             case KeyEvent.KEYCODE_DPAD_RIGHT:
3849                 if (firstDown && event.isMetaPressed()) {
3850                     if (event.isCtrlPressed()) {
3851                         moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyEvent(event),
3852                                 false /* leftOrTop */);
3853                         notifyKeyGestureCompleted(event,
3854                                 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT);
3855                         return true;
3856                     }
3857                 }
3858                 break;
3859             case KeyEvent.KEYCODE_SLASH:
3860                 if (firstDown && event.isMetaPressed() && !keyguardOn) {
3861                     toggleKeyboardShortcutsMenu(event.getDeviceId());
3862                     notifyKeyGestureCompleted(event,
3863                             KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER);
3864                     return true;
3865                 }
3866                 break;
3867             case KeyEvent.KEYCODE_ASSIST:
3868                 Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing");
3869                 return true;
3870             case KeyEvent.KEYCODE_VOICE_ASSIST:
3871                 Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in"
3872                         + " interceptKeyBeforeQueueing");
3873                 return true;
3874             case KeyEvent.KEYCODE_BRIGHTNESS_UP:
3875             case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
3876                 if (down) {
3877                     int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1;
3878 
3879                     changeDisplayBrightnessValue(displayId, direction);
3880 
3881                     int gestureType = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN
3882                             ? KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN
3883                             : KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP;
3884                     notifyKeyGestureCompleted(event, gestureType);
3885                 }
3886                 return true;
3887             case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN:
3888                 if (down) {
3889                     mInputManagerInternal.decrementKeyboardBacklight(event.getDeviceId());
3890                     notifyKeyGestureCompleted(event,
3891                             KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN);
3892                 }
3893                 return true;
3894             case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_UP:
3895                 if (down) {
3896                     mInputManagerInternal.incrementKeyboardBacklight(event.getDeviceId());
3897                     notifyKeyGestureCompleted(event,
3898                             KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP);
3899                 }
3900                 return true;
3901             case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE:
3902                 // TODO: Add logic
3903                 if (!down) {
3904                     notifyKeyGestureCompleted(event,
3905                             KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE);
3906                 }
3907                 return true;
3908             case KeyEvent.KEYCODE_VOLUME_UP:
3909             case KeyEvent.KEYCODE_VOLUME_DOWN:
3910             case KeyEvent.KEYCODE_VOLUME_MUTE:
3911                 if (mUseTvRouting || mHandleVolumeKeysInWM) {
3912                     // On TVs or when the configuration is enabled, volume keys never
3913                     // go to the foreground app.
3914                     dispatchDirectAudioEvent(event);
3915                     return true;
3916                 }
3917 
3918                 // If the device is in VR mode and keys are "internal" (e.g. on the side of the
3919                 // device), then drop the volume keys and don't forward it to the
3920                 // application/dispatch the audio event.
3921                 if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) {
3922                     final InputDevice d = event.getDevice();
3923                     if (d != null && !d.isExternal()) {
3924                         return true;
3925                     }
3926                 }
3927                 break;
3928             case KeyEvent.KEYCODE_TAB:
3929                 if (firstDown && !keyguardOn && isUserSetupComplete()) {
3930                     if (event.isMetaPressed()) {
3931                         showRecentApps(false);
3932                         notifyKeyGestureCompleted(event,
3933                                 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS);
3934                         return true;
3935                     } else if (mRecentAppsHeldModifiers == 0) {
3936                         final int shiftlessModifiers =
3937                                 event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
3938                         if (KeyEvent.metaStateHasModifiers(
3939                                 shiftlessModifiers, KeyEvent.META_ALT_ON)) {
3940                             mRecentAppsHeldModifiers = shiftlessModifiers;
3941                             showRecentApps(true);
3942                             notifyKeyGestureCompleted(event,
3943                                     KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS);
3944                             return true;
3945                         }
3946                     }
3947                 }
3948                 break;
3949             case KeyEvent.KEYCODE_ALL_APPS:
3950                 if (firstDown) {
3951                     mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
3952                     Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS, new KeyEvent(event));
3953                     msg.setAsynchronous(true);
3954                     msg.sendToTarget();
3955 
3956                     notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
3957                 }
3958                 return true;
3959             case KeyEvent.KEYCODE_NOTIFICATION:
3960                 if (!down) {
3961                     toggleNotificationPanel();
3962                     notifyKeyGestureCompleted(event,
3963                             KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
3964                 }
3965                 return true;
3966             case KeyEvent.KEYCODE_SEARCH:
3967                 if (firstDown && !keyguardOn) {
3968                     switch (mSearchKeyBehavior) {
3969                         case SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY: {
3970                             launchTargetSearchActivity();
3971                             notifyKeyGestureCompleted(event,
3972                                     KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH);
3973                             return true;
3974                         }
3975                         case SEARCH_KEY_BEHAVIOR_DEFAULT_SEARCH:
3976                         default:
3977                             break;
3978                     }
3979                 }
3980                 break;
3981             case KeyEvent.KEYCODE_LANGUAGE_SWITCH:
3982                 if (firstDown) {
3983                     int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
3984                     sendSwitchKeyboardLayout(displayId, focusedToken, direction);
3985                     notifyKeyGestureCompleted(event,
3986                             KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH);
3987                     return true;
3988                 }
3989                 break;
3990             case KeyEvent.KEYCODE_META_LEFT:
3991             case KeyEvent.KEYCODE_META_RIGHT:
3992                 if (down) {
3993                     if (event.isAltPressed()) {
3994                         mPendingCapsLockToggle = true;
3995                         mPendingMetaAction = false;
3996                     } else {
3997                         mPendingCapsLockToggle = false;
3998                         mPendingMetaAction = true;
3999                     }
4000                 } else {
4001                     // Toggle Caps Lock on META-ALT.
4002                     if (mPendingCapsLockToggle) {
4003                         mInputManagerInternal.toggleCapsLock(event.getDeviceId());
4004                         mPendingCapsLockToggle = false;
4005                         notifyKeyGestureCompleted(event,
4006                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
4007                     } else if (mPendingMetaAction) {
4008                         if (!canceled) {
4009                             if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
4010                                     "launchAllAppsViaA11y")) {
4011                                 launchAllAppsAction();
4012                             }
4013                             notifyKeyGestureCompleted(event,
4014                                     KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
4015                         }
4016                         mPendingMetaAction = false;
4017                     }
4018                 }
4019                 return true;
4020             case KeyEvent.KEYCODE_ALT_LEFT:
4021             case KeyEvent.KEYCODE_ALT_RIGHT:
4022                 if (down) {
4023                     if (event.isMetaPressed()) {
4024                         mPendingCapsLockToggle = true;
4025                         mPendingMetaAction = false;
4026                     } else {
4027                         mPendingCapsLockToggle = false;
4028                     }
4029                 } else {
4030                     // hide recent if triggered by ALT-TAB.
4031                     if (mRecentAppsHeldModifiers != 0
4032                             && (metaState & mRecentAppsHeldModifiers) == 0) {
4033                         mRecentAppsHeldModifiers = 0;
4034                         hideRecentApps(true, false);
4035                         return true;
4036                     }
4037 
4038                     // Toggle Caps Lock on META-ALT.
4039                     if (mPendingCapsLockToggle) {
4040                         mInputManagerInternal.toggleCapsLock(event.getDeviceId());
4041                         mPendingCapsLockToggle = false;
4042                         notifyKeyGestureCompleted(event,
4043                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
4044                         return true;
4045                     }
4046                 }
4047                 break;
4048             case KeyEvent.KEYCODE_CAPS_LOCK:
4049                 if (!down) {
4050                     notifyKeyGestureCompleted(event,
4051                             KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
4052                 }
4053                 break;
4054             case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY:
4055             case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY:
4056             case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY:
4057             case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL:
4058                 Slog.wtf(TAG, "KEYCODE_STYLUS_BUTTON_* should be handled in"
4059                         + " interceptKeyBeforeQueueing");
4060                 return true;
4061             case KeyEvent.KEYCODE_SETTINGS:
4062                 if (firstDown) {
4063                     if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL) {
4064                         toggleNotificationPanel();
4065                         notifyKeyGestureCompleted(event,
4066                                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
4067                     } else if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY) {
4068                         showSystemSettings();
4069                         notifyKeyGestureCompleted(event,
4070                                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS);
4071                     }
4072                 }
4073                 return true;
4074             case KeyEvent.KEYCODE_STEM_PRIMARY:
4075                 if (prepareToSendSystemKeyToApplication(focusedToken, event)) {
4076                     // Send to app.
4077                     return false;
4078                 } else {
4079                     // Intercepted.
4080                     sendSystemKeyToStatusBarAsync(event);
4081                     return true;
4082                 }
4083             case KeyEvent.KEYCODE_SCREENSHOT:
4084                 if (firstDown) {
4085                     interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
4086                 }
4087                 return true;
4088             case KeyEvent.KEYCODE_DO_NOT_DISTURB:
4089             case KeyEvent.KEYCODE_LOCK:
4090             case KeyEvent.KEYCODE_FULLSCREEN:
4091                 return true;
4092         }
4093         if (isValidGlobalKey(keyCode)
4094                 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
4095             return true;
4096         }
4097 
4098         // Reserve all the META modifier combos for system behavior
4099         return (metaState & KeyEvent.META_META_ON) != 0;
4100     }
4101 
4102     private boolean interceptSystemKeysAndShortcutsNew(IBinder focusedToken, KeyEvent event) {
4103         final int keyCode = event.getKeyCode();
4104         final int metaState = event.getMetaState();
4105 
4106         switch (keyCode) {
4107             case KeyEvent.KEYCODE_HOME:
4108                 return handleHomeShortcuts(focusedToken, event);
4109             case KeyEvent.KEYCODE_VOLUME_UP:
4110             case KeyEvent.KEYCODE_VOLUME_DOWN:
4111             case KeyEvent.KEYCODE_VOLUME_MUTE:
4112                 if (mUseTvRouting || mHandleVolumeKeysInWM) {
4113                     // On TVs or when the configuration is enabled, volume keys never
4114                     // go to the foreground app.
4115                     dispatchDirectAudioEvent(event);
4116                     return true;
4117                 }
4118 
4119                 // If the device is in VR mode and keys are "internal" (e.g. on the side of the
4120                 // device), then drop the volume keys and don't forward it to the
4121                 // application/dispatch the audio event.
4122                 if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) {
4123                     final InputDevice d = event.getDevice();
4124                     if (d != null && !d.isExternal()) {
4125                         return true;
4126                     }
4127                 }
4128                 break;
4129             case KeyEvent.KEYCODE_STEM_PRIMARY:
4130                 if (prepareToSendSystemKeyToApplication(focusedToken, event)) {
4131                     // Send to app.
4132                     return false;
4133                 } else {
4134                     // Intercepted.
4135                     sendSystemKeyToStatusBarAsync(event);
4136                     return true;
4137                 }
4138         }
4139         if (isValidGlobalKey(keyCode)
4140                 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
4141             return true;
4142         }
4143 
4144         if (fixSearchModifierFallbacks()) {
4145             // Pass event as unhandled to give other services, e.g. InputManagerService, the
4146             // opportunity to determine if the event can be modified, e.g. generating a fallback for
4147             // meta/search events.
4148             return false;
4149         }
4150 
4151         // Reserve all the META modifier combos for system behavior
4152         return (metaState & KeyEvent.META_META_ON) != 0;
4153     }
4154 
4155     @SuppressLint("MissingPermission")
4156     private void initKeyGestures() {
4157         if (!useKeyGestureEventHandler()) {
4158             return;
4159         }
4160         List<Integer> supportedGestures = new ArrayList<>(List.of(
4161                 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS,
4162                 KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH,
4163                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT,
4164                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT,
4165                 KeyGestureEvent.KEY_GESTURE_TYPE_HOME,
4166                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS,
4167                 KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN,
4168                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
4169                 KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT,
4170                 KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT,
4171                 KeyGestureEvent.KEY_GESTURE_TYPE_BACK,
4172                 KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION,
4173                 KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE,
4174                 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT,
4175                 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT,
4176                 KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER,
4177                 KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP,
4178                 KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN,
4179                 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER,
4180                 KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS,
4181                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH,
4182                 KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH,
4183                 KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT,
4184                 KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS,
4185                 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
4186                 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB,
4187                 KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD,
4188                 KeyGestureEvent.KEY_GESTURE_TYPE_RINGER_TOGGLE_CHORD,
4189                 KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS,
4190                 KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT
4191         ));
4192         if (enableTalkbackAndMagnifierKeyGestures()) {
4193             supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
4194         }
4195         if (enableVoiceAccessKeyGestures()) {
4196             supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS);
4197         }
4198         mInputManager.registerKeyGestureEventHandler(supportedGestures,
4199                 PhoneWindowManager.this::handleKeyGestureEvent);
4200     }
4201 
4202     @VisibleForTesting
4203     void handleKeyGestureEvent(KeyGestureEvent event, IBinder focusedToken) {
4204         boolean start = event.getAction() == KeyGestureEvent.ACTION_GESTURE_START;
4205         boolean complete = event.getAction() == KeyGestureEvent.ACTION_GESTURE_COMPLETE
4206                 && !event.isCancelled();
4207         int deviceId = event.getDeviceId();
4208         int gestureType = event.getKeyGestureType();
4209         int displayId = event.getDisplayId();
4210         int modifierState = event.getModifierState();
4211         boolean keyguardOn = keyguardOn();
4212         boolean canLaunchApp = isUserSetupComplete() && !keyguardOn;
4213         if (!event.isCancelled() && Arrays.stream(event.getKeycodes()).anyMatch(
4214                 (keycode) -> keycode == KeyEvent.KEYCODE_POWER)) {
4215             mPowerKeyHandled = true;
4216         }
4217         switch (gestureType) {
4218             case KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS:
4219                 if (complete) {
4220                     showRecentApps(false);
4221                 }
4222                 break;
4223             case KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH:
4224                 if (!keyguardOn) {
4225                     if (start) {
4226                         preloadRecentApps();
4227                     } else if (complete) {
4228                         toggleRecentApps();
4229                     }
4230                 }
4231                 break;
4232             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT:
4233             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT:
4234                 if (complete && canLaunchApp) {
4235                     launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD,
4236                             deviceId, SystemClock.uptimeMillis(),
4237                             AssistUtils.INVOCATION_TYPE_UNKNOWN);
4238                 }
4239                 break;
4240             case KeyGestureEvent.KEY_GESTURE_TYPE_HOME:
4241                 if (complete) {
4242                     // Post to main thread to avoid blocking input pipeline.
4243                     mHandler.post(() -> handleShortPressOnHome(displayId));
4244                 }
4245                 break;
4246             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS:
4247                 if (complete && canLaunchApp) {
4248                     showSystemSettings();
4249                 }
4250                 break;
4251             case KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN:
4252                 if (complete) {
4253                     lockNow(null /* options */);
4254                 }
4255                 break;
4256             case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL:
4257                 if (complete) {
4258                     toggleNotificationPanel();
4259                 }
4260                 break;
4261             case KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT:
4262                 if (complete) {
4263                     interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
4264                 }
4265                 break;
4266             case KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT:
4267                 if (complete && mEnableBugReportKeyboardShortcut) {
4268                     try {
4269                         if (!mActivityManagerService.launchBugReportHandlerApp()) {
4270                             mActivityManagerService.requestInteractiveBugReport();
4271                         }
4272                     } catch (RemoteException e) {
4273                         Slog.d(TAG, "Error taking bugreport", e);
4274                     }
4275                 }
4276                 break;
4277             case KeyGestureEvent.KEY_GESTURE_TYPE_BACK:
4278                 if (complete) {
4279                     injectBackGesture(SystemClock.uptimeMillis());
4280                 }
4281                 break;
4282             case KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION:
4283                 if (complete) {
4284                     StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4285                     if (statusbar != null) {
4286                         statusbar.moveFocusedTaskToFullscreen(
4287                                 getTargetDisplayIdForKeyGestureEvent(event));
4288                     }
4289                 }
4290                 break;
4291             case KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE:
4292                 if (complete) {
4293                     StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4294                     if (statusbar != null) {
4295                         statusbar.moveFocusedTaskToDesktop(
4296                                 getTargetDisplayIdForKeyGestureEvent(event));
4297                     }
4298                 }
4299                 break;
4300             case KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT:
4301                 if (complete) {
4302                     moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyGestureEvent(event),
4303                             true /* leftOrTop */);
4304                 }
4305                 break;
4306             case KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT:
4307                 if (complete) {
4308                     moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyGestureEvent(event),
4309                             false /* leftOrTop */);
4310                 }
4311                 break;
4312             case KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER:
4313                 if (complete) {
4314                     toggleKeyboardShortcutsMenu(deviceId);
4315                 }
4316                 break;
4317             case KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP:
4318             case KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN:
4319                 if (complete) {
4320                     int direction =
4321                             gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP ? 1 : -1;
4322                     changeDisplayBrightnessValue(displayId, direction);
4323                 }
4324                 break;
4325             case KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER:
4326                 if (start) {
4327                     showRecentApps(true);
4328                 } else {
4329                     hideRecentApps(true, false);
4330                 }
4331                 break;
4332             case KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS:
4333                 if (complete && isKeyEventForCurrentUser(event.getDisplayId(),
4334                         event.getKeycodes()[0], "launchAllAppsViaA11y")) {
4335                     launchAllAppsAction();
4336                 }
4337                 break;
4338             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH:
4339                 if (complete && canLaunchApp) {
4340                     launchTargetSearchActivity();
4341                 }
4342                 break;
4343             case KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH:
4344                 if (complete) {
4345                     int direction = (modifierState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
4346                     sendSwitchKeyboardLayout(displayId, focusedToken, direction);
4347                 }
4348                 break;
4349             case KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD:
4350                 if (start) {
4351                     // Screenshot chord is pressed: Wait for long press delay before taking
4352                     // screenshot
4353                     interceptScreenshotChord(SCREENSHOT_KEY_CHORD,
4354                             getScreenshotChordLongPressDelay());
4355                 } else {
4356                     cancelPendingScreenshotChordAction();
4357                 }
4358                 break;
4359             case KeyGestureEvent.KEY_GESTURE_TYPE_RINGER_TOGGLE_CHORD:
4360                 if (start) {
4361                     interceptRingerToggleChord();
4362                 } else {
4363                     cancelPendingRingerToggleChordAction();
4364                 }
4365                 break;
4366             case KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS:
4367                 if (start) {
4368                     performHapticFeedback(
4369                             HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON,
4370                             "KEY_GESTURE_TYPE_GLOBAL_ACTIONS - Global Actions");
4371                     showGlobalActions();
4372                 } else {
4373                     cancelGlobalActionsAction();
4374                 }
4375                 break;
4376             case KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT:
4377                 if (start) {
4378                     interceptBugreportGestureTv();
4379                 } else {
4380                     cancelBugreportGestureTv();
4381                 }
4382                 break;
4383             case KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT:
4384                 if (complete && mAccessibilityShortcutController.isAccessibilityShortcutAvailable(
4385                         isKeyguardLocked())) {
4386                     mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT));
4387                 }
4388                 break;
4389             case KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS:
4390                 if (complete) {
4391                     mContext.closeSystemDialogs();
4392                 }
4393                 break;
4394             case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
4395                 if (complete) {
4396                     mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
4397                             TalkbackShortcutController.ShortcutSource.KEYBOARD);
4398                 }
4399                 break;
4400             case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
4401                 if (complete) {
4402                     mVoiceAccessShortcutController.toggleVoiceAccess(mCurrentUserId);
4403                 }
4404                 break;
4405             case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
4406                 AppLaunchData data = event.getAppLaunchData();
4407                 if (complete && canLaunchApp && data != null
4408                         && mModifierShortcutManager.launchApplication(data)) {
4409                     dismissKeyboardShortcutsMenu();
4410                 }
4411                 break;
4412             case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB:
4413                 NotificationManager nm = getNotificationService();
4414                 if (nm != null) {
4415                     boolean isEnabled = nm.getZenMode() != Settings.Global.ZEN_MODE_OFF;
4416                     nm.setZenMode(isEnabled ? Settings.Global.ZEN_MODE_OFF
4417                                     : Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
4418                             "Key gesture DND", true);
4419                 }
4420                 break;
4421             default:
4422                 Log.w(TAG, "Received a key gesture " + event
4423                         + " that was not registered by this handler");
4424                 break;
4425         }
4426     }
4427 
4428     private void changeDisplayBrightnessValue(int displayId, int direction) {
4429         int screenDisplayId = displayId < 0 ? DEFAULT_DISPLAY : displayId;
4430 
4431         float minLinearBrightness = mPowerManager.getBrightnessConstraint(
4432                 screenDisplayId, PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
4433         float maxLinearBrightness = mPowerManager.getBrightnessConstraint(
4434                 screenDisplayId, PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
4435         float linearBrightness = mDisplayManager.getBrightness(screenDisplayId);
4436 
4437         float gammaBrightness = BrightnessUtils.convertLinearToGamma(linearBrightness);
4438         float adjustedGammaBrightness = gammaBrightness + 1f / BRIGHTNESS_STEPS * direction;
4439         adjustedGammaBrightness = MathUtils.constrain(adjustedGammaBrightness, 0f, 1f);
4440         float adjustedLinearBrightness = BrightnessUtils.convertGammaToLinear(
4441                 adjustedGammaBrightness);
4442         adjustedLinearBrightness = MathUtils.constrain(adjustedLinearBrightness,
4443                 minLinearBrightness, maxLinearBrightness);
4444         mDisplayManager.setBrightness(screenDisplayId, adjustedLinearBrightness);
4445 
4446         Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
4447         intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION
4448                 | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
4449         intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true);
4450         startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
4451     }
4452 
4453     /**
4454      * In this function, we check whether a system key should be sent to the application. We also
4455      * detect the key gesture on this key, even if the key will be sent to the app. The gesture
4456      * action, if any, will not be executed immediately. It will be queued and execute only after
4457      * the application tells us that it didn't handle this key.
4458      *
4459      * @return true if this key should be sent to the application. This also means that the target
4460      *     application has the necessary permissions to receive this key. Return false otherwise.
4461      */
4462     private boolean prepareToSendSystemKeyToApplication(IBinder focusedToken, KeyEvent event) {
4463         final int keyCode = event.getKeyCode();
4464         if (!event.isSystem()) {
4465             Log.wtf(
4466                     TAG,
4467                     "Illegal keycode provided to prepareToSendSystemKeyToApplication: "
4468                             + KeyEvent.keyCodeToString(keyCode));
4469             return false;
4470         }
4471         final boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
4472         if (isDown && event.getRepeatCount() == 0) {
4473             // This happens at the initial DOWN event. Check focused window permission now.
4474             final KeyInterceptionInfo info =
4475                     mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);
4476             if (info != null
4477                     && mButtonOverridePermissionChecker.canAppOverrideSystemKey(
4478                             mContext, info.windowOwnerUid)) {
4479                 // Focused window has the permission. Pass the event to it.
4480                 return true;
4481             } else {
4482                 // Focused window doesn't have the permission. Intercept the event.
4483                 // If the initial DOWN event is intercepted, follow-up events will be intercepted
4484                 // too. So we know the gesture won't be handled by app, and can handle the gesture
4485                 // in system.
4486                 setDeferredKeyActionsExecutableAsync(keyCode, event.getDownTime());
4487                 return false;
4488             }
4489         } else {
4490             // This happens after the initial DOWN event. We will just reuse the initial decision.
4491             // I.e., if the initial DOWN event was dispatched, follow-up events should be
4492             // dispatched. Otherwise, follow-up events should be consumed.
4493             final Set<Integer> consumedKeys = mConsumedKeysForDevice.get(event.getDeviceId());
4494             final boolean wasConsumed = consumedKeys != null && consumedKeys.contains(keyCode);
4495             return !wasConsumed;
4496         }
4497     }
4498 
4499     private void setDeferredKeyActionsExecutableAsync(int keyCode, long downTime) {
4500         Message msg = Message.obtain(mHandler, MSG_SET_DEFERRED_KEY_ACTIONS_EXECUTABLE);
4501         msg.arg1 = keyCode;
4502         msg.obj = downTime;
4503         msg.setAsynchronous(true);
4504         msg.sendToTarget();
4505     }
4506 
4507     @SuppressLint("MissingPermission")
4508     private void injectBackGesture(long downtime) {
4509         if (mActivityTaskManagerInternal.requestBackGesture()) {
4510             return;
4511         }
4512         // Create and inject down event
4513         KeyEvent downEvent = new KeyEvent(downtime, downtime, KeyEvent.ACTION_DOWN,
4514                 KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */,
4515                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
4516                 KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
4517                 InputDevice.SOURCE_KEYBOARD);
4518         mInputManager.injectInputEvent(downEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
4519 
4520 
4521         // Create and inject up event
4522         KeyEvent upEvent = KeyEvent.changeAction(downEvent, KeyEvent.ACTION_UP);
4523         mInputManager.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
4524 
4525         downEvent.recycle();
4526         upEvent.recycle();
4527     }
4528 
4529     private boolean handleHomeShortcuts(IBinder focusedToken, KeyEvent event) {
4530         // First we always handle the home key here, so applications
4531         // can never break it, although if keyguard is on, we do let
4532         // it handle it, because that gives us the correct 5 second
4533         // timeout.
4534         DisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(event.getDisplayId());
4535         if (handler == null) {
4536             handler = new DisplayHomeButtonHandler(event.getDisplayId());
4537             mDisplayHomeButtonHandlers.put(event.getDisplayId(), handler);
4538         }
4539         return handler.handleHomeButton(focusedToken, event);
4540     }
4541 
4542     private void toggleMicrophoneMuteFromKey() {
4543         if (mSensorPrivacyManager.supportsSensorToggle(
4544                 SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
4545                 SensorPrivacyManager.Sensors.MICROPHONE)) {
4546             boolean isEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled(
4547                     SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
4548                     SensorPrivacyManager.Sensors.MICROPHONE);
4549 
4550             mSensorPrivacyManager.setSensorPrivacy(SensorPrivacyToggleSourceProto.OTHER,
4551                     SensorPrivacyManager.Sensors.MICROPHONE, !isEnabled, mCurrentUserId);
4552 
4553             int toastTextResId;
4554             if (isEnabled) {
4555                 toastTextResId = R.string.mic_access_on_toast;
4556             } else {
4557                 toastTextResId = R.string.mic_access_off_toast;
4558             }
4559 
4560             Toast.makeText(
4561                 mContext,
4562                 UiThread.get().getLooper(),
4563                 mContext.getString(toastTextResId),
4564                 Toast.LENGTH_SHORT)
4565                 .show();
4566         }
4567     }
4568 
4569     /**
4570      * TV only: recognizes a remote control gesture for capturing a bug report.
4571      */
4572     private void interceptBugreportGestureTv() {
4573         mHandler.removeMessages(MSG_BUGREPORT_TV);
4574         // The bugreport capture chord is a long press on DPAD CENTER and BACK simultaneously.
4575         Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV);
4576         msg.setAsynchronous(true);
4577         mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS);
4578     }
4579 
4580     private void cancelBugreportGestureTv() {
4581         mHandler.removeMessages(MSG_BUGREPORT_TV);
4582     }
4583 
4584     /**
4585      * TV only: recognizes a remote control gesture as Accessibility shortcut.
4586      * Shortcut: Long press (BACK + DPAD_DOWN)
4587      */
4588     private void interceptAccessibilityGestureTv() {
4589         mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
4590         Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV);
4591         msg.setAsynchronous(true);
4592         mHandler.sendMessageDelayed(msg, getAccessibilityShortcutTimeout());
4593     }
4594     private void cancelAccessibilityGestureTv() {
4595         mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
4596     }
4597 
4598     @VisibleForTesting
4599     void requestBugreportForTv() {
4600         try {
4601             if (!ActivityManager.getService().launchBugReportHandlerApp()) {
4602                 ActivityManager.getService().requestInteractiveBugReport();
4603             }
4604         } catch (RemoteException e) {
4605             Slog.e(TAG, "Error taking bugreport", e);
4606         }
4607     }
4608 
4609     // TODO(b/117479243): handle it in InputPolicy
4610     /** {@inheritDoc} */
4611     @Override
4612     public boolean interceptUnhandledKey(KeyEvent event, IBinder focusedToken) {
4613         // Note: This method is only called if the initial down was unhandled.
4614         if (DEBUG_INPUT) {
4615             final KeyInterceptionInfo info =
4616                     mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);
4617             final String title = info == null ? "<unknown>" : info.windowTitle;
4618             Slog.d(TAG, "Unhandled key: inputToken=" + focusedToken
4619                     + ", title=" + title
4620                     + ", action=" + event.getAction()
4621                     + ", flags=" + event.getFlags()
4622                     + ", keyCode=" + event.getKeyCode()
4623                     + ", scanCode=" + event.getScanCode()
4624                     + ", metaState=" + event.getMetaState()
4625                     + ", repeatCount=" + event.getRepeatCount());
4626         }
4627 
4628         final int keyCode = event.getKeyCode();
4629         final int repeatCount = event.getRepeatCount();
4630         final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
4631         final int metaState = event.getModifiers();
4632 
4633         // TODO(b/358569822): Shift to KeyGestureEvent based handling
4634         if (keyCode == KeyEvent.KEYCODE_STEM_PRIMARY) {
4635             handleUnhandledSystemKey(event);
4636             sendSystemKeyToStatusBarAsync(event);
4637             return true;
4638         }
4639 
4640         if (useKeyGestureEventHandler()) {
4641             return false;
4642         }
4643 
4644         switch (keyCode) {
4645             case KeyEvent.KEYCODE_SPACE:
4646                 if (down && repeatCount == 0) {
4647                     // Handle keyboard layout switching. (CTRL + SPACE)
4648                     if (KeyEvent.metaStateHasModifiers(metaState & ~KeyEvent.META_SHIFT_MASK,
4649                             KeyEvent.META_CTRL_ON)) {
4650                         int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
4651                         sendSwitchKeyboardLayout(event.getDisplayId(), focusedToken, direction);
4652                         return true;
4653                     }
4654                 }
4655                 break;
4656             case KeyEvent.KEYCODE_Z:
4657                 if (down && KeyEvent.metaStateHasModifiers(metaState,
4658                         KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON)) {
4659                     // Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users.
4660                     if (mAccessibilityShortcutController
4661                             .isAccessibilityShortcutAvailable(isKeyguardLocked())) {
4662                         mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT));
4663                         return true;
4664                     }
4665                 }
4666                 break;
4667             case KeyEvent.KEYCODE_SYSRQ:
4668                 if (down && repeatCount == 0) {
4669                     interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
4670                     return true;
4671                 }
4672                 break;
4673             case KeyEvent.KEYCODE_ESCAPE:
4674                 if (down
4675                         && KeyEvent.metaStateHasNoModifiers(metaState)
4676                         && repeatCount == 0) {
4677                     mContext.closeSystemDialogs();
4678                     return true;
4679                 }
4680                 break;
4681         }
4682 
4683         return false;
4684     }
4685 
4686     /**
4687      * Called when a system key was sent to application and was unhandled. We will execute any
4688      * queued actions associated with this key code at this point.
4689      */
4690     private void handleUnhandledSystemKey(KeyEvent event) {
4691         if (!event.isSystem()) {
4692             Log.wtf(
4693                     TAG,
4694                     "Illegal keycode provided to handleUnhandledSystemKey: "
4695                             + KeyEvent.keyCodeToString(event.getKeyCode()));
4696             return;
4697         }
4698         if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
4699             // If the initial DOWN event is unhandled by app, follow-up events will also be
4700             // unhandled by app. So we can handle the key event in system.
4701             setDeferredKeyActionsExecutableAsync(event.getKeyCode(), event.getDownTime());
4702         }
4703     }
4704 
4705     private void sendSwitchKeyboardLayout(int displayId, @Nullable IBinder focusedToken,
4706             int direction) {
4707         SwitchKeyboardLayoutMessageObject object =
4708                 new SwitchKeyboardLayoutMessageObject(displayId, focusedToken, direction);
4709         mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, object).sendToTarget();
4710     }
4711 
4712     private void handleSwitchKeyboardLayout(int displayId, int direction, IBinder focusedToken) {
4713         IBinder targetWindowToken =
4714                 mWindowManagerInternal.getTargetWindowTokenFromInputToken(focusedToken);
4715         InputMethodManagerInternal.get().onSwitchKeyboardLayoutShortcut(direction, displayId,
4716                 targetWindowToken);
4717     }
4718 
4719     @Override
4720     public void setTopFocusedDisplay(int displayId) {
4721         mTopFocusedDisplayId = displayId;
4722     }
4723 
4724     @Override
4725     public void registerDisplayFoldListener(IDisplayFoldListener listener) {
4726         if (mDisplayFoldController != null) {
4727             mDisplayFoldController.registerDisplayFoldListener(listener);
4728         }
4729     }
4730 
4731     @Override
4732     public void unregisterDisplayFoldListener(IDisplayFoldListener listener) {
4733         if (mDisplayFoldController != null) {
4734             mDisplayFoldController.unregisterDisplayFoldListener(listener);
4735         }
4736     }
4737 
4738     @Override
4739     public void setOverrideFoldedArea(Rect area) {
4740         if (mDisplayFoldController != null) {
4741             mDisplayFoldController.setOverrideFoldedArea(area);
4742         }
4743     }
4744 
4745     @Override
4746     public Rect getFoldedArea() {
4747         if (mDisplayFoldController != null) {
4748             return mDisplayFoldController.getFoldedArea();
4749         }
4750         return new Rect();
4751     }
4752 
4753     @Override
4754     public void onDefaultDisplayFocusChangedLw(WindowState newFocus) {
4755         if (mDisplayFoldController != null) {
4756             mDisplayFoldController.onDefaultDisplayFocusChanged(
4757                     newFocus != null ? newFocus.getOwningPackage() : null);
4758         }
4759     }
4760 
4761     @Override
4762     public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService)
4763             throws RemoteException {
4764         synchronized (mLock) {
4765             if (useKeyGestureEventHandler()) {
4766                 mInputManagerInternal.registerShortcutKey(shortcutCode, shortcutService);
4767                 return;
4768             }
4769             mModifierShortcutManager.registerShortcutKey(shortcutCode, shortcutService);
4770         }
4771     }
4772 
4773     @Override
4774     public void onKeyguardOccludedChangedLw(boolean occluded) {
4775         if (mKeyguardDelegate != null) {
4776             mPendingKeyguardOccluded = occluded;
4777             mKeyguardOccludedChanged = true;
4778         }
4779     }
4780 
4781     @Override
4782     public int applyKeyguardOcclusionChange() {
4783         if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded commit occluded="
4784                 + mPendingKeyguardOccluded + " changed=" + mKeyguardOccludedChanged);
4785 
4786         // TODO(b/276433230): Explicitly save before/after for occlude state in each
4787         // Transition so we don't need to update SysUI every time.
4788         if (setKeyguardOccludedLw(mPendingKeyguardOccluded)) {
4789             return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER;
4790         } else {
4791             return 0;
4792         }
4793     }
4794 
4795     /**
4796      * Called when keyguard related app transition starts, or cancelled.
4797      *
4798      * @param startKeyguardExitAnimation Trigger IKeyguardService#startKeyguardExitAnimation to
4799      *                                  start keyguard exit animation.
4800      * @param notifyOccluded Trigger IKeyguardService#setOccluded binder call to notify whether
4801      *                      the top activity can occlude the keyguard or not.
4802      *
4803      * @return Whether the flags have changed and we have to redo the layout.
4804      */
4805     private int handleTransitionForKeyguardLw(boolean startKeyguardExitAnimation,
4806             boolean notifyOccluded) {
4807         int redoLayout = 0;
4808         if (notifyOccluded) {
4809             redoLayout = applyKeyguardOcclusionChange();
4810         }
4811         if (startKeyguardExitAnimation) {
4812             if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
4813             startKeyguardExitAnimation(SystemClock.uptimeMillis());
4814         }
4815         return redoLayout;
4816     }
4817 
4818     /**
4819      * Shows the keyguard without immediately locking the device.
4820      */
4821     @Override
4822     public void showDismissibleKeyguard() {
4823         mKeyguardDelegate.showDismissibleKeyguard();
4824     }
4825 
4826     // There are several different flavors of "assistant" that can be launched from
4827     // various parts of the UI.
4828 
4829     /** Asks the status bar to startAssist(), usually a full "assistant" interface */
4830     private void launchAssistAction(String hint, int deviceId, long eventTime,
4831             int invocationType) {
4832         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
4833         if (!isUserSetupComplete()) {
4834             // Disable opening assist window during setup
4835             return;
4836         }
4837 
4838         // Add Intent Extra data.
4839         Bundle args = null;
4840         args = new Bundle();
4841         if (deviceId != INVALID_INPUT_DEVICE_ID) {
4842             args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, deviceId);
4843         }
4844         if (hint != null) {
4845             args.putBoolean(hint, true);
4846         }
4847         args.putLong(Intent.EXTRA_TIME, eventTime);
4848         args.putInt(AssistUtils.INVOCATION_TYPE_KEY, invocationType);
4849 
4850         SearchManager searchManager = mContext.getSystemService(SearchManager.class);
4851         if (searchManager != null) {
4852             searchManager.launchAssist(args);
4853         } else {
4854             // Fallback to status bar if search manager doesn't exist (e.g. on wear).
4855             StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
4856             if (statusBar != null) {
4857                 statusBar.startAssist(args);
4858             }
4859         }
4860     }
4861 
4862     /**
4863      * Launches ACTION_VOICE_ASSIST_RETAIL if in retail mode, or ACTION_VOICE_ASSIST otherwise
4864      * Does nothing on keyguard except for watches. Delegates it to keyguard if present on watch.
4865      */
4866     private void launchVoiceAssist(boolean allowDuringSetup) {
4867         final boolean keyguardActive =
4868                 mKeyguardDelegate != null && mKeyguardDelegate.isShowing();
4869         if (!keyguardActive) {
4870             startActivityAsUser(
4871                     new Intent(Intent.ACTION_VOICE_ASSIST),
4872                     /* bundle= */ null,
4873                     UserHandle.CURRENT_OR_SELF,
4874                     allowDuringSetup);
4875         } else {
4876             mKeyguardDelegate.dismissKeyguardToLaunch(new Intent(Intent.ACTION_VOICE_ASSIST));
4877         }
4878     }
4879 
4880     private boolean isInRetailMode() {
4881         return Settings.Global.getInt(mContext.getContentResolver(),
4882                 Settings.Global.DEVICE_DEMO_MODE, 0) == 1;
4883     }
4884 
4885     private void startActivityAsUser(Intent intent, UserHandle handle) {
4886         startActivityAsUser(intent, null, handle);
4887     }
4888 
4889     private void startActivityAsUser(Intent intent, Bundle bundle, UserHandle handle) {
4890         startActivityAsUser(intent, bundle, handle, false /* allowDuringSetup */);
4891     }
4892 
4893     private void startActivityAsUser(Intent intent, Bundle bundle, UserHandle handle,
4894             boolean allowDuringSetup) {
4895         if (allowDuringSetup || isUserSetupComplete()) {
4896             mContext.startActivityAsUser(intent, bundle, handle);
4897             dismissKeyboardShortcutsMenu();
4898         } else {
4899             Slog.i(TAG, "Not starting activity because user setup is in progress: " + intent);
4900         }
4901     }
4902 
4903     private void preloadRecentApps() {
4904         mPreloadedRecentApps = true;
4905         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4906         if (statusbar != null) {
4907             statusbar.preloadRecentApps();
4908         }
4909     }
4910 
4911     private void cancelPreloadRecentApps() {
4912         if (mPreloadedRecentApps) {
4913             mPreloadedRecentApps = false;
4914             StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4915             if (statusbar != null) {
4916                 statusbar.cancelPreloadRecentApps();
4917             }
4918         }
4919     }
4920 
4921     private void toggleTaskbar() {
4922         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4923         if (statusbar != null) {
4924             statusbar.toggleTaskbar();
4925         }
4926     }
4927 
4928     private void toggleRecentApps() {
4929         mPreloadedRecentApps = false; // preloading no longer needs to be canceled
4930         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4931         if (statusbar != null) {
4932             statusbar.toggleRecentApps();
4933         }
4934     }
4935 
4936     @Override
4937     public void showRecentApps() {
4938         mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS);
4939         mHandler.obtainMessage(MSG_DISPATCH_SHOW_RECENTS).sendToTarget();
4940     }
4941 
4942     private void showRecentApps(boolean triggeredFromAltTab) {
4943         mPreloadedRecentApps = false; // preloading no longer needs to be canceled
4944         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4945         if (statusbar != null) {
4946             statusbar.showRecentApps(triggeredFromAltTab);
4947         }
4948         dismissKeyboardShortcutsMenu();
4949     }
4950 
4951     private void toggleKeyboardShortcutsMenu(int deviceId) {
4952         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4953         if (statusbar != null) {
4954             statusbar.toggleKeyboardShortcutsMenu(deviceId);
4955         }
4956     }
4957 
4958     private void dismissKeyboardShortcutsMenu() {
4959         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4960         if (statusbar != null) {
4961             statusbar.dismissKeyboardShortcutsMenu();
4962         }
4963     }
4964 
4965     private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) {
4966         mPreloadedRecentApps = false; // preloading no longer needs to be canceled
4967         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4968         if (statusbar != null) {
4969             statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome);
4970         }
4971     }
4972 
4973     private void moveFocusedTaskToStageSplit(int displayId, boolean leftOrTop) {
4974         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
4975         if (statusbar != null) {
4976             statusbar.moveFocusedTaskToStageSplit(displayId, leftOrTop);
4977         }
4978     }
4979 
4980     void launchHomeFromHotKey(int displayId) {
4981         launchHomeFromHotKey(displayId, true /* awakenFromDreams */, true /*respectKeyguard*/);
4982     }
4983 
4984     /**
4985      * A home key -> launch home action was detected.  Take the appropriate action
4986      * given the situation with the keyguard.
4987      */
4988     void launchHomeFromHotKey(int displayId, final boolean awakenFromDreams,
4989             final boolean respectKeyguard) {
4990         if (respectKeyguard) {
4991             if (isKeyguardShowingAndNotOccluded()) {
4992                 // don't launch home if keyguard showing
4993                 return;
4994             }
4995 
4996             if (!isKeyguardOccluded() && mKeyguardDelegate.isInputRestricted()) {
4997                 // when in keyguard restricted mode, must first verify unlock
4998                 // before launching home
4999                 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
5000                     @Override
5001                     public void onKeyguardExitResult(boolean success) {
5002                         if (success) {
5003                             final long origId = Binder.clearCallingIdentity();
5004                             try {
5005                                 startDockOrHome(displayId, true /*fromHomeKey*/, awakenFromDreams);
5006                             } finally {
5007                                 Binder.restoreCallingIdentity(origId);
5008                             }
5009                         }
5010                     }
5011                 });
5012                 return;
5013             }
5014         }
5015 
5016         // no keyguard stuff to worry about, just launch home!
5017         // If Recents is visible and the action is not from visible background users,
5018         // hide Recents and notify it to launch Home.
5019         if (mRecentsVisible
5020                 && (!mVisibleBackgroundUsersEnabled || displayId == DEFAULT_DISPLAY)) {
5021             try {
5022                 ActivityManager.getService().stopAppSwitches();
5023             } catch (RemoteException e) {}
5024 
5025             // Hide Recents and notify it to launch Home
5026             if (awakenFromDreams) {
5027                 awakenDreams();
5028             }
5029             hideRecentApps(false, true);
5030         } else {
5031             // Otherwise, just launch Home
5032             startDockOrHome(displayId, true /*fromHomeKey*/, awakenFromDreams);
5033         }
5034     }
5035 
5036     @Override
5037     public void setRecentsVisibilityLw(boolean visible) {
5038         mRecentsVisible = visible;
5039     }
5040 
5041     @Override
5042     public void setPipVisibilityLw(boolean visible) {
5043         mPictureInPictureVisible = visible;
5044     }
5045 
5046     @Override
5047     public void setNavBarVirtualKeyHapticFeedbackEnabledLw(boolean enabled) {
5048         mNavBarVirtualKeyHapticFeedbackEnabled = enabled;
5049     }
5050 
5051     /**
5052      * Updates the occluded state of the Keyguard immediately via {@link IKeyguardService}.
5053      *
5054      * @param isOccluded Whether the Keyguard is occluded by another window.
5055      * @return Whether the flags have changed and we have to redo the layout.
5056      */
5057     private boolean setKeyguardOccludedLw(boolean isOccluded) {
5058         if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded);
5059         mKeyguardOccludedChanged = false;
5060         mPendingKeyguardOccluded = isOccluded;
5061         mKeyguardDelegate.setOccluded(isOccluded, true /* notify */);
5062         return mKeyguardDelegate.isShowing();
5063     }
5064 
5065     /** {@inheritDoc} */
5066     @Override
5067     public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
5068         // lid changed state
5069         final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED;
5070         if (newLidState == mDefaultDisplayPolicy.getLidState()) {
5071             return;
5072         }
5073 
5074         mDefaultDisplayPolicy.setLidState(newLidState);
5075         applyLidSwitchState();
5076         updateRotation(true);
5077 
5078         if (lidOpen) {
5079             mWindowWakeUpPolicy.wakeUpFromLid();
5080         } else if (getLidBehavior() != LID_BEHAVIOR_SLEEP) {
5081             mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
5082         }
5083     }
5084 
5085     @Override
5086     public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) {
5087         int lensCoverState = lensCovered ? CAMERA_LENS_COVERED : CAMERA_LENS_UNCOVERED;
5088         if (mCameraLensCoverState == lensCoverState) {
5089             return;
5090         }
5091         if (!mContext.getResources().getBoolean(
5092                 R.bool.config_launchCameraOnCameraLensCoverToggle)) {
5093             return;
5094         }
5095         if (mCameraLensCoverState == CAMERA_LENS_COVERED &&
5096                 lensCoverState == CAMERA_LENS_UNCOVERED) {
5097             Intent intent;
5098             final boolean keyguardActive = mKeyguardDelegate == null ? false :
5099                     mKeyguardDelegate.isShowing();
5100             if (keyguardActive) {
5101                 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
5102             } else {
5103                 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
5104             }
5105             mWindowWakeUpPolicy.wakeUpFromCameraCover(whenNanos / 1000000);
5106             startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
5107         }
5108         mCameraLensCoverState = lensCoverState;
5109     }
5110 
5111     void initializeHdmiState() {
5112         final int oldMask = StrictMode.allowThreadDiskReadsMask();
5113         try {
5114             initializeHdmiStateInternal();
5115         } finally {
5116             StrictMode.setThreadPolicyMask(oldMask);
5117         }
5118     }
5119 
5120     void initializeHdmiStateInternal() {
5121         boolean plugged = false;
5122         // watch for HDMI plug messages if the hdmi switch exists
5123         if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) {
5124             mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi");
5125 
5126             final String filename = "/sys/class/switch/hdmi/state";
5127             FileReader reader = null;
5128             try {
5129                 reader = new FileReader(filename);
5130                 char[] buf = new char[15];
5131                 int n = reader.read(buf);
5132                 if (n > 1) {
5133                     plugged = 0 != Integer.parseInt(new String(buf, 0, n - 1));
5134                 }
5135             } catch (IOException ex) {
5136                 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
5137             } catch (NumberFormatException ex) {
5138                 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
5139             } finally {
5140                 if (reader != null) {
5141                     try {
5142                         reader.close();
5143                     } catch (IOException ex) {
5144                     }
5145                 }
5146             }
5147         } else {
5148             final List<ExtconUEventObserver.ExtconInfo> extcons =
5149                     ExtconUEventObserver.ExtconInfo.getExtconInfoForTypes(
5150                             new String[] {ExtconUEventObserver.ExtconInfo.EXTCON_HDMI});
5151             if (!extcons.isEmpty()) {
5152                 // TODO: handle more than one HDMI
5153                 HdmiVideoExtconUEventObserver observer = new HdmiVideoExtconUEventObserver();
5154                 plugged = observer.init(extcons.get(0));
5155                 mHDMIObserver = observer;
5156             } else if (localLOGV) {
5157                 Slog.v(TAG, "Not observing HDMI plug state because HDMI was not found.");
5158             }
5159         }
5160 
5161         // This dance forces the code in setHdmiPlugged to run.
5162         // Always do this so the sticky intent is stuck (to false) if there is no hdmi.
5163         mDefaultDisplayPolicy.setHdmiPlugged(plugged, true /* force */);
5164     }
5165 
5166     // TODO(b/117479243): handle it in InputPolicy
5167     /** {@inheritDoc} */
5168     @Override
5169     public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
5170         final int keyCode = event.getKeyCode();
5171         final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
5172         boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
5173                 || event.isWakeKey();
5174         boolean isKeyGestureTriggered = (policyFlags & FLAG_KEY_GESTURE_TRIGGERED) != 0;
5175 
5176         // There are key events that perform the operation as the current user,
5177         // and these should be ignored for visible background users.
5178         if (mVisibleBackgroundUsersEnabled
5179                 && !KeyEvent.isVisibleBackgroundUserAllowedKey(keyCode)
5180                 && !isKeyEventForCurrentUser(event.getDisplayId(), keyCode, null)) {
5181             return 0;
5182         }
5183 
5184         if (!mSystemBooted) {
5185             // If we have not yet booted, don't let key events do anything.
5186             // Exception: Wake and power key events are forwarded to PowerManager to allow it to
5187             // wake from quiescent mode during boot. On these key events we also explicitly turn on
5188             // the connected TV and switch HDMI input if we're a HDMI playback device.
5189             boolean shouldTurnOnTv = false;
5190             if (down && (keyCode == KeyEvent.KEYCODE_POWER
5191                     || keyCode == KeyEvent.KEYCODE_TV_POWER)) {
5192                 wakeUpFromWakeKey(event);
5193                 shouldTurnOnTv = true;
5194             } else if (down && (isWakeKey || keyCode == KeyEvent.KEYCODE_WAKEUP)
5195                     && isWakeKeyWhenScreenOff(keyCode)) {
5196                 wakeUpFromWakeKey(event);
5197                 shouldTurnOnTv = true;
5198             }
5199             if (shouldTurnOnTv) {
5200                 final HdmiControl hdmiControl = getHdmiControl();
5201                 if (hdmiControl != null) {
5202                     hdmiControl.turnOnTv();
5203                 }
5204             }
5205             return 0;
5206         }
5207 
5208         final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
5209         final boolean canceled = event.isCanceled();
5210         final int displayId = event.getDisplayId();
5211         final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
5212 
5213         if (DEBUG_INPUT) {
5214             // If screen is off then we treat the case where the keyguard is open but hidden
5215             // the same as if it were open and in front.
5216             // This will prevent any keys other than the power button from waking the screen
5217             // when the keyguard is hidden by another activity.
5218             final boolean keyguardActive = (mKeyguardDelegate != null
5219                     && (interactive ? isKeyguardShowingAndNotOccluded() :
5220                     mKeyguardDelegate.isShowing()));
5221             Log.d(TAG, "interceptKeyTq keycode=" + keyCode
5222                     + " interactive=" + interactive + " keyguardActive=" + keyguardActive
5223                     + " policyFlags=" + Integer.toHexString(policyFlags));
5224         }
5225 
5226         // Basic policy based on interactive state.
5227         int result;
5228         if (interactive || (isInjected && !isWakeKey)) {
5229             // When the device is interactive or the key is injected pass the
5230             // key to the application.
5231             result = ACTION_PASS_TO_USER;
5232             isWakeKey = false;
5233 
5234             if (interactive) {
5235                 // If the screen is awake, but the button pressed was the one that woke the device
5236                 // then don't pass it to the application
5237                 if (keyCode == mPendingWakeKey && !down) {
5238                     result = 0;
5239                 }
5240                 // Reset the pending key
5241                 mPendingWakeKey = PENDING_KEY_NULL;
5242             }
5243         } else if (shouldDispatchInputWhenNonInteractive(displayId, keyCode)) {
5244             // If we're currently dozing with the screen on and the keyguard showing, pass the key
5245             // to the application but preserve its wake key status to make sure we still move
5246             // from dozing to fully interactive if we would normally go from off to fully
5247             // interactive.
5248             result = ACTION_PASS_TO_USER;
5249             // Since we're dispatching the input, reset the pending key
5250             mPendingWakeKey = PENDING_KEY_NULL;
5251         } else {
5252             // When the screen is off and the key is not injected, determine whether
5253             // to wake the device but don't pass the key to the application.
5254             result = 0;
5255             if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) {
5256                 isWakeKey = false;
5257             }
5258             // Cache the wake key on down event so we can also avoid sending the up event to the app
5259             if (isWakeKey && down) {
5260                 mPendingWakeKey = keyCode;
5261             }
5262         }
5263 
5264         // If the key would be handled globally, just return the result, don't worry about special
5265         // key processing.
5266         if (isValidGlobalKey(keyCode)
5267                 && mGlobalKeyManager.shouldHandleGlobalKey(keyCode)) {
5268             // Dispatch if global key defined dispatchWhenNonInteractive.
5269             if (!interactive && isWakeKey && down
5270                     && mGlobalKeyManager.shouldDispatchFromNonInteractive(keyCode)) {
5271                 mGlobalKeyManager.setBeganFromNonInteractive();
5272                 result = ACTION_PASS_TO_USER;
5273                 // Since we're dispatching the input, reset the pending key
5274                 mPendingWakeKey = PENDING_KEY_NULL;
5275             }
5276 
5277             if (isWakeKey) {
5278                 wakeUpFromWakeKey(event);
5279             }
5280             return result;
5281         }
5282 
5283         // Alternate TV power to power key for Android TV device.
5284         final HdmiControlManager hdmiControlManager = getHdmiControlManager();
5285         if (keyCode == KeyEvent.KEYCODE_TV_POWER && mHasFeatureLeanback
5286                 && (hdmiControlManager == null || !hdmiControlManager.shouldHandleTvPowerKey())) {
5287             event = KeyEvent.obtain(
5288                     event.getDownTime(), event.getEventTime(),
5289                     event.getAction(), KeyEvent.KEYCODE_POWER,
5290                     event.getRepeatCount(), event.getMetaState(),
5291                     event.getDeviceId(), event.getScanCode(),
5292                     event.getFlags(), event.getSource(), event.getDisplayId(), null);
5293             return interceptKeyBeforeQueueing(event, policyFlags);
5294         }
5295 
5296         // This could prevent some wrong state in multi-displays environment,
5297         // the default display may turned off but interactive is true.
5298         final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
5299         final boolean isDefaultDisplayAwake = mDefaultDisplayPolicy.isAwake();
5300         final boolean interactiveAndAwake = interactive && isDefaultDisplayAwake;
5301         if (isKeyGestureTriggered) {
5302             // If key gesture is triggered outside policy, reset gesture handlers here
5303             mSingleKeyGestureDetector.reset();
5304         } else {
5305             if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
5306                 handleKeyGesture(event, interactiveAndAwake, isDefaultDisplayOn);
5307             }
5308         }
5309 
5310         // Enable haptics if down and virtual key without multiple repetitions. If this is a hard
5311         // virtual key such as a navigation bar button, only vibrate if flag is enabled.
5312         final boolean isNavBarVirtKey = ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0);
5313         boolean useHapticFeedback = down
5314                 && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
5315                 && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled)
5316                 && event.getRepeatCount() == 0;
5317 
5318         // Handle special keys.
5319         switch (keyCode) {
5320             case KeyEvent.KEYCODE_BACK: {
5321                 notifyKeyGestureCompletedOnActionUp(event,
5322                         KeyGestureEvent.KEY_GESTURE_TYPE_BACK);
5323                 if (down) {
5324                     // There may have other embedded activities on the same Task. Try to move the
5325                     // focus before processing the back event.
5326                     mWindowManagerInternal.moveFocusToAdjacentEmbeddedActivityIfNeeded();
5327                     mBackKeyHandled = false;
5328                 } else {
5329                     if (!hasLongPressOnBackBehavior()) {
5330                         mBackKeyHandled |= backKeyPress();
5331                     }
5332                     // Don't pass back press to app if we've already handled it via long press
5333                     if (mBackKeyHandled) {
5334                         result &= ~ACTION_PASS_TO_USER;
5335                     }
5336                 }
5337                 break;
5338             }
5339 
5340             case KeyEvent.KEYCODE_VOLUME_DOWN:
5341             case KeyEvent.KEYCODE_VOLUME_UP:
5342             case KeyEvent.KEYCODE_VOLUME_MUTE: {
5343                 int gestureType = keyCode == KEYCODE_VOLUME_DOWN
5344                         ? KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_DOWN
5345                         : keyCode == KEYCODE_VOLUME_UP
5346                                 ? KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_UP
5347                                 : KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_MUTE;
5348                 notifyKeyGestureCompletedOnActionDown(event, gestureType);
5349                 if (down) {
5350                     sendSystemKeyToStatusBarAsync(event);
5351 
5352                     NotificationManager nm = getNotificationService();
5353                     if (nm != null && !mHandleVolumeKeysInWM) {
5354                         nm.silenceNotificationSound();
5355                     }
5356 
5357                     TelecomManager telecomManager = getTelecommService();
5358                     if (telecomManager != null && !mHandleVolumeKeysInWM) {
5359                         // When {@link #mHandleVolumeKeysInWM} is set, volume key events
5360                         // should be dispatched to WM.
5361                         if (telecomManager.isRinging()) {
5362                             // If an incoming call is ringing, either VOLUME key means
5363                             // "silence ringer".  We handle these keys here, rather than
5364                             // in the InCallScreen, to make sure we'll respond to them
5365                             // even if the InCallScreen hasn't come to the foreground yet.
5366                             // Look for the DOWN event here, to agree with the "fallback"
5367                             // behavior in the InCallScreen.
5368                             Log.i(TAG, "interceptKeyBeforeQueueing:"
5369                                   + " VOLUME key-down while ringing: Silence ringer!");
5370 
5371                             // Silence the ringer.  (It's safe to call this
5372                             // even if the ringer has already been silenced.)
5373                             telecomManager.silenceRinger();
5374 
5375                             // And *don't* pass this key thru to the current activity
5376                             // (which is probably the InCallScreen.)
5377                             result &= ~ACTION_PASS_TO_USER;
5378                             break;
5379                         }
5380                     }
5381                     int audioMode = AudioManager.MODE_NORMAL;
5382                     try {
5383                         audioMode = getAudioService().getMode();
5384                     } catch (Exception e) {
5385                         Log.e(TAG, "Error getting AudioService in interceptKeyBeforeQueueing.", e);
5386                     }
5387                     boolean isInCall = (telecomManager != null && telecomManager.isInCall()) ||
5388                             audioMode == AudioManager.MODE_IN_COMMUNICATION;
5389                     if (isInCall && (result & ACTION_PASS_TO_USER) == 0) {
5390                         // If we are in call but we decided not to pass the key to
5391                         // the application, just pass it to the session service.
5392                         MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
5393                                 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false);
5394                         break;
5395                     }
5396                 }
5397                 if (mUseTvRouting || mHandleVolumeKeysInWM) {
5398                     // Defer special key handlings to
5399                     // {@link interceptKeyBeforeDispatching()}.
5400                     result |= ACTION_PASS_TO_USER;
5401                 } else if ((result & ACTION_PASS_TO_USER) == 0) {
5402                     // If we aren't passing to the user and no one else
5403                     // handled it send it to the session manager to
5404                     // figure out.
5405                     MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
5406                             event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
5407                 }
5408                 break;
5409             }
5410 
5411             case KeyEvent.KEYCODE_ENDCALL: {
5412                 result &= ~ACTION_PASS_TO_USER;
5413                 if (down) {
5414                     TelecomManager telecomManager = getTelecommService();
5415                     boolean hungUp = false;
5416                     if (telecomManager != null) {
5417                         hungUp = telecomManager.endCall();
5418                     }
5419                     if (interactive && !hungUp) {
5420                         mEndCallKeyHandled = false;
5421                         mHandler.postDelayed(mEndCallLongPress,
5422                                 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
5423                     } else {
5424                         mEndCallKeyHandled = true;
5425                     }
5426                 } else {
5427                     if (!mEndCallKeyHandled) {
5428                         mHandler.removeCallbacks(mEndCallLongPress);
5429                         if (!canceled) {
5430                             if ((mEndcallBehavior
5431                                     & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
5432                                 if (goHome()) {
5433                                     break;
5434                                 }
5435                             }
5436                             if ((mEndcallBehavior
5437                                     & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
5438                                 sleepDefaultDisplay(event.getEventTime(),
5439                                         PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
5440                                 isWakeKey = false;
5441                             }
5442                         }
5443                     }
5444                 }
5445                 break;
5446             }
5447 
5448             case KeyEvent.KEYCODE_TV_POWER: {
5449                 notifyKeyGestureCompletedOnActionUp(event,
5450                         KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER);
5451                 result &= ~ACTION_PASS_TO_USER;
5452                 isWakeKey = false; // wake-up will be handled separately
5453                 if (down && hdmiControlManager != null) {
5454                     hdmiControlManager.toggleAndFollowTvPower();
5455                 }
5456                 break;
5457             }
5458 
5459             case KeyEvent.KEYCODE_POWER: {
5460                 notifyKeyGestureCompletedOnActionUp(event,
5461                         KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER);
5462                 EventLogTags.writeInterceptPower(
5463                         KeyEvent.actionToString(event.getAction()),
5464                         mPowerKeyHandled ? 1 : 0,
5465                         mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));
5466                 // Any activity on the power button stops the accessibility shortcut
5467                 result &= ~ACTION_PASS_TO_USER;
5468                 isWakeKey = false; // wake-up will be handled separately
5469                 if (down) {
5470                     interceptPowerKeyDown(event, interactiveAndAwake, isKeyGestureTriggered);
5471                 } else {
5472                     interceptPowerKeyUp(event, canceled);
5473                 }
5474                 break;
5475             }
5476 
5477             case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN:
5478                 // fall through
5479             case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP:
5480                 // fall through
5481             case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
5482                 // fall through
5483             case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: {
5484                 notifyKeyGestureCompletedOnActionUp(event,
5485                         KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_NAVIGATION);
5486                 result &= ~ACTION_PASS_TO_USER;
5487                 interceptSystemNavigationKey(event);
5488                 break;
5489             }
5490 
5491             case KeyEvent.KEYCODE_SLEEP: {
5492                 notifyKeyGestureCompletedOnActionUp(event,
5493                         KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP);
5494                 result &= ~ACTION_PASS_TO_USER;
5495                 isWakeKey = false;
5496                 if (!mPowerManager.isInteractive()) {
5497                     useHapticFeedback = false; // suppress feedback if already non-interactive
5498                 }
5499                 if (down) {
5500                     sleepPress();
5501                 } else {
5502                     sleepRelease(event.getEventTime());
5503                 }
5504                 sendSystemKeyToStatusBarAsync(event);
5505                 break;
5506             }
5507 
5508             case KeyEvent.KEYCODE_SOFT_SLEEP: {
5509                 notifyKeyGestureCompletedOnActionUp(event,
5510                         KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP);
5511                 result &= ~ACTION_PASS_TO_USER;
5512                 isWakeKey = false;
5513                 if (!down) {
5514                     mPowerManagerInternal.setUserInactiveOverrideFromWindowManager();
5515                 }
5516                 sendSystemKeyToStatusBarAsync(event);
5517                 break;
5518             }
5519 
5520             case KeyEvent.KEYCODE_WAKEUP: {
5521                 notifyKeyGestureCompletedOnActionUp(event,
5522                         KeyGestureEvent.KEY_GESTURE_TYPE_WAKEUP);
5523                 result &= ~ACTION_PASS_TO_USER;
5524                 isWakeKey = true;
5525                 break;
5526             }
5527 
5528             case KeyEvent.KEYCODE_MUTE:
5529                 result &= ~ACTION_PASS_TO_USER;
5530                 if (down && event.getRepeatCount() == 0) {
5531                     notifyKeyGestureCompleted(event,
5532                             KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_MUTE);
5533                     toggleMicrophoneMuteFromKey();
5534                 }
5535                 break;
5536             case KeyEvent.KEYCODE_MEDIA_PLAY:
5537             case KeyEvent.KEYCODE_MEDIA_PAUSE:
5538             case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
5539             case KeyEvent.KEYCODE_HEADSETHOOK:
5540             case KeyEvent.KEYCODE_MEDIA_STOP:
5541             case KeyEvent.KEYCODE_MEDIA_NEXT:
5542             case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
5543             case KeyEvent.KEYCODE_MEDIA_REWIND:
5544             case KeyEvent.KEYCODE_MEDIA_RECORD:
5545             case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
5546             case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
5547                 notifyKeyGestureCompletedOnActionUp(event,
5548                         KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY);
5549                 if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) {
5550                     // If the global session is active pass all media keys to it
5551                     // instead of the active window.
5552                     result &= ~ACTION_PASS_TO_USER;
5553                 }
5554                 if ((result & ACTION_PASS_TO_USER) == 0) {
5555                     // Only do this if we would otherwise not pass it to the user. In that
5556                     // case, the PhoneWindow class will do the same thing, except it will
5557                     // only do it if the showing app doesn't process the key on its own.
5558                     // Note that we need to make a copy of the key event here because the
5559                     // original key event will be recycled when we return.
5560                     mBroadcastWakeLock.acquire();
5561                     Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK,
5562                             new KeyEvent(event));
5563                     msg.setAsynchronous(true);
5564                     msg.sendToTarget();
5565                 }
5566                 break;
5567             }
5568 
5569             case KeyEvent.KEYCODE_CALL: {
5570                 if (down) {
5571                     TelecomManager telecomManager = getTelecommService();
5572                     if (telecomManager != null) {
5573                         if (telecomManager.isRinging()) {
5574                             Log.i(TAG, "interceptKeyBeforeQueueing:"
5575                                   + " CALL key-down while ringing: Answer the call!");
5576                             telecomManager.acceptRingingCall();
5577 
5578                             // And *don't* pass this key thru to the current activity
5579                             // (which is presumably the InCallScreen.)
5580                             result &= ~ACTION_PASS_TO_USER;
5581                         }
5582                     }
5583                 }
5584                 break;
5585             }
5586             case KeyEvent.KEYCODE_ASSIST: {
5587                 final boolean longPressed = event.getRepeatCount() > 0;
5588                 if (down && !longPressed) {
5589                     Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST, event.getDeviceId(),
5590                             0 /* unused */, event.getEventTime() /* eventTime */);
5591                     msg.setAsynchronous(true);
5592                     msg.sendToTarget();
5593                     notifyKeyGestureCompleted(event,
5594                             KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
5595                 }
5596                 result &= ~ACTION_PASS_TO_USER;
5597                 break;
5598             }
5599             case KeyEvent.KEYCODE_VOICE_ASSIST: {
5600                 if (!down) {
5601                     mBroadcastWakeLock.acquire();
5602                     Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK);
5603                     msg.setAsynchronous(true);
5604                     msg.sendToTarget();
5605                     notifyKeyGestureCompleted(event,
5606                             KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT);
5607                 }
5608                 result &= ~ACTION_PASS_TO_USER;
5609                 break;
5610             }
5611             case KeyEvent.KEYCODE_WINDOW: {
5612                 if (mShortPressOnWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) {
5613                     if (mPictureInPictureVisible) {
5614                         // Consumes the key only if picture-in-picture is visible to show
5615                         // picture-in-picture control menu. This gives a chance to the foreground
5616                         // activity to customize PIP key behavior.
5617                         if (!down) {
5618                             showPictureInPictureMenu(event);
5619                         }
5620                         result &= ~ACTION_PASS_TO_USER;
5621                     }
5622                 }
5623                 break;
5624             }
5625             case KeyEvent.KEYCODE_STEM_PRIMARY: {
5626                 if (down && event.getRepeatCount() == 0 && (result & ACTION_PASS_TO_USER) == 0) {
5627                     // We've decided not to pass key to user at queueing stage. Make the gesture
5628                     // executable.
5629                     setDeferredKeyActionsExecutableAsync(keyCode, event.getDownTime());
5630                 }
5631                 break;
5632             }
5633             case KeyEvent.KEYCODE_VIDEO_APP_1:
5634             case KeyEvent.KEYCODE_VIDEO_APP_2:
5635             case KeyEvent.KEYCODE_VIDEO_APP_3:
5636             case KeyEvent.KEYCODE_VIDEO_APP_4:
5637             case KeyEvent.KEYCODE_VIDEO_APP_5:
5638             case KeyEvent.KEYCODE_VIDEO_APP_6:
5639             case KeyEvent.KEYCODE_VIDEO_APP_7:
5640             case KeyEvent.KEYCODE_VIDEO_APP_8:
5641             case KeyEvent.KEYCODE_FEATURED_APP_1:
5642             case KeyEvent.KEYCODE_FEATURED_APP_2:
5643             case KeyEvent.KEYCODE_FEATURED_APP_3:
5644             case KeyEvent.KEYCODE_FEATURED_APP_4:
5645             case KeyEvent.KEYCODE_DEMO_APP_1:
5646             case KeyEvent.KEYCODE_DEMO_APP_2:
5647             case KeyEvent.KEYCODE_DEMO_APP_3:
5648             case KeyEvent.KEYCODE_DEMO_APP_4: {
5649                 // Just drop if keys are not intercepted for direct key.
5650                 result &= ~ACTION_PASS_TO_USER;
5651                 break;
5652             }
5653             case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY:
5654             case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY:
5655             case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY:
5656             case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL: {
5657                 Slog.i(TAG, "Stylus buttons event: " + keyCode + " received. Should handle event? "
5658                         + mStylusButtonsEnabled);
5659                 if (mStylusButtonsEnabled) {
5660                     sendSystemKeyToStatusBarAsync(event);
5661                 }
5662                 result &= ~ACTION_PASS_TO_USER;
5663                 break;
5664             }
5665             case KeyEvent.KEYCODE_MACRO_1:
5666             case KeyEvent.KEYCODE_MACRO_2:
5667             case KeyEvent.KEYCODE_MACRO_3:
5668             case KeyEvent.KEYCODE_MACRO_4:
5669                 result &= ~ACTION_PASS_TO_USER;
5670                 break;
5671             case KeyEvent.KEYCODE_DICTATE:
5672             case KeyEvent.KEYCODE_NEW:
5673             case KeyEvent.KEYCODE_CLOSE:
5674             case KeyEvent.KEYCODE_PRINT:
5675             case KeyEvent.KEYCODE_F13:
5676             case KeyEvent.KEYCODE_F14:
5677             case KeyEvent.KEYCODE_F15:
5678             case KeyEvent.KEYCODE_F16:
5679             case KeyEvent.KEYCODE_F17:
5680             case KeyEvent.KEYCODE_F18:
5681             case KeyEvent.KEYCODE_F19:
5682             case KeyEvent.KEYCODE_F20:
5683             case KeyEvent.KEYCODE_F21:
5684             case KeyEvent.KEYCODE_F22:
5685             case KeyEvent.KEYCODE_F23:
5686             case KeyEvent.KEYCODE_F24:
5687                 if (!enableNew25q2Keycodes()) {
5688                     result &= ~ACTION_PASS_TO_USER;
5689                 }
5690                 break;
5691         }
5692 
5693         if (useHapticFeedback) {
5694             performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, "Virtual Key - Press");
5695         }
5696 
5697         if (isWakeKey) {
5698             wakeUpFromWakeKey(event);
5699         }
5700 
5701         // If the key event is targeted to a specific display, then the user is interacting with
5702         // that display. Therefore, try to give focus to the display that the user is interacting
5703         // with.
5704         if ((result & ACTION_PASS_TO_USER) != 0 && displayId != INVALID_DISPLAY
5705                 && displayId != mTopFocusedDisplayId) {
5706             // An event is targeting a non-focused display. Move the display to top so that
5707             // it can become the focused display to interact with the user.
5708             // This should be done asynchronously, once the focus logic is fully moved to input
5709             // from windowmanager. Currently, we need to ensure the setInputWindows completes,
5710             // which would force the focus event to be queued before the current key event.
5711             // TODO(b/70668286): post call to 'moveDisplayToTop' to mHandler instead
5712             Log.i(TAG, "Attempting to move non-focused display " + displayId + " to top "
5713                     + "because a key is targeting it");
5714             mWindowManagerFuncs.moveDisplayToTopIfAllowed(displayId);
5715         }
5716 
5717         return result;
5718     }
5719 
5720     private void handleKeyGesture(KeyEvent event, boolean interactive, boolean defaultDisplayOn) {
5721         if (!InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures()
5722                 && mKeyCombinationManager.interceptKey(event, interactive)) {
5723             // handled by combo keys manager.
5724             mSingleKeyGestureDetector.reset();
5725             return;
5726         }
5727 
5728         if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) {
5729             mPowerKeyHandled = handleCameraGesture(event, interactive);
5730             if (mPowerKeyHandled) {
5731                 // handled by camera gesture.
5732                 mSingleKeyGestureDetector.reset();
5733                 return;
5734             }
5735         }
5736 
5737         mSingleKeyGestureDetector.interceptKey(event, interactive, defaultDisplayOn);
5738     }
5739 
5740     // The camera gesture will be detected by GestureLauncherService.
5741     private boolean handleCameraGesture(KeyEvent event, boolean interactive) {
5742         // camera gesture.
5743         if (mGestureLauncherService == null) {
5744             return false;
5745         }
5746         mPowerButtonLaunchGestureTriggered = false;
5747         final MutableBoolean outLaunched = new MutableBoolean(false);
5748         final boolean intercept =
5749                 mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched);
5750         if (!outLaunched.value) {
5751             // If GestureLauncherService intercepted the power key, but didn't launch camera app,
5752             // we should still return the intercept result. This prevents the single key gesture
5753             // detector from processing the power key later on.
5754             return intercept;
5755         }
5756         mPowerButtonLaunchGestureTriggered = true;
5757         if (mRequestedOrSleepingDefaultDisplay) {
5758             mPowerButtonLaunchGestureTriggeredDuringGoingToSleep = true;
5759             // Wake device up early to prevent display doing redundant turning off/on stuff.
5760             mWindowWakeUpPolicy.wakeUpFromPowerKeyCameraGesture();
5761         }
5762         return true;
5763     }
5764 
5765     /**
5766      * Handle statusbar expansion events.
5767      * @param event
5768      */
5769     private void interceptSystemNavigationKey(KeyEvent event) {
5770         if (event.getAction() == KeyEvent.ACTION_UP) {
5771             if (!mAccessibilityManager.isEnabled()
5772                     || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) {
5773                 if (mSystemNavigationKeysEnabled) {
5774                     sendSystemKeyToStatusBarAsync(event);
5775                 }
5776             }
5777         }
5778     }
5779 
5780     /**
5781      * Notify the StatusBar that a system key was pressed.
5782      */
5783     private void sendSystemKeyToStatusBar(KeyEvent key) {
5784         if (!isKeyEventForCurrentUser(key.getDisplayId(), key.getKeyCode(), "handleSystemKey")) {
5785             return;
5786         }
5787         IStatusBarService statusBar = getStatusBarService();
5788         if (statusBar != null) {
5789             try {
5790                 statusBar.handleSystemKey(key);
5791             } catch (RemoteException e) {
5792                 // Oh well.
5793             }
5794         }
5795     }
5796 
5797     /**
5798      * Notify the StatusBar that a system key was pressed without blocking the current thread.
5799      */
5800     private void sendSystemKeyToStatusBarAsync(KeyEvent keyEvent) {
5801         // Make a copy because the event may be recycled.
5802         Message message = mHandler.obtainMessage(MSG_SYSTEM_KEY_PRESS, KeyEvent.obtain(keyEvent));
5803         message.setAsynchronous(true);
5804         mHandler.sendMessage(message);
5805     }
5806 
5807     /**
5808      * Returns true if the key can have global actions attached to it.
5809      * We reserve all power management keys for the system since they require
5810      * very careful handling.
5811      */
5812     private static boolean isValidGlobalKey(int keyCode) {
5813         switch (keyCode) {
5814             case KeyEvent.KEYCODE_POWER:
5815             case KeyEvent.KEYCODE_WAKEUP:
5816             case KeyEvent.KEYCODE_SLEEP:
5817                 return false;
5818             default:
5819                 return true;
5820         }
5821     }
5822 
5823     /**
5824      * When the screen is off we ignore some keys that might otherwise typically
5825      * be considered wake keys.  We filter them out here.
5826      *
5827      * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it
5828      * is always considered a wake key.
5829      */
5830     private boolean isWakeKeyWhenScreenOff(int keyCode) {
5831         switch (keyCode) {
5832             case KeyEvent.KEYCODE_DPAD_UP:
5833             case KeyEvent.KEYCODE_DPAD_DOWN:
5834             case KeyEvent.KEYCODE_DPAD_LEFT:
5835             case KeyEvent.KEYCODE_DPAD_RIGHT:
5836             case KeyEvent.KEYCODE_DPAD_CENTER:
5837                 return mWakeOnDpadKeyPress;
5838 
5839             case KeyEvent.KEYCODE_ASSIST:
5840                 return mWakeOnAssistKeyPress;
5841 
5842             case KeyEvent.KEYCODE_BACK:
5843                 return mWakeOnBackKeyPress;
5844 
5845             case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY:
5846             case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY:
5847             case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY:
5848             case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL:
5849                 return mStylusButtonsEnabled;
5850         }
5851 
5852         return true;
5853     }
5854 
5855     // TODO(b/117479243): handle it in InputPolicy
5856     /** {@inheritDoc} */
5857     @Override
5858     public int interceptMotionBeforeQueueingNonInteractive(int displayId, int source, int action,
5859             long whenNanos, int policyFlags) {
5860         if ((policyFlags & FLAG_WAKE) != 0) {
5861             if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source,
5862                     action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) {
5863                 // Woke up. Pass motion events to user.
5864                 return ACTION_PASS_TO_USER;
5865             }
5866         }
5867 
5868         if (shouldDispatchInputWhenNonInteractive(displayId, KEYCODE_UNKNOWN)) {
5869             return ACTION_PASS_TO_USER;
5870         }
5871 
5872         // If we have not passed the action up and we are in theater mode without dreaming,
5873         // there will be no dream to intercept the touch and wake into ambient.  The device should
5874         // wake up in this case.
5875         if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
5876             if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source,
5877                     action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) {
5878                 // Woke up. Pass motion events to user.
5879                 return ACTION_PASS_TO_USER;
5880             }
5881         }
5882 
5883         return 0;
5884     }
5885 
5886     private boolean shouldDispatchInputWhenNonInteractive(int displayId, int keyCode) {
5887         // Apply the default display policy to unknown displays as well.
5888         final boolean isDefaultDisplay = displayId == DEFAULT_DISPLAY
5889                 || displayId == INVALID_DISPLAY;
5890         final Display display = isDefaultDisplay
5891                 ? mDefaultDisplay
5892                 : mDisplayManager.getDisplay(displayId);
5893         final boolean displayOff = (display == null
5894                 || display.getState() == STATE_OFF);
5895 
5896         if (displayOff) {
5897             return false;
5898         }
5899 
5900         // Send events to keyguard while the screen is on and it's showing.
5901         if (isKeyguardShowingAndNotOccluded()) {
5902             return true;
5903         }
5904 
5905         // TODO(b/123372519): Refine when dream can support multi display.
5906         if (isDefaultDisplay) {
5907             // Send events to a dozing dream since the dream is in control of the state of the
5908             // screen.
5909             IDreamManager dreamManager = getDreamManager();
5910 
5911             try {
5912                 if (dreamManager != null && dreamManager.isDreaming()) {
5913                     return true;
5914                 }
5915             } catch (RemoteException e) {
5916                 Slog.e(TAG, "RemoteException when checking if dreaming", e);
5917             }
5918         }
5919 
5920         // Otherwise, consume events since the user can't see what is being
5921         // interacted with.
5922         return false;
5923     }
5924 
5925     // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
5926     //                                   KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
5927     private void dispatchDirectAudioEvent(KeyEvent event) {
5928         // When System Audio Mode is off, volume keys received by AVR can be either consumed by AVR
5929         // or forwarded to the TV. It's up to Amplifier manufacturer’s implementation.
5930         HdmiControlManager hdmiControlManager = getHdmiControlManager();
5931         if (null != hdmiControlManager
5932                 && !hdmiControlManager.getSystemAudioMode()
5933                 && shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff()) {
5934             HdmiAudioSystemClient audioSystemClient = hdmiControlManager.getAudioSystemClient();
5935             if (audioSystemClient != null) {
5936                 audioSystemClient.sendKeyEvent(
5937                         event.getKeyCode(), event.getAction() == KeyEvent.ACTION_DOWN);
5938                 return;
5939             }
5940         }
5941         try {
5942             getAudioService().handleVolumeKey(event, mUseTvRouting,
5943                     mContext.getOpPackageName(), TAG);
5944         } catch (Exception e) {
5945             Log.e(TAG, "Error dispatching volume key in handleVolumeKey for event:"
5946                     + event, e);
5947         }
5948     }
5949 
5950     @Nullable
5951     private HdmiControlManager getHdmiControlManager() {
5952         if (!mHasFeatureHdmiCec) {
5953             return null;
5954         }
5955         return (HdmiControlManager) mContext.getSystemService(HdmiControlManager.class);
5956     }
5957 
5958     private boolean shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff() {
5959         return RoSystemProperties.CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF;
5960     }
5961 
5962     void dispatchMediaKeyWithWakeLock(KeyEvent event) {
5963         if (DEBUG_INPUT) {
5964             Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event);
5965         }
5966 
5967         if (mHavePendingMediaKeyRepeatWithWakeLock) {
5968             if (DEBUG_INPUT) {
5969                 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat");
5970             }
5971 
5972             mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK);
5973             mHavePendingMediaKeyRepeatWithWakeLock = false;
5974             mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock
5975         }
5976 
5977         dispatchMediaKeyWithWakeLockToAudioService(event);
5978 
5979         if (event.getAction() == KeyEvent.ACTION_DOWN
5980                 && event.getRepeatCount() == 0) {
5981             mHavePendingMediaKeyRepeatWithWakeLock = true;
5982 
5983             Message msg = mHandler.obtainMessage(
5984                     MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event);
5985             msg.setAsynchronous(true);
5986             mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout());
5987         } else {
5988             mBroadcastWakeLock.release();
5989         }
5990     }
5991 
5992     void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) {
5993         mHavePendingMediaKeyRepeatWithWakeLock = false;
5994 
5995         KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event,
5996                 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS);
5997         if (DEBUG_INPUT) {
5998             Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent);
5999         }
6000 
6001         dispatchMediaKeyWithWakeLockToAudioService(repeatEvent);
6002         mBroadcastWakeLock.release();
6003     }
6004 
6005     void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
6006         if (mActivityManagerInternal.isSystemReady()) {
6007             MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true);
6008         }
6009     }
6010 
6011     void launchVoiceAssistWithWakeLock() {
6012         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
6013 
6014         final Intent voiceIntent;
6015         if (!keyguardOn()) {
6016             voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
6017         } else {
6018             DeviceIdleManager dim = mContext.getSystemService(DeviceIdleManager.class);
6019             if (dim != null) {
6020                 dim.endIdle("voice-search");
6021             }
6022             voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
6023             voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true);
6024         }
6025         startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF);
6026         mBroadcastWakeLock.release();
6027     }
6028 
6029     BroadcastReceiver mDockReceiver = new BroadcastReceiver() {
6030         @Override
6031         public void onReceive(Context context, Intent intent) {
6032             if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
6033                 mDefaultDisplayPolicy.setDockMode(intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
6034                         Intent.EXTRA_DOCK_STATE_UNDOCKED));
6035             } else {
6036                 try {
6037                     IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
6038                             ServiceManager.getService(Context.UI_MODE_SERVICE));
6039                     mUiMode = uiModeService.getCurrentModeType();
6040                 } catch (RemoteException e) {
6041                 }
6042             }
6043             updateRotation(true);
6044             mDefaultDisplayRotation.updateOrientationListener();
6045         }
6046     };
6047 
6048     BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() {
6049         @Override
6050         public void onReceive(Context context, Intent intent) {
6051             if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
6052                 // tickle the settings observer: this first ensures that we're
6053                 // observing the relevant settings for the newly-active user,
6054                 // and then updates our own bookkeeping based on the now-
6055                 // current user.
6056                 mSettingsObserver.onChange(false);
6057                 mDefaultDisplayRotation.onUserSwitch();
6058                 mWindowManagerFuncs.onUserSwitched();
6059             }
6060         }
6061     };
6062 
6063     @Override
6064     public void startedWakingUpGlobal(@WakeReason int reason) {
6065 
6066     }
6067 
6068     @Override
6069     public void finishedWakingUpGlobal(@WakeReason int reason) {
6070 
6071     }
6072 
6073     @Override
6074     public void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
6075         mDeviceGoingToSleep = true;
6076     }
6077 
6078     @Override
6079     public void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
6080         mDeviceGoingToSleep = false;
6081     }
6082 
6083     // Called on the PowerManager's Notifier thread.
6084     @Override
6085     public void startedGoingToSleep(int displayGroupId,
6086             @PowerManager.GoToSleepReason int pmSleepReason) {
6087         if (DEBUG_WAKEUP) {
6088             Slog.i(TAG, "Started going to sleep... (groupId=" + displayGroupId + " why="
6089                     + WindowManagerPolicyConstants.offReasonToString(
6090                             WindowManagerPolicyConstants.translateSleepReasonToOffReason(
6091                                     pmSleepReason)) + ")");
6092         }
6093         if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
6094             return;
6095         }
6096 
6097         mRequestedOrSleepingDefaultDisplay = true;
6098         mIsGoingToSleepDefaultDisplay = true;
6099 
6100         if (mKeyguardDelegate != null) {
6101             mKeyguardDelegate.onStartedGoingToSleep(pmSleepReason);
6102         }
6103     }
6104 
6105     // Called on the PowerManager's Notifier thread.
6106     @Override
6107     public void finishedGoingToSleep(int displayGroupId,
6108             @PowerManager.GoToSleepReason int pmSleepReason) {
6109         if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
6110             return;
6111         }
6112         EventLogTags.writeScreenToggled(0);
6113         if (DEBUG_WAKEUP) {
6114             Slog.i(TAG, "Finished going to sleep... (groupId=" + displayGroupId + " why="
6115                     + WindowManagerPolicyConstants.offReasonToString(
6116                             WindowManagerPolicyConstants.translateSleepReasonToOffReason(
6117                                     pmSleepReason)) + ")");
6118         }
6119         MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
6120 
6121         mRequestedOrSleepingDefaultDisplay = false;
6122         mIsGoingToSleepDefaultDisplay = false;
6123         mDefaultDisplayPolicy.setAwake(false);
6124 
6125         // We must get this work done here because the power manager will drop
6126         // the wake lock and let the system suspend once this function returns.
6127         synchronized (mLock) {
6128             updateWakeGestureListenerLp();
6129             updateLockScreenTimeout();
6130         }
6131         mDefaultDisplayRotation.updateOrientationListener();
6132 
6133         if (mKeyguardDelegate != null) {
6134             mKeyguardDelegate.onFinishedGoingToSleep(pmSleepReason,
6135                     mPowerButtonLaunchGestureTriggeredDuringGoingToSleep);
6136         }
6137         if (mDisplayFoldController != null) {
6138             mDisplayFoldController.finishedGoingToSleep();
6139         }
6140         mPowerButtonLaunchGestureTriggeredDuringGoingToSleep = false;
6141         mPowerButtonLaunchGestureTriggered = false;
6142     }
6143 
6144     // Called on the PowerManager's Notifier thread.
6145     @Override
6146     public void startedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
6147         if (DEBUG_WAKEUP) {
6148             Slog.i(TAG, "Started waking up... (groupId=" + displayGroupId + " why="
6149                     + WindowManagerPolicyConstants.onReasonToString(
6150                     WindowManagerPolicyConstants.translateWakeReasonToOnReason(
6151                             pmWakeReason)) + ")");
6152         }
6153         if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
6154             return;
6155         }
6156         EventLogTags.writeScreenToggled(1);
6157 
6158         mIsGoingToSleepDefaultDisplay = false;
6159         mDefaultDisplayPolicy.setAwake(true);
6160 
6161         // Since goToSleep performs these functions synchronously, we must
6162         // do the same here.  We cannot post this work to a handler because
6163         // that might cause it to become reordered with respect to what
6164         // may happen in a future call to goToSleep.
6165         synchronized (mLock) {
6166             updateWakeGestureListenerLp();
6167             updateLockScreenTimeout();
6168         }
6169         mDefaultDisplayRotation.updateOrientationListener();
6170 
6171         if (mKeyguardDelegate != null) {
6172             mKeyguardDelegate.onStartedWakingUp(pmWakeReason, mPowerButtonLaunchGestureTriggered);
6173         }
6174 
6175         mPowerButtonLaunchGestureTriggered = false;
6176     }
6177 
6178     // Called on the PowerManager's Notifier thread.
6179     @Override
6180     public void finishedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
6181         if (DEBUG_WAKEUP) {
6182             Slog.i(TAG, "Finished waking up... (groupId=" + displayGroupId + " why="
6183                     + WindowManagerPolicyConstants.onReasonToString(
6184                             WindowManagerPolicyConstants.translateWakeReasonToOnReason(
6185                                     pmWakeReason)) + ")");
6186         }
6187         if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
6188             return;
6189         }
6190 
6191         if (mKeyguardDelegate != null) {
6192             mKeyguardDelegate.onFinishedWakingUp();
6193         }
6194         if (mDisplayFoldController != null) {
6195             mDisplayFoldController.finishedWakingUp();
6196         }
6197     }
6198 
6199     private boolean shouldWakeUpWithHomeIntent() {
6200         if (mWakeUpToLastStateTimeout <= 0) {
6201             return false;
6202         }
6203 
6204         final long sleepDurationRealtime =
6205                 mPowerManagerInternal.getLastWakeup().sleepDurationRealtime;
6206         if (DEBUG_WAKEUP) {
6207             Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDurationRealtime= " + sleepDurationRealtime
6208                     + " mWakeUpToLastStateTimeout= " + mWakeUpToLastStateTimeout);
6209         }
6210         return sleepDurationRealtime > mWakeUpToLastStateTimeout;
6211     }
6212 
6213     private void wakeUpFromWakeKey(KeyEvent event) {
6214         if (!isKeyEventForCurrentUser(
6215                 event.getDisplayId(), event.getKeyCode(), "wakeUpFromWakeKey")) {
6216             return;
6217         }
6218         wakeUpFromWakeKey(
6219                 event.getEventTime(),
6220                 event.getKeyCode(),
6221                 event.getAction() == KeyEvent.ACTION_DOWN);
6222     }
6223 
6224     private void wakeUpFromWakeKey(long eventTime, int keyCode, boolean isDown) {
6225         if (mWindowWakeUpPolicy.wakeUpFromKey(DEFAULT_DISPLAY, eventTime, keyCode, isDown)) {
6226             final boolean keyCanLaunchHome = keyCode == KEYCODE_HOME || keyCode == KEYCODE_POWER;
6227             // Start HOME with "reason" extra if sleeping for more than mWakeUpToLastStateTimeout
6228             if (shouldWakeUpWithHomeIntent() &&  keyCanLaunchHome) {
6229                 startDockOrHome(
6230                         DEFAULT_DISPLAY,
6231                         /*fromHomeKey*/ keyCode == KEYCODE_HOME,
6232                         /*wakenFromDreams*/ true,
6233                         "Wake from " + KeyEvent. keyCodeToString(keyCode));
6234             }
6235         }
6236     }
6237 
6238     private void finishKeyguardDrawn() {
6239         if (!mDefaultDisplayPolicy.finishKeyguardDrawn()) {
6240             return;
6241         }
6242 
6243         synchronized (mLock) {
6244             if (mKeyguardDelegate != null) {
6245                 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
6246             }
6247         }
6248 
6249         // ... eventually calls finishWindowsDrawn which will finalize our screen turn on
6250         // as well as enabling the orientation change logic/sensor.
6251         Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
6252                 TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD, INVALID_DISPLAY /* cookie */);
6253         mWindowManagerInternal.waitForAllWindowsDrawn(mHandler.obtainMessage(
6254                 MSG_WINDOW_MANAGER_DRAWN_COMPLETE, INVALID_DISPLAY, 0),
6255                 WAITING_FOR_DRAWN_TIMEOUT, INVALID_DISPLAY);
6256     }
6257 
6258     // Called on the DisplayManager's DisplayPowerController thread.
6259     @Override
6260     public void screenTurnedOff(int displayId, boolean isSwappingDisplay) {
6261         if (DEBUG_WAKEUP) Slog.i(TAG, "Display" + displayId + " turned off...");
6262 
6263         if (displayId == DEFAULT_DISPLAY) {
6264             final boolean acquireSleepToken = !isSwappingDisplay || mIsGoingToSleepDefaultDisplay;
6265             mRequestedOrSleepingDefaultDisplay = false;
6266             mDefaultDisplayPolicy.screenTurnedOff(acquireSleepToken);
6267             synchronized (mLock) {
6268                 if (mKeyguardDelegate != null) {
6269                     mKeyguardDelegate.onScreenTurnedOff();
6270                 }
6271             }
6272             mDefaultDisplayRotation.updateOrientationListener();
6273             reportScreenStateToVrManager(false);
6274         }
6275     }
6276 
6277     @Override
6278     public void onDisplaySwitchStart(int displayId) {
6279         if (displayId == DEFAULT_DISPLAY) {
6280             mDefaultDisplayPolicy.onDisplaySwitchStart();
6281         }
6282     }
6283 
6284     private long getKeyguardDrawnTimeout() {
6285         final boolean bootCompleted =
6286                 LocalServices.getService(SystemServiceManager.class).isBootCompleted();
6287         // Set longer timeout if it has not booted yet to prevent showing empty window.
6288         return bootCompleted ? mKeyguardDrawnTimeout : 5000;
6289     }
6290 
6291     @Nullable
6292     private WallpaperManagerInternal getWallpaperManagerInternal() {
6293         if (mWallpaperManagerInternal == null) {
6294             mWallpaperManagerInternal = LocalServices.getService(WallpaperManagerInternal.class);
6295         }
6296         return mWallpaperManagerInternal;
6297     }
6298 
6299     private void reportScreenTurningOnToWallpaper(int displayId) {
6300         WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
6301         if (wallpaperManagerInternal != null) {
6302             wallpaperManagerInternal.onScreenTurningOn(displayId);
6303         }
6304     }
6305 
6306     private void reportScreenTurnedOnToWallpaper(int displayId) {
6307         WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
6308         if (wallpaperManagerInternal != null) {
6309             wallpaperManagerInternal.onScreenTurnedOn(displayId);
6310         }
6311     }
6312 
6313     // Called on the DisplayManager's DisplayPowerController thread.
6314     @Override
6315     public void screenTurningOn(int displayId, final ScreenOnListener screenOnListener) {
6316         if (DEBUG_WAKEUP) Slog.i(TAG, "Display " + displayId + " turning on...");
6317 
6318         reportScreenTurningOnToWallpaper(displayId);
6319         if (displayId == DEFAULT_DISPLAY) {
6320             Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn",
6321                     0 /* cookie */);
6322             mDefaultDisplayPolicy.screenTurningOn(screenOnListener);
6323             mBootAnimationDismissable = false;
6324 
6325             synchronized (mLock) {
6326                 if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
6327                     mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
6328                     mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
6329                             getKeyguardDrawnTimeout());
6330                     mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
6331                 } else {
6332                     if (DEBUG_WAKEUP) Slog.d(TAG,
6333                             "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
6334                     mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
6335                 }
6336             }
6337         } else {
6338             mScreenOnListeners.put(displayId, screenOnListener);
6339 
6340             Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
6341                     TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD, displayId /* cookie */);
6342             mWindowManagerInternal.waitForAllWindowsDrawn(mHandler.obtainMessage(
6343                     MSG_WINDOW_MANAGER_DRAWN_COMPLETE, displayId, 0),
6344                     WAITING_FOR_DRAWN_TIMEOUT, displayId);
6345         }
6346     }
6347 
6348     // Called on the DisplayManager's DisplayPowerController thread.
6349     @Override
6350     public void screenTurnedOn(int displayId) {
6351         if (DEBUG_WAKEUP) Slog.i(TAG, "Display " + displayId + " turned on...");
6352 
6353         reportScreenTurnedOnToWallpaper(displayId);
6354 
6355         if (displayId != DEFAULT_DISPLAY) {
6356             return;
6357         }
6358 
6359         synchronized (mLock) {
6360             if (mKeyguardDelegate != null) {
6361                 mKeyguardDelegate.onScreenTurnedOn();
6362             }
6363         }
6364         mDefaultDisplayPolicy.screenTurnedOn();
6365         reportScreenStateToVrManager(true);
6366     }
6367 
6368     @Override
6369     public void screenTurningOff(int displayId, ScreenOffListener screenOffListener) {
6370         mWindowManagerFuncs.screenTurningOff(displayId, screenOffListener);
6371         if (displayId != DEFAULT_DISPLAY) {
6372             return;
6373         }
6374 
6375         mRequestedOrSleepingDefaultDisplay = true;
6376         synchronized (mLock) {
6377             if (mKeyguardDelegate != null) {
6378                 mKeyguardDelegate.onScreenTurningOff();
6379             }
6380         }
6381     }
6382 
6383     private void reportScreenStateToVrManager(boolean isScreenOn) {
6384         if (mVrManagerInternal == null) {
6385             return;
6386         }
6387         mVrManagerInternal.onScreenStateChanged(isScreenOn);
6388     }
6389 
6390     private void finishWindowsDrawn(int displayId) {
6391         if (displayId != DEFAULT_DISPLAY && displayId != INVALID_DISPLAY) {
6392             final ScreenOnListener screenOnListener = mScreenOnListeners.removeReturnOld(displayId);
6393             if (screenOnListener != null) {
6394                 screenOnListener.onScreenOn();
6395             }
6396             return;
6397         }
6398 
6399         if (!mDefaultDisplayPolicy.finishWindowsDrawn()) {
6400             return;
6401         }
6402 
6403         finishScreenTurningOn();
6404     }
6405 
6406     private void finishScreenTurningOn() {
6407         // We have just finished drawing screen content. Since the orientation listener
6408         // gets only installed when all windows are drawn, we try to install it again.
6409         mDefaultDisplayRotation.updateOrientationListener();
6410 
6411         final ScreenOnListener listener = mDefaultDisplayPolicy.getScreenOnListener();
6412         if (!mDefaultDisplayPolicy.finishScreenTurningOn()) {
6413             return; // Spurious or not ready yet.
6414         }
6415         Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */);
6416 
6417         enableScreen(listener, true /* report */);
6418     }
6419 
6420     private void enableScreen(ScreenOnListener listener, boolean report) {
6421         final boolean enableScreen;
6422         final boolean awake = mDefaultDisplayPolicy.isAwake();
6423         synchronized (mLock) {
6424             // Remember the first time we draw the keyguard so we know when we're done with
6425             // the main part of booting and can enable the screen and hide boot messages.
6426             if (!mKeyguardDrawnOnce && awake) {
6427                 mKeyguardDrawnOnce = true;
6428                 enableScreen = true;
6429                 if (mBootMessageNeedsHiding) {
6430                     mBootMessageNeedsHiding = false;
6431                     hideBootMessages();
6432                 }
6433             } else {
6434                 enableScreen = false;
6435             }
6436         }
6437 
6438         if (report) {
6439             if (listener != null) {
6440                 listener.onScreenOn();
6441             }
6442         }
6443 
6444         if (enableScreen) {
6445             mWindowManagerFuncs.enableScreenIfNeeded();
6446         }
6447     }
6448 
6449     private void handleHideBootMessage() {
6450         synchronized (mLock) {
6451             if (!mKeyguardDrawnOnce) {
6452                 mBootMessageNeedsHiding = true;
6453                 return; // keyguard hasn't drawn the first time yet, not done booting
6454             }
6455         }
6456 
6457         if (mBootMsgDialog != null) {
6458             if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing");
6459             mBootMsgDialog.dismiss();
6460             mBootMsgDialog = null;
6461         }
6462     }
6463 
6464     @Override
6465     public boolean isScreenOn() {
6466         return mDefaultDisplayPolicy.isScreenOnEarly();
6467     }
6468 
6469     @Override
6470     public boolean okToAnimate(boolean ignoreScreenOn) {
6471         return (ignoreScreenOn || isScreenOn()) && !mDeviceGoingToSleep;
6472     }
6473 
6474     /** {@inheritDoc} */
6475     @Override
6476     public void enableKeyguard(boolean enabled) {
6477         if (mKeyguardDelegate != null) {
6478             mKeyguardDelegate.setKeyguardEnabled(enabled);
6479         }
6480     }
6481 
6482     /** {@inheritDoc} */
6483     @Override
6484     public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
6485         if (mKeyguardDelegate != null) {
6486             mKeyguardDelegate.verifyUnlock(callback);
6487         }
6488     }
6489 
6490     @Override
6491     public boolean isKeyguardShowing() {
6492         if (mKeyguardDelegate == null) return false;
6493         return mKeyguardDelegate.isShowing();
6494     }
6495 
6496     @Override
6497     public boolean isKeyguardShowingAndNotOccluded() {
6498         if (mKeyguardDelegate == null) return false;
6499         return mKeyguardDelegate.isShowing() && !isKeyguardOccluded();
6500     }
6501 
6502     @Override
6503     public boolean isKeyguardTrustedLw() {
6504         if (mKeyguardDelegate == null) return false;
6505         return mKeyguardDelegate.isTrusted();
6506     }
6507 
6508     /** {@inheritDoc} */
6509     @Override
6510     public boolean isKeyguardLocked() {
6511         return keyguardOn();
6512     }
6513 
6514     /** {@inheritDoc} */
6515     @Override
6516     public boolean isKeyguardSecure(int userId) {
6517         if (mKeyguardDelegate == null) return false;
6518         return mKeyguardDelegate.isSecure(userId);
6519     }
6520 
6521     /** {@inheritDoc} */
6522     @Override
6523     public boolean isKeyguardOccluded() {
6524         if (mKeyguardDelegate == null) return false;
6525         return mKeyguardDelegate.isOccluded();
6526     }
6527 
6528     /** {@inheritDoc} */
6529     @Override
6530     public boolean inKeyguardRestrictedKeyInputMode() {
6531         if (mKeyguardDelegate == null) return false;
6532         return mKeyguardDelegate.isInputRestricted();
6533     }
6534 
6535     @Override
6536     public void dismissKeyguardLw(IKeyguardDismissCallback callback, CharSequence message) {
6537         if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
6538             if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw");
6539 
6540             // ask the keyguard to prompt the user to authenticate if necessary
6541             mKeyguardDelegate.dismiss(callback, message);
6542         } else if (callback != null) {
6543             try {
6544                 callback.onDismissError();
6545             } catch (RemoteException e) {
6546                 Slog.w(TAG, "Failed to call callback", e);
6547             }
6548         }
6549     }
6550 
6551     @Override
6552     public boolean isKeyguardDrawnLw() {
6553         synchronized (mLock) {
6554             return mKeyguardDrawnOnce;
6555         }
6556     }
6557 
6558     @Override
6559     public void startKeyguardExitAnimation(long startTime) {
6560         if (mKeyguardDelegate != null) {
6561             if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
6562             mKeyguardDelegate.startKeyguardExitAnimation(startTime);
6563         }
6564     }
6565 
6566     void sendCloseSystemWindows() {
6567         PhoneWindow.sendCloseSystemWindows(mContext, null);
6568     }
6569 
6570     void sendCloseSystemWindows(String reason) {
6571         PhoneWindow.sendCloseSystemWindows(mContext, reason);
6572     }
6573 
6574     @Override
6575     public void setSafeMode(boolean safeMode) {
6576         mSafeMode = safeMode;
6577         if (safeMode) {
6578             performHapticFeedback(
6579                     HapticFeedbackConstants.SAFE_MODE_ENABLED,
6580                     "Safe Mode Enabled" /* reason */,
6581                     HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
6582         }
6583     }
6584 
6585     private void bindKeyguard() {
6586         synchronized (mLock) {
6587             if (mKeyguardBound) {
6588                 return;
6589             }
6590             mKeyguardBound = true;
6591         }
6592         mKeyguardDelegate.bindService(mContext);
6593     }
6594 
6595     @Override
6596     public void onSystemUiStarted() {
6597         bindKeyguard();
6598     }
6599 
6600     /** {@inheritDoc} */
6601     @Override
6602     public void systemReady() {
6603         // In normal flow, systemReady is called before other system services are ready.
6604         // So it is better not to bind keyguard here.
6605         mKeyguardDelegate.onSystemReady();
6606         mModifierShortcutManager.onSystemReady();
6607 
6608         mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
6609         if (mVrManagerInternal != null) {
6610             mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
6611         }
6612 
6613         mDockObserverInternal = LocalServices.getService(DockObserverInternal.class);
6614         if (mDockObserverInternal != null) {
6615             // Get initial state from DockObserverInternal, DockObserver starts after WM.
6616             int dockMode = mDockObserverInternal.getActualDockState();
6617             mDefaultDisplayPolicy.setDockMode(dockMode);
6618         }
6619 
6620         readCameraLensCoverState();
6621         updateUiMode();
6622         mDefaultDisplayRotation.updateOrientationListener();
6623         synchronized (mLock) {
6624             mSystemReady = true;
6625             updateSettings(mHandler);
6626             // If this happens, for whatever reason, systemReady came later than systemBooted.
6627             // And keyguard should be already bound from systemBooted
6628             if (mSystemBooted) {
6629                 mKeyguardDelegate.onBootCompleted();
6630             }
6631         }
6632 
6633         mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
6634         mGestureLauncherService = LocalServices.getService(GestureLauncherService.class);
6635     }
6636 
6637     /** {@inheritDoc} */
6638     @Override
6639     public void systemBooted() {
6640         bindKeyguard();
6641         synchronized (mLock) {
6642             mSystemBooted = true;
6643             if (mSystemReady) {
6644                 mKeyguardDelegate.onBootCompleted();
6645             }
6646         }
6647         mSideFpsEventHandler.onFingerprintSensorReady();
6648         startedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);
6649         finishedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);
6650 
6651         int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState();
6652         boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON;
6653         boolean defaultScreenTurningOn = mDefaultDisplayPolicy.getScreenOnListener() != null;
6654         if (defaultDisplayOn || defaultScreenTurningOn) {
6655             // Now that system is booted, wait for keyguard and windows to be drawn before
6656             // updating the orientation listener, stopping the boot animation and enabling screen.
6657             screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener());
6658             screenTurnedOn(DEFAULT_DISPLAY);
6659         } else {
6660             // We're not turning the screen on, so don't wait for keyguard to be drawn
6661             // to dismiss the boot animation and finish booting
6662             mBootAnimationDismissable = true;
6663             enableScreen(null, false /* report */);
6664         }
6665     }
6666 
6667     @Override
6668     public boolean canDismissBootAnimation() {
6669         // Allow to dismiss the boot animation if the keyguard has finished drawing,
6670         // or mBootAnimationDismissable has been set
6671         return mDefaultDisplayPolicy.isKeyguardDrawComplete() || mBootAnimationDismissable;
6672     }
6673 
6674     ProgressDialog mBootMsgDialog = null;
6675 
6676     /** {@inheritDoc} */
6677     @Override
6678     public void showBootMessage(final CharSequence msg, final boolean always) {
6679         mHandler.post(new Runnable() {
6680             @Override public void run() {
6681                 if (mBootMsgDialog == null) {
6682                     int theme;
6683                     if (mPackageManager.hasSystemFeature(FEATURE_LEANBACK)) {
6684                         theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert;
6685                     } else {
6686                         theme = 0;
6687                     }
6688 
6689                     mBootMsgDialog = new ProgressDialog(mContext, theme) {
6690                         // This dialog will consume all events coming in to
6691                         // it, to avoid it trying to do things too early in boot.
6692                         @Override public boolean dispatchKeyEvent(KeyEvent event) {
6693                             return true;
6694                         }
6695                         @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) {
6696                             return true;
6697                         }
6698                         @Override public boolean dispatchTouchEvent(MotionEvent ev) {
6699                             return true;
6700                         }
6701                         @Override public boolean dispatchTrackballEvent(MotionEvent ev) {
6702                             return true;
6703                         }
6704                         @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) {
6705                             return true;
6706                         }
6707                         @Override public boolean dispatchPopulateAccessibilityEvent(
6708                                 AccessibilityEvent event) {
6709                             return true;
6710                         }
6711                     };
6712                     if (mPackageManager.isDeviceUpgrading()) {
6713                         mBootMsgDialog.setTitle(R.string.android_upgrading_title);
6714                     } else {
6715                         mBootMsgDialog.setTitle(R.string.android_start_title);
6716                     }
6717                     mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
6718                     mBootMsgDialog.setIndeterminate(true);
6719                     mBootMsgDialog.getWindow().setType(
6720                             WindowManager.LayoutParams.TYPE_BOOT_PROGRESS);
6721                     mBootMsgDialog.getWindow().addFlags(
6722                             WindowManager.LayoutParams.FLAG_DIM_BEHIND
6723                             | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
6724                     mBootMsgDialog.getWindow().setDimAmount(1);
6725                     WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes();
6726                     lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
6727                     lp.setFitInsetsTypes(0 /* types */);
6728                     mBootMsgDialog.getWindow().setAttributes(lp);
6729                     mBootMsgDialog.setCancelable(false);
6730                     mBootMsgDialog.show();
6731                 }
6732                 mBootMsgDialog.setMessage(msg);
6733             }
6734         });
6735     }
6736 
6737     /** {@inheritDoc} */
6738     @Override
6739     public void hideBootMessages() {
6740         mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE);
6741     }
6742 
6743     /** {@inheritDoc} */
6744     @Override
6745     public void userActivity(int displayGroupId, int event) {
6746         if (displayGroupId == DEFAULT_DISPLAY && event == PowerManager.USER_ACTIVITY_EVENT_TOUCH) {
6747             mDefaultDisplayPolicy.onUserActivityEventTouch();
6748         }
6749         synchronized (mScreenLockTimeout) {
6750             if (mLockScreenTimerActive) {
6751                 // reset the timer
6752                 mHandler.removeCallbacks(mScreenLockTimeout);
6753                 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
6754             }
6755         }
6756     }
6757 
6758     class ScreenLockTimeout implements Runnable {
6759         Bundle options;
6760 
6761         @Override
6762         public void run() {
6763             synchronized (this) {
6764                 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard");
6765                 if (mKeyguardDelegate != null) {
6766                     mKeyguardDelegate.doKeyguardTimeout(options);
6767                 }
6768                 mLockScreenTimerActive = false;
6769                 mLockNowPending = false;
6770                 options = null;
6771             }
6772         }
6773 
6774         public void setLockOptions(Bundle options) {
6775             this.options = options;
6776         }
6777     }
6778 
6779     final ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();
6780 
6781     @Override
6782     public void lockNow(Bundle options) {
6783         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
6784         mHandler.removeCallbacks(mScreenLockTimeout);
6785         if (options != null) {
6786             // In case multiple calls are made to lockNow, we don't wipe out the options
6787             // until the runnable actually executes.
6788             mScreenLockTimeout.setLockOptions(options);
6789         }
6790         mHandler.post(mScreenLockTimeout);
6791         synchronized (mScreenLockTimeout) {
6792             mLockNowPending = true;
6793         }
6794     }
6795 
6796     // TODO (b/113840485): Move this logic to DisplayPolicy when lockscreen supports multi-display.
6797     @Override
6798     public void setAllowLockscreenWhenOn(int displayId, boolean allow) {
6799         // We should ignore this operation for visible background users
6800         // until lockscreen supports multi-display.
6801         if (mVisibleBackgroundUsersEnabled
6802                 && mUserManagerInternal.getUserAssignedToDisplay(displayId) != mCurrentUserId) {
6803             return;
6804         }
6805         if (allow) {
6806             mAllowLockscreenWhenOnDisplays.add(displayId);
6807         } else {
6808             mAllowLockscreenWhenOnDisplays.remove(displayId);
6809         }
6810         updateLockScreenTimeout();
6811     }
6812 
6813     private void updateLockScreenTimeout() {
6814         synchronized (mScreenLockTimeout) {
6815             if (mLockNowPending) {
6816                 Log.w(TAG, "lockNow pending, ignore updating lockscreen timeout");
6817                 return;
6818             }
6819             final boolean enable = !mAllowLockscreenWhenOnDisplays.isEmpty()
6820                     && mDefaultDisplayPolicy.isAwake()
6821                     && mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId);
6822             if (mLockScreenTimerActive != enable) {
6823                 if (enable) {
6824                     if (localLOGV) Log.v(TAG, "setting lockscreen timer");
6825                     mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests
6826                     mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
6827                 } else {
6828                     if (localLOGV) Log.v(TAG, "clearing lockscreen timer");
6829                     mHandler.removeCallbacks(mScreenLockTimeout);
6830                 }
6831                 mLockScreenTimerActive = enable;
6832             }
6833         }
6834     }
6835 
6836     /** {@inheritDoc} */
6837     @Override
6838     public void enableScreenAfterBoot() {
6839         readLidState();
6840         applyLidSwitchState();
6841         updateRotation(true);
6842     }
6843 
6844     private void applyLidSwitchState() {
6845         final int lidState = mDefaultDisplayPolicy.getLidState();
6846         if (lidState == LID_CLOSED) {
6847             int lidBehavior = getLidBehavior();
6848             switch (lidBehavior) {
6849                 case LID_BEHAVIOR_LOCK:
6850                     mWindowManagerFuncs.lockDeviceNow();
6851                     break;
6852                 case LID_BEHAVIOR_SLEEP:
6853                     sleepDefaultDisplay(SystemClock.uptimeMillis(),
6854                             PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
6855                             PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
6856                     break;
6857                 case LID_BEHAVIOR_NONE:
6858                     // fall through
6859                 default:
6860                     break;
6861             }
6862         }
6863 
6864         synchronized (mLock) {
6865             updateWakeGestureListenerLp();
6866         }
6867     }
6868 
6869     void updateUiMode() {
6870         if (mUiModeManager == null) {
6871             mUiModeManager = IUiModeManager.Stub.asInterface(
6872                     ServiceManager.getService(Context.UI_MODE_SERVICE));
6873         }
6874         try {
6875             mUiMode = mUiModeManager.getCurrentModeType();
6876         } catch (RemoteException e) {
6877         }
6878     }
6879 
6880     @Override
6881     public int getUiMode() {
6882         return mUiMode;
6883     }
6884 
6885     void updateRotation(boolean alwaysSendConfiguration) {
6886         mWindowManagerFuncs.updateRotation(alwaysSendConfiguration, false /* forceRelayout */);
6887     }
6888 
6889     /**
6890      * Return an Intent to launch the currently active dock app as home.  Returns
6891      * null if the standard home should be launched, which is the case if any of the following is
6892      * true:
6893      * <ul>
6894      *  <li>The device is not in either car mode or desk mode
6895      *  <li>The device is in car mode but mEnableCarDockHomeCapture is false
6896      *  <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
6897      *  <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
6898      *  <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
6899      * </ul>
6900      * @return A dock intent.
6901      */
6902     Intent createHomeDockIntent() {
6903         Intent intent = null;
6904 
6905         // What home does is based on the mode, not the dock state.  That
6906         // is, when in car mode you should be taken to car home regardless
6907         // of whether we are actually in a car dock.
6908         if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
6909             if (mEnableCarDockHomeCapture) {
6910                 intent = mCarDockIntent;
6911             }
6912         } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
6913             if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
6914                 intent = mDeskDockIntent;
6915             }
6916         } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH) {
6917             final int dockMode = mDefaultDisplayPolicy.getDockMode();
6918             if (dockMode == Intent.EXTRA_DOCK_STATE_DESK
6919                     || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK
6920                     || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK) {
6921                 // Always launch dock home from home when watch is docked, if it exists.
6922                 intent = mDeskDockIntent;
6923             }
6924         } else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) {
6925             if (ENABLE_VR_HEADSET_HOME_CAPTURE) {
6926                 intent = mVrHeadsetHomeIntent;
6927             }
6928         }
6929 
6930         if (intent == null) {
6931             return null;
6932         }
6933 
6934         ActivityInfo ai = null;
6935         ResolveInfo info = mPackageManager.resolveActivityAsUser(
6936                 intent,
6937                 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
6938                 mCurrentUserId);
6939         if (info != null) {
6940             ai = info.activityInfo;
6941         }
6942         if (ai != null
6943                 && ai.metaData != null
6944                 && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) {
6945             intent = new Intent(intent);
6946             intent.setClassName(ai.packageName, ai.name);
6947             return intent;
6948         }
6949 
6950         return null;
6951     }
6952 
6953     void startDockOrHome(int displayId, boolean fromHomeKey, boolean awakenFromDreams,
6954             String startReason) {
6955         try {
6956             ActivityManager.getService().stopAppSwitches();
6957         } catch (RemoteException e) {}
6958         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
6959 
6960         if (awakenFromDreams) {
6961             awakenDreams();
6962         }
6963 
6964         if (!mHasFeatureAuto && !isUserSetupComplete()) {
6965             Slog.i(TAG, "Not going home because user setup is in progress.");
6966             return;
6967         }
6968 
6969         // Start dock.
6970         Intent dock = createHomeDockIntent();
6971         if (dock != null) {
6972             try {
6973                 if (fromHomeKey) {
6974                     dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey);
6975                 }
6976                 startActivityAsUser(dock, UserHandle.CURRENT);
6977                 return;
6978             } catch (ActivityNotFoundException e) {
6979             }
6980         }
6981 
6982         if (DEBUG_WAKEUP) {
6983             Log.d(TAG, "startDockOrHome: startReason= " + startReason);
6984         }
6985 
6986         int userId = mUserManagerInternal.getUserAssignedToDisplay(displayId);
6987         // Start home.
6988         mActivityTaskManagerInternal.startHomeOnDisplay(userId, startReason,
6989                 displayId, true /* allowInstrumenting */, fromHomeKey);
6990     }
6991 
6992     void startDockOrHome(int displayId, boolean fromHomeKey, boolean awakenFromDreams) {
6993         startDockOrHome(displayId, fromHomeKey, awakenFromDreams, /*startReason*/
6994                 "startDockOrHome");
6995     }
6996 
6997     /**
6998      * goes to the home screen
6999      * @return whether it did anything
7000      */
7001     boolean goHome() {
7002         if (!isUserSetupComplete()) {
7003             Slog.i(TAG, "Not going home because user setup is in progress.");
7004             return false;
7005         }
7006         if (false) {
7007             // This code always brings home to the front.
7008             startDockOrHome(DEFAULT_DISPLAY, false /*fromHomeKey*/, true /* awakenFromDreams */);
7009         } else {
7010             // This code brings home to the front or, if it is already
7011             // at the front, puts the device to sleep.
7012             try {
7013                 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) {
7014                     /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry.
7015                     Log.d(TAG, "UTS-TEST-MODE");
7016                 } else {
7017                     ActivityManager.getService().stopAppSwitches();
7018                     sendCloseSystemWindows();
7019                     final Intent dock = createHomeDockIntent();
7020                     if (dock != null) {
7021                         int result = ActivityTaskManager.getService()
7022                                 .startActivityAsUser(null, mContext.getOpPackageName(),
7023                                         mContext.getAttributionTag(), dock,
7024                                         dock.resolveTypeIfNeeded(mContext.getContentResolver()),
7025                                         null, null, 0,
7026                                         ActivityManager.START_FLAG_ONLY_IF_NEEDED,
7027                                         null, null, UserHandle.USER_CURRENT);
7028                         if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
7029                             return false;
7030                         }
7031                     }
7032                 }
7033                 int result = ActivityTaskManager.getService()
7034                         .startActivityAsUser(null, mContext.getOpPackageName(),
7035                                 mContext.getAttributionTag(), mHomeIntent,
7036                                 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
7037                                 null, null, 0,
7038                                 ActivityManager.START_FLAG_ONLY_IF_NEEDED,
7039                                 null, null, UserHandle.USER_CURRENT);
7040                 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
7041                     return false;
7042                 }
7043             } catch (RemoteException ex) {
7044                 // bummer, the activity manager, which is in this process, is dead
7045             }
7046         }
7047         return true;
7048     }
7049 
7050     private boolean isTheaterModeEnabled() {
7051         return Settings.Global.getInt(mContext.getContentResolver(),
7052                 Settings.Global.THEATER_MODE_ON, 0) == 1;
7053     }
7054 
7055     private void performHapticFeedback(int effectId, String reason) {
7056         performHapticFeedback(effectId, reason, 0 /* flags */);
7057     }
7058 
7059     private void performHapticFeedback(
7060             int effectId, String reason, @HapticFeedbackConstants.Flags int flags) {
7061         mVibrator.performHapticFeedback(effectId, reason, flags, 0 /* privFlags */);
7062     }
7063 
7064     @Override
7065     public boolean isGlobalKey(int keyCode) {
7066         return mGlobalKeyManager.shouldHandleGlobalKey(keyCode);
7067     }
7068 
7069 
7070     @Override
7071     public void keepScreenOnStartedLw() {
7072     }
7073 
7074     @Override
7075     public void keepScreenOnStoppedLw() {
7076         if (isKeyguardShowingAndNotOccluded()) {
7077             mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
7078         }
7079     }
7080 
7081     // Use this instead of checking config_showNavigationBar so that it can be consistently
7082     // overridden by qemu.hw.mainkeys in the emulator.
7083     @Override
7084     public boolean hasNavigationBar() {
7085         return mDefaultDisplayPolicy.hasNavigationBar();
7086     }
7087 
7088     @Override
7089     public void setDismissImeOnBackKeyPressed(boolean newValue) {
7090         mDismissImeOnBackKeyPressed = newValue;
7091     }
7092 
7093     @Override
7094     public void setCurrentUserLw(int newUserId) {
7095         mCurrentUserId = newUserId;
7096         if (mKeyguardDelegate != null) {
7097             mKeyguardDelegate.setCurrentUser(newUserId);
7098         }
7099         if (mAccessibilityShortcutController != null) {
7100             mAccessibilityShortcutController.setCurrentUser(newUserId);
7101         }
7102         StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
7103         if (statusBar != null) {
7104             statusBar.setCurrentUser(newUserId);
7105         }
7106         if (modifierShortcutManagerMultiuser()) {
7107             mModifierShortcutManager.setCurrentUser(UserHandle.of(newUserId));
7108         }
7109         if (!inputManagerLifecycleSupport()) {
7110             mInputManagerInternal.setCurrentUser(newUserId);
7111         }
7112     }
7113 
7114     @Override
7115     public void setSwitchingUser(boolean switching) {
7116         mKeyguardDelegate.setSwitchingUser(switching);
7117         if (switching) {
7118             dismissKeyboardShortcutsMenu();
7119         }
7120     }
7121 
7122     @Override
7123     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
7124         final long token = proto.start(fieldId);
7125         proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode());
7126         proto.write(ROTATION, mDefaultDisplayRotation.getUserRotation());
7127         proto.write(ORIENTATION, mDefaultDisplayRotation.getCurrentAppOrientation());
7128         proto.write(SCREEN_ON_FULLY, mDefaultDisplayPolicy.isScreenOnFully());
7129         proto.write(KEYGUARD_DRAW_COMPLETE, mDefaultDisplayPolicy.isKeyguardDrawComplete());
7130         proto.write(WINDOW_MANAGER_DRAW_COMPLETE,
7131                 mDefaultDisplayPolicy.isWindowManagerDrawComplete());
7132         proto.write(KEYGUARD_OCCLUDED, isKeyguardOccluded());
7133         proto.write(KEYGUARD_OCCLUDED_CHANGED, mKeyguardOccludedChanged);
7134         proto.write(KEYGUARD_OCCLUDED_PENDING, mPendingKeyguardOccluded);
7135         if (mKeyguardDelegate != null) {
7136             mKeyguardDelegate.dumpDebug(proto, KEYGUARD_DELEGATE);
7137         }
7138         proto.end(token);
7139     }
7140 
7141     @Override
7142     public void dump(String prefix, PrintWriter pw, String[] args) {
7143         pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
7144                 pw.print(" mSystemReady="); pw.print(mSystemReady);
7145                 pw.print(" mSystemBooted="); pw.println(mSystemBooted);
7146         pw.print(prefix); pw.print("mCameraLensCoverState=");
7147                 pw.println(WindowManagerFuncs.cameraLensStateToString(mCameraLensCoverState));
7148         pw.print(prefix); pw.print("mWakeGestureEnabledSetting=");
7149                 pw.println(mWakeGestureEnabledSetting);
7150 
7151         pw.print(prefix);
7152                 pw.print("mUiMode=");
7153                 pw.print(Configuration.uiModeToString(mUiMode));
7154                 pw.print("mEnableCarDockHomeCapture="); pw.println(mEnableCarDockHomeCapture);
7155         pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
7156                 pw.print(mLidKeyboardAccessibility);
7157                 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
7158                 pw.print(" getLidBehavior="); pw.println(lidBehaviorToString(getLidBehavior()));
7159         pw.print(prefix);
7160                 pw.print("mLongPressOnBackBehavior=");
7161                 pw.println(longPressOnBackBehaviorToString(mLongPressOnBackBehavior));
7162         pw.print(prefix);
7163                 pw.print("mLongPressOnHomeBehavior=");
7164                 pw.println(longPressOnHomeBehaviorToString(mLongPressOnHomeBehavior));
7165         pw.print(prefix);
7166                 pw.print("mDoubleTapOnHomeBehavior=");
7167                 pw.println(doubleTapOnHomeBehaviorToString(mDoubleTapOnHomeBehavior));
7168         pw.print(prefix);
7169                 pw.print("mShortPressOnPowerBehavior=");
7170                 pw.println(shortPressOnPowerBehaviorToString(mShortPressOnPowerBehavior));
7171         pw.print(prefix);
7172                 pw.print("mLongPressOnPowerBehavior=");
7173                 pw.println(longPressOnPowerBehaviorToString(mLongPressOnPowerBehavior));
7174         pw.print(prefix);
7175         pw.print("mSettingsKeyBehavior=");
7176         pw.println(settingsKeyBehaviorToString(mSettingsKeyBehavior));
7177         pw.print(prefix);
7178         pw.print("mLongPressOnPowerAssistantTimeoutMs=");
7179         pw.println(mLongPressOnPowerAssistantTimeoutMs);
7180         pw.print(prefix);
7181                 pw.print("mVeryLongPressOnPowerBehavior=");
7182                 pw.println(veryLongPressOnPowerBehaviorToString(mVeryLongPressOnPowerBehavior));
7183         pw.print(prefix);
7184                 pw.print("mDoublePressOnPowerBehavior=");
7185                 pw.println(multiPressOnPowerBehaviorToString(mDoublePressOnPowerBehavior));
7186         pw.print(prefix);
7187                 pw.print("mTriplePressOnPowerBehavior=");
7188                 pw.println(multiPressOnPowerBehaviorToString(mTriplePressOnPowerBehavior));
7189         pw.print(prefix);
7190                 pw.print("mSupportShortPressPowerWhenDefaultDisplayOn=");
7191                 pw.println(mSupportShortPressPowerWhenDefaultDisplayOn);
7192         pw.print(prefix);
7193         pw.print("mPowerVolUpBehavior=");
7194         pw.println(powerVolumeUpBehaviorToString(mPowerVolUpBehavior));
7195         pw.print(prefix);
7196                 pw.print("mShortPressOnSleepBehavior=");
7197                 pw.println(shortPressOnSleepBehaviorToString(mShortPressOnSleepBehavior));
7198         pw.print(prefix);
7199                 pw.print("mShortPressOnWindowBehavior=");
7200                 pw.println(shortPressOnWindowBehaviorToString(mShortPressOnWindowBehavior));
7201         pw.print(prefix);
7202                 pw.print("mShortPressOnStemPrimaryBehavior=");
7203                 pw.println(shortPressOnStemPrimaryBehaviorToString(
7204                     mShortPressOnStemPrimaryBehavior));
7205         pw.print(prefix);
7206                 pw.print("mDoublePressOnStemPrimaryBehavior=");
7207                 pw.println(doublePressOnStemPrimaryBehaviorToString(
7208                     mDoublePressOnStemPrimaryBehavior));
7209         pw.print(prefix);
7210                 pw.print("mTriplePressOnStemPrimaryBehavior=");
7211                 pw.println(triplePressOnStemPrimaryBehaviorToString(
7212                     mTriplePressOnStemPrimaryBehavior));
7213         pw.print(prefix);
7214                 pw.print("mLongPressOnStemPrimaryBehavior=");
7215                 pw.println(longPressOnStemPrimaryBehaviorToString(
7216                     mLongPressOnStemPrimaryBehavior));
7217         pw.print(prefix);
7218                 pw.print("mAllowStartActivityForLongPressOnPowerDuringSetup=");
7219                 pw.println(mAllowStartActivityForLongPressOnPowerDuringSetup);
7220         pw.print(prefix);
7221                 pw.print("mHasSoftInput="); pw.println(mHasSoftInput);
7222         pw.print(prefix);
7223                 pw.print("mDismissImeOnBackKeyPressed="); pw.print(mDismissImeOnBackKeyPressed);
7224                 pw.print(" mIncallPowerBehavior=");
7225                 pw.println(incallPowerBehaviorToString(mIncallPowerBehavior));
7226         pw.print(prefix);
7227                 pw.print("mIncallBackBehavior=");
7228                 pw.print(incallBackBehaviorToString(mIncallBackBehavior));
7229                 pw.print(" mEndcallBehavior=");
7230                 pw.println(endcallBehaviorToString(mEndcallBehavior));
7231         pw.print(prefix);
7232         // TODO(b/117479243): handle it in InputPolicy
7233         pw.println("mDisplayHomeButtonHandlers=");
7234         for (int i = 0; i < mDisplayHomeButtonHandlers.size(); i++) {
7235             final int key = mDisplayHomeButtonHandlers.keyAt(i);
7236             pw.print(prefix); pw.print("  "); pw.println(mDisplayHomeButtonHandlers.get(key));
7237         }
7238         pw.print(prefix); pw.print("mKeyguardOccluded="); pw.print(isKeyguardOccluded());
7239                 pw.print(" mKeyguardOccludedChanged="); pw.print(mKeyguardOccludedChanged);
7240                 pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded);
7241         pw.print(prefix); pw.print("mAllowLockscreenWhenOnDisplays=");
7242                 pw.print(!mAllowLockscreenWhenOnDisplays.isEmpty());
7243                 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
7244                 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
7245         pw.print(prefix); pw.print("mKidsModeEnabled="); pw.println(mKidsModeEnabled);
7246 
7247         mGlobalKeyManager.dump(prefix, pw);
7248         mKeyCombinationManager.dump(prefix, pw);
7249         mSingleKeyGestureDetector.dump(prefix, pw);
7250         mDeferredKeyActionExecutor.dump(prefix, pw);
7251 
7252         if (mWakeGestureListener != null) {
7253             mWakeGestureListener.dump(pw, prefix);
7254         }
7255         if (mBurnInProtectionHelper != null) {
7256             mBurnInProtectionHelper.dump(prefix, pw);
7257         }
7258         if (mKeyguardDelegate != null) {
7259             mKeyguardDelegate.dump(prefix, pw);
7260         }
7261 
7262         pw.print(prefix); pw.println("Looper state:");
7263         mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + "  ");
7264         if (modifierShortcutDump()) {
7265             mModifierShortcutManager.dump(prefix, pw);
7266         }
7267     }
7268 
7269     private static String endcallBehaviorToString(int behavior) {
7270         StringBuilder sb = new StringBuilder();
7271         if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0 ) {
7272             sb.append("home|");
7273         }
7274         if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
7275             sb.append("sleep|");
7276         }
7277 
7278         final int N = sb.length();
7279         if (N == 0) {
7280             return "<nothing>";
7281         } else {
7282             // Chop off the trailing '|'
7283             return sb.substring(0, N - 1);
7284         }
7285     }
7286 
7287     private static String incallPowerBehaviorToString(int behavior) {
7288         if ((behavior & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0) {
7289             return "hangup";
7290         } else {
7291             return "sleep";
7292         }
7293     }
7294 
7295     private static String incallBackBehaviorToString(int behavior) {
7296         if ((behavior & Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_HANGUP) != 0) {
7297             return "hangup";
7298         } else {
7299             return "<nothing>";
7300         }
7301     }
7302 
7303     private static String longPressOnBackBehaviorToString(int behavior) {
7304         switch (behavior) {
7305             case LONG_PRESS_BACK_NOTHING:
7306                 return "LONG_PRESS_BACK_NOTHING";
7307             case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST:
7308                 return "LONG_PRESS_BACK_GO_TO_VOICE_ASSIST";
7309             default:
7310                 return Integer.toString(behavior);
7311         }
7312     }
7313 
7314     private static String longPressOnHomeBehaviorToString(int behavior) {
7315         switch (behavior) {
7316             case LONG_PRESS_HOME_NOTHING:
7317                 return "LONG_PRESS_HOME_NOTHING";
7318             case LONG_PRESS_HOME_ALL_APPS:
7319                 return "LONG_PRESS_HOME_ALL_APPS";
7320             case LONG_PRESS_HOME_ASSIST:
7321                 return "LONG_PRESS_HOME_ASSIST";
7322             case LONG_PRESS_HOME_NOTIFICATION_PANEL:
7323                 return "LONG_PRESS_HOME_NOTIFICATION_PANEL";
7324             default:
7325                 return Integer.toString(behavior);
7326         }
7327     }
7328 
7329     private static String doubleTapOnHomeBehaviorToString(int behavior) {
7330         switch (behavior) {
7331             case DOUBLE_TAP_HOME_NOTHING:
7332                 return "DOUBLE_TAP_HOME_NOTHING";
7333             case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI:
7334                 return "DOUBLE_TAP_HOME_RECENT_SYSTEM_UI";
7335             case DOUBLE_TAP_HOME_PIP_MENU:
7336                 return "DOUBLE_TAP_HOME_PIP_MENU";
7337             default:
7338                 return Integer.toString(behavior);
7339         }
7340     }
7341 
7342     private static String shortPressOnPowerBehaviorToString(int behavior) {
7343         switch (behavior) {
7344             case SHORT_PRESS_POWER_NOTHING:
7345                 return "SHORT_PRESS_POWER_NOTHING";
7346             case SHORT_PRESS_POWER_GO_TO_SLEEP:
7347                 return "SHORT_PRESS_POWER_GO_TO_SLEEP";
7348             case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
7349                 return "SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP";
7350             case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
7351                 return "SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME";
7352             case SHORT_PRESS_POWER_GO_HOME:
7353                 return "SHORT_PRESS_POWER_GO_HOME";
7354             case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME:
7355                 return "SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME";
7356             default:
7357                 return Integer.toString(behavior);
7358         }
7359     }
7360 
7361     private static String longPressOnPowerBehaviorToString(int behavior) {
7362         switch (behavior) {
7363             case LONG_PRESS_POWER_NOTHING:
7364                 return "LONG_PRESS_POWER_NOTHING";
7365             case LONG_PRESS_POWER_GLOBAL_ACTIONS:
7366                 return "LONG_PRESS_POWER_GLOBAL_ACTIONS";
7367             case LONG_PRESS_POWER_SHUT_OFF:
7368                 return "LONG_PRESS_POWER_SHUT_OFF";
7369             case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
7370                 return "LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM";
7371             case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
7372                 return "LONG_PRESS_POWER_GO_TO_VOICE_ASSIST";
7373             case LONG_PRESS_POWER_ASSISTANT:
7374                 return "LONG_PRESS_POWER_ASSISTANT";
7375             default:
7376                 return Integer.toString(behavior);
7377         }
7378     }
7379 
7380     private static String settingsKeyBehaviorToString(int behavior) {
7381         switch (behavior) {
7382             case SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY:
7383                 return "SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY";
7384             case SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL:
7385                 return "SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL";
7386             case SETTINGS_KEY_BEHAVIOR_NOTHING:
7387                 return "SETTINGS_KEY_BEHAVIOR_NOTHING";
7388             default:
7389                 return Integer.toString(behavior);
7390         }
7391     }
7392 
7393     private static String veryLongPressOnPowerBehaviorToString(int behavior) {
7394         switch (behavior) {
7395             case VERY_LONG_PRESS_POWER_NOTHING:
7396                 return "VERY_LONG_PRESS_POWER_NOTHING";
7397             case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS:
7398                 return "VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS";
7399             default:
7400                 return Integer.toString(behavior);
7401         }
7402     }
7403 
7404     private static String powerVolumeUpBehaviorToString(int behavior) {
7405         switch (behavior) {
7406             case POWER_VOLUME_UP_BEHAVIOR_NOTHING:
7407                 return "POWER_VOLUME_UP_BEHAVIOR_NOTHING";
7408             case POWER_VOLUME_UP_BEHAVIOR_MUTE:
7409                 return "POWER_VOLUME_UP_BEHAVIOR_MUTE";
7410             case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS:
7411                 return "POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS";
7412             default:
7413                 return Integer.toString(behavior);
7414         }
7415     }
7416 
7417     private static String multiPressOnPowerBehaviorToString(int behavior) {
7418         switch (behavior) {
7419             case MULTI_PRESS_POWER_NOTHING:
7420                 return "MULTI_PRESS_POWER_NOTHING";
7421             case MULTI_PRESS_POWER_THEATER_MODE:
7422                 return "MULTI_PRESS_POWER_THEATER_MODE";
7423             case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
7424                 return "MULTI_PRESS_POWER_BRIGHTNESS_BOOST";
7425             case MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY:
7426                 return "MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY";
7427             default:
7428                 return Integer.toString(behavior);
7429         }
7430     }
7431 
7432     private static String shortPressOnSleepBehaviorToString(int behavior) {
7433         switch (behavior) {
7434             case SHORT_PRESS_SLEEP_GO_TO_SLEEP:
7435                 return "SHORT_PRESS_SLEEP_GO_TO_SLEEP";
7436             case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME:
7437                 return "SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME";
7438             default:
7439                 return Integer.toString(behavior);
7440         }
7441     }
7442 
7443     private static String shortPressOnWindowBehaviorToString(int behavior) {
7444         switch (behavior) {
7445             case SHORT_PRESS_WINDOW_NOTHING:
7446                 return "SHORT_PRESS_WINDOW_NOTHING";
7447             case SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE:
7448                 return "SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE";
7449             default:
7450                 return Integer.toString(behavior);
7451         }
7452     }
7453 
7454     private static String shortPressOnStemPrimaryBehaviorToString(int behavior) {
7455         switch (behavior) {
7456             case SHORT_PRESS_PRIMARY_NOTHING:
7457                 return "SHORT_PRESS_PRIMARY_NOTHING";
7458             case SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS:
7459                 return "SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS";
7460             case SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY:
7461                 return "SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY";
7462             default:
7463                 return Integer.toString(behavior);
7464         }
7465     }
7466 
7467     private static String doublePressOnStemPrimaryBehaviorToString(int behavior) {
7468         switch (behavior) {
7469             case DOUBLE_PRESS_PRIMARY_NOTHING:
7470                 return "DOUBLE_PRESS_PRIMARY_NOTHING";
7471             case DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP:
7472                 return "DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP";
7473             case DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP:
7474                 return "DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP";
7475             default:
7476                 return Integer.toString(behavior);
7477         }
7478     }
7479 
7480     private static String triplePressOnStemPrimaryBehaviorToString(int behavior) {
7481         switch (behavior) {
7482             case TRIPLE_PRESS_PRIMARY_NOTHING:
7483                 return "TRIPLE_PRESS_PRIMARY_NOTHING";
7484             case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY:
7485                 return "TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY";
7486             default:
7487                 return Integer.toString(behavior);
7488         }
7489     }
7490 
7491     private static String longPressOnStemPrimaryBehaviorToString(int behavior) {
7492         switch (behavior) {
7493             case LONG_PRESS_PRIMARY_NOTHING:
7494                 return "LONG_PRESS_PRIMARY_NOTHING";
7495             case LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT:
7496                 return "LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT";
7497             default:
7498                 return Integer.toString(behavior);
7499         }
7500     }
7501 
7502     private static String lidBehaviorToString(int behavior) {
7503         switch (behavior) {
7504             case LID_BEHAVIOR_LOCK:
7505                 return "LID_BEHAVIOR_LOCK";
7506             case LID_BEHAVIOR_SLEEP:
7507                 return "LID_BEHAVIOR_SLEEP";
7508             case LID_BEHAVIOR_NONE:
7509                 return "LID_BEHAVIOR_NONE";
7510             default:
7511                 return Integer.toString(behavior);
7512         }
7513     }
7514 
7515     public static boolean isLongPressToAssistantEnabled(Context context) {
7516         ContentResolver resolver = context.getContentResolver();
7517         int longPressToAssistant = Settings.System.getIntForUser(resolver,
7518                 Settings.Global.Wearable.CLOCKWORK_LONG_PRESS_TO_ASSISTANT_ENABLED,
7519                 /* def= */ 1,
7520                 UserHandle.USER_CURRENT);
7521         if(Log.isLoggable(TAG, Log.DEBUG)) {
7522             Log.d(TAG, "longPressToAssistant = " + longPressToAssistant);
7523         }
7524         return (longPressToAssistant == 1);
7525     }
7526 
7527     private class HdmiVideoExtconUEventObserver extends ExtconStateObserver<Boolean> {
7528         private static final String HDMI_EXIST = "HDMI=1";
7529         private static final String DP_EXIST = "DP=1";
7530         private static final String NAME = "hdmi";
7531 
7532         private boolean init(ExtconInfo hdmi) {
7533             boolean plugged = false;
7534             try {
7535                 plugged = parseStateFromFile(hdmi);
7536             } catch (FileNotFoundException e) {
7537                 Slog.w(TAG,
7538                         hdmi.getStatePath()
7539                                 + " not found while attempting to determine initial state",
7540                         e);
7541             } catch (IOException e) {
7542                 Slog.e(TAG,
7543                         "Error reading " + hdmi.getStatePath()
7544                                 + " while attempting to determine initial state",
7545                         e);
7546             }
7547             startObserving(hdmi);
7548             return plugged;
7549         }
7550 
7551         @Override
7552         public void updateState(ExtconInfo extconInfo, String eventName, Boolean state) {
7553             mDefaultDisplayPolicy.setHdmiPlugged(state);
7554         }
7555 
7556         @Override
7557         public Boolean parseState(ExtconInfo extconIfno, String state) {
7558             // extcon event state changes from kernel4.9
7559             // new state will be like STATE=HDMI=1
7560             // or like STATE=DP=1 for newer kernel
7561             return state.contains(HDMI_EXIST) || state.contains(DP_EXIST);
7562         }
7563     }
7564 
7565     private void launchTargetSearchActivity() {
7566         Intent intent;
7567         if (mSearchKeyTargetActivity != null) {
7568             intent = new Intent();
7569             intent.setComponent(mSearchKeyTargetActivity);
7570         } else {
7571             intent = new Intent(Intent.ACTION_WEB_SEARCH);
7572         }
7573         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
7574                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
7575         try {
7576             startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
7577         } catch (ActivityNotFoundException ignore) {
7578             Slog.e(TAG, "Could not resolve activity with : "
7579                     + intent.getComponent().flattenToString()
7580                     + " name.");
7581         }
7582     }
7583 
7584     /** A helper class to check button override permission. */
7585     static class ButtonOverridePermissionChecker {
7586         boolean canAppOverrideSystemKey(Context context, int uid) {
7587             return PermissionChecker.checkPermissionForDataDelivery(
7588                     context,
7589                     OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW,
7590                     PID_UNKNOWN,
7591                     uid,
7592                     null,
7593                     null,
7594                     null)
7595                     == PERMISSION_GRANTED;
7596         }
7597     }
7598 
7599     private int getTargetDisplayIdForKeyEvent(KeyEvent event) {
7600         if (event.getDisplayId() != INVALID_DISPLAY) {
7601             return event.getDisplayId();
7602         }
7603         if (mTopFocusedDisplayId != INVALID_DISPLAY) {
7604             return mTopFocusedDisplayId;
7605         }
7606         return DEFAULT_DISPLAY;
7607     }
7608 
7609     private int getTargetDisplayIdForKeyGestureEvent(KeyGestureEvent event) {
7610         if (event.getDisplayId() != INVALID_DISPLAY) {
7611             return event.getDisplayId();
7612         }
7613         if (mTopFocusedDisplayId != INVALID_DISPLAY) {
7614             return mTopFocusedDisplayId;
7615         }
7616         return DEFAULT_DISPLAY;
7617     }
7618 
7619     /**
7620      * This method is intended to prevent key events for visible background users
7621      * from interfering with the current user's experience in MUMD environment.
7622      *
7623      * @param displayId the displayId of the key event.
7624      * @param keyCode the key code of the event.
7625      *
7626      * @return false if the key event is for a visible background user.
7627      */
7628     private boolean isKeyEventForCurrentUser(int displayId, int keyCode, @Nullable String purpose) {
7629         if (!mVisibleBackgroundUsersEnabled) {
7630             return true;
7631         }
7632         int assignedUser = mUserManagerInternal.getUserAssignedToDisplay(displayId);
7633         if (assignedUser == mCurrentUserId) {
7634             return true;
7635         }
7636         if (DEBUG_INPUT) {
7637             Slog.w(TAG, "Cannot handle " + KeyEvent.keyCodeToString(keyCode)
7638                     + (purpose != null ? " to " + purpose : "")
7639                     + " for visible background user(u" + assignedUser + ")");
7640         }
7641         return false;
7642     }
7643 }
7644