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