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