Home | History | Annotate | Download | only in policy
      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>();
    333         sApplicationLaunchKeyCategories.append(
    334                 KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER);
    335         sApplicationLaunchKeyCategories.append(
    336                 KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL);
    337         sApplicationLaunchKeyCategories.append(
    338                 KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS);
    339         sApplicationLaunchKeyCategories.append(
    340                 KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR);
    341         sApplicationLaunchKeyCategories.append(
    342                 KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC);
    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
    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 {
    751         SettingsObserver(Handler handler) {
    752             super(handler);
    753         }
    754 
    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 
    794         @Override public void onChange(boolean selfChange) {
    795             updateSettings();
    796             updateRotation(false);
    797         }
    798     }
    799 
    800     class MyWakeGestureListener extends WakeGestureListener {
    801         MyWakeGestureListener(Context context, Handler handler) {
    802             super(context, handler);
    803         }
    804 
    805         @Override
    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 
    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 
    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 
    853     StatusBarManagerInternal getStatusBarManagerInternal() {
    854         synchronized (mServiceAquireLock) {
    855             if (mStatusBarManagerInternal == null) {
    856                 mStatusBarManagerInternal =
    857                         LocalServices.getService(StatusBarManagerInternal.class);
    858             }
    859             return mStatusBarManagerInternal;
    860         }
    861     }
    862 
    863     AudioManagerInternal getAudioManagerInternal() {
    864         synchronized (mServiceAquireLock) {
    865             if (mAudioManagerInternal == null) {
    866                 mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
    867             }
    868             return mAudioManagerInternal;
    869         }
    870     }
    871 
    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
    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 
    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 
   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 
   1069     private void finishPowerKeyPress() {
   1070         mBeganFromNonInteractive = false;
   1071         mPowerKeyPressCounter = 0;
   1072         if (mPowerKeyWakeLock.isHeld()) {
   1073             mPowerKeyWakeLock.release();
   1074         }
   1075     }
   1076 
   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 
   1088     private void cancelPendingBackKeyAction() {
   1089         if (!mBackKeyHandled) {
   1090             mBackKeyHandled = true;
   1091             mHandler.removeMessages(MSG_BACK_LONG_PRESS);
   1092         }
   1093     }
   1094 
   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      */
   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 
   1175     private void goToSleep(long eventTime, int reason, int flags) {
   1176         mRequestedOrGoingToSleep = true;
   1177         mPowerManager.goToSleep(eventTime, reason, flags);
   1178     }
   1179 
   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 
   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 
   1227     private int getLidBehavior() {
   1228         return Settings.Global.getInt(mContext.getContentResolver(),
   1229                 Settings.Global.LID_BEHAVIOR, LID_BEHAVIOR_NONE);
   1230     }
   1231 
   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 
   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 
   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 
   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 
   1305     private void accessibilityShortcutActivated() {
   1306         mAccessibilityShortcutController.performAccessibilityShortcut();
   1307     }
   1308 
   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 
   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 
   1326     private int getResolvedLongPressOnPowerBehavior() {
   1327         if (FactoryTest.isLongPressOnPowerOffEnabled()) {
   1328             return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
   1329         }
   1330         return mLongPressOnPowerBehavior;
   1331     }
   1332 
   1333     private boolean hasLongPressOnPowerBehavior() {
   1334         return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING;
   1335     }
   1336 
   1337     private boolean hasVeryLongPressOnPowerBehavior() {
   1338         return mVeryLongPressOnPowerBehavior != VERY_LONG_PRESS_POWER_NOTHING;
   1339     }
   1340 
   1341     private boolean hasLongPressOnBackBehavior() {
   1342         return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING;
   1343     }
   1344 
   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 
   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 
   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 
   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 
   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 
   1410     private long getRingerToggleChordDelay() {
   1411         // Always timeout like a tap
   1412         return ViewConfiguration.getTapTimeout();
   1413     }
   1414 
   1415     private void cancelPendingScreenshotChordAction() {
   1416         mHandler.removeCallbacks(mScreenshotRunnable);
   1417     }
   1418 
   1419     private void cancelPendingAccessibilityShortcutAction() {
   1420         mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT);
   1421     }
   1422 
   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 
   1440         public void setScreenshotType(int screenshotType) {
   1441             mScreenshotType = screenshotType;
   1442         }
   1443 
   1444         @Override
   1445         public void run() {
   1446             mDefaultDisplayPolicy.takeScreenshot(mScreenshotType);
   1447         }
   1448     }
   1449 
   1450     private final ScreenshotRunnable mScreenshotRunnable = new ScreenshotRunnable();
   1451 
   1452     @Override
   1453     public void showGlobalActions() {
   1454         mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
   1455         mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
   1456     }
   1457 
   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 
   1469     boolean isDeviceProvisioned() {
   1470         return Settings.Global.getInt(
   1471                 mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
   1472     }
   1473 
   1474     @Override
   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 
   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 
   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      */
   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 
   1532         private HdmiControl(HdmiPlaybackClient client) {
   1533             mClient = client;
   1534         }
   1535 
   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 
   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 
   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 
   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 
   1601         DisplayHomeButtonHandler(int displayId) {
   1602             mDisplayId = displayId;
   1603         }
   1604 
   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 
   1688         private void handleDoubleTapOnHome() {
   1689             if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
   1690                 mHomeConsumed = true;
   1691                 toggleRecentApps();
   1692             }
   1693         }
   1694 
   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
   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 
   1726     private boolean isRoundWindow() {
   1727         return mContext.getResources().getConfiguration().isScreenRound();
   1728     }
   1729 
   1730     @Override
   1731     public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
   1732         mDefaultDisplay = displayContentInfo.getDisplay();
   1733         mDefaultDisplayRotation = displayContentInfo.getDisplayRotation();
   1734         mDefaultDisplayPolicy = mDefaultDisplayRotation.getDisplayPolicy();
   1735     }
   1736 
   1737     /** {@inheritDoc} */
   1738     @Override
   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      */
   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 
   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 
   2061     private void updateWakeGestureListenerLp() {
   2062         if (shouldEnableWakeGestureLp()) {
   2063             mWakeGestureListener.requestWakeUpTrigger();
   2064         } else {
   2065             mWakeGestureListener.cancelWakeUpTrigger();
   2066         }
   2067     }
   2068 
   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
   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
   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 
   2224     void readLidState() {
   2225         mDefaultDisplayPolicy.setLidState(mWindowManagerFuncs.getLidState());
   2226     }
   2227 
   2228     private void readCameraLensCoverState() {
   2229         mCameraLensCoverState = mWindowManagerFuncs.getCameraLensCoverState();
   2230     }
   2231 
   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
   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
   2270     public int getMaxWallpaperLayer() {
   2271         return getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
   2272     }
   2273 
   2274     @Override
   2275     public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
   2276         return attrs.type == TYPE_STATUS_BAR;
   2277     }
   2278 
   2279     @Override
   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 
   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
   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 
   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. */
   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
   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
   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 
   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 
   2559     static IDreamManager getDreamManager() {
   2560         return IDreamManager.Stub.asInterface(
   2561                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
   2562     }
   2563 
   2564     TelecomManager getTelecommService() {
   2565         return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
   2566     }
   2567 
   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 
   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
   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 
   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      */
   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      */
   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 
   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
   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 
   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
   3201     public void setTopFocusedDisplay(int displayId) {
   3202         mTopFocusedDisplayId = displayId;
   3203     }
   3204 
   3205     @Override
   3206     public void registerDisplayFoldListener(IDisplayFoldListener listener) {
   3207         if (mDisplayFoldController != null) {
   3208             mDisplayFoldController.registerDisplayFoldListener(listener);
   3209         }
   3210     }
   3211 
   3212     @Override
   3213     public void unregisterDisplayFoldListener(IDisplayFoldListener listener) {
   3214         if (mDisplayFoldController != null) {
   3215             mDisplayFoldController.unregisterDisplayFoldListener(listener);
   3216         }
   3217     }
   3218 
   3219     @Override
   3220     public void setOverrideFoldedArea(Rect area) {
   3221         if (mDisplayFoldController != null) {
   3222             mDisplayFoldController.setOverrideFoldedArea(area);
   3223         }
   3224     }
   3225 
   3226     @Override
   3227     public Rect getFoldedArea() {
   3228         if (mDisplayFoldController != null) {
   3229             return mDisplayFoldController.getFoldedArea();
   3230         }
   3231         return new Rect();
   3232     }
   3233 
   3234     @Override
   3235     public void onDefaultDisplayFocusChangedLw(WindowState newFocus) {
   3236         if (mDisplayFoldController != null) {
   3237             mDisplayFoldController.onDefaultDisplayFocusChanged(
   3238                     newFocus != null ? newFocus.getOwningPackage() : null);
   3239         }
   3240     }
   3241 
   3242     @Override
   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
   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 
   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 */
   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 */
   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. */
   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 
   3350     private void startActivityAsUser(Intent intent, UserHandle handle) {
   3351         startActivityAsUser(intent, null, handle);
   3352     }
   3353 
   3354     private void startActivityAsUser(Intent intent, Bundle bundle, UserHandle handle) {
   3355         startActivityAsUser(intent, bundle, handle, false /* allowDuringSetup */);
   3356     }
   3357 
   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 
   3367     private SearchManager getSearchManager() {
   3368         if (mSearchManager == null) {
   3369             mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
   3370         }
   3371         return mSearchManager;
   3372     }
   3373 
   3374     private void preloadRecentApps() {
   3375         mPreloadedRecentApps = true;
   3376         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
   3377         if (statusbar != null) {
   3378             statusbar.preloadRecentApps();
   3379         }
   3380     }
   3381 
   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 
   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
   3401     public void showRecentApps() {
   3402         mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS);
   3403         mHandler.obtainMessage(MSG_DISPATCH_SHOW_RECENTS).sendToTarget();
   3404     }
   3405 
   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 
   3414     private void toggleKeyboardShortcutsMenu(int deviceId) {
   3415         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
   3416         if (statusbar != null) {
   3417             statusbar.toggleKeyboardShortcutsMenu(deviceId);
   3418         }
   3419     }
   3420 
   3421     private void dismissKeyboardShortcutsMenu() {
   3422         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
   3423         if (statusbar != null) {
   3424             statusbar.dismissKeyboardShortcutsMenu();
   3425         }
   3426     }
   3427 
   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 
   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      */
   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
   3485     public void setRecentsVisibilityLw(boolean visible) {
   3486         mRecentsVisible = visible;
   3487     }
   3488 
   3489     @Override
   3490     public void setPipVisibilityLw(boolean visible) {
   3491         mPictureInPictureVisible = visible;
   3492     }
   3493 
   3494     @Override
   3495     public void setNavBarVirtualKeyHapticFeedbackEnabledLw(boolean enabled) {
   3496         mNavBarVirtualKeyHapticFeedbackEnabled = enabled;
   3497     }
   3498 
   3499     /** {@inheritDoc} */
   3500     @Override
   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
   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      */
   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
   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
   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 
   3599     void initializeHdmiState() {
   3600         final int oldMask = StrictMode.allowThreadDiskReadsMask();
   3601         try {
   3602             initializeHdmiStateInternal();
   3603         } finally {
   3604             StrictMode.setThreadPolicyMask(oldMask);
   3605         }
   3606     }
   3607 
   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
   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      */
   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      */
   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      */
   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      */
   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      */
   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
   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 
   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 
   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 manufacturers 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
   4296     private HdmiControlManager getHdmiControlManager() {
   4297         if (!mHasFeatureHdmiCec) {
   4298             return null;
   4299         }
   4300         return (HdmiControlManager) mContext.getSystemService(HdmiControlManager.class);
   4301     }
   4302 
   4303     private boolean shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff() {
   4304         return RoSystemProperties.CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF;
   4305     }
   4306 
   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 
   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 
   4350     void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
   4351         if (mActivityManagerInternal.isSystemReady()) {
   4352             MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true);
   4353         }
   4354     }
   4355 
   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
   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
   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
   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
   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 
   4517     private void wakeUpFromPowerKey(long eventTime) {
   4518         wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey,
   4519                 PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER");
   4520     }
   4521 
   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 
   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
   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 
   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
   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
   4602     public void screenTurnedOn() {
   4603         synchronized (mLock) {
   4604             if (mKeyguardDelegate != null) {
   4605                 mKeyguardDelegate.onScreenTurnedOn();
   4606             }
   4607         }
   4608         reportScreenStateToVrManager(true);
   4609     }
   4610 
   4611     @Override
   4612     public void screenTurningOff(ScreenOffListener screenOffListener) {
   4613         mWindowManagerFuncs.screenTurningOff(screenOffListener);
   4614         synchronized (mLock) {
   4615             if (mKeyguardDelegate != null) {
   4616                 mKeyguardDelegate.onScreenTurningOff();
   4617             }
   4618         }
   4619     }
   4620 
   4621     private void reportScreenStateToVrManager(boolean isScreenOn) {
   4622         if (mVrManagerInternal == null) {
   4623             return;
   4624         }
   4625         mVrManagerInternal.onScreenStateChanged(isScreenOn);
   4626     }
   4627 
   4628     private void finishWindowsDrawn() {
   4629         if (!mDefaultDisplayPolicy.finishWindowsDrawn()) {
   4630             return;
   4631         }
   4632 
   4633         finishScreenTurningOn();
   4634     }
   4635 
   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 
   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
   4691     public boolean isScreenOn() {
   4692         return mDefaultDisplayPolicy.isScreenOnEarly();
   4693     }
   4694 
   4695     @Override
   4696     public boolean okToAnimate() {
   4697         return mDefaultDisplayPolicy.isAwake() && !mGoingToSleep;
   4698     }
   4699 
   4700     /** {@inheritDoc} */
   4701     @Override
   4702     public void enableKeyguard(boolean enabled) {
   4703         if (mKeyguardDelegate != null) {
   4704             mKeyguardDelegate.setKeyguardEnabled(enabled);
   4705         }
   4706     }
   4707 
   4708     /** {@inheritDoc} */
   4709     @Override
   4710     public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
   4711         if (mKeyguardDelegate != null) {
   4712             mKeyguardDelegate.verifyUnlock(callback);
   4713         }
   4714     }
   4715 
   4716     @Override
   4717     public boolean isKeyguardShowingAndNotOccluded() {
   4718         if (mKeyguardDelegate == null) return false;
   4719         return mKeyguardDelegate.isShowing() && !mKeyguardOccluded;
   4720     }
   4721 
   4722     @Override
   4723     public boolean isKeyguardTrustedLw() {
   4724         if (mKeyguardDelegate == null) return false;
   4725         return mKeyguardDelegate.isTrusted();
   4726     }
   4727 
   4728     /** {@inheritDoc} */
   4729     @Override
   4730     public boolean isKeyguardLocked() {
   4731         return keyguardOn();
   4732     }
   4733 
   4734     /** {@inheritDoc} */
   4735     @Override
   4736     public boolean isKeyguardSecure(int userId) {
   4737         if (mKeyguardDelegate == null) return false;
   4738         return mKeyguardDelegate.isSecure(userId);
   4739     }
   4740 
   4741     /** {@inheritDoc} */
   4742     @Override
   4743     public boolean isKeyguardOccluded() {
   4744         if (mKeyguardDelegate == null) return false;
   4745         return mKeyguardOccluded;
   4746     }
   4747 
   4748     /** {@inheritDoc} */
   4749     @Override
   4750     public boolean inKeyguardRestrictedKeyInputMode() {
   4751         if (mKeyguardDelegate == null) return false;
   4752         return mKeyguardDelegate.isInputRestricted();
   4753     }
   4754 
   4755     @Override
   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
   4772     public boolean isKeyguardDrawnLw() {
   4773         synchronized (mLock) {
   4774             return mKeyguardDrawnOnce;
   4775         }
   4776     }
   4777 
   4778     @Override
   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 
   4786     void sendCloseSystemWindows() {
   4787         PhoneWindow.sendCloseSystemWindows(mContext, null);
   4788     }
   4789 
   4790     void sendCloseSystemWindows(String reason) {
   4791         PhoneWindow.sendCloseSystemWindows(mContext, reason);
   4792     }
   4793 
   4794     @Override
   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 
   4803     static long[] getLongIntArray(Resources r, int resid) {
   4804         return ArrayUtils.convertToLongArray(r.getIntArray(resid));
   4805     }
   4806 
   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
   4818     public void onSystemUiStarted() {
   4819         bindKeyguard();
   4820     }
   4821 
   4822     /** {@inheritDoc} */
   4823     @Override
   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
   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
   4872     public boolean canDismissBootAnimation() {
   4873         return mDefaultDisplayPolicy.isKeyguardDrawComplete();
   4874     }
   4875 
   4876     ProgressDialog mBootMsgDialog = null;
   4877 
   4878     /** {@inheritDoc} */
   4879     @Override
   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
   4940     public void hideBootMessages() {
   4941         mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE);
   4942     }
   4943 
   4944     @Override
   4945     public void requestUserActivityNotification() {
   4946         if (!mNotifyUserActivity && !mHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
   4947             mNotifyUserActivity = true;
   4948         }
   4949     }
   4950 
   4951     /** {@inheritDoc} */
   4952     @Override
   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
   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 
   4995         public void setLockOptions(Bundle options) {
   4996             this.options = options;
   4997         }
   4998     }
   4999 
   5000     ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();
   5001 
   5002     @Override
   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
   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 
   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 
   5044     private void schedulePossibleVeryLongPressReboot() {
   5045         mHandler.removeCallbacks(mPossibleVeryLongPressReboot);
   5046         mHandler.postDelayed(mPossibleVeryLongPressReboot, mVeryLongPressTimeout);
   5047     }
   5048 
   5049     private void cancelPossibleVeryLongPressReboot() {
   5050         mHandler.removeCallbacks(mPossibleVeryLongPressReboot);
   5051     }
   5052 
   5053     // TODO (multidisplay): Support multiple displays in WindowManagerPolicy.
   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
   5070     public void enableScreenAfterBoot() {
   5071         readLidState();
   5072         applyLidSwitchState();
   5073         updateRotation(true);
   5074     }
   5075 
   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 
   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
   5115     public int getUiMode() {
   5116         return mUiMode;
   5117     }
   5118 
   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      */
   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 
   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      */
   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 
   5276     private boolean isTheaterModeEnabled() {
   5277         return Settings.Global.getInt(mContext.getContentResolver(),
   5278                 Settings.Global.THEATER_MODE_ON, 0) == 1;
   5279     }
   5280 
   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
   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 
   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
   5360     public void keepScreenOnStartedLw() {
   5361     }
   5362 
   5363     @Override
   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
   5373     public boolean hasNavigationBar() {
   5374         return mDefaultDisplayPolicy.hasNavigationBar();
   5375     }
   5376 
   5377     @Override
   5378     public void setDismissImeOnBackKeyPressed(boolean newValue) {
   5379         mDismissImeOnBackKeyPressed = newValue;
   5380     }
   5381 
   5382     @Override
   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
   5398     public void setSwitchingUser(boolean switching) {
   5399         mKeyguardDelegate.setSwitchingUser(switching);
   5400     }
   5401 
   5402     @Override
   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
   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
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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
   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 
   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
   5731         public void updateState(ExtconInfo extconInfo, String eventName, Boolean state) {
   5732             mDefaultDisplayPolicy.setHdmiPlugged(state);
   5733         }
   5734 
   5735         @Override
   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