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