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