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