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