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