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