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.CREATE_VIRTUAL_DEVICE; 20 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 21 import static android.Manifest.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW; 22 import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; 23 import static android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY; 24 import static android.app.AppOpsManager.OP_CREATE_ACCESSIBILITY_OVERLAY; 25 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; 26 import static android.app.AppOpsManager.OP_TOAST_WINDOW; 27 import static android.content.PermissionChecker.PID_UNKNOWN; 28 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 29 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; 30 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; 31 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; 32 import static android.content.pm.PackageManager.FEATURE_HDMI_CEC; 33 import static android.content.pm.PackageManager.FEATURE_LEANBACK; 34 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; 35 import static android.content.pm.PackageManager.FEATURE_WATCH; 36 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 37 import static android.os.Build.VERSION_CODES.M; 38 import static android.os.Build.VERSION_CODES.O; 39 import static android.os.IInputConstants.INVALID_INPUT_DEVICE_ID; 40 import static android.os.UserManager.isVisibleBackgroundUsersEnabled; 41 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; 42 import static android.view.Display.DEFAULT_DISPLAY; 43 import static android.view.Display.INVALID_DISPLAY; 44 import static android.view.Display.STATE_OFF; 45 import static android.view.KeyEvent.KEYCODE_BACK; 46 import static android.view.KeyEvent.KEYCODE_DPAD_CENTER; 47 import static android.view.KeyEvent.KEYCODE_DPAD_DOWN; 48 import static android.view.KeyEvent.KEYCODE_HOME; 49 import static android.view.KeyEvent.KEYCODE_POWER; 50 import static android.view.KeyEvent.KEYCODE_STEM_PRIMARY; 51 import static android.view.KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL; 52 import static android.view.KeyEvent.KEYCODE_UNKNOWN; 53 import static android.view.KeyEvent.KEYCODE_VOLUME_DOWN; 54 import static android.view.KeyEvent.KEYCODE_VOLUME_UP; 55 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; 56 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 57 import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; 58 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 59 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 60 import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW; 61 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 62 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 63 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 64 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; 65 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 66 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; 67 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; 68 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; 69 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; 70 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; 71 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; 72 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL; 73 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; 74 import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 75 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; 76 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING; 77 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 78 import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; 79 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD; 80 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER; 81 import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; 82 import static android.view.WindowManagerGlobal.ADD_OKAY; 83 import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED; 84 import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled; 85 86 import static com.android.hardware.input.Flags.enableNew25q2Keycodes; 87 import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures; 88 import static com.android.hardware.input.Flags.enableVoiceAccessKeyGestures; 89 import static com.android.hardware.input.Flags.fixSearchModifierFallbacks; 90 import static com.android.hardware.input.Flags.inputManagerLifecycleSupport; 91 import static com.android.hardware.input.Flags.keyboardA11yShortcutControl; 92 import static com.android.hardware.input.Flags.modifierShortcutDump; 93 import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow; 94 import static com.android.hardware.input.Flags.useKeyGestureEventHandler; 95 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY; 96 import static com.android.server.GestureLauncherService.DOUBLE_POWER_TAP_COUNT_THRESHOLD; 97 import static com.android.server.flags.Flags.modifierShortcutManagerMultiuser; 98 import static com.android.server.flags.Flags.newBugreportKeyboardShortcut; 99 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED; 100 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT; 101 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED; 102 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_BEHAVIOR_LOCK; 103 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_BEHAVIOR_NONE; 104 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_BEHAVIOR_SLEEP; 105 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED; 106 import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN; 107 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_DELEGATE; 108 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_DRAW_COMPLETE; 109 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED; 110 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED_CHANGED; 111 import static com.android.server.wm.WindowManagerPolicyProto.KEYGUARD_OCCLUDED_PENDING; 112 import static com.android.server.wm.WindowManagerPolicyProto.ORIENTATION; 113 import static com.android.server.wm.WindowManagerPolicyProto.ROTATION; 114 import static com.android.server.wm.WindowManagerPolicyProto.ROTATION_MODE; 115 import static com.android.server.wm.WindowManagerPolicyProto.SCREEN_ON_FULLY; 116 import static com.android.server.wm.WindowManagerPolicyProto.WINDOW_MANAGER_DRAW_COMPLETE; 117 import static com.android.systemui.shared.Flags.enableLppSqueezeEffect; 118 119 import android.accessibilityservice.AccessibilityService; 120 import android.annotation.Nullable; 121 import android.annotation.SuppressLint; 122 import android.app.ActivityManager; 123 import android.app.ActivityManager.RecentTaskInfo; 124 import android.app.ActivityManagerInternal; 125 import android.app.ActivityTaskManager; 126 import android.app.ActivityTaskManager.RootTaskInfo; 127 import android.app.AppOpsManager; 128 import android.app.IActivityManager; 129 import android.app.IUiModeManager; 130 import android.app.NotificationManager; 131 import android.app.ProgressDialog; 132 import android.app.SearchManager; 133 import android.app.UiModeManager; 134 import android.content.ActivityNotFoundException; 135 import android.content.BroadcastReceiver; 136 import android.content.ComponentName; 137 import android.content.ContentResolver; 138 import android.content.Context; 139 import android.content.Intent; 140 import android.content.IntentFilter; 141 import android.content.PermissionChecker; 142 import android.content.pm.ActivityInfo; 143 import android.content.pm.ApplicationInfo; 144 import android.content.pm.PackageManager; 145 import android.content.pm.ResolveInfo; 146 import android.content.res.Configuration; 147 import android.content.res.Resources; 148 import android.database.ContentObserver; 149 import android.graphics.Rect; 150 import android.hardware.SensorPrivacyManager; 151 import android.hardware.display.DisplayManager; 152 import android.hardware.display.DisplayManagerInternal; 153 import android.hardware.hdmi.HdmiAudioSystemClient; 154 import android.hardware.hdmi.HdmiControlManager; 155 import android.hardware.hdmi.HdmiPlaybackClient; 156 import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback; 157 import android.hardware.input.AppLaunchData; 158 import android.hardware.input.InputManager; 159 import android.hardware.input.InputSettings; 160 import android.hardware.input.KeyGestureEvent; 161 import android.media.AudioManager; 162 import android.media.AudioManagerInternal; 163 import android.media.AudioSystem; 164 import android.media.IAudioService; 165 import android.media.session.MediaSessionLegacyHelper; 166 import android.os.Binder; 167 import android.os.Bundle; 168 import android.os.DeviceIdleManager; 169 import android.os.FactoryTest; 170 import android.os.Handler; 171 import android.os.IBinder; 172 import android.os.Looper; 173 import android.os.Message; 174 import android.os.PowerManager; 175 import android.os.PowerManager.WakeReason; 176 import android.os.PowerManagerInternal; 177 import android.os.Process; 178 import android.os.RemoteException; 179 import android.os.ServiceManager; 180 import android.os.StrictMode; 181 import android.os.SystemClock; 182 import android.os.SystemProperties; 183 import android.os.Trace; 184 import android.os.UEventObserver; 185 import android.os.UserHandle; 186 import android.os.Vibrator; 187 import android.provider.DeviceConfig; 188 import android.provider.MediaStore; 189 import android.provider.Settings; 190 import android.provider.Settings.Secure; 191 import android.service.SensorPrivacyToggleSourceProto; 192 import android.service.dreams.DreamManagerInternal; 193 import android.service.dreams.DreamService; 194 import android.service.dreams.IDreamManager; 195 import android.service.vr.IPersistentVrStateCallbacks; 196 import android.speech.RecognizerIntent; 197 import android.telecom.TelecomManager; 198 import android.text.TextUtils; 199 import android.util.Log; 200 import android.util.MathUtils; 201 import android.util.MutableBoolean; 202 import android.util.PrintWriterPrinter; 203 import android.util.Slog; 204 import android.util.SparseArray; 205 import android.util.proto.ProtoOutputStream; 206 import android.view.Display; 207 import android.view.HapticFeedbackConstants; 208 import android.view.IDisplayFoldListener; 209 import android.view.InputDevice; 210 import android.view.KeyCharacterMap; 211 import android.view.KeyEvent; 212 import android.view.KeyboardShortcutGroup; 213 import android.view.MotionEvent; 214 import android.view.ViewConfiguration; 215 import android.view.WindowManager; 216 import android.view.WindowManagerGlobal; 217 import android.view.WindowManagerPolicyConstants; 218 import android.view.accessibility.AccessibilityEvent; 219 import android.view.accessibility.AccessibilityManager; 220 import android.view.animation.Animation; 221 import android.view.animation.AnimationUtils; 222 import android.view.autofill.AutofillManagerInternal; 223 import android.widget.Toast; 224 225 import com.android.internal.R; 226 import com.android.internal.accessibility.AccessibilityShortcutController; 227 import com.android.internal.annotations.VisibleForTesting; 228 import com.android.internal.app.AssistUtils; 229 import com.android.internal.display.BrightnessUtils; 230 import com.android.internal.inputmethod.SoftInputShowHideReason; 231 import com.android.internal.logging.MetricsLogger; 232 import com.android.internal.logging.nano.MetricsProto; 233 import com.android.internal.os.RoSystemProperties; 234 import com.android.internal.policy.IKeyguardDismissCallback; 235 import com.android.internal.policy.IKeyguardService; 236 import com.android.internal.policy.IShortcutService; 237 import com.android.internal.policy.KeyInterceptionInfo; 238 import com.android.internal.policy.LogDecelerateInterpolator; 239 import com.android.internal.policy.PhoneWindow; 240 import com.android.internal.policy.TransitionAnimation; 241 import com.android.internal.statusbar.IStatusBarService; 242 import com.android.internal.widget.LockPatternUtils; 243 import com.android.server.AccessibilityManagerInternal; 244 import com.android.server.DockObserverInternal; 245 import com.android.server.ExtconStateObserver; 246 import com.android.server.ExtconUEventObserver; 247 import com.android.server.GestureLauncherService; 248 import com.android.server.LocalServices; 249 import com.android.server.SystemServiceManager; 250 import com.android.server.UiThread; 251 import com.android.server.input.InputManagerInternal; 252 import com.android.server.inputmethod.InputMethodManagerInternal; 253 import com.android.server.pm.UserManagerInternal; 254 import com.android.server.policy.KeyCombinationManager.TwoKeysCombinationRule; 255 import com.android.server.policy.keyguard.KeyguardServiceDelegate; 256 import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener; 257 import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback; 258 import com.android.server.statusbar.StatusBarManagerInternal; 259 import com.android.server.vr.VrManagerInternal; 260 import com.android.server.wallpaper.WallpaperManagerInternal; 261 import com.android.server.wm.ActivityTaskManagerInternal; 262 import com.android.server.wm.DisplayPolicy; 263 import com.android.server.wm.DisplayRotation; 264 import com.android.server.wm.WindowManagerInternal; 265 import com.android.server.wm.WindowManagerInternal.AppTransitionListener; 266 267 import java.io.File; 268 import java.io.FileNotFoundException; 269 import java.io.FileReader; 270 import java.io.IOException; 271 import java.io.PrintWriter; 272 import java.util.ArrayList; 273 import java.util.Arrays; 274 import java.util.HashSet; 275 import java.util.List; 276 import java.util.Set; 277 import java.util.function.Supplier; 278 279 /** 280 * WindowManagerPolicy implementation for the Android phone UI. This 281 * introduces a new method suffix, Lp, for an internal lock of the 282 * PhoneWindowManager. This is used to protect some internal state, and 283 * can be acquired with either the Lw and Li lock held, so has the restrictions 284 * of both of those when held. 285 */ 286 public class PhoneWindowManager implements WindowManagerPolicy { 287 static final String TAG = "WindowManager"; 288 static final boolean localLOGV = false; 289 static final boolean DEBUG_INPUT = false; 290 static final boolean DEBUG_KEYGUARD = false; 291 static final boolean DEBUG_WAKEUP = false; 292 293 // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key. 294 // No longer recommended for desk docks; 295 static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false; 296 297 // Whether to allow devices placed in vr headset viewers to have an alternative Home intent. 298 static final boolean ENABLE_VR_HEADSET_HOME_CAPTURE = true; 299 300 // --------- Key behavior definitions below. --------- 301 // NOTE: When updating the valid range of any of these behaviors, and if that behavior has a 302 // Settings key associated to it for dynamic update, update its valid Settings value range in 303 // android.provider.settings.validators.GlobalSettingsValidators. 304 305 // must match: config_shortPressOnPowerBehavior in config.xml 306 // The config value can be overridden using Settings.Global.POWER_BUTTON_SHORT_PRESS 307 static final int SHORT_PRESS_POWER_NOTHING = 0; 308 static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1; 309 static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2; 310 static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3; 311 static final int SHORT_PRESS_POWER_GO_HOME = 4; 312 static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5; 313 static final int SHORT_PRESS_POWER_LOCK_OR_SLEEP = 6; 314 static final int SHORT_PRESS_POWER_DREAM_OR_SLEEP = 7; 315 static final int SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP = 8; 316 static final int SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP = 9; 317 318 // must match: config_LongPressOnPowerBehavior in config.xml 319 // The config value can be overridden using Settings.Global.POWER_BUTTON_LONG_PRESS 320 static final int LONG_PRESS_POWER_NOTHING = 0; 321 static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; 322 static final int LONG_PRESS_POWER_SHUT_OFF = 2; 323 static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3; 324 static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4; 325 static final int LONG_PRESS_POWER_ASSISTANT = 5; // Settings.Secure.ASSISTANT 326 327 // must match: config_veryLongPresOnPowerBehavior in config.xml 328 // The config value can be overridden using Settings.Global.POWER_BUTTON_VERY_LONG_PRESS 329 static final int VERY_LONG_PRESS_POWER_NOTHING = 0; 330 static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; 331 332 // must match: config_keyChordPowerVolumeUp in config.xml 333 static final int POWER_VOLUME_UP_BEHAVIOR_NOTHING = 0; 334 static final int POWER_VOLUME_UP_BEHAVIOR_MUTE = 1; 335 static final int POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS = 2; 336 337 // must match: config_doublePressOnPowerBehavior in config.xml 338 // The config value can be overridden using Settings.Global.POWER_BUTTON_DOUBLE_PRESS and/or 339 // Settings.Global.POWER_BUTTON_TRIPLE_PRESS 340 static final int MULTI_PRESS_POWER_NOTHING = 0; 341 static final int MULTI_PRESS_POWER_THEATER_MODE = 1; 342 static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2; 343 static final int MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY = 3; 344 345 // must match: config_longPressOnBackBehavior in config.xml 346 static final int LONG_PRESS_BACK_NOTHING = 0; 347 static final int LONG_PRESS_BACK_GO_TO_VOICE_ASSIST = 1; 348 349 // must match: config_longPressOnHomeBehavior in config.xml 350 static final int LONG_PRESS_HOME_NOTHING = 0; 351 static final int LONG_PRESS_HOME_ALL_APPS = 1; 352 static final int LONG_PRESS_HOME_ASSIST = 2; 353 static final int LONG_PRESS_HOME_NOTIFICATION_PANEL = 3; 354 static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_NOTIFICATION_PANEL; 355 356 // must match: config_doubleTapOnHomeBehavior in config.xml 357 static final int DOUBLE_TAP_HOME_NOTHING = 0; 358 static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1; 359 static final int DOUBLE_TAP_HOME_PIP_MENU = 2; 360 361 static final int SHORT_PRESS_WINDOW_NOTHING = 0; 362 static final int SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE = 1; 363 364 static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0; 365 static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1; 366 367 // must match: config_settingsKeyBehavior in config.xml 368 static final int SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY = 0; 369 static final int SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL = 1; 370 static final int SETTINGS_KEY_BEHAVIOR_NOTHING = 2; 371 static final int LAST_SETTINGS_KEY_BEHAVIOR = SETTINGS_KEY_BEHAVIOR_NOTHING; 372 373 static final int PENDING_KEY_NULL = -1; 374 375 // Must match: config_shortPressOnStemPrimaryBehavior in config.xml 376 // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS 377 static final int SHORT_PRESS_PRIMARY_NOTHING = 0; 378 static final int SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS = 1; 379 static final int SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY = 2; 380 381 // Must match: config_longPressOnStemPrimaryBehavior in config.xml 382 // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS 383 static final int LONG_PRESS_PRIMARY_NOTHING = 0; 384 static final int LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT = 1; 385 386 // Must match: config_doublePressOnStemPrimaryBehavior in config.xml 387 //The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_DOUBLE_PRESS 388 static final int DOUBLE_PRESS_PRIMARY_NOTHING = 0; 389 static final int DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP = 1; 390 static final int DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP = 2; 391 392 // Must match: config_triplePressOnStemPrimaryBehavior in config.xml 393 // The config value can be overridden using Settings.Global.STEM_PRIMARY_BUTTON_TRIPLE_PRESS 394 static final int TRIPLE_PRESS_PRIMARY_NOTHING = 0; 395 static final int TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY = 1; 396 397 // Must match: config_searchKeyBehavior in config.xml 398 static final int SEARCH_KEY_BEHAVIOR_DEFAULT_SEARCH = 0; 399 static final int SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY = 1; 400 401 static public final String SYSTEM_DIALOG_REASON_KEY = "reason"; 402 static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; 403 static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; 404 static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; 405 static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist"; 406 static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot"; 407 static public final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav"; 408 409 public static final String TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD = "waitForAllWindowsDrawn"; 410 411 /** 412 * String extra key passed in the bundle of {@link IKeyguardService#doKeyguardTimeout(Bundle)} 413 * if the value is {@code true}, indicates to keyguard that the device should show the 414 * glanceable hub upon locking. If the hub is already visible, the device should go to sleep. 415 */ 416 public static final String EXTRA_TRIGGER_HUB = "extra_trigger_hub"; 417 418 private static final int POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS = 800; 419 420 /** 421 * Keyguard stuff 422 */ 423 private boolean mKeyguardDrawnOnce; 424 425 /** Amount of time (in milliseconds) to wait for windows drawn before powering on. */ 426 static final int WAITING_FOR_DRAWN_TIMEOUT = 1000; 427 428 /** 429 * Extra time for additional SystemUI animations. 430 * <p>Since legacy apps can add Toast windows directly instead of using Toast APIs, 431 * {@link DisplayPolicy} ensures that the window manager removes toast windows after 432 * TOAST_WINDOW_TIMEOUT. We increase this timeout by TOAST_WINDOW_ANIM_BUFFER to account for 433 * SystemUI's in/out toast animations, so that the toast text is still shown for a minimum 434 * of 3.5 seconds and the animations are finished before window manager removes the window. 435 */ 436 public static final int TOAST_WINDOW_ANIM_BUFFER = 600; 437 438 /** 439 * Amount of time (in milliseconds) a toast window can be shown before it's automatically 440 * removed by window manager. 441 */ 442 public static final int TOAST_WINDOW_TIMEOUT = 3500 + TOAST_WINDOW_ANIM_BUFFER; 443 444 /** 445 * Action for launching assistant in retail mode 446 */ 447 private static final String ACTION_VOICE_ASSIST_RETAIL = 448 "android.intent.action.VOICE_ASSIST_RETAIL"; 449 450 /** 451 * Maximum amount of time in milliseconds between consecutive power onKeyDown events to be 452 * considered a multi-press, only used for the power button. 453 * Note: To maintain backwards compatibility for the power button, we are measuring the times 454 * between consecutive down events instead of the first tap's up event and the second tap's 455 * down event. 456 */ 457 @VisibleForTesting public static final int POWER_MULTI_PRESS_TIMEOUT_MILLIS = 458 ViewConfiguration.getMultiPressTimeout(); 459 460 /** 461 * Lock protecting internal state. Must not call out into window 462 * manager with lock held. (This lock will be acquired in places 463 * where the window manager is calling in with its own lock held.) 464 */ 465 private final Object mLock = new Object(); 466 467 /** List of {@link ScreenOnListener}s which do not belong to the default display. */ 468 private final SparseArray<ScreenOnListener> mScreenOnListeners = new SparseArray<>(); 469 470 Context mContext; 471 WindowManagerFuncs mWindowManagerFuncs; 472 WindowManagerInternal mWindowManagerInternal; 473 PowerManager mPowerManager; 474 ActivityManagerInternal mActivityManagerInternal; 475 IActivityManager mActivityManagerService; 476 ActivityTaskManagerInternal mActivityTaskManagerInternal; 477 AutofillManagerInternal mAutofillManagerInternal; 478 InputManager mInputManager; 479 InputManagerInternal mInputManagerInternal; 480 DreamManagerInternal mDreamManagerInternal; 481 PowerManagerInternal mPowerManagerInternal; 482 IStatusBarService mStatusBarService; 483 StatusBarManagerInternal mStatusBarManagerInternal; 484 AudioManagerInternal mAudioManagerInternal; 485 SensorPrivacyManager mSensorPrivacyManager; 486 DisplayManager mDisplayManager; 487 DisplayManagerInternal mDisplayManagerInternal; 488 UserManagerInternal mUserManagerInternal; 489 DockObserverInternal mDockObserverInternal; 490 491 private WallpaperManagerInternal mWallpaperManagerInternal; 492 493 boolean mPreloadedRecentApps; 494 final Object mServiceAcquireLock = new Object(); 495 Vibrator mVibrator; // Vibrator for giving feedback of orientation changes 496 AccessibilityManager mAccessibilityManager; 497 AccessibilityManagerInternal mAccessibilityManagerInternal; 498 BurnInProtectionHelper mBurnInProtectionHelper; 499 private DisplayFoldController mDisplayFoldController; 500 AppOpsManager mAppOpsManager; 501 PackageManager mPackageManager; 502 SideFpsEventHandler mSideFpsEventHandler; 503 LockPatternUtils mLockPatternUtils; 504 private boolean mHasFeatureAuto; 505 private boolean mHasFeatureWatch; 506 private boolean mHasFeatureLeanback; 507 private boolean mHasFeatureHdmiCec; 508 509 // Assigned on main thread, accessed on UI thread 510 volatile VrManagerInternal mVrManagerInternal; 511 512 /** If true, can use a keyboard shortcut to trigger a bugreport. */ 513 boolean mEnableBugReportKeyboardShortcut = false; 514 515 /** Controller that supports enabling an AccessibilityService by holding down the volume keys */ 516 private AccessibilityShortcutController mAccessibilityShortcutController; 517 518 private TalkbackShortcutController mTalkbackShortcutController; 519 520 private VoiceAccessShortcutController mVoiceAccessShortcutController; 521 522 private WindowWakeUpPolicy mWindowWakeUpPolicy; 523 524 boolean mSafeMode; 525 526 // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key. 527 // This is for car dock and this is updated from resource. 528 private boolean mEnableCarDockHomeCapture = true; 529 530 boolean mBootMessageNeedsHiding; 531 volatile boolean mBootAnimationDismissable; 532 @VisibleForTesting KeyguardServiceDelegate mKeyguardDelegate; 533 private boolean mKeyguardBound; 534 final DrawnListener mKeyguardDrawnCallback = new DrawnListener() { 535 @Override 536 public void onDrawn() { 537 if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn."); 538 mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE); 539 } 540 }; 541 542 private Supplier<GlobalActions> mGlobalActionsFactory; 543 private GlobalActions mGlobalActions; 544 private Handler mHandler; 545 546 // FIXME This state is shared between the input reader and handler thread. 547 // Technically it's broken and buggy but it has been like this for many years 548 // and we have not yet seen any problems. Someday we'll rewrite this logic 549 // so that only one thread is involved in handling input policy. Unfortunately 550 // it's on a critical path for power management so we can't just post the work to the 551 // handler thread. We'll need to resolve this someday by teaching the input dispatcher 552 // to hold wakelocks during dispatch and eliminating the critical path. 553 volatile boolean mPowerKeyHandled; 554 volatile boolean mBackKeyHandled; 555 volatile boolean mEndCallKeyHandled; 556 volatile boolean mPowerButtonLaunchGestureTriggered; 557 volatile boolean mPowerButtonLaunchGestureTriggeredDuringGoingToSleep; 558 559 /** 560 * {@code true} if the device is entering a low-power state; {@code false otherwise}. 561 * 562 * <p>This differs from {@link #mRequestedOrSleepingDefaultDisplay} which tracks the power state 563 * of the {@link #mDefaultDisplay default display} versus the power state of the entire device. 564 */ 565 volatile boolean mDeviceGoingToSleep; 566 567 /** 568 * {@code true} if the {@link #mDefaultDisplay default display} is entering or was requested to 569 * enter a low-power state; {@code false otherwise}. 570 * 571 * <p>This differs from {@link #mDeviceGoingToSleep} which tracks the power state of the entire 572 * device versus the power state of the {@link #mDefaultDisplay default display}. 573 */ 574 // TODO(b/178103325): Track sleep/requested sleep for every display. 575 volatile boolean mRequestedOrSleepingDefaultDisplay; 576 577 /** 578 * This is used to check whether to acquire screen-off sleep token when screen is 579 * turned off. E.g. if it is false when screen is turned off and the display is swapping, it 580 * is expected that the screen will be on in a short time. Then it is unnecessary to acquire 581 * screen-off-sleep-token, so it can avoid intermediate visibility or lifecycle changes. 582 */ 583 volatile boolean mIsGoingToSleepDefaultDisplay; 584 585 volatile boolean mRecentsVisible; 586 volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled = true; 587 volatile boolean mPictureInPictureVisible; 588 volatile private boolean mDismissImeOnBackKeyPressed; 589 590 // Used to hold the last user key used to wake the device. This helps us prevent up events 591 // from being passed to the foregrounded app without a corresponding down event 592 volatile int mPendingWakeKey = PENDING_KEY_NULL; 593 594 int mRecentAppsHeldModifiers; 595 596 int mCameraLensCoverState = CAMERA_LENS_COVER_ABSENT; 597 boolean mHaveBuiltInKeyboard; 598 599 boolean mSystemReady; 600 boolean mSystemBooted; 601 HdmiControl mHdmiControl; 602 IUiModeManager mUiModeManager; 603 int mUiMode; 604 605 boolean mWakeGestureEnabledSetting; 606 MyWakeGestureListener mWakeGestureListener; 607 608 int mLidKeyboardAccessibility; 609 int mLidNavigationAccessibility; 610 int mShortPressOnPowerBehavior; 611 private boolean mShouldEarlyShortPressOnPower; 612 boolean mShouldEarlyShortPressOnStemPrimary; 613 int mLongPressOnPowerBehavior; 614 long mLongPressOnPowerAssistantTimeoutMs; 615 int mVeryLongPressOnPowerBehavior; 616 int mDoublePressOnPowerBehavior; 617 ComponentName mPowerDoublePressTargetActivity; 618 int mTriplePressOnPowerBehavior; 619 int mLongPressOnBackBehavior; 620 int mShortPressOnSleepBehavior; 621 int mShortPressOnWindowBehavior; 622 int mPowerVolUpBehavior; 623 boolean mStylusButtonsEnabled = true; 624 boolean mKidsModeEnabled; 625 boolean mHasSoftInput = false; 626 boolean mUseTvRouting; 627 boolean mAllowStartActivityForLongPressOnPowerDuringSetup; 628 MetricsLogger mLogger; 629 boolean mWakeOnDpadKeyPress; 630 boolean mWakeOnAssistKeyPress; 631 boolean mWakeOnBackKeyPress; 632 boolean mSilenceRingerOnSleepKey; 633 long mWakeUpToLastStateTimeout; 634 int mSearchKeyBehavior; 635 ComponentName mSearchKeyTargetActivity; 636 637 // Key Behavior - Stem Primary 638 private int mShortPressOnStemPrimaryBehavior; 639 private int mDoublePressOnStemPrimaryBehavior; 640 private int mTriplePressOnStemPrimaryBehavior; 641 private int mLongPressOnStemPrimaryBehavior; 642 private RecentTaskInfo mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp; 643 644 // The focused task at the time when the first STEM_PRIMARY key was released. This can only 645 // be accessed from the looper thread. 646 private RootTaskInfo mFocusedTaskInfoOnStemPrimarySingleKeyUp; 647 648 private boolean mHandleVolumeKeysInWM; 649 650 private boolean mPendingKeyguardOccluded; 651 private boolean mKeyguardOccludedChanged; 652 653 Intent mHomeIntent; 654 Intent mCarDockIntent; 655 Intent mDeskDockIntent; 656 Intent mVrHeadsetHomeIntent; 657 boolean mPendingMetaAction; 658 boolean mPendingCapsLockToggle; 659 660 // support for activating the lock screen while the screen is on 661 private HashSet<Integer> mAllowLockscreenWhenOnDisplays = new HashSet<>(); 662 int mLockScreenTimeout; 663 boolean mLockScreenTimerActive; 664 665 // Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.) 666 int mEndcallBehavior; 667 668 // Behavior of POWER button while in-call and screen on. 669 // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.) 670 int mIncallPowerBehavior; 671 672 // Behavior of Back button while in-call and screen on 673 int mIncallBackBehavior; 674 675 // Whether system navigation keys are enabled 676 boolean mSystemNavigationKeysEnabled; 677 678 // TODO(b/111361251): Remove default when the dependencies are multi-display ready. 679 Display mDefaultDisplay; 680 DisplayRotation mDefaultDisplayRotation; 681 DisplayPolicy mDefaultDisplayPolicy; 682 683 // What we do when the user long presses on home 684 int mLongPressOnHomeBehavior; 685 686 // What we do when the user double-taps on home 687 int mDoubleTapOnHomeBehavior; 688 689 // What we do when the user presses the settings key 690 int mSettingsKeyBehavior; 691 692 // Must match config_primaryShortPressTargetActivity in config.xml 693 ComponentName mPrimaryShortPressTargetActivity; 694 695 // Whether to lock the device after the next dreaming transition has finished. 696 private boolean mLockAfterDreamingTransitionFinished; 697 698 // If true, the power button long press behavior will be invoked even if the default display is 699 // non-interactive. If false, the power button long press behavior will be skipped if the 700 // default display is non-interactive. 701 private boolean mSupportLongPressPowerWhenNonInteractive; 702 703 // If true, the power button short press behavior will be always invoked as long as the default 704 // display is on, even if the display is not interactive. If false, the power button short press 705 // behavior will be skipped if the default display is non-interactive. 706 private boolean mSupportShortPressPowerWhenDefaultDisplayOn; 707 708 // Whether to go to sleep entering theater mode from power button 709 private boolean mGoToSleepOnButtonPressTheaterMode; 710 711 // Screenshot trigger states 712 // Increase the chord delay when taking a screenshot from the keyguard 713 private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f; 714 715 // Ringer toggle should reuse timing and triggering from screenshot power and a11y vol up 716 int mRingerToggleChord = VOLUME_HUSH_OFF; 717 718 private static final long BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS = 1000; 719 720 /* The number of steps between min and max brightness */ 721 private static final int BRIGHTNESS_STEPS = 10; 722 723 SettingsObserver mSettingsObserver; 724 ModifierShortcutManager mModifierShortcutManager; 725 /** Currently fully consumed key codes per device */ 726 private final SparseArray<Set<Integer>> mConsumedKeysForDevice = new SparseArray<>(); 727 PowerManager.WakeLock mBroadcastWakeLock; 728 PowerManager.WakeLock mPowerKeyWakeLock; 729 boolean mHavePendingMediaKeyRepeatWithWakeLock; 730 731 private int mCurrentUserId; 732 733 // Maps global key codes to the components that will handle them. 734 private GlobalKeyManager mGlobalKeyManager; 735 736 private final com.android.internal.policy.LogDecelerateInterpolator mLogDecelerateInterpolator 737 = new LogDecelerateInterpolator(100, 0); 738 private final DeferredKeyActionExecutor mDeferredKeyActionExecutor = 739 new DeferredKeyActionExecutor(); 740 741 private volatile int mTopFocusedDisplayId = INVALID_DISPLAY; 742 743 private int mPowerButtonSuppressionDelayMillis = POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS; 744 745 private KeyCombinationManager mKeyCombinationManager; 746 private SingleKeyGestureDetector mSingleKeyGestureDetector; 747 private GestureLauncherService mGestureLauncherService; 748 private ButtonOverridePermissionChecker mButtonOverridePermissionChecker; 749 750 private boolean mLockNowPending = false; 751 752 // Timeout for showing the keyguard after the screen is on, in case no "ready" is received. 753 private int mKeyguardDrawnTimeout = 1000; 754 755 private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled(); 756 757 private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3; 758 private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4; 759 private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5; 760 private static final int MSG_KEYGUARD_DRAWN_TIMEOUT = 6; 761 private static final int MSG_WINDOW_MANAGER_DRAWN_COMPLETE = 7; 762 private static final int MSG_DISPATCH_SHOW_RECENTS = 9; 763 private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10; 764 private static final int MSG_HIDE_BOOT_MESSAGE = 11; 765 private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12; 766 private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 15; 767 private static final int MSG_SCREENSHOT_CHORD = 16; 768 private static final int MSG_ACCESSIBILITY_SHORTCUT = 17; 769 private static final int MSG_BUGREPORT_TV = 18; 770 private static final int MSG_ACCESSIBILITY_TV = 19; 771 private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 20; 772 private static final int MSG_SYSTEM_KEY_PRESS = 21; 773 private static final int MSG_HANDLE_ALL_APPS = 22; 774 private static final int MSG_LAUNCH_ASSIST = 23; 775 private static final int MSG_RINGER_TOGGLE_CHORD = 24; 776 private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 25; 777 private static final int MSG_SET_DEFERRED_KEY_ACTIONS_EXECUTABLE = 27; 778 779 private class PolicyHandler extends Handler { 780 PolicyHandler(Looper looper)781 private PolicyHandler(Looper looper) { 782 super(looper); 783 } 784 785 @Override handleMessage(Message msg)786 public void handleMessage(Message msg) { 787 switch (msg.what) { 788 case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK: 789 dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj); 790 break; 791 case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK: 792 dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj); 793 break; 794 case MSG_DISPATCH_SHOW_RECENTS: 795 showRecentApps(false); 796 break; 797 case MSG_DISPATCH_SHOW_GLOBAL_ACTIONS: 798 showGlobalActionsInternal(); 799 break; 800 case MSG_KEYGUARD_DRAWN_COMPLETE: 801 if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete"); 802 finishKeyguardDrawn(); 803 break; 804 case MSG_KEYGUARD_DRAWN_TIMEOUT: 805 Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete"); 806 finishKeyguardDrawn(); 807 break; 808 case MSG_WINDOW_MANAGER_DRAWN_COMPLETE: 809 final int displayId = msg.arg1; 810 if (DEBUG_WAKEUP) Slog.w(TAG, "All windows drawn on display " + displayId); 811 Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, 812 TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD, displayId /* cookie */); 813 finishWindowsDrawn(displayId); 814 break; 815 case MSG_HIDE_BOOT_MESSAGE: 816 handleHideBootMessage(); 817 break; 818 case MSG_LAUNCH_ASSIST: 819 final int deviceId = msg.arg1; 820 final Long eventTime = (Long) msg.obj; 821 launchAssistAction(null /* hint */, deviceId, eventTime, 822 AssistUtils.INVOCATION_TYPE_ASSIST_BUTTON); 823 break; 824 case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK: 825 launchVoiceAssistWithWakeLock(); 826 break; 827 case MSG_SHOW_PICTURE_IN_PICTURE_MENU: 828 showPictureInPictureMenuInternal(); 829 break; 830 case MSG_ACCESSIBILITY_SHORTCUT: 831 accessibilityShortcutActivated(); 832 break; 833 case MSG_BUGREPORT_TV: 834 requestBugreportForTv(); 835 break; 836 case MSG_ACCESSIBILITY_TV: 837 if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false)) { 838 accessibilityShortcutActivated(); 839 } 840 break; 841 case MSG_DISPATCH_BACK_KEY_TO_AUTOFILL: 842 mAutofillManagerInternal.onBackKeyPressed(); 843 break; 844 case MSG_SYSTEM_KEY_PRESS: 845 KeyEvent event = (KeyEvent) msg.obj; 846 sendSystemKeyToStatusBar(event); 847 event.recycle(); 848 break; 849 case MSG_HANDLE_ALL_APPS: 850 KeyEvent keyEvent = (KeyEvent) msg.obj; 851 if (isKeyEventForCurrentUser(keyEvent.getDisplayId(), keyEvent.getKeyCode(), 852 "launchAllAppsViaA11y")) { 853 launchAllAppsAction(); 854 } 855 break; 856 case MSG_RINGER_TOGGLE_CHORD: 857 handleRingerChordGesture(); 858 break; 859 case MSG_SCREENSHOT_CHORD: 860 handleScreenShot(msg.arg1); 861 break; 862 case MSG_SWITCH_KEYBOARD_LAYOUT: 863 SwitchKeyboardLayoutMessageObject object = 864 (SwitchKeyboardLayoutMessageObject) msg.obj; 865 handleSwitchKeyboardLayout(object.displayId, object.direction, 866 object.focusedToken); 867 break; 868 case MSG_SET_DEFERRED_KEY_ACTIONS_EXECUTABLE: 869 final int keyCode = msg.arg1; 870 final long downTime = (Long) msg.obj; 871 mDeferredKeyActionExecutor.setActionsExecutable(keyCode, downTime); 872 break; 873 } 874 } 875 } 876 877 private UEventObserver mHDMIObserver = new UEventObserver() { 878 @Override 879 public void onUEvent(UEventObserver.UEvent event) { 880 mDefaultDisplayPolicy.setHdmiPlugged("1".equals(event.get("SWITCH_STATE"))); 881 } 882 }; 883 884 class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)885 SettingsObserver(Handler handler) { 886 super(handler); 887 } 888 observe()889 void observe() { 890 // Observe all users' changes 891 ContentResolver resolver = mContext.getContentResolver(); 892 resolver.registerContentObserver(Settings.System.getUriFor( 893 Settings.System.END_BUTTON_BEHAVIOR), false, this, 894 UserHandle.USER_ALL); 895 resolver.registerContentObserver(Settings.Secure.getUriFor( 896 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this, 897 UserHandle.USER_ALL); 898 resolver.registerContentObserver(Settings.Secure.getUriFor( 899 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR), false, this, 900 UserHandle.USER_ALL); 901 resolver.registerContentObserver(Settings.Secure.getUriFor( 902 Settings.Secure.WAKE_GESTURE_ENABLED), false, this, 903 UserHandle.USER_ALL); 904 resolver.registerContentObserver(Settings.System.getUriFor( 905 Settings.System.SCREEN_OFF_TIMEOUT), false, this, 906 UserHandle.USER_ALL); 907 resolver.registerContentObserver(Settings.Secure.getUriFor( 908 Settings.Secure.DEFAULT_INPUT_METHOD), false, this, 909 UserHandle.USER_ALL); 910 resolver.registerContentObserver(Settings.Secure.getUriFor( 911 Settings.Secure.VOLUME_HUSH_GESTURE), false, this, 912 UserHandle.USER_ALL); 913 resolver.registerContentObserver(Settings.Secure.getUriFor( 914 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED), false, this, 915 UserHandle.USER_ALL); 916 resolver.registerContentObserver(Settings.Global.getUriFor( 917 Settings.Global.POWER_BUTTON_SHORT_PRESS), false, this, 918 UserHandle.USER_ALL); 919 resolver.registerContentObserver(Settings.Global.getUriFor( 920 Settings.Global.POWER_BUTTON_DOUBLE_PRESS), false, this, 921 UserHandle.USER_ALL); 922 resolver.registerContentObserver(Settings.Global.getUriFor( 923 Settings.Global.POWER_BUTTON_TRIPLE_PRESS), false, this, 924 UserHandle.USER_ALL); 925 resolver.registerContentObserver(Settings.Global.getUriFor( 926 Settings.Global.POWER_BUTTON_LONG_PRESS), false, this, 927 UserHandle.USER_ALL); 928 resolver.registerContentObserver(Settings.Global.getUriFor( 929 Settings.Global.POWER_BUTTON_LONG_PRESS_DURATION_MS), false, this, 930 UserHandle.USER_ALL); 931 resolver.registerContentObserver(Settings.Global.getUriFor( 932 Settings.Global.POWER_BUTTON_VERY_LONG_PRESS), false, this, 933 UserHandle.USER_ALL); 934 resolver.registerContentObserver(Settings.Global.getUriFor( 935 Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS), false, this, 936 UserHandle.USER_ALL); 937 resolver.registerContentObserver(Settings.Global.getUriFor( 938 Settings.Global.STEM_PRIMARY_BUTTON_DOUBLE_PRESS), false, this, 939 UserHandle.USER_ALL); 940 resolver.registerContentObserver(Settings.Global.getUriFor( 941 Settings.Global.STEM_PRIMARY_BUTTON_TRIPLE_PRESS), false, this, 942 UserHandle.USER_ALL); 943 resolver.registerContentObserver(Settings.Global.getUriFor( 944 Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS), false, this, 945 UserHandle.USER_ALL); 946 resolver.registerContentObserver(Settings.Global.getUriFor( 947 Settings.Global.KEY_CHORD_POWER_VOLUME_UP), false, this, 948 UserHandle.USER_ALL); 949 resolver.registerContentObserver(Settings.Global.getUriFor( 950 Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE), false, this, 951 UserHandle.USER_ALL); 952 resolver.registerContentObserver(Settings.Secure.getUriFor( 953 Settings.Secure.STYLUS_BUTTONS_ENABLED), false, this, 954 UserHandle.USER_ALL); 955 resolver.registerContentObserver(Settings.Secure.getUriFor( 956 Settings.Secure.NAV_BAR_KIDS_MODE), false, this, 957 UserHandle.USER_ALL); 958 updateSettings(); 959 } 960 onChange(boolean selfChange)961 @Override public void onChange(boolean selfChange) { 962 updateSettings(); 963 } 964 } 965 966 class MyWakeGestureListener extends WakeGestureListener { MyWakeGestureListener(Context context, Handler handler)967 MyWakeGestureListener(Context context, Handler handler) { 968 super(context, handler); 969 } 970 971 @Override onWakeUp()972 public void onWakeUp() { 973 synchronized (mLock) { 974 if (shouldEnableWakeGestureLp()) { 975 performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, "Wake Up"); 976 mWindowWakeUpPolicy.wakeUpFromWakeGesture(); 977 } 978 } 979 } 980 } 981 SwitchKeyboardLayoutMessageObject(int displayId, IBinder focusedToken, int direction)982 private record SwitchKeyboardLayoutMessageObject(int displayId, IBinder focusedToken, 983 int direction) { 984 } 985 986 final IPersistentVrStateCallbacks mPersistentVrModeListener = 987 new IPersistentVrStateCallbacks.Stub() { 988 @Override 989 public void onPersistentVrStateChanged(boolean enabled) { 990 mDefaultDisplayPolicy.setPersistentVrModeEnabled(enabled); 991 } 992 }; 993 handleRingerChordGesture()994 private void handleRingerChordGesture() { 995 if (mRingerToggleChord == VOLUME_HUSH_OFF) { 996 return; 997 } 998 getAudioManagerInternal(); 999 mAudioManagerInternal.silenceRingerModeInternal("volume_hush"); 1000 Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.HUSH_GESTURE_USED, 1); 1001 mLogger.action(MetricsProto.MetricsEvent.ACTION_HUSH_GESTURE, mRingerToggleChord); 1002 } 1003 getStatusBarService()1004 IStatusBarService getStatusBarService() { 1005 synchronized (mServiceAcquireLock) { 1006 if (mStatusBarService == null) { 1007 mStatusBarService = IStatusBarService.Stub.asInterface( 1008 ServiceManager.getService("statusbar")); 1009 } 1010 return mStatusBarService; 1011 } 1012 } 1013 getStatusBarManagerInternal()1014 StatusBarManagerInternal getStatusBarManagerInternal() { 1015 synchronized (mServiceAcquireLock) { 1016 if (mStatusBarManagerInternal == null) { 1017 mStatusBarManagerInternal = 1018 LocalServices.getService(StatusBarManagerInternal.class); 1019 } 1020 return mStatusBarManagerInternal; 1021 } 1022 } 1023 getAudioManagerInternal()1024 AudioManagerInternal getAudioManagerInternal() { 1025 synchronized (mServiceAcquireLock) { 1026 if (mAudioManagerInternal == null) { 1027 mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); 1028 } 1029 return mAudioManagerInternal; 1030 } 1031 } 1032 getAccessibilityManagerInternal()1033 AccessibilityManagerInternal getAccessibilityManagerInternal() { 1034 synchronized (mServiceAcquireLock) { 1035 if (mAccessibilityManagerInternal == null) { 1036 mAccessibilityManagerInternal = 1037 LocalServices.getService(AccessibilityManagerInternal.class); 1038 } 1039 return mAccessibilityManagerInternal; 1040 } 1041 } 1042 1043 // returns true if the key was handled and should not be passed to the user backKeyPress()1044 private boolean backKeyPress() { 1045 mLogger.count("key_back_press", 1); 1046 // Cache handled state 1047 boolean handled = mBackKeyHandled; 1048 1049 if (mHasFeatureWatch) { 1050 TelecomManager telecomManager = getTelecommService(); 1051 1052 if (telecomManager != null) { 1053 if (telecomManager.isRinging()) { 1054 // Pressing back while there's a ringing incoming 1055 // call should silence the ringer. 1056 telecomManager.silenceRinger(); 1057 1058 // It should not prevent navigating away 1059 return false; 1060 } else if ( 1061 (mIncallBackBehavior & Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_HANGUP) != 0 1062 && telecomManager.isInCall()) { 1063 // Otherwise, if "Back button ends call" is enabled, 1064 // the Back button will hang up any current active call. 1065 return telecomManager.endCall(); 1066 } 1067 } 1068 } 1069 1070 if (mAutofillManagerInternal != null) { 1071 mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_BACK_KEY_TO_AUTOFILL)); 1072 } 1073 return handled; 1074 } 1075 interceptPowerKeyDown(KeyEvent event, boolean interactive, boolean isKeyGestureTriggered)1076 private void interceptPowerKeyDown(KeyEvent event, boolean interactive, 1077 boolean isKeyGestureTriggered) { 1078 // Hold a wake lock until the power key is released. 1079 if (!mPowerKeyWakeLock.isHeld()) { 1080 mPowerKeyWakeLock.acquire(); 1081 } 1082 1083 mWindowManagerFuncs.onPowerKeyDown(interactive); 1084 1085 // Stop ringing or end call if configured to do so when power is pressed. 1086 TelecomManager telecomManager = getTelecommService(); 1087 boolean hungUp = false; 1088 if (telecomManager != null) { 1089 if (telecomManager.isRinging()) { 1090 // Pressing Power while there's a ringing incoming 1091 // call should silence the ringer. 1092 telecomManager.silenceRinger(); 1093 } else if ((mIncallPowerBehavior 1094 & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0 1095 && telecomManager.isInCall() && interactive) { 1096 // Otherwise, if "Power button ends call" is enabled, 1097 // the Power button will hang up any current active call. 1098 hungUp = telecomManager.endCall(); 1099 } 1100 } 1101 1102 final boolean handledByPowerManager = mPowerManagerInternal.interceptPowerKeyDown(event); 1103 1104 // Inform the StatusBar; but do not allow it to consume the event. 1105 sendSystemKeyToStatusBarAsync(event); 1106 1107 // If the power key has still not yet been handled, then detect short 1108 // press, long press, or multi press and decide what to do. 1109 mPowerKeyHandled = mPowerKeyHandled || hungUp 1110 || handledByPowerManager || isKeyGestureTriggered 1111 || mKeyCombinationManager.isPowerKeyIntercepted(); 1112 1113 if (!mPowerKeyHandled) { 1114 if (!interactive) { 1115 wakeUpFromWakeKey(event); 1116 } 1117 } else { 1118 // handled by another power key policy. 1119 if (mSingleKeyGestureDetector.isKeyIntercepted(KEYCODE_POWER)) { 1120 Slog.d(TAG, "Skip power key gesture for other policy has handled it."); 1121 mSingleKeyGestureDetector.reset(); 1122 } 1123 } 1124 } 1125 interceptPowerKeyUp(KeyEvent event, boolean canceled)1126 private void interceptPowerKeyUp(KeyEvent event, boolean canceled) { 1127 // Inform the StatusBar; but do not allow it to consume the event. 1128 sendSystemKeyToStatusBarAsync(event); 1129 finishPowerKeyPress(); 1130 } 1131 finishPowerKeyPress()1132 private void finishPowerKeyPress() { 1133 mPowerKeyHandled = false; 1134 if (mPowerKeyWakeLock.isHeld()) { 1135 mPowerKeyWakeLock.release(); 1136 } 1137 } 1138 1139 @VisibleForTesting powerPress(long eventTime, int count, int displayId)1140 void powerPress(long eventTime, int count, int displayId) { 1141 // SideFPS still needs to know about suppressed power buttons, in case it needs to block 1142 // an auth attempt. 1143 if (count == 1) { 1144 mSideFpsEventHandler.notifyPowerPressed(); 1145 } 1146 if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) { 1147 Slog.i(TAG, "Suppressed redundant power key press while " 1148 + "already in the process of turning the screen on."); 1149 return; 1150 } 1151 1152 final boolean interactive = mDefaultDisplayPolicy.isAwake(); 1153 1154 Slog.d( 1155 TAG, 1156 "powerPress: eventTime=" 1157 + eventTime 1158 + " interactive=" 1159 + interactive 1160 + " count=" 1161 + count 1162 + " mShortPressOnPowerBehavior=" 1163 + mShortPressOnPowerBehavior); 1164 1165 if (count == 2) { 1166 powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior); 1167 } else if (count == 3) { 1168 powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior); 1169 } else if (count > 3 && count <= getMaxMultiPressPowerCount()) { 1170 Slog.d(TAG, "No behavior defined for power press count " + count); 1171 } else if (count == 1 && shouldHandleShortPressPowerAction(interactive, eventTime)) { 1172 switch (mShortPressOnPowerBehavior) { 1173 case SHORT_PRESS_POWER_NOTHING: 1174 break; 1175 case SHORT_PRESS_POWER_GO_TO_SLEEP: 1176 sleepDefaultDisplayFromPowerButton(eventTime, 0); 1177 break; 1178 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: 1179 sleepDefaultDisplayFromPowerButton(eventTime, 1180 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 1181 break; 1182 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME: 1183 if (sleepDefaultDisplayFromPowerButton(eventTime, 1184 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE)) { 1185 launchHomeFromHotKey(DEFAULT_DISPLAY); 1186 } 1187 break; 1188 case SHORT_PRESS_POWER_GO_HOME: 1189 shortPressPowerGoHome(); 1190 break; 1191 case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: { 1192 if (mDismissImeOnBackKeyPressed) { 1193 InputMethodManagerInternal.get().hideInputMethod( 1194 SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, displayId); 1195 } else { 1196 shortPressPowerGoHome(); 1197 } 1198 break; 1199 } 1200 case SHORT_PRESS_POWER_LOCK_OR_SLEEP: { 1201 if (mKeyguardDelegate == null || !mKeyguardDelegate.hasKeyguard() 1202 || !mKeyguardDelegate.isSecure(mCurrentUserId) || keyguardOn()) { 1203 sleepDefaultDisplayFromPowerButton(eventTime, 0); 1204 } else { 1205 lockNow(null /*options*/); 1206 } 1207 break; 1208 } 1209 case SHORT_PRESS_POWER_DREAM_OR_SLEEP: { 1210 attemptToDreamOrAwakeFromShortPowerButtonPress( 1211 /* isScreenOn */ true, 1212 /* awakeWhenDream */ false, 1213 /* noDreamAction */ 1214 () -> sleepDefaultDisplayFromPowerButton(eventTime, 0)); 1215 break; 1216 } 1217 case SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP: { 1218 // With this power button behavior, the following behavior is expected from each 1219 // system space on a power button short press: 1220 // - Unlocked: go to hub if available, dream if not, screen off if neither 1221 // - Lock screen, hub, or dream: go to screen off 1222 // - Screen off: go to hub if available, dream if not, lock screen if enabled, 1223 // unlocked if lockscreen is disabled 1224 // TODO(b/394657933): consolidate policy into SysUI 1225 final boolean hubEnabled = Settings.Secure.getIntForUser( 1226 mContext.getContentResolver(), Settings.Secure.GLANCEABLE_HUB_ENABLED, 1227 1, mCurrentUserId) == 1; 1228 1229 final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal(); 1230 if (dreamManagerInternal == null) { 1231 break; 1232 } 1233 1234 if (dreamManagerInternal.isDreaming() || isKeyguardShowing()) { 1235 // If the device is already dreaming or on keyguard, go to sleep. 1236 sleepDefaultDisplayFromPowerButton(eventTime, 0); 1237 break; 1238 } 1239 1240 // Check isLockScreenDisabled to exclude NONE lock screen option, which cannot 1241 // show hub. 1242 boolean keyguardAvailable = !mLockPatternUtils.isLockScreenDisabled( 1243 mCurrentUserId); 1244 if (mUserManagerInternal.isUserUnlocked(mCurrentUserId) && hubEnabled 1245 && keyguardAvailable && dreamManagerInternal.dreamConditionActive()) { 1246 // If the hub can be launched, send a message to keyguard. 1247 Bundle options = new Bundle(); 1248 options.putBoolean(EXTRA_TRIGGER_HUB, true); 1249 lockNow(options); 1250 } else { 1251 // If the hub cannot be run, attempt to dream instead. 1252 attemptToDreamOrAwakeFromShortPowerButtonPress( 1253 /* isScreenOn */ true, 1254 /* awakeWhenDream */ false, 1255 /* noDreamAction */ 1256 () -> sleepDefaultDisplayFromPowerButton(eventTime, 0)); 1257 } 1258 break; 1259 } 1260 case SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP: { 1261 attemptToDreamOrAwakeFromShortPowerButtonPress( 1262 /* isScreenOn */ true, 1263 /* awakeWhenDream */ true, 1264 /* noDreamAction */ 1265 () -> sleepDefaultDisplayFromPowerButton(eventTime, 0)); 1266 break; 1267 } 1268 } 1269 } 1270 } 1271 shouldHandleShortPressPowerAction(boolean interactive, long eventTime)1272 private boolean shouldHandleShortPressPowerAction(boolean interactive, long eventTime) { 1273 if (mSupportShortPressPowerWhenDefaultDisplayOn) { 1274 final boolean defaultDisplayOn = Display.isOnState(mDefaultDisplay.getState()); 1275 final boolean beganFromDefaultDisplayOn = 1276 mSingleKeyGestureDetector.beganFromDefaultDisplayOn(); 1277 if (!defaultDisplayOn || !beganFromDefaultDisplayOn) { 1278 Slog.v( 1279 TAG, 1280 "Ignoring short press of power button because the default display is not" 1281 + " on. defaultDisplayOn=" 1282 + defaultDisplayOn 1283 + ", beganFromDefaultDisplayOn=" 1284 + beganFromDefaultDisplayOn); 1285 return false; 1286 } 1287 return true; 1288 } 1289 final boolean beganFromNonInteractive = mSingleKeyGestureDetector.beganFromNonInteractive(); 1290 if (!interactive || beganFromNonInteractive) { 1291 Slog.v( 1292 TAG, 1293 "Ignoring short press of power button because the device is not interactive." 1294 + " interactive=" 1295 + interactive 1296 + ", beganFromNonInteractive=" 1297 + beganFromNonInteractive); 1298 return false; 1299 } 1300 if (mSideFpsEventHandler.shouldConsumeSinglePress(eventTime)) { 1301 Slog.i( 1302 TAG, 1303 "Suppressing power key because the user is interacting with the " 1304 + "fingerprint sensor"); 1305 return false; 1306 } 1307 return true; 1308 } 1309 1310 /** 1311 * Attempt to dream, awake or sleep from a power button press. 1312 * 1313 * @param isScreenOn Whether the screen is currently on. 1314 * @param awakeWhenDream When it's set to {@code true}, awake the device from dreaming. 1315 * Otherwise, go to sleep. 1316 * @param noDreamAction The action to perform if dreaming is not possible. 1317 */ attemptToDreamOrAwakeFromShortPowerButtonPress( boolean isScreenOn, boolean awakeWhenDream, Runnable noDreamAction)1318 private void attemptToDreamOrAwakeFromShortPowerButtonPress( 1319 boolean isScreenOn, boolean awakeWhenDream, Runnable noDreamAction) { 1320 if (mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_SLEEP 1321 && mShortPressOnPowerBehavior != SHORT_PRESS_POWER_HUB_OR_DREAM_OR_SLEEP 1322 && mShortPressOnPowerBehavior != SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP) { 1323 // If the power button behavior isn't one that should be able to trigger the dream, give 1324 // up. 1325 noDreamAction.run(); 1326 return; 1327 } 1328 1329 final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal(); 1330 if (dreamManagerInternal == null) { 1331 Slog.d(TAG, 1332 "Can't access dream manager dreaming when attempting to start or stop dream " 1333 + "from short power press (isScreenOn=" 1334 + isScreenOn + ", awakeWhenDream=" + awakeWhenDream + ")"); 1335 noDreamAction.run(); 1336 return; 1337 } 1338 1339 if (!dreamManagerInternal.canStartDreaming(isScreenOn)) { 1340 if (awakeWhenDream && dreamManagerInternal.isDreaming()) { 1341 dreamManagerInternal.stopDream(false /*immediate*/, "short press power" /*reason*/); 1342 return; 1343 } 1344 Slog.d(TAG, 1345 "Can't start dreaming and the device is not dreaming when attempting to start " 1346 + "or stop dream from short power press (isScreenOn=" 1347 + isScreenOn + ", awakeWhenDream=" + awakeWhenDream + ")"); 1348 noDreamAction.run(); 1349 return; 1350 } 1351 1352 synchronized (mLock) { 1353 // If the setting to lock instantly on power button press is true, then set the flag to 1354 // lock after the dream transition has finished. 1355 mLockAfterDreamingTransitionFinished = 1356 mLockPatternUtils.getPowerButtonInstantlyLocks(mCurrentUserId); 1357 } 1358 1359 dreamManagerInternal.requestDream(); 1360 } 1361 1362 /** 1363 * Sends the default display to sleep as a result of a power button press. 1364 * 1365 * @return {@code true} if the device was sent to sleep, {@code false} if the device did not 1366 * sleep. 1367 */ sleepDefaultDisplayFromPowerButton(long eventTime, int flags)1368 private boolean sleepDefaultDisplayFromPowerButton(long eventTime, int flags) { 1369 // Before we actually go to sleep, we check the last wakeup reason. 1370 // If the device very recently woke up from a gesture (like user lifting their device) 1371 // then ignore the sleep instruction. This is because users have developed 1372 // a tendency to hit the power button immediately when they pick up their device, and we 1373 // don't want to put the device back to sleep in those cases. 1374 final PowerManager.WakeData lastWakeUp = mPowerManagerInternal.getLastWakeup(); 1375 if (lastWakeUp != null && (lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE 1376 || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_LIFT 1377 || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_BIOMETRIC)) { 1378 final long now = SystemClock.uptimeMillis(); 1379 if (mPowerButtonSuppressionDelayMillis > 0 1380 && (now < lastWakeUp.wakeTime + mPowerButtonSuppressionDelayMillis)) { 1381 Slog.i(TAG, "Sleep from power button suppressed. Time since gesture: " 1382 + (now - lastWakeUp.wakeTime) + "ms"); 1383 return false; 1384 } 1385 } 1386 1387 sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags); 1388 return true; 1389 } 1390 sleepDefaultDisplay(long eventTime, int reason, int flags)1391 private void sleepDefaultDisplay(long eventTime, int reason, int flags) { 1392 mRequestedOrSleepingDefaultDisplay = true; 1393 mPowerManager.goToSleep(eventTime, reason, flags); 1394 } 1395 shortPressPowerGoHome()1396 private void shortPressPowerGoHome() { 1397 launchHomeFromHotKey(DEFAULT_DISPLAY, true /* awakenFromDreams */, 1398 false /*respectKeyguard*/); 1399 if (isKeyguardShowingAndNotOccluded()) { 1400 // Notify keyguard so it can do any special handling for the power button since the 1401 // device will not power off and only launch home. 1402 mKeyguardDelegate.onShortPowerPressedGoHome(); 1403 } 1404 } 1405 powerMultiPressAction(long eventTime, boolean interactive, int behavior)1406 private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) { 1407 switch (behavior) { 1408 case MULTI_PRESS_POWER_NOTHING: 1409 break; 1410 case MULTI_PRESS_POWER_THEATER_MODE: 1411 if (!isUserSetupComplete()) { 1412 Slog.i(TAG, "Ignoring toggling theater mode - device not setup."); 1413 break; 1414 } 1415 1416 if (isTheaterModeEnabled()) { 1417 Slog.i(TAG, "Toggling theater mode off."); 1418 Settings.Global.putInt(mContext.getContentResolver(), 1419 Settings.Global.THEATER_MODE_ON, 0); 1420 if (!interactive) { 1421 wakeUpFromWakeKey(eventTime, KEYCODE_POWER, /* isDown= */ false); 1422 } 1423 } else { 1424 Slog.i(TAG, "Toggling theater mode on."); 1425 Settings.Global.putInt(mContext.getContentResolver(), 1426 Settings.Global.THEATER_MODE_ON, 1); 1427 1428 if (mGoToSleepOnButtonPressTheaterMode && interactive) { 1429 sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 1430 0); 1431 } 1432 } 1433 break; 1434 case MULTI_PRESS_POWER_BRIGHTNESS_BOOST: 1435 Slog.i(TAG, "Starting brightness boost."); 1436 if (!interactive) { 1437 wakeUpFromWakeKey(eventTime, KEYCODE_POWER, /* isDown= */ false); 1438 } 1439 mPowerManager.boostScreenBrightness(eventTime); 1440 break; 1441 case MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY: 1442 launchTargetActivityOnMultiPressPower(); 1443 break; 1444 } 1445 } 1446 launchTargetActivityOnMultiPressPower()1447 private void launchTargetActivityOnMultiPressPower() { 1448 if (DEBUG_INPUT) { 1449 Slog.d(TAG, "Executing the double press power action."); 1450 } 1451 if (mPowerDoublePressTargetActivity != null) { 1452 Intent intent = new Intent(); 1453 intent.setComponent(mPowerDoublePressTargetActivity); 1454 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity( 1455 intent, /* flags= */0); 1456 if (resolveInfo != null) { 1457 final boolean keyguardActive = 1458 mKeyguardDelegate != null && mKeyguardDelegate.isShowing(); 1459 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1460 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1461 if (!keyguardActive) { 1462 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 1463 } else { 1464 mKeyguardDelegate.dismissKeyguardToLaunch(intent); 1465 } 1466 } else { 1467 Slog.e(TAG, "Could not resolve activity with : " 1468 + mPowerDoublePressTargetActivity.flattenToString() 1469 + " name."); 1470 } 1471 } 1472 } 1473 getLidBehavior()1474 private int getLidBehavior() { 1475 return Settings.Global.getInt(mContext.getContentResolver(), 1476 Settings.Global.LID_BEHAVIOR, LID_BEHAVIOR_NONE); 1477 } 1478 getMaxMultiPressPowerCount()1479 private int getMaxMultiPressPowerCount() { 1480 // The actual max power button press count is 5 1481 // (EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD), which is coming from 1482 // GestureLauncherService. 1483 // To speed up the handling of single-press of power button inside SingleKeyGestureDetector, 1484 // however, we limit the max count to the number of button presses actually handled by the 1485 // SingleKeyGestureDetector except for wearable devices, where we want to de-dup the double 1486 // press gesture with the emergency gesture. 1487 if (mHasFeatureWatch 1488 && GestureLauncherService.isEmergencyGestureSettingEnabled( 1489 mContext, ActivityManager.getCurrentUser())) { 1490 return 5; 1491 } 1492 if (mTriplePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) { 1493 return 3; 1494 } 1495 if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) { 1496 return 2; 1497 } 1498 return 1; 1499 } 1500 powerLongPress(long eventTime)1501 private void powerLongPress(long eventTime) { 1502 final int behavior = getResolvedLongPressOnPowerBehavior(); 1503 Slog.d(TAG, "powerLongPress: eventTime=" + eventTime 1504 + " mLongPressOnPowerBehavior=" + mLongPressOnPowerBehavior); 1505 1506 // Sending a synthetic KeyEvent to StatusBar service with flag FLAG_LONG_PRESS set, when 1507 // power button is long pressed 1508 if (enableLppSqueezeEffect()) { 1509 // Long press is detected in a callback, so there's no explicit hardware KeyEvent 1510 // available here. Instead, we create a synthetic power key event that has properties 1511 // similar to the original one. 1512 final KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KEYCODE_POWER); 1513 event.setFlags(KeyEvent.FLAG_LONG_PRESS); 1514 // setting both downTime and eventTime as same as downTime is sent as eventTime for long 1515 // press event in SingleKeyGestureDetector's handler 1516 event.setTime(eventTime, eventTime); 1517 sendSystemKeyToStatusBarAsync(event); 1518 } 1519 1520 switch (behavior) { 1521 case LONG_PRESS_POWER_NOTHING: 1522 break; 1523 case LONG_PRESS_POWER_GLOBAL_ACTIONS: 1524 mPowerKeyHandled = true; 1525 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, 1526 "Power - Long Press - Global Actions"); 1527 showGlobalActions(); 1528 break; 1529 case LONG_PRESS_POWER_SHUT_OFF: 1530 case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM: 1531 mPowerKeyHandled = true; 1532 // don't actually trigger the shutdown if we are running stability 1533 // tests via monkey 1534 if (ActivityManager.isUserAMonkey()) { 1535 break; 1536 } 1537 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, 1538 "Power - Long Press - Shut Off"); 1539 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); 1540 mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF); 1541 break; 1542 case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST: 1543 mPowerKeyHandled = true; 1544 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, 1545 "Power - Long Press - Go To Voice Assist"); 1546 // Some devices allow the voice assistant intent during setup (and use that intent 1547 // to launch something else, like Settings). So we explicitly allow that via the 1548 // config_allowStartActivityForLongPressOnPowerInSetup resource in config.xml. 1549 launchVoiceAssist(mAllowStartActivityForLongPressOnPowerDuringSetup); 1550 break; 1551 case LONG_PRESS_POWER_ASSISTANT: 1552 mPowerKeyHandled = true; 1553 performHapticFeedback(HapticFeedbackConstants.ASSISTANT_BUTTON, 1554 "Power - Long Press - Go To Assistant"); 1555 final int powerKeyDeviceId = INVALID_INPUT_DEVICE_ID; 1556 launchAssistAction(null, powerKeyDeviceId, eventTime, 1557 AssistUtils.INVOCATION_TYPE_POWER_BUTTON_LONG_PRESS); 1558 break; 1559 } 1560 } 1561 powerVeryLongPress()1562 private void powerVeryLongPress() { 1563 switch (mVeryLongPressOnPowerBehavior) { 1564 case VERY_LONG_PRESS_POWER_NOTHING: 1565 break; 1566 case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS: 1567 mPowerKeyHandled = true; 1568 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, 1569 "Power - Very Long Press - Show Global Actions"); 1570 showGlobalActions(); 1571 break; 1572 } 1573 } 1574 backLongPress()1575 private void backLongPress() { 1576 mBackKeyHandled = true; 1577 1578 switch (mLongPressOnBackBehavior) { 1579 case LONG_PRESS_BACK_NOTHING: 1580 break; 1581 case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST: 1582 launchVoiceAssist(false /* allowDuringSetup */); 1583 break; 1584 } 1585 } 1586 accessibilityShortcutActivated()1587 private void accessibilityShortcutActivated() { 1588 mAccessibilityShortcutController.performAccessibilityShortcut(); 1589 } 1590 sleepPress()1591 private void sleepPress() { 1592 if (mShortPressOnSleepBehavior == SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME) { 1593 launchHomeFromHotKey(DEFAULT_DISPLAY, false /* awakenDreams */, 1594 true /*respectKeyguard*/); 1595 } 1596 } 1597 sleepRelease(long eventTime)1598 private void sleepRelease(long eventTime) { 1599 if (mSilenceRingerOnSleepKey) { 1600 TelecomManager telecomManager = getTelecommService(); 1601 if (telecomManager != null && telecomManager.isRinging()) { 1602 telecomManager.silenceRinger(); 1603 Slog.i(TAG, "sleepRelease() silence ringer"); 1604 return; 1605 } 1606 } 1607 1608 switch (mShortPressOnSleepBehavior) { 1609 case SHORT_PRESS_SLEEP_GO_TO_SLEEP: 1610 case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME: 1611 Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)"); 1612 sleepDefaultDisplay(eventTime, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); 1613 break; 1614 } 1615 } 1616 getResolvedLongPressOnPowerBehavior()1617 private int getResolvedLongPressOnPowerBehavior() { 1618 if (FactoryTest.isLongPressOnPowerOffEnabled()) { 1619 return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM; 1620 } 1621 1622 // If the config indicates the assistant behavior but the device isn't yet provisioned, show 1623 // global actions instead. 1624 if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_ASSISTANT && !isDeviceProvisioned()) { 1625 return LONG_PRESS_POWER_GLOBAL_ACTIONS; 1626 } 1627 1628 // If long press to launch assistant is disabled in settings, do nothing. 1629 if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_GO_TO_VOICE_ASSIST 1630 && !isLongPressToAssistantEnabled(mContext)) { 1631 return LONG_PRESS_POWER_NOTHING; 1632 } 1633 1634 return mLongPressOnPowerBehavior; 1635 } 1636 stemPrimaryPress(int count)1637 private void stemPrimaryPress(int count) { 1638 Slog.d(TAG, "stemPrimaryPress: " + count); 1639 if (count == 3) { 1640 stemPrimaryTriplePressAction(mTriplePressOnStemPrimaryBehavior); 1641 } else if (count == 2) { 1642 stemPrimaryDoublePressAction(mDoublePressOnStemPrimaryBehavior); 1643 } else if (count == 1) { 1644 stemPrimarySinglePressAction(mShortPressOnStemPrimaryBehavior); 1645 } 1646 } 1647 stemPrimarySinglePressAction(int behavior)1648 private void stemPrimarySinglePressAction(int behavior) { 1649 Slog.d(TAG, "stemPrimarySinglePressAction: behavior=" + behavior); 1650 if (behavior == SHORT_PRESS_PRIMARY_NOTHING) return; 1651 1652 final boolean keyguardActive = mKeyguardDelegate != null && mKeyguardDelegate.isShowing(); 1653 if (keyguardActive) { 1654 // If keyguarded then notify the keyguard. 1655 mKeyguardDelegate.onSystemKeyPressed(KeyEvent.KEYCODE_STEM_PRIMARY); 1656 Slog.d(TAG, "stemPrimarySinglePressAction: skip due to keyguard"); 1657 return; 1658 } 1659 switch (behavior) { 1660 case SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS: 1661 Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS); 1662 allAppsIntent.addFlags( 1663 Intent.FLAG_ACTIVITY_NEW_TASK 1664 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1665 startActivityAsUser(allAppsIntent, UserHandle.CURRENT_OR_SELF); 1666 break; 1667 case SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY: 1668 if (mPrimaryShortPressTargetActivity != null) { 1669 Intent targetActivityIntent = new Intent(); 1670 targetActivityIntent.setComponent(mPrimaryShortPressTargetActivity); 1671 ResolveInfo resolveInfo = 1672 mContext.getPackageManager() 1673 .resolveActivity(targetActivityIntent, /* flags= */ 0); 1674 if (resolveInfo != null) { 1675 targetActivityIntent.addFlags( 1676 Intent.FLAG_ACTIVITY_NEW_TASK 1677 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 1678 | Intent.FLAG_ACTIVITY_TASK_ON_HOME); 1679 startActivityAsUser(targetActivityIntent, UserHandle.CURRENT_OR_SELF); 1680 } else { 1681 Slog.wtf( 1682 TAG, 1683 "Could not resolve activity with : " 1684 + mPrimaryShortPressTargetActivity.flattenToString() 1685 + " name."); 1686 } 1687 } else { 1688 Slog.wtf( 1689 TAG, 1690 "mPrimaryShortPressTargetActivity must not be null and correctly" 1691 + " specified"); 1692 } 1693 break; 1694 } 1695 } 1696 stemPrimaryDoublePressAction(int behavior)1697 private void stemPrimaryDoublePressAction(int behavior) { 1698 Slog.d(TAG, "stemPrimaryDoublePressAction: " + behavior); 1699 switch (behavior) { 1700 case DOUBLE_PRESS_PRIMARY_NOTHING: 1701 break; 1702 case DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP: 1703 final boolean keyguardActive = mKeyguardDelegate == null 1704 ? false 1705 : mKeyguardDelegate.isShowing(); 1706 if (!keyguardActive) { 1707 performStemPrimaryDoublePressSwitchToRecentTask(); 1708 } 1709 break; 1710 case DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP: 1711 final int stemPrimaryKeyDeviceId = INVALID_INPUT_DEVICE_ID; 1712 handleKeyGestureInKeyGestureController( 1713 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS, 1714 stemPrimaryKeyDeviceId, KEYCODE_STEM_PRIMARY, /* metaState= */ 0); 1715 break; 1716 } 1717 } 1718 stemPrimaryTriplePressAction(int behavior)1719 private void stemPrimaryTriplePressAction(int behavior) { 1720 Slog.d(TAG, "stemPrimaryTriplePressAction: " + behavior); 1721 switch (behavior) { 1722 case TRIPLE_PRESS_PRIMARY_NOTHING: 1723 break; 1724 case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY: 1725 mTalkbackShortcutController.toggleTalkback(mCurrentUserId, 1726 TalkbackShortcutController.ShortcutSource.GESTURE); 1727 if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) { 1728 performHapticFeedback(HapticFeedbackConstants.CONFIRM, 1729 "Stem primary - Triple Press - Toggle Accessibility"); 1730 } 1731 break; 1732 } 1733 } 1734 stemPrimaryLongPress(long eventTime)1735 private void stemPrimaryLongPress(long eventTime) { 1736 Slog.d(TAG, "stemPrimaryLongPress: " + mLongPressOnStemPrimaryBehavior); 1737 1738 switch (mLongPressOnStemPrimaryBehavior) { 1739 case LONG_PRESS_PRIMARY_NOTHING: 1740 break; 1741 case LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT: 1742 final int stemPrimaryKeyDeviceId = INVALID_INPUT_DEVICE_ID; 1743 launchAssistAction( 1744 null, 1745 stemPrimaryKeyDeviceId, 1746 eventTime, 1747 AssistUtils.INVOCATION_TYPE_UNKNOWN); 1748 break; 1749 } 1750 } 1751 1752 /** 1753 * Load most recent task (expect current task) and bring it to the front. 1754 */ performStemPrimaryDoublePressSwitchToRecentTask()1755 void performStemPrimaryDoublePressSwitchToRecentTask() { 1756 RecentTaskInfo targetTask = mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp; 1757 if (targetTask == null) { 1758 if (DEBUG_INPUT) { 1759 Slog.w(TAG, "No recent task available! Show wallpaper."); 1760 } 1761 goHome(); 1762 return; 1763 } 1764 1765 if (DEBUG_INPUT) { 1766 Slog.d( 1767 TAG, 1768 "Starting task from recents. id=" 1769 + targetTask.id 1770 + ", persistentId=" 1771 + targetTask.persistentId 1772 + ", topActivity=" 1773 + targetTask.topActivity 1774 + ", baseIntent=" 1775 + targetTask.baseIntent); 1776 } 1777 try { 1778 mActivityManagerService.startActivityFromRecents(targetTask.persistentId, null); 1779 } catch (RemoteException | IllegalArgumentException e) { 1780 Slog.e(TAG, "Failed to start task " + targetTask.persistentId + " from recents", e); 1781 } 1782 } 1783 getMaxMultiPressStemPrimaryCount()1784 private int getMaxMultiPressStemPrimaryCount() { 1785 switch (mTriplePressOnStemPrimaryBehavior) { 1786 case TRIPLE_PRESS_PRIMARY_NOTHING: 1787 break; 1788 case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY: 1789 if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) { 1790 return 3; 1791 } 1792 break; 1793 } 1794 if (mDoublePressOnStemPrimaryBehavior != DOUBLE_PRESS_PRIMARY_NOTHING) { 1795 return 2; 1796 } 1797 return 1; 1798 } 1799 hasLongPressOnPowerBehavior()1800 private boolean hasLongPressOnPowerBehavior() { 1801 return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING; 1802 } 1803 hasVeryLongPressOnPowerBehavior()1804 private boolean hasVeryLongPressOnPowerBehavior() { 1805 return mVeryLongPressOnPowerBehavior != VERY_LONG_PRESS_POWER_NOTHING; 1806 } 1807 hasLongPressOnBackBehavior()1808 private boolean hasLongPressOnBackBehavior() { 1809 return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING; 1810 } 1811 hasLongPressOnStemPrimaryBehavior()1812 private boolean hasLongPressOnStemPrimaryBehavior() { 1813 return mLongPressOnStemPrimaryBehavior != LONG_PRESS_PRIMARY_NOTHING; 1814 } 1815 1816 /** Determine whether the device has any stem primary behaviors. */ hasStemPrimaryBehavior()1817 private boolean hasStemPrimaryBehavior() { 1818 // Read the default stem behaviors from the XML config to determine whether stem primary 1819 // behaviors are supported in this build. If they are supported, then the behaviors may be 1820 // overridden at runtime through their respective Settings overrides. If they are not 1821 // supported, the Settings overrides will not apply. 1822 final int defaultShortPressOnStemPrimaryBehavior = mContext.getResources().getInteger( 1823 com.android.internal.R.integer.config_shortPressOnStemPrimaryBehavior); 1824 final int defaultLongPressOnStemPrimaryBehavior = mContext.getResources().getInteger( 1825 com.android.internal.R.integer.config_longPressOnStemPrimaryBehavior); 1826 return getMaxMultiPressStemPrimaryCount() > 1 1827 || defaultLongPressOnStemPrimaryBehavior != LONG_PRESS_PRIMARY_NOTHING 1828 || defaultShortPressOnStemPrimaryBehavior != SHORT_PRESS_PRIMARY_NOTHING; 1829 } 1830 interceptScreenshotChord(int source, long pressDelay)1831 private void interceptScreenshotChord(int source, long pressDelay) { 1832 mHandler.removeMessages(MSG_SCREENSHOT_CHORD); 1833 // arg2 is unused, but necessary to insure we call the correct method signature 1834 // since the screenshot source is read from message.arg1 1835 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SCREENSHOT_CHORD, source, 0), 1836 pressDelay); 1837 } 1838 interceptAccessibilityShortcutChord()1839 private void interceptAccessibilityShortcutChord() { 1840 mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT); 1841 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT), 1842 getAccessibilityShortcutTimeout()); 1843 } 1844 interceptRingerToggleChord()1845 private void interceptRingerToggleChord() { 1846 mHandler.removeMessages(MSG_RINGER_TOGGLE_CHORD); 1847 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RINGER_TOGGLE_CHORD), 1848 getRingerToggleChordDelay()); 1849 } 1850 getAccessibilityShortcutTimeout()1851 private long getAccessibilityShortcutTimeout() { 1852 final ViewConfiguration config = ViewConfiguration.get(mContext); 1853 final boolean hasDialogShown = Settings.Secure.getIntForUser(mContext.getContentResolver(), 1854 Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0, mCurrentUserId) != 0; 1855 final boolean skipTimeoutRestriction = 1856 Settings.Secure.getIntForUser(mContext.getContentResolver(), 1857 Settings.Secure.SKIP_ACCESSIBILITY_SHORTCUT_DIALOG_TIMEOUT_RESTRICTION, 0, 1858 mCurrentUserId) != 0; 1859 1860 // If users manually set the volume key shortcut for any accessibility service, the 1861 // system would bypass the timeout restriction of the shortcut dialog. 1862 return hasDialogShown || skipTimeoutRestriction 1863 ? config.getAccessibilityShortcutKeyTimeoutAfterConfirmation() 1864 : config.getAccessibilityShortcutKeyTimeout(); 1865 } 1866 getScreenshotChordLongPressDelay()1867 private long getScreenshotChordLongPressDelay() { 1868 long delayMs = DeviceConfig.getLong( 1869 DeviceConfig.NAMESPACE_SYSTEMUI, SCREENSHOT_KEYCHORD_DELAY, 1870 ViewConfiguration.get(mContext).getScreenshotChordKeyTimeout()); 1871 if (mKeyguardDelegate.isShowing()) { 1872 // Double the time it takes to take a screenshot from the keyguard 1873 return (long) (KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER * delayMs); 1874 } 1875 return delayMs; 1876 } 1877 getRingerToggleChordDelay()1878 private long getRingerToggleChordDelay() { 1879 // Always timeout like a tap 1880 return ViewConfiguration.getTapTimeout(); 1881 } 1882 cancelPendingScreenshotChordAction()1883 private void cancelPendingScreenshotChordAction() { 1884 mHandler.removeMessages(MSG_SCREENSHOT_CHORD); 1885 } 1886 cancelPendingAccessibilityShortcutAction()1887 private void cancelPendingAccessibilityShortcutAction() { 1888 mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT); 1889 } 1890 cancelPendingRingerToggleChordAction()1891 private void cancelPendingRingerToggleChordAction() { 1892 mHandler.removeMessages(MSG_RINGER_TOGGLE_CHORD); 1893 } 1894 1895 private final Runnable mEndCallLongPress = new Runnable() { 1896 @Override 1897 public void run() { 1898 mEndCallKeyHandled = true; 1899 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, 1900 "End Call - Long Press - Show Global Actions"); 1901 showGlobalActionsInternal(); 1902 } 1903 }; 1904 handleScreenShot(@indowManager.ScreenshotSource int source)1905 private void handleScreenShot(@WindowManager.ScreenshotSource int source) { 1906 mDefaultDisplayPolicy.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, source); 1907 } 1908 1909 @Override showGlobalActions()1910 public void showGlobalActions() { 1911 mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS); 1912 mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS); 1913 } 1914 showGlobalActionsInternal()1915 void showGlobalActionsInternal() { 1916 if (mGlobalActions == null) { 1917 mGlobalActions = mGlobalActionsFactory.get(); 1918 } 1919 final boolean keyguardShowing = isKeyguardShowingAndNotOccluded(); 1920 mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); 1921 // since it took two seconds of long press to bring this up, 1922 // poke the wake lock so they have some time to see the dialog. 1923 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 1924 } 1925 cancelGlobalActionsAction()1926 private void cancelGlobalActionsAction() { 1927 mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS); 1928 } 1929 isDeviceProvisioned()1930 boolean isDeviceProvisioned() { 1931 return Settings.Global.getInt( 1932 mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0; 1933 } 1934 1935 @Override isUserSetupComplete()1936 public boolean isUserSetupComplete() { 1937 boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(), 1938 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; 1939 if (mHasFeatureLeanback) { 1940 isSetupComplete &= isTvUserSetupComplete(); 1941 } else if (mHasFeatureAuto) { 1942 isSetupComplete &= isAutoUserSetupComplete(); 1943 } 1944 return isSetupComplete; 1945 } 1946 isAutoUserSetupComplete()1947 private boolean isAutoUserSetupComplete() { 1948 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 1949 "android.car.SETUP_WIZARD_IN_PROGRESS", 0, UserHandle.USER_CURRENT) == 0; 1950 } 1951 isTvUserSetupComplete()1952 private boolean isTvUserSetupComplete() { 1953 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 1954 Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; 1955 } 1956 handleShortPressOnHome(int displayId)1957 private void handleShortPressOnHome(int displayId) { 1958 // Turn on the connected TV and switch HDMI input if we're a HDMI playback device. 1959 final HdmiControl hdmiControl = getHdmiControl(); 1960 if (hdmiControl != null) { 1961 hdmiControl.turnOnTv(); 1962 } 1963 1964 // If there's a dream running then use home to escape the dream 1965 // but don't actually go home. 1966 final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal(); 1967 if (dreamManagerInternal != null && dreamManagerInternal.isDreaming()) { 1968 dreamManagerInternal.stopDream(false /*immediate*/, "short press on home" /*reason*/); 1969 return; 1970 } 1971 1972 // Go home! 1973 launchHomeFromHotKey(displayId); 1974 } 1975 1976 /** 1977 * Creates an accessor to HDMI control service that performs the operation of 1978 * turning on TV (optional) and switching input to us. If HDMI control service 1979 * is not available or we're not a HDMI playback device, the operation is no-op. 1980 * @return {@link HdmiControl} instance if available, null otherwise. 1981 */ getHdmiControl()1982 private HdmiControl getHdmiControl() { 1983 if (null == mHdmiControl) { 1984 if (!mHasFeatureHdmiCec) { 1985 return null; 1986 } 1987 HdmiControlManager manager = (HdmiControlManager) mContext.getSystemService( 1988 Context.HDMI_CONTROL_SERVICE); 1989 HdmiPlaybackClient client = null; 1990 if (manager != null) { 1991 client = manager.getPlaybackClient(); 1992 } 1993 mHdmiControl = new HdmiControl(client); 1994 } 1995 return mHdmiControl; 1996 } 1997 1998 private static class HdmiControl { 1999 private final HdmiPlaybackClient mClient; 2000 HdmiControl(HdmiPlaybackClient client)2001 private HdmiControl(HdmiPlaybackClient client) { 2002 mClient = client; 2003 } 2004 turnOnTv()2005 public void turnOnTv() { 2006 if (mClient == null) { 2007 return; 2008 } 2009 mClient.oneTouchPlay(new OneTouchPlayCallback() { 2010 @Override 2011 public void onComplete(int result) { 2012 if (result != HdmiControlManager.RESULT_SUCCESS) { 2013 Log.w(TAG, "One touch play failed: " + result); 2014 } 2015 } 2016 }); 2017 } 2018 } 2019 launchAllAppsAction()2020 private void launchAllAppsAction() { 2021 if (mHasFeatureLeanback || mHasFeatureWatch) { 2022 // TV and watch support the all apps intent 2023 Intent intent = new Intent(Intent.ACTION_ALL_APPS); 2024 if (mHasFeatureLeanback) { 2025 Intent intentLauncher = new Intent(Intent.ACTION_MAIN); 2026 intentLauncher.addCategory(Intent.CATEGORY_HOME); 2027 ResolveInfo resolveInfo = mPackageManager.resolveActivityAsUser(intentLauncher, 2028 PackageManager.MATCH_SYSTEM_ONLY, 2029 mCurrentUserId); 2030 if (resolveInfo != null) { 2031 intent.setPackage(resolveInfo.activityInfo.packageName); 2032 } 2033 } 2034 startActivityAsUser(intent, UserHandle.CURRENT); 2035 } else { 2036 AccessibilityManagerInternal accessibilityManager = getAccessibilityManagerInternal(); 2037 if (accessibilityManager != null) { 2038 accessibilityManager.performSystemAction( 2039 AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS); 2040 } 2041 } 2042 dismissKeyboardShortcutsMenu(); 2043 } 2044 toggleNotificationPanel()2045 private void toggleNotificationPanel() { 2046 IStatusBarService statusBarService = getStatusBarService(); 2047 if (isUserSetupComplete() && statusBarService != null) { 2048 try { 2049 statusBarService.togglePanel(); 2050 } catch (RemoteException e) { 2051 // do nothing. 2052 } 2053 } 2054 } 2055 showSystemSettings()2056 private void showSystemSettings() { 2057 startActivityAsUser(new Intent(android.provider.Settings.ACTION_SETTINGS), 2058 UserHandle.CURRENT_OR_SELF); 2059 } 2060 showPictureInPictureMenu(KeyEvent event)2061 private void showPictureInPictureMenu(KeyEvent event) { 2062 if (DEBUG_INPUT) Log.d(TAG, "showPictureInPictureMenu event=" + event); 2063 mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 2064 Message msg = mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 2065 msg.setAsynchronous(true); 2066 msg.sendToTarget(); 2067 } 2068 showPictureInPictureMenuInternal()2069 private void showPictureInPictureMenuInternal() { 2070 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 2071 if (statusbar != null) { 2072 statusbar.showPictureInPictureMenu(); 2073 } 2074 } 2075 2076 /** A handler to handle home keys per display */ 2077 private class DisplayHomeButtonHandler { 2078 2079 private final int mDisplayId; 2080 private boolean mHomePressed; 2081 private boolean mHomeConsumed; 2082 private KeyEvent mPendingHomeKeyEvent; 2083 private final Runnable mHomeDoubleTapTimeoutRunnable = new Runnable() { 2084 @Override 2085 public void run() { 2086 if (mPendingHomeKeyEvent != null) { 2087 notifyKeyGestureCompleted(mPendingHomeKeyEvent, 2088 KeyGestureEvent.KEY_GESTURE_TYPE_HOME); 2089 handleShortPressOnHome(mPendingHomeKeyEvent.getDisplayId()); 2090 mPendingHomeKeyEvent = null; 2091 } 2092 } 2093 }; 2094 DisplayHomeButtonHandler(int displayId)2095 DisplayHomeButtonHandler(int displayId) { 2096 mDisplayId = displayId; 2097 } 2098 handleHomeButton(IBinder focusedToken, KeyEvent event)2099 boolean handleHomeButton(IBinder focusedToken, KeyEvent event) { 2100 final boolean keyguardOn = keyguardOn(); 2101 final int repeatCount = event.getRepeatCount(); 2102 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 2103 final boolean canceled = event.isCanceled(); 2104 2105 if (DEBUG_INPUT) { 2106 Log.d(TAG, String.format("handleHomeButton in display#%d mHomePressed = %b", 2107 mDisplayId, mHomePressed)); 2108 } 2109 2110 // If we have released the home key, and didn't do anything else 2111 // while it was pressed, then it is time to go home! 2112 if (!down) { 2113 if (mDisplayId == DEFAULT_DISPLAY) { 2114 cancelPreloadRecentApps(); 2115 } 2116 2117 mHomePressed = false; 2118 if (mHomeConsumed) { 2119 mHomeConsumed = false; 2120 return true; 2121 } 2122 2123 if (canceled) { 2124 Log.i(TAG, "Ignoring HOME; event canceled."); 2125 return true; 2126 } 2127 2128 // Delay handling home if a double-tap is possible. 2129 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) { 2130 // For the picture-in-picture menu, only add the delay if a pip is there. 2131 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_PIP_MENU 2132 || mPictureInPictureVisible) { 2133 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case 2134 mPendingHomeKeyEvent = event; 2135 mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable, 2136 ViewConfiguration.getDoubleTapTimeout()); 2137 return true; 2138 } 2139 } 2140 2141 // Post to main thread to avoid blocking input pipeline. 2142 mHandler.post(() -> { 2143 notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_HOME); 2144 handleShortPressOnHome(event.getDisplayId()); 2145 }); 2146 return true; 2147 } 2148 2149 final KeyInterceptionInfo info = 2150 mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken); 2151 if (info != null) { 2152 // If a system window has focus, then it doesn't make sense 2153 // right now to interact with applications. 2154 if (info.layoutParamsType == TYPE_KEYGUARD_DIALOG 2155 || (info.layoutParamsType == TYPE_NOTIFICATION_SHADE 2156 && isKeyguardShowing())) { 2157 // the "app" is keyguard, so give it the key 2158 return false; 2159 } 2160 for (int t : WINDOW_TYPES_WHERE_HOME_DOESNT_WORK) { 2161 if (info.layoutParamsType == t) { 2162 // don't do anything, but also don't pass it to the app 2163 return true; 2164 } 2165 } 2166 } 2167 2168 // Remember that home is pressed and handle special actions. 2169 if (repeatCount == 0) { 2170 mHomePressed = true; 2171 if (mPendingHomeKeyEvent != null) { 2172 mPendingHomeKeyEvent = null; 2173 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); 2174 mHandler.post(() -> handleDoubleTapOnHome(event)); 2175 // TODO(multi-display): Remove display id check once we support recents on 2176 // multi-display 2177 } else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI 2178 && mDisplayId == DEFAULT_DISPLAY) { 2179 preloadRecentApps(); 2180 } 2181 } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) { 2182 if (!keyguardOn) { 2183 // Post to main thread to avoid blocking input pipeline. 2184 mHandler.post(() -> handleLongPressOnHome(event)); 2185 } 2186 } 2187 return true; 2188 } 2189 handleDoubleTapOnHome(KeyEvent event)2190 private void handleDoubleTapOnHome(KeyEvent event) { 2191 if (mHomeConsumed) { 2192 return; 2193 } 2194 switch (mDoubleTapOnHomeBehavior) { 2195 case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI: 2196 if (!isKeyEventForCurrentUser( 2197 event.getDisplayId(), event.getKeyCode(), "toggleRecentApps")) { 2198 break; 2199 } 2200 notifyKeyGestureCompleted(event, 2201 KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH); 2202 mHomeConsumed = true; 2203 toggleRecentApps(); 2204 break; 2205 case DOUBLE_TAP_HOME_PIP_MENU: 2206 if (!isKeyEventForCurrentUser( 2207 event.getDisplayId(), event.getKeyCode(), 2208 "showPictureInPictureMenu")) { 2209 break; 2210 } 2211 mHomeConsumed = true; 2212 showPictureInPictureMenuInternal(); 2213 break; 2214 default: 2215 Log.w(TAG, "No action or undefined behavior for double tap home: " 2216 + mDoubleTapOnHomeBehavior); 2217 break; 2218 } 2219 } 2220 handleLongPressOnHome(KeyEvent event)2221 private void handleLongPressOnHome(KeyEvent event) { 2222 if (mHomeConsumed) { 2223 return; 2224 } 2225 if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_NOTHING) { 2226 return; 2227 } 2228 mHomeConsumed = true; 2229 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, "Home - Long Press"); 2230 switch (mLongPressOnHomeBehavior) { 2231 case LONG_PRESS_HOME_ALL_APPS: 2232 notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS); 2233 if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(), 2234 "launchAllAppsViaA11y")) { 2235 launchAllAppsAction(); 2236 } 2237 break; 2238 case LONG_PRESS_HOME_ASSIST: 2239 if (!isKeyEventForCurrentUser( 2240 event.getDisplayId(), event.getKeyCode(), "launchAssistAction")) { 2241 break; 2242 } 2243 notifyKeyGestureCompleted(event, 2244 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT); 2245 launchAssistAction(null, event.getDeviceId(), event.getEventTime(), 2246 AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS); 2247 break; 2248 case LONG_PRESS_HOME_NOTIFICATION_PANEL: 2249 if (!isKeyEventForCurrentUser( 2250 event.getDisplayId(), event.getKeyCode(), "toggleNotificationPanel")) { 2251 break; 2252 } 2253 notifyKeyGestureCompleted(event, 2254 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL); 2255 toggleNotificationPanel(); 2256 break; 2257 default: 2258 Log.w(TAG, "Undefined long press on home behavior: " 2259 + mLongPressOnHomeBehavior); 2260 break; 2261 } 2262 } 2263 2264 @Override toString()2265 public String toString() { 2266 return String.format("mDisplayId = %d, mHomePressed = %b", mDisplayId, mHomePressed); 2267 } 2268 } 2269 2270 /** A DisplayHomeButtonHandler map indexed by display id */ 2271 private final SparseArray<DisplayHomeButtonHandler> mDisplayHomeButtonHandlers = 2272 new SparseArray<>(); 2273 isRoundWindow()2274 private boolean isRoundWindow() { 2275 return mContext.getResources().getConfiguration().isScreenRound(); 2276 } 2277 2278 @Override setDefaultDisplay(DisplayContentInfo displayContentInfo)2279 public void setDefaultDisplay(DisplayContentInfo displayContentInfo) { 2280 mDefaultDisplay = displayContentInfo.getDisplay(); 2281 mDefaultDisplayRotation = displayContentInfo.getDisplayRotation(); 2282 mDefaultDisplayPolicy = mDefaultDisplayRotation.getDisplayPolicy(); 2283 } 2284 2285 /** Point of injection for test dependencies. */ 2286 @VisibleForTesting 2287 static class Injector { 2288 private final Context mContext; 2289 private final WindowManagerFuncs mWindowManagerFuncs; 2290 Injector(Context context, WindowManagerFuncs funcs)2291 Injector(Context context, WindowManagerFuncs funcs) { 2292 mContext = context; 2293 mWindowManagerFuncs = funcs; 2294 } 2295 getContext()2296 Context getContext() { 2297 return mContext; 2298 } 2299 getWindowManagerFuncs()2300 WindowManagerFuncs getWindowManagerFuncs() { 2301 return mWindowManagerFuncs; 2302 } 2303 getLooper()2304 Looper getLooper() { 2305 return Looper.myLooper(); 2306 } 2307 getAccessibilityShortcutController( Context context, Handler handler, int initialUserId)2308 AccessibilityShortcutController getAccessibilityShortcutController( 2309 Context context, Handler handler, int initialUserId) { 2310 return new AccessibilityShortcutController(context, handler, initialUserId); 2311 } 2312 getGlobalActionsFactory()2313 Supplier<GlobalActions> getGlobalActionsFactory() { 2314 return () -> new GlobalActions(mContext, mWindowManagerFuncs); 2315 } 2316 getKeyguardServiceDelegate()2317 KeyguardServiceDelegate getKeyguardServiceDelegate() { 2318 return new KeyguardServiceDelegate(mContext, 2319 new StateCallback() { 2320 @Override 2321 public void onTrustedChanged() { 2322 mWindowManagerFuncs.notifyKeyguardTrustedChanged(); 2323 } 2324 2325 @Override 2326 public void onShowingChanged() { 2327 mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged(); 2328 } 2329 }); 2330 } 2331 getActivityManagerService()2332 IActivityManager getActivityManagerService() { 2333 return ActivityManager.getService(); 2334 } 2335 getLockPatternUtils()2336 LockPatternUtils getLockPatternUtils() { 2337 return new LockPatternUtils(mContext); 2338 } 2339 getButtonOverridePermissionChecker()2340 ButtonOverridePermissionChecker getButtonOverridePermissionChecker() { 2341 return new ButtonOverridePermissionChecker(); 2342 } 2343 getTalkbackShortcutController()2344 TalkbackShortcutController getTalkbackShortcutController() { 2345 return new TalkbackShortcutController(mContext); 2346 } 2347 getVoiceAccessShortcutController()2348 VoiceAccessShortcutController getVoiceAccessShortcutController() { 2349 return new VoiceAccessShortcutController(mContext); 2350 } 2351 getWindowWakeUpPolicy()2352 WindowWakeUpPolicy getWindowWakeUpPolicy() { 2353 return new WindowWakeUpPolicy(mContext); 2354 } 2355 } 2356 2357 /** {@inheritDoc} */ 2358 @Override 2359 public void init(Context context, WindowManagerFuncs funcs) { 2360 init(new Injector(context, funcs)); 2361 } 2362 2363 @VisibleForTesting 2364 void init(Injector injector) { 2365 mContext = injector.getContext(); 2366 mWindowManagerFuncs = injector.getWindowManagerFuncs(); 2367 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); 2368 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 2369 mActivityManagerService = injector.getActivityManagerService(); 2370 mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class); 2371 mInputManager = mContext.getSystemService(InputManager.class); 2372 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 2373 mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); 2374 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 2375 mAppOpsManager = mContext.getSystemService(AppOpsManager.class); 2376 mSensorPrivacyManager = mContext.getSystemService(SensorPrivacyManager.class); 2377 mDisplayManager = mContext.getSystemService(DisplayManager.class); 2378 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 2379 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 2380 mPackageManager = mContext.getPackageManager(); 2381 mHasFeatureWatch = mPackageManager.hasSystemFeature(FEATURE_WATCH); 2382 mHasFeatureLeanback = mPackageManager.hasSystemFeature(FEATURE_LEANBACK); 2383 mHasFeatureAuto = mPackageManager.hasSystemFeature(FEATURE_AUTOMOTIVE); 2384 mHasFeatureHdmiCec = mPackageManager.hasSystemFeature(FEATURE_HDMI_CEC); 2385 mAccessibilityShortcutController = injector.getAccessibilityShortcutController( 2386 mContext, new Handler(), mCurrentUserId); 2387 mGlobalActionsFactory = injector.getGlobalActionsFactory(); 2388 mLockPatternUtils = injector.getLockPatternUtils(); 2389 mLogger = new MetricsLogger(); 2390 2391 Resources res = mContext.getResources(); 2392 mWakeOnDpadKeyPress = 2393 res.getBoolean(com.android.internal.R.bool.config_wakeOnDpadKeyPress); 2394 mWakeOnAssistKeyPress = 2395 res.getBoolean(com.android.internal.R.bool.config_wakeOnAssistKeyPress); 2396 mWakeOnBackKeyPress = 2397 res.getBoolean(com.android.internal.R.bool.config_wakeOnBackKeyPress); 2398 2399 // Init display burn-in protection 2400 boolean burnInProtectionEnabled = mContext.getResources().getBoolean( 2401 com.android.internal.R.bool.config_enableBurnInProtection); 2402 // Allow a system property to override this. Used by developer settings. 2403 boolean burnInProtectionDevMode = 2404 SystemProperties.getBoolean("persist.debug.force_burn_in", false); 2405 if (burnInProtectionEnabled || burnInProtectionDevMode) { 2406 final int minHorizontal; 2407 final int maxHorizontal; 2408 final int minVertical; 2409 final int maxVertical; 2410 final int maxRadius; 2411 if (burnInProtectionDevMode) { 2412 minHorizontal = -8; 2413 maxHorizontal = 8; 2414 minVertical = -8; 2415 maxVertical = -4; 2416 maxRadius = (isRoundWindow()) ? 6 : -1; 2417 } else { 2418 Resources resources = mContext.getResources(); 2419 minHorizontal = resources.getInteger( 2420 com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset); 2421 maxHorizontal = resources.getInteger( 2422 com.android.internal.R.integer.config_burnInProtectionMaxHorizontalOffset); 2423 minVertical = resources.getInteger( 2424 com.android.internal.R.integer.config_burnInProtectionMinVerticalOffset); 2425 maxVertical = resources.getInteger( 2426 com.android.internal.R.integer.config_burnInProtectionMaxVerticalOffset); 2427 maxRadius = resources.getInteger( 2428 com.android.internal.R.integer.config_burnInProtectionMaxRadius); 2429 } 2430 mBurnInProtectionHelper = new BurnInProtectionHelper( 2431 mContext, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius); 2432 } 2433 2434 mHandler = new PolicyHandler(injector.getLooper()); 2435 mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler); 2436 mSettingsObserver = new SettingsObserver(mHandler); 2437 mSettingsObserver.observe(); 2438 mModifierShortcutManager = new ModifierShortcutManager( 2439 mContext, mHandler, UserHandle.of(mCurrentUserId)); 2440 mUiMode = mContext.getResources().getInteger( 2441 com.android.internal.R.integer.config_defaultUiModeType); 2442 mHomeIntent = new Intent(Intent.ACTION_MAIN, null); 2443 mHomeIntent.addCategory(Intent.CATEGORY_HOME); 2444 mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 2445 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 2446 mEnableCarDockHomeCapture = mContext.getResources().getBoolean( 2447 com.android.internal.R.bool.config_enableCarDockHomeLaunch); 2448 mCarDockIntent = new Intent(Intent.ACTION_MAIN, null); 2449 mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK); 2450 mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 2451 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 2452 mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null); 2453 mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK); 2454 mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 2455 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 2456 mVrHeadsetHomeIntent = new Intent(Intent.ACTION_MAIN, null); 2457 mVrHeadsetHomeIntent.addCategory(Intent.CATEGORY_VR_HOME); 2458 mVrHeadsetHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 2459 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 2460 2461 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 2462 mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 2463 "PhoneWindowManager.mBroadcastWakeLock"); 2464 mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 2465 "PhoneWindowManager.mPowerKeyWakeLock"); 2466 mEnableBugReportKeyboardShortcut = "1".equals(SystemProperties.get("ro.debuggable")); 2467 mLidKeyboardAccessibility = mContext.getResources().getInteger( 2468 com.android.internal.R.integer.config_lidKeyboardAccessibility); 2469 mLidNavigationAccessibility = mContext.getResources().getInteger( 2470 com.android.internal.R.integer.config_lidNavigationAccessibility); 2471 2472 mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean( 2473 com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode); 2474 2475 mSupportLongPressPowerWhenNonInteractive = mContext.getResources().getBoolean( 2476 com.android.internal.R.bool.config_supportLongPressPowerWhenNonInteractive); 2477 mSupportShortPressPowerWhenDefaultDisplayOn = 2478 mContext.getResources() 2479 .getBoolean( 2480 com.android.internal.R.bool 2481 .config_supportShortPressPowerWhenDefaultDisplayOn); 2482 2483 mLongPressOnBackBehavior = mContext.getResources().getInteger( 2484 com.android.internal.R.integer.config_longPressOnBackBehavior); 2485 2486 mLongPressOnPowerBehavior = mContext.getResources().getInteger( 2487 com.android.internal.R.integer.config_longPressOnPowerBehavior); 2488 mLongPressOnPowerAssistantTimeoutMs = mContext.getResources().getInteger( 2489 com.android.internal.R.integer.config_longPressOnPowerDurationMs); 2490 mVeryLongPressOnPowerBehavior = mContext.getResources().getInteger( 2491 com.android.internal.R.integer.config_veryLongPressOnPowerBehavior); 2492 mPowerDoublePressTargetActivity = ComponentName.unflattenFromString( 2493 mContext.getResources().getString( 2494 com.android.internal.R.string.config_doublePressOnPowerTargetActivity)); 2495 mPrimaryShortPressTargetActivity = ComponentName.unflattenFromString( 2496 mContext.getResources().getString( 2497 com.android.internal.R.string.config_primaryShortPressTargetActivity)); 2498 mShortPressOnSleepBehavior = mContext.getResources().getInteger( 2499 com.android.internal.R.integer.config_shortPressOnSleepBehavior); 2500 mSilenceRingerOnSleepKey = mContext.getResources().getBoolean( 2501 com.android.internal.R.bool.config_silenceRingerOnSleepKey); 2502 mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean( 2503 com.android.internal.R.bool.config_allowStartActivityForLongPressOnPowerInSetup); 2504 2505 mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION; 2506 2507 mHandleVolumeKeysInWM = mContext.getResources().getBoolean( 2508 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager); 2509 2510 mWakeUpToLastStateTimeout = mContext.getResources().getInteger( 2511 com.android.internal.R.integer.config_wakeUpToLastStateTimeoutMillis); 2512 2513 mSearchKeyBehavior = mContext.getResources().getInteger( 2514 com.android.internal.R.integer.config_searchKeyBehavior); 2515 2516 mSearchKeyTargetActivity = ComponentName.unflattenFromString( 2517 mContext.getResources().getString( 2518 com.android.internal.R.string.config_searchKeyTargetActivity)); 2519 readConfigurationDependentBehaviors(); 2520 2521 mDisplayFoldController = DisplayFoldController.create(mContext, DEFAULT_DISPLAY); 2522 2523 mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class); 2524 2525 // register for dock events 2526 IntentFilter filter = new IntentFilter(); 2527 filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE); 2528 filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE); 2529 filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE); 2530 filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE); 2531 filter.addAction(Intent.ACTION_DOCK_EVENT); 2532 mContext.registerReceiver(mDockReceiver, filter); 2533 2534 // register for multiuser-relevant broadcasts 2535 filter = new IntentFilter(Intent.ACTION_USER_SWITCHED); 2536 mContext.registerReceiver(mMultiuserReceiver, filter); 2537 2538 mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); 2539 2540 mGlobalKeyManager = new GlobalKeyManager(mContext); 2541 2542 // Controls rotation and the like. 2543 initializeHdmiState(); 2544 2545 // Match current screen state. 2546 if (!mPowerManager.isInteractive()) { 2547 startedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP, 2548 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT); 2549 finishedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP, 2550 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT); 2551 } 2552 2553 final var transitionListener = new AppTransitionListener(DEFAULT_DISPLAY) { 2554 @Override 2555 public int onAppTransitionStartingLocked(long statusBarAnimationStartTime, 2556 long statusBarAnimationDuration) { 2557 return handleTransitionForKeyguardLw(false /* startKeyguardExitAnimation */, 2558 false /* notifyOccluded */); 2559 } 2560 2561 @Override 2562 public void onAppTransitionCancelledLocked(boolean keyguardGoingAwayCancelled) { 2563 // When KEYGUARD_GOING_AWAY app transition is canceled, we need to trigger relevant 2564 // IKeyguardService calls to sync keyguard status in WindowManagerService and SysUI. 2565 handleTransitionForKeyguardLw( 2566 keyguardGoingAwayCancelled /* startKeyguardExitAnimation */, 2567 true /* notifyOccluded */); 2568 2569 synchronized (mLock) { 2570 mLockAfterDreamingTransitionFinished = false; 2571 } 2572 } 2573 2574 @Override 2575 public void onAppTransitionFinishedLocked(IBinder token) { 2576 synchronized (mLock) { 2577 final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal(); 2578 // check both isDreaming and mLockAfterDreamingTransitionFinished before lockNow 2579 // so it won't relock after dreaming has stopped 2580 if (dreamManagerInternal != null && dreamManagerInternal.isDreaming() 2581 && mLockAfterDreamingTransitionFinished) { 2582 lockNow(null); 2583 } 2584 mLockAfterDreamingTransitionFinished = false; 2585 } 2586 } 2587 }; 2588 mWindowManagerInternal.registerAppTransitionListener(transitionListener); 2589 2590 mKeyguardDrawnTimeout = mContext.getResources().getInteger( 2591 com.android.internal.R.integer.config_keyguardDrawnTimeout); 2592 mKeyguardDelegate = injector.getKeyguardServiceDelegate(); 2593 mTalkbackShortcutController = injector.getTalkbackShortcutController(); 2594 mVoiceAccessShortcutController = injector.getVoiceAccessShortcutController(); 2595 mWindowWakeUpPolicy = injector.getWindowWakeUpPolicy(); 2596 initKeyCombinationRules(); 2597 initSingleKeyGestureRules(injector.getLooper()); 2598 initKeyGestures(); 2599 mButtonOverridePermissionChecker = injector.getButtonOverridePermissionChecker(); 2600 mSideFpsEventHandler = new SideFpsEventHandler(mContext, mHandler, mPowerManager); 2601 } 2602 2603 private void initKeyCombinationRules() { 2604 mKeyCombinationManager = new KeyCombinationManager(mHandler); 2605 if (InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures()) { 2606 return; 2607 } 2608 final boolean screenshotChordEnabled = mContext.getResources().getBoolean( 2609 com.android.internal.R.bool.config_enableScreenshotChord); 2610 2611 if (screenshotChordEnabled) { 2612 mKeyCombinationManager.addRule( 2613 new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_POWER) { 2614 @Override 2615 public void execute() { 2616 mPowerKeyHandled = true; 2617 interceptScreenshotChord( 2618 SCREENSHOT_KEY_CHORD, getScreenshotChordLongPressDelay()); 2619 } 2620 @Override 2621 public void cancel() { 2622 cancelPendingScreenshotChordAction(); 2623 } 2624 }); 2625 2626 if (mHasFeatureWatch) { 2627 mKeyCombinationManager.addRule( 2628 new TwoKeysCombinationRule(KEYCODE_POWER, KEYCODE_STEM_PRIMARY) { 2629 @Override 2630 public void execute() { 2631 mPowerKeyHandled = true; 2632 interceptScreenshotChord(SCREENSHOT_KEY_CHORD, 2633 getScreenshotChordLongPressDelay()); 2634 } 2635 @Override 2636 public void cancel() { 2637 cancelPendingScreenshotChordAction(); 2638 } 2639 }); 2640 } 2641 } 2642 2643 mKeyCombinationManager.addRule( 2644 new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_VOLUME_UP) { 2645 @Override 2646 public boolean preCondition() { 2647 return mAccessibilityShortcutController 2648 .isAccessibilityShortcutAvailable(isKeyguardLocked()); 2649 } 2650 @Override 2651 public void execute() { 2652 interceptAccessibilityShortcutChord(); 2653 } 2654 @Override 2655 public void cancel() { 2656 cancelPendingAccessibilityShortcutAction(); 2657 } 2658 }); 2659 2660 // Volume up + power can either be the "ringer toggle chord" or as another way to 2661 // launch GlobalActions. This behavior can change at runtime so we must check behavior 2662 // inside the TwoKeysCombinationRule. 2663 mKeyCombinationManager.addRule( 2664 new TwoKeysCombinationRule(KEYCODE_VOLUME_UP, KEYCODE_POWER) { 2665 @Override 2666 public boolean preCondition() { 2667 switch (mPowerVolUpBehavior) { 2668 case POWER_VOLUME_UP_BEHAVIOR_MUTE: 2669 return mRingerToggleChord != VOLUME_HUSH_OFF; 2670 default: 2671 return true; 2672 } 2673 } 2674 @Override 2675 public void execute() { 2676 switch (mPowerVolUpBehavior) { 2677 case POWER_VOLUME_UP_BEHAVIOR_MUTE: 2678 // no haptic feedback here since 2679 interceptRingerToggleChord(); 2680 mPowerKeyHandled = true; 2681 break; 2682 case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS: 2683 performHapticFeedback( 2684 HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, 2685 "Power + Volume Up - Global Actions"); 2686 showGlobalActions(); 2687 mPowerKeyHandled = true; 2688 break; 2689 default: 2690 break; 2691 } 2692 } 2693 @Override 2694 public void cancel() { 2695 switch (mPowerVolUpBehavior) { 2696 case POWER_VOLUME_UP_BEHAVIOR_MUTE: 2697 cancelPendingRingerToggleChordAction(); 2698 break; 2699 case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS: 2700 cancelGlobalActionsAction(); 2701 break; 2702 } 2703 } 2704 }); 2705 2706 if (mHasFeatureLeanback) { 2707 mKeyCombinationManager.addRule( 2708 new TwoKeysCombinationRule(KEYCODE_BACK, KEYCODE_DPAD_DOWN) { 2709 @Override 2710 public void execute() { 2711 mBackKeyHandled = true; 2712 interceptAccessibilityGestureTv(); 2713 } 2714 @Override 2715 public void cancel() { 2716 cancelAccessibilityGestureTv(); 2717 } 2718 @Override 2719 public long getKeyInterceptDelayMs() { 2720 // Use a timeout of 0 to prevent additional latency in processing of 2721 // this key. This will potentially cause some unwanted UI actions if the 2722 // user does end up triggering the key combination later, but in most 2723 // cases, the user will simply hit a single key, and this will allow us 2724 // to process it without first waiting to see if the combination is 2725 // going to be triggered. 2726 return 0; 2727 } 2728 }); 2729 2730 mKeyCombinationManager.addRule( 2731 new TwoKeysCombinationRule(KEYCODE_DPAD_CENTER, KEYCODE_BACK) { 2732 @Override 2733 public void execute() { 2734 mBackKeyHandled = true; 2735 interceptBugreportGestureTv(); 2736 } 2737 @Override 2738 public void cancel() { 2739 cancelBugreportGestureTv(); 2740 } 2741 @Override 2742 public long getKeyInterceptDelayMs() { 2743 return 0; 2744 } 2745 }); 2746 } 2747 } 2748 2749 /** 2750 * Rule for single power key gesture. 2751 */ 2752 private final class PowerKeyRule extends SingleKeyGestureDetector.SingleKeyRule { 2753 PowerKeyRule() { 2754 super(KEYCODE_POWER); 2755 } 2756 2757 @Override 2758 boolean supportLongPress() { 2759 return hasLongPressOnPowerBehavior(); 2760 } 2761 2762 @Override 2763 boolean supportVeryLongPress() { 2764 return hasVeryLongPressOnPowerBehavior(); 2765 } 2766 2767 2768 @Override 2769 int getMaxMultiPressCount() { 2770 return getMaxMultiPressPowerCount(); 2771 } 2772 2773 @Override 2774 void onPress(long downTime, int displayId) { 2775 if (mShouldEarlyShortPressOnPower) { 2776 return; 2777 } 2778 powerPress(downTime, 1 /*count*/, displayId); 2779 } 2780 2781 @Override 2782 long getLongPressTimeoutMs() { 2783 if (getResolvedLongPressOnPowerBehavior() == LONG_PRESS_POWER_ASSISTANT) { 2784 return mLongPressOnPowerAssistantTimeoutMs; 2785 } else { 2786 return super.getLongPressTimeoutMs(); 2787 } 2788 } 2789 2790 @Override 2791 void onLongPress(long eventTime) { 2792 if (mSingleKeyGestureDetector.beganFromNonInteractive() 2793 && !mSupportLongPressPowerWhenNonInteractive) { 2794 Slog.v(TAG, "Not support long press power when device is not interactive."); 2795 return; 2796 } 2797 2798 powerLongPress(eventTime); 2799 } 2800 2801 @Override 2802 void onVeryLongPress(long eventTime) { 2803 mActivityManagerInternal.prepareForPossibleShutdown(); 2804 powerVeryLongPress(); 2805 } 2806 2807 @Override 2808 void onMultiPress(long downTime, int count, int displayId) { 2809 powerPress(downTime, count, displayId); 2810 } 2811 2812 @Override 2813 void onKeyUp(long eventTime, int count, int displayId, int deviceId, int metaState) { 2814 if (mShouldEarlyShortPressOnPower && count == 1) { 2815 powerPress(eventTime, 1 /*pressCount*/, displayId); 2816 } 2817 } 2818 } 2819 2820 /** 2821 * Rule for single back key gesture. 2822 */ 2823 private final class BackKeyRule extends SingleKeyGestureDetector.SingleKeyRule { 2824 BackKeyRule() { 2825 super(KEYCODE_BACK); 2826 } 2827 2828 @Override 2829 boolean supportLongPress() { 2830 return hasLongPressOnBackBehavior(); 2831 } 2832 2833 @Override 2834 int getMaxMultiPressCount() { 2835 return 1; 2836 } 2837 2838 @Override 2839 void onPress(long downTime, int unusedDisplayId) { 2840 mBackKeyHandled |= backKeyPress(); 2841 } 2842 2843 @Override 2844 void onLongPress(long downTime) { 2845 backLongPress(); 2846 } 2847 } 2848 2849 /** 2850 * Rule for single stem primary key gesture. 2851 */ 2852 private final class StemPrimaryKeyRule extends SingleKeyGestureDetector.SingleKeyRule { 2853 StemPrimaryKeyRule() { 2854 super(KeyEvent.KEYCODE_STEM_PRIMARY); 2855 } 2856 2857 @Override 2858 boolean supportLongPress() { 2859 return hasLongPressOnStemPrimaryBehavior(); 2860 } 2861 2862 @Override 2863 int getMaxMultiPressCount() { 2864 return getMaxMultiPressStemPrimaryCount(); 2865 } 2866 2867 @Override 2868 void onPress(long downTime, int unusedDisplayId) { 2869 if (shouldHandleStemPrimaryEarlyShortPress()) { 2870 return; 2871 } 2872 // Short-press should be triggered only if app doesn't handle it. 2873 mDeferredKeyActionExecutor.queueKeyAction( 2874 KeyEvent.KEYCODE_STEM_PRIMARY, downTime, () -> stemPrimaryPress(1 /*count*/)); 2875 } 2876 2877 @Override 2878 void onLongPress(long eventTime) { 2879 if (mLongPressOnStemPrimaryBehavior == LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT) { 2880 // Long-press to assistant gesture is not overridable by apps. 2881 stemPrimaryLongPress(eventTime); 2882 } else { 2883 // Other long-press actions should be triggered only if app doesn't handle it. 2884 mDeferredKeyActionExecutor.queueKeyAction( 2885 KeyEvent.KEYCODE_STEM_PRIMARY, 2886 eventTime, 2887 () -> stemPrimaryLongPress(eventTime)); 2888 } 2889 } 2890 2891 @Override 2892 void onMultiPress(long downTime, int count, int unusedDisplayId) { 2893 // Triple-press stem to toggle accessibility gesture should always be triggered 2894 // regardless of if app handles it. 2895 if (count == 3 2896 && mTriplePressOnStemPrimaryBehavior 2897 == TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY) { 2898 // Cancel any queued actions for current key code to prevent them from being 2899 // launched after a11y layer enabled. If the action happens early, 2900 // undoEarlySinglePress will make sure the correct task is on top. 2901 mDeferredKeyActionExecutor.cancelQueuedAction(KeyEvent.KEYCODE_STEM_PRIMARY); 2902 undoEarlySinglePress(); 2903 stemPrimaryPress(count); 2904 } else { 2905 // Other multi-press gestures should be triggered only if app doesn't handle it. 2906 mDeferredKeyActionExecutor.queueKeyAction( 2907 KeyEvent.KEYCODE_STEM_PRIMARY, downTime, () -> stemPrimaryPress(count)); 2908 } 2909 } 2910 2911 /** 2912 * This method undo the previously launched early-single-press action by bringing the 2913 * focused task before launching early-single-press back to top. 2914 */ 2915 private void undoEarlySinglePress() { 2916 if (shouldHandleStemPrimaryEarlyShortPress() 2917 && mFocusedTaskInfoOnStemPrimarySingleKeyUp != null) { 2918 try { 2919 mActivityManagerService.startActivityFromRecents( 2920 mFocusedTaskInfoOnStemPrimarySingleKeyUp.taskId, null); 2921 } catch (RemoteException | IllegalArgumentException e) { 2922 Slog.e( 2923 TAG, 2924 "Failed to start task " 2925 + mFocusedTaskInfoOnStemPrimarySingleKeyUp.taskId 2926 + " from recents", 2927 e); 2928 } 2929 } 2930 } 2931 2932 @Override 2933 void onKeyUp(long eventTime, int count, int displayId, int deviceId, int metaState) { 2934 if (count == 1) { 2935 // Save info about the most recent task on the first press of the stem key. This 2936 // may be used later to switch to the most recent app using double press gesture. 2937 // It is possible that we may navigate away from this task before the double 2938 // press is detected, as a result of the first press, so we save the current 2939 // most recent task before that happens. 2940 // TODO(b/311497918): guard this with DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP 2941 mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp = 2942 mActivityTaskManagerInternal.getMostRecentTaskFromBackground(); 2943 2944 mFocusedTaskInfoOnStemPrimarySingleKeyUp = null; 2945 2946 if (shouldHandleStemPrimaryEarlyShortPress()) { 2947 // Key-up gesture should be triggered only if app doesn't handle it. 2948 mDeferredKeyActionExecutor.queueKeyAction( 2949 KeyEvent.KEYCODE_STEM_PRIMARY, 2950 eventTime, 2951 () -> { 2952 Slog.d(TAG, "StemPrimaryKeyRule: executing deferred onKeyUp"); 2953 // Save the info of the focused task on screen. This may be used 2954 // later to bring the current focused task back to top. For 2955 // example, stem primary triple press enables the A11y interface 2956 // on top of the current focused task. When early single press is 2957 // enabled for stem primary, the focused task could change to 2958 // something else upon first key up event. In that case, we will 2959 // bring the task recorded by this variable back to top. Then, start 2960 // A11y interface. 2961 try { 2962 mFocusedTaskInfoOnStemPrimarySingleKeyUp = 2963 mActivityManagerService.getFocusedRootTaskInfo(); 2964 } catch (RemoteException e) { 2965 Slog.e( 2966 TAG, 2967 "StemPrimaryKeyRule: onKeyUp: error while getting " 2968 + "focused task " 2969 + "info.", 2970 e); 2971 } 2972 2973 stemPrimaryPress(1); 2974 }); 2975 } 2976 } 2977 } 2978 2979 // TODO(b/311497918): make a shouldHandlePowerEarlyShortPress for power button. 2980 private boolean shouldHandleStemPrimaryEarlyShortPress() { 2981 return mShouldEarlyShortPressOnStemPrimary 2982 && mShortPressOnStemPrimaryBehavior == SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS; 2983 } 2984 } 2985 2986 // TODO(b/358569822): Move to KeyGestureController. 2987 private final class StylusTailButtonRule extends SingleKeyGestureDetector.SingleKeyRule { 2988 StylusTailButtonRule() { 2989 super(KEYCODE_STYLUS_BUTTON_TAIL); 2990 } 2991 2992 @Override 2993 int getMaxMultiPressCount() { 2994 return 2; 2995 } 2996 2997 @Override 2998 void onPress(long downTime, int displayId) { 2999 3000 } 3001 3002 @Override 3003 void onKeyUp(long eventTime, int pressCount, int displayId, int deviceId, int metaState) { 3004 if (pressCount != 1) { 3005 return; 3006 } 3007 // Single press on tail button triggers the open notes gesture. 3008 handleKeyGestureInKeyGestureController(KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_NOTES, 3009 deviceId, KEYCODE_STYLUS_BUTTON_TAIL, metaState); 3010 } 3011 } 3012 3013 private void initSingleKeyGestureRules(Looper looper) { 3014 mSingleKeyGestureDetector = SingleKeyGestureDetector.get(mContext, looper); 3015 mSingleKeyGestureDetector.addRule(new PowerKeyRule()); 3016 if (hasLongPressOnBackBehavior()) { 3017 mSingleKeyGestureDetector.addRule(new BackKeyRule()); 3018 } 3019 if (hasStemPrimaryBehavior()) { 3020 mSingleKeyGestureDetector.addRule(new StemPrimaryKeyRule()); 3021 } 3022 mSingleKeyGestureDetector.addRule(new StylusTailButtonRule()); 3023 } 3024 3025 /** 3026 * Read values from config.xml that may be overridden depending on 3027 * the configuration of the device. 3028 * eg. Disable long press on home goes to recents on sw600dp. 3029 */ 3030 private void readConfigurationDependentBehaviors() { 3031 final Resources res = mContext.getResources(); 3032 3033 mLongPressOnHomeBehavior = res.getInteger( 3034 com.android.internal.R.integer.config_longPressOnHomeBehavior); 3035 if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING || 3036 mLongPressOnHomeBehavior > LAST_LONG_PRESS_HOME_BEHAVIOR) { 3037 mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING; 3038 } 3039 3040 mDoubleTapOnHomeBehavior = res.getInteger( 3041 com.android.internal.R.integer.config_doubleTapOnHomeBehavior); 3042 if (mDoubleTapOnHomeBehavior < DOUBLE_TAP_HOME_NOTHING || 3043 mDoubleTapOnHomeBehavior > DOUBLE_TAP_HOME_PIP_MENU) { 3044 mDoubleTapOnHomeBehavior = DOUBLE_TAP_HOME_NOTHING; 3045 } 3046 3047 mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_NOTHING; 3048 if (mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { 3049 mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE; 3050 } 3051 3052 mSettingsKeyBehavior = res.getInteger( 3053 com.android.internal.R.integer.config_settingsKeyBehavior); 3054 if (mSettingsKeyBehavior < SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY 3055 || mSettingsKeyBehavior > LAST_SETTINGS_KEY_BEHAVIOR) { 3056 mSettingsKeyBehavior = SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY; 3057 } 3058 } 3059 3060 private void updateSettings() { 3061 updateSettings(null); 3062 } 3063 3064 /** 3065 * Update provider Setting values on a given {@code handler}, or synchronously if {@code null} 3066 * is passed for handler. 3067 */ 3068 void updateSettings(Handler handler) { 3069 if (handler != null) { 3070 handler.post(() -> updateSettings(null)); 3071 return; 3072 } 3073 ContentResolver resolver = mContext.getContentResolver(); 3074 boolean updateRotation = false; 3075 boolean updateKidsModeSettings = false; 3076 final boolean kidsModeEnabled; 3077 synchronized (mLock) { 3078 mEndcallBehavior = Settings.System.getIntForUser(resolver, 3079 Settings.System.END_BUTTON_BEHAVIOR, 3080 Settings.System.END_BUTTON_BEHAVIOR_DEFAULT, 3081 UserHandle.USER_CURRENT); 3082 mIncallPowerBehavior = Settings.Secure.getIntForUser(resolver, 3083 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 3084 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT, 3085 UserHandle.USER_CURRENT); 3086 mIncallBackBehavior = Settings.Secure.getIntForUser(resolver, 3087 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR, 3088 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_DEFAULT, 3089 UserHandle.USER_CURRENT); 3090 mSystemNavigationKeysEnabled = Settings.Secure.getIntForUser(resolver, 3091 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, 3092 0, UserHandle.USER_CURRENT) == 1; 3093 mRingerToggleChord = Settings.Secure.getIntForUser(resolver, 3094 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, 3095 UserHandle.USER_CURRENT); 3096 mPowerButtonSuppressionDelayMillis = Settings.Global.getInt(resolver, 3097 Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE, 3098 POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS); 3099 if (!mContext.getResources() 3100 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { 3101 mRingerToggleChord = VOLUME_HUSH_OFF; 3102 } 3103 3104 // Configure wake gesture. 3105 boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver, 3106 Settings.Secure.WAKE_GESTURE_ENABLED, 0, 3107 UserHandle.USER_CURRENT) != 0; 3108 if (mWakeGestureEnabledSetting != wakeGestureEnabledSetting) { 3109 mWakeGestureEnabledSetting = wakeGestureEnabledSetting; 3110 updateWakeGestureListenerLp(); 3111 } 3112 3113 // use screen off timeout setting as the timeout for the lockscreen 3114 mLockScreenTimeout = Settings.System.getIntForUser(resolver, 3115 Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT); 3116 String imId = Settings.Secure.getStringForUser(resolver, 3117 Settings.Secure.DEFAULT_INPUT_METHOD, UserHandle.USER_CURRENT); 3118 boolean hasSoftInput = imId != null && imId.length() > 0; 3119 if (mHasSoftInput != hasSoftInput) { 3120 mHasSoftInput = hasSoftInput; 3121 updateRotation = true; 3122 } 3123 3124 mShortPressOnPowerBehavior = Settings.Global.getInt(resolver, 3125 Settings.Global.POWER_BUTTON_SHORT_PRESS, 3126 mContext.getResources().getInteger( 3127 com.android.internal.R.integer.config_shortPressOnPowerBehavior)); 3128 mDoublePressOnPowerBehavior = Settings.Global.getInt(resolver, 3129 Settings.Global.POWER_BUTTON_DOUBLE_PRESS, 3130 mContext.getResources().getInteger( 3131 com.android.internal.R.integer.config_doublePressOnPowerBehavior)); 3132 mTriplePressOnPowerBehavior = Settings.Global.getInt(resolver, 3133 Settings.Global.POWER_BUTTON_TRIPLE_PRESS, 3134 mContext.getResources().getInteger( 3135 com.android.internal.R.integer.config_triplePressOnPowerBehavior)); 3136 3137 final int longPressOnPowerBehavior = Settings.Global.getInt(resolver, 3138 Settings.Global.POWER_BUTTON_LONG_PRESS, 3139 mContext.getResources().getInteger( 3140 com.android.internal.R.integer.config_longPressOnPowerBehavior)); 3141 final int veryLongPressOnPowerBehavior = Settings.Global.getInt(resolver, 3142 Settings.Global.POWER_BUTTON_VERY_LONG_PRESS, 3143 mContext.getResources().getInteger( 3144 com.android.internal.R.integer.config_veryLongPressOnPowerBehavior)); 3145 if (mLongPressOnPowerBehavior != longPressOnPowerBehavior 3146 || mVeryLongPressOnPowerBehavior != veryLongPressOnPowerBehavior) { 3147 mLongPressOnPowerBehavior = longPressOnPowerBehavior; 3148 mVeryLongPressOnPowerBehavior = veryLongPressOnPowerBehavior; 3149 } 3150 3151 mLongPressOnPowerAssistantTimeoutMs = Settings.Global.getLong( 3152 mContext.getContentResolver(), 3153 Settings.Global.POWER_BUTTON_LONG_PRESS_DURATION_MS, 3154 mContext.getResources().getInteger( 3155 com.android.internal.R.integer.config_longPressOnPowerDurationMs)); 3156 3157 mPowerVolUpBehavior = Settings.Global.getInt(resolver, 3158 Settings.Global.KEY_CHORD_POWER_VOLUME_UP, 3159 mContext.getResources().getInteger( 3160 com.android.internal.R.integer.config_keyChordPowerVolumeUp)); 3161 3162 mShortPressOnStemPrimaryBehavior = Settings.Global.getInt(resolver, 3163 Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS, 3164 mContext.getResources().getInteger( 3165 com.android.internal.R.integer.config_shortPressOnStemPrimaryBehavior)); 3166 mDoublePressOnStemPrimaryBehavior = Settings.Global.getInt(resolver, 3167 Settings.Global.STEM_PRIMARY_BUTTON_DOUBLE_PRESS, 3168 mContext.getResources().getInteger( 3169 com.android.internal.R.integer 3170 .config_doublePressOnStemPrimaryBehavior)); 3171 mTriplePressOnStemPrimaryBehavior = Settings.Global.getInt(resolver, 3172 Settings.Global.STEM_PRIMARY_BUTTON_TRIPLE_PRESS, 3173 mContext.getResources().getInteger( 3174 com.android.internal.R.integer 3175 .config_triplePressOnStemPrimaryBehavior)); 3176 mLongPressOnStemPrimaryBehavior = Settings.Global.getInt(resolver, 3177 Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS, 3178 mContext.getResources().getInteger( 3179 com.android.internal.R.integer.config_longPressOnStemPrimaryBehavior)); 3180 mShouldEarlyShortPressOnPower = 3181 mContext.getResources() 3182 .getBoolean(com.android.internal.R.bool.config_shortPressEarlyOnPower); 3183 mShouldEarlyShortPressOnStemPrimary = mContext.getResources().getBoolean( 3184 com.android.internal.R.bool.config_shortPressEarlyOnStemPrimary); 3185 3186 mStylusButtonsEnabled = Settings.Secure.getIntForUser(resolver, 3187 Secure.STYLUS_BUTTONS_ENABLED, 1, UserHandle.USER_CURRENT) == 1; 3188 mInputManagerInternal.setStylusButtonMotionEventsEnabled(mStylusButtonsEnabled); 3189 3190 kidsModeEnabled = Settings.Secure.getIntForUser(resolver, 3191 Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1; 3192 if (mKidsModeEnabled != kidsModeEnabled) { 3193 mKidsModeEnabled = kidsModeEnabled; 3194 updateKidsModeSettings = true; 3195 } 3196 } 3197 if (updateKidsModeSettings) { 3198 updateKidsModeSettings(kidsModeEnabled); 3199 } 3200 if (updateRotation) { 3201 updateRotation(true); 3202 } 3203 } 3204 3205 private void updateKidsModeSettings(boolean kidsModeEnabled) { 3206 if (kidsModeEnabled) { 3207 // Needed since many Kids apps aren't optimised to support both orientations and it 3208 // will be hard for kids to understand the app compat mode. 3209 // TODO(229961548): Remove ignoreOrientationRequest exception for Kids Mode once 3210 // possible. 3211 if (mContext.getResources().getBoolean(R.bool.config_reverseDefaultRotation)) { 3212 mWindowManagerInternal.setOrientationRequestPolicy( 3213 true /* isIgnoreOrientationRequestDisabled */, 3214 new int[]{SCREEN_ORIENTATION_LANDSCAPE, 3215 SCREEN_ORIENTATION_REVERSE_LANDSCAPE}, 3216 new int[]{SCREEN_ORIENTATION_SENSOR_LANDSCAPE, 3217 SCREEN_ORIENTATION_SENSOR_LANDSCAPE}); 3218 } else { 3219 mWindowManagerInternal.setOrientationRequestPolicy( 3220 true /* isIgnoreOrientationRequestDisabled */, 3221 null /* fromOrientations */, null /* toOrientations */); 3222 } 3223 } else { 3224 mWindowManagerInternal.setOrientationRequestPolicy( 3225 false /* isIgnoreOrientationRequestDisabled */, 3226 null /* fromOrientations */, null /* toOrientations */); 3227 } 3228 } 3229 3230 private DreamManagerInternal getDreamManagerInternal() { 3231 if (mDreamManagerInternal == null) { 3232 // If mDreamManagerInternal is null, attempt to re-fetch it. 3233 mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); 3234 } 3235 3236 return mDreamManagerInternal; 3237 } 3238 3239 private void updateWakeGestureListenerLp() { 3240 if (shouldEnableWakeGestureLp()) { 3241 mWakeGestureListener.requestWakeUpTrigger(); 3242 } else { 3243 mWakeGestureListener.cancelWakeUpTrigger(); 3244 } 3245 } 3246 3247 private boolean shouldEnableWakeGestureLp() { 3248 return mWakeGestureEnabledSetting && !mDefaultDisplayPolicy.isAwake() 3249 && (getLidBehavior() != LID_BEHAVIOR_SLEEP 3250 || mDefaultDisplayPolicy.getLidState() != LID_CLOSED) 3251 && mWakeGestureListener.isSupported(); 3252 } 3253 3254 /** {@inheritDoc} */ 3255 @Override 3256 public int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName, 3257 int[] outAppOp, int displayId) { 3258 if (isRoundedCornerOverlay && mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) 3259 != PERMISSION_GRANTED) { 3260 return ADD_PERMISSION_DENIED; 3261 } 3262 3263 outAppOp[0] = AppOpsManager.OP_NONE; 3264 3265 if (!((type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) 3266 || (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) 3267 || (type >= FIRST_SYSTEM_WINDOW && type <= LAST_SYSTEM_WINDOW))) { 3268 return WindowManagerGlobal.ADD_INVALID_TYPE; 3269 } 3270 3271 if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) { 3272 // Window manager will make sure these are okay. 3273 return ADD_OKAY; 3274 } 3275 3276 if (!isSystemAlertWindowType(type)) { 3277 switch (type) { 3278 case TYPE_TOAST: 3279 // Only apps that target older than O SDK can add window without a token, after 3280 // that we require a token so apps cannot add toasts directly as the token is 3281 // added by the notification system. 3282 // Window manager does the checking for this. 3283 outAppOp[0] = OP_TOAST_WINDOW; 3284 return ADD_OKAY; 3285 case TYPE_ACCESSIBILITY_OVERLAY: 3286 if (createAccessibilityOverlayAppOpEnabled()) { 3287 outAppOp[0] = OP_CREATE_ACCESSIBILITY_OVERLAY; 3288 return ADD_OKAY; 3289 } 3290 case TYPE_INPUT_METHOD: 3291 case TYPE_WALLPAPER: 3292 case TYPE_PRESENTATION: 3293 case TYPE_PRIVATE_PRESENTATION: 3294 case TYPE_VOICE_INTERACTION: 3295 case TYPE_QS_DIALOG: 3296 case TYPE_NAVIGATION_BAR_PANEL: 3297 case TYPE_STATUS_BAR: 3298 case TYPE_NOTIFICATION_SHADE: 3299 case TYPE_NAVIGATION_BAR: 3300 case TYPE_STATUS_BAR_ADDITIONAL: 3301 case TYPE_STATUS_BAR_SUB_PANEL: 3302 case TYPE_VOICE_INTERACTION_STARTING: 3303 // The window manager will check these. 3304 return ADD_OKAY; 3305 } 3306 3307 return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) 3308 == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED; 3309 } 3310 3311 // Things get a little more interesting for alert windows... 3312 outAppOp[0] = OP_SYSTEM_ALERT_WINDOW; 3313 3314 final int callingUid = Binder.getCallingUid(); 3315 // system processes will be automatically granted privilege to draw 3316 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 3317 return ADD_OKAY; 3318 } 3319 3320 ApplicationInfo appInfo; 3321 try { 3322 appInfo = mPackageManager.getApplicationInfoAsUser( 3323 packageName, 3324 0 /* flags */, 3325 UserHandle.getUserId(callingUid)); 3326 } catch (PackageManager.NameNotFoundException e) { 3327 appInfo = null; 3328 } 3329 3330 if (appInfo == null || (type != TYPE_APPLICATION_OVERLAY && appInfo.targetSdkVersion >= O)) { 3331 /** 3332 * Apps targeting >= {@link Build.VERSION_CODES#O} are required to hold 3333 * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} (system signature apps) 3334 * permission to add alert windows that aren't 3335 * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}. 3336 */ 3337 return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) 3338 == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED; 3339 } 3340 3341 if (mContext.checkCallingOrSelfPermission(SYSTEM_APPLICATION_OVERLAY) 3342 == PERMISSION_GRANTED) { 3343 return ADD_OKAY; 3344 } 3345 3346 // Allow virtual device owners to add overlays on the trusted displays they own. 3347 if (mWindowManagerFuncs.isCallerVirtualDeviceOwner(displayId, callingUid) 3348 && mWindowManagerFuncs.isDisplayTrusted(displayId) 3349 && mContext.checkCallingOrSelfPermission(CREATE_VIRTUAL_DEVICE) 3350 == PERMISSION_GRANTED) { 3351 return ADD_OKAY; 3352 } 3353 3354 // check if user has enabled this operation. SecurityException will be thrown if this app 3355 // has not been allowed by the user. The reason to use "noteOp" (instead of checkOp) is to 3356 // make sure the usage is logged. 3357 final int mode = mAppOpsManager.noteOpNoThrow(outAppOp[0], callingUid, packageName, 3358 null /* featureId */, "check-add"); 3359 switch (mode) { 3360 case AppOpsManager.MODE_ALLOWED: 3361 case AppOpsManager.MODE_IGNORED: 3362 // although we return ADD_OKAY for MODE_IGNORED, the added window will 3363 // actually be hidden in WindowManagerService 3364 return ADD_OKAY; 3365 case AppOpsManager.MODE_ERRORED: 3366 // Don't crash legacy apps 3367 if (appInfo.targetSdkVersion < M) { 3368 return ADD_OKAY; 3369 } 3370 return ADD_PERMISSION_DENIED; 3371 default: 3372 // in the default mode, we will make a decision here based on 3373 // checkCallingPermission() 3374 return (mContext.checkCallingOrSelfPermission(SYSTEM_ALERT_WINDOW) 3375 == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED; 3376 } 3377 } 3378 3379 void readLidState() { 3380 mDefaultDisplayPolicy.setLidState(mWindowManagerFuncs.getLidState()); 3381 } 3382 3383 private void readCameraLensCoverState() { 3384 mCameraLensCoverState = mWindowManagerFuncs.getCameraLensCoverState(); 3385 } 3386 3387 private boolean isHidden(int accessibilityMode) { 3388 final int lidState = mDefaultDisplayPolicy.getLidState(); 3389 switch (accessibilityMode) { 3390 case 1: 3391 return lidState == LID_CLOSED; 3392 case 2: 3393 return lidState == LID_OPEN; 3394 default: 3395 return false; 3396 } 3397 } 3398 3399 /** {@inheritDoc} */ 3400 @Override 3401 public void adjustConfigurationLw(Configuration config, int keyboardPresence, 3402 int navigationPresence) { 3403 mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0; 3404 3405 readConfigurationDependentBehaviors(); 3406 readLidState(); 3407 3408 if (config.keyboard == Configuration.KEYBOARD_NOKEYS 3409 || (keyboardPresence == PRESENCE_INTERNAL 3410 && isHidden(mLidKeyboardAccessibility))) { 3411 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES; 3412 if (!mHasSoftInput) { 3413 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES; 3414 } 3415 } 3416 3417 if (config.navigation == Configuration.NAVIGATION_NONAV 3418 || (navigationPresence == PRESENCE_INTERNAL 3419 && isHidden(mLidNavigationAccessibility))) { 3420 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES; 3421 } 3422 } 3423 3424 @Override 3425 public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) { 3426 return attrs.type == TYPE_NOTIFICATION_SHADE; 3427 } 3428 3429 @Override 3430 public Animation createHiddenByKeyguardExit(boolean onWallpaper, 3431 boolean goingToNotificationShade, boolean subtleAnimation) { 3432 return TransitionAnimation.createHiddenByKeyguardExit(mContext, 3433 mLogDecelerateInterpolator, onWallpaper, goingToNotificationShade, subtleAnimation); 3434 } 3435 3436 3437 @Override 3438 public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) { 3439 if (goingToNotificationShade) { 3440 return null; 3441 } else { 3442 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit); 3443 } 3444 } 3445 3446 private static void awakenDreams() { 3447 IDreamManager dreamManager = getDreamManager(); 3448 if (dreamManager != null) { 3449 try { 3450 dreamManager.awaken(); 3451 } catch (RemoteException e) { 3452 // fine, stay asleep then 3453 } 3454 } 3455 } 3456 3457 static IDreamManager getDreamManager() { 3458 return IDreamManager.Stub.asInterface( 3459 ServiceManager.checkService(DreamService.DREAM_SERVICE)); 3460 } 3461 3462 TelecomManager getTelecommService() { 3463 return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 3464 } 3465 3466 NotificationManager getNotificationService() { 3467 return mContext.getSystemService(NotificationManager.class); 3468 } 3469 3470 static IAudioService getAudioService() { 3471 IAudioService audioService = IAudioService.Stub.asInterface( 3472 ServiceManager.checkService(Context.AUDIO_SERVICE)); 3473 if (audioService == null) { 3474 Log.w(TAG, "Unable to find IAudioService interface."); 3475 } 3476 return audioService; 3477 } 3478 3479 boolean keyguardOn() { 3480 return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode(); 3481 } 3482 3483 private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = { 3484 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 3485 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, 3486 }; 3487 3488 private void notifyKeyGestureCompletedOnActionUp(KeyEvent event, 3489 @KeyGestureEvent.KeyGestureType int gestureType) { 3490 if (event.getAction() != KeyEvent.ACTION_UP) { 3491 return; 3492 } 3493 notifyKeyGestureCompleted(event, gestureType); 3494 } 3495 3496 private void notifyKeyGestureCompletedOnActionDown(KeyEvent event, 3497 @KeyGestureEvent.KeyGestureType int gestureType) { 3498 if (event.getAction() != KeyEvent.ACTION_DOWN) { 3499 return; 3500 } 3501 notifyKeyGestureCompleted(event, gestureType); 3502 } 3503 3504 private void notifyKeyGestureCompleted(KeyEvent event, 3505 @KeyGestureEvent.KeyGestureType int gestureType) { 3506 if (gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED) { 3507 return; 3508 } 3509 mInputManagerInternal.notifyKeyGestureCompleted(event.getDeviceId(), 3510 new int[]{event.getKeyCode()}, event.getMetaState(), gestureType); 3511 } 3512 3513 private void handleKeyGestureInKeyGestureController( 3514 @KeyGestureEvent.KeyGestureType int gestureType, int deviceId, int keyCode, 3515 int metaState) { 3516 if (gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED) { 3517 return; 3518 } 3519 mInputManagerInternal.handleKeyGestureInKeyGestureController(deviceId, new int[]{keyCode}, 3520 metaState, gestureType); 3521 } 3522 3523 @Override 3524 public KeyboardShortcutGroup getApplicationLaunchKeyboardShortcuts(int deviceId) { 3525 if (useKeyGestureEventHandler()) { 3526 return mModifierShortcutManager.getApplicationLaunchKeyboardShortcuts(deviceId, 3527 mInputManager.getAppLaunchBookmarks()); 3528 } 3529 return mModifierShortcutManager.getApplicationLaunchKeyboardShortcuts(deviceId); 3530 } 3531 3532 // TODO(b/117479243): handle it in InputPolicy 3533 // TODO (b/283241997): Add the remaining keyboard shortcut logging after refactoring 3534 /** {@inheritDoc} */ 3535 @Override 3536 public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event, 3537 int policyFlags) { 3538 final int keyCode = event.getKeyCode(); 3539 final int flags = event.getFlags(); 3540 final long keyConsumed = -1; 3541 final long keyNotConsumed = 0; 3542 final int deviceId = event.getDeviceId(); 3543 3544 if (DEBUG_INPUT) { 3545 Log.d(TAG, 3546 "interceptKeyTi keyCode=" + keyCode + " action=" + event.getAction() 3547 + " repeatCount=" + event.getRepeatCount() + " keyguardOn=" 3548 + keyguardOn() + " canceled=" + event.isCanceled()); 3549 } 3550 3551 if (!InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures()) { 3552 if (mKeyCombinationManager.isKeyConsumed(event)) { 3553 return keyConsumed; 3554 } 3555 3556 if ((flags & KeyEvent.FLAG_FALLBACK) == 0) { 3557 final long now = SystemClock.uptimeMillis(); 3558 final long interceptTimeout = mKeyCombinationManager.getKeyInterceptTimeout( 3559 keyCode); 3560 if (now < interceptTimeout) { 3561 return interceptTimeout - now; 3562 } 3563 } 3564 } 3565 3566 Set<Integer> consumedKeys = mConsumedKeysForDevice.get(deviceId); 3567 if (consumedKeys == null) { 3568 consumedKeys = new HashSet<>(); 3569 mConsumedKeysForDevice.put(deviceId, consumedKeys); 3570 } 3571 3572 if (interceptSystemKeysAndShortcuts(focusedToken, event) 3573 && event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 3574 consumedKeys.add(keyCode); 3575 return keyConsumed; 3576 } 3577 3578 boolean needToConsumeKey = consumedKeys.contains(keyCode); 3579 if (event.getAction() == KeyEvent.ACTION_UP || event.isCanceled()) { 3580 consumedKeys.remove(keyCode); 3581 if (consumedKeys.isEmpty()) { 3582 mConsumedKeysForDevice.remove(deviceId); 3583 } 3584 } 3585 3586 return needToConsumeKey ? keyConsumed : keyNotConsumed; 3587 } 3588 3589 // You can only start consuming the key gesture if ACTION_DOWN and repeat count 3590 // is 0. If you start intercepting the key halfway, then key will not be consumed 3591 // and will be sent to apps for processing too. 3592 // e.g. If a certain combination is only handled on ACTION_UP (i.e. 3593 // interceptShortcut() returns true only for ACTION_UP), then since we already 3594 // sent the ACTION_DOWN events to the application, we MUST also send the 3595 // ACTION_UP to the application. 3596 // So, to ensure that your intercept logic works properly, and we don't send any 3597 // conflicting events to application, make sure to consume the event on 3598 // ACTION_DOWN even if you want to do something on ACTION_UP. This is essential 3599 // to maintain event parity and to not have incomplete key gestures. 3600 // 3601 // NOTE: Please try not to add new Shortcut combinations here and instead use KeyGestureEvents. 3602 // Add shortcut trigger logic in {@code KeyGestureController} and add handling logic in 3603 // {@link handleKeyGesture()} 3604 private boolean interceptSystemKeysAndShortcuts(IBinder focusedToken, KeyEvent event) { 3605 if (useKeyGestureEventHandler()) { 3606 return interceptSystemKeysAndShortcutsNew(focusedToken, event); 3607 } else { 3608 return interceptSystemKeysAndShortcutsOld(focusedToken, event); 3609 } 3610 } 3611 3612 @SuppressLint("MissingPermission") 3613 private boolean interceptSystemKeysAndShortcutsOld(IBinder focusedToken, KeyEvent event) { 3614 final boolean keyguardOn = keyguardOn(); 3615 final int keyCode = event.getKeyCode(); 3616 final int repeatCount = event.getRepeatCount(); 3617 final int metaState = event.getMetaState(); 3618 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 3619 final boolean canceled = event.isCanceled(); 3620 final int displayId = event.getDisplayId(); 3621 final int deviceId = event.getDeviceId(); 3622 final boolean firstDown = down && repeatCount == 0; 3623 3624 // Cancel any pending meta actions if we see any other keys being pressed between the 3625 // down of the meta key and its corresponding up. 3626 if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) { 3627 mPendingMetaAction = false; 3628 } 3629 // Any key that is not Alt or Meta cancels Caps Lock combo tracking. 3630 if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) { 3631 mPendingCapsLockToggle = false; 3632 } 3633 3634 if (isUserSetupComplete() && !keyguardOn) { 3635 if (mModifierShortcutManager.interceptKey(event)) { 3636 if (isKeyEventForCurrentUser( 3637 event.getDisplayId(), event.getKeyCode(), 3638 "dismissKeyboardShortcutsMenu")) { 3639 dismissKeyboardShortcutsMenu(); 3640 } 3641 mPendingMetaAction = false; 3642 mPendingCapsLockToggle = false; 3643 return true; 3644 } 3645 } 3646 3647 switch (keyCode) { 3648 case KeyEvent.KEYCODE_HOME: 3649 return handleHomeShortcuts(focusedToken, event); 3650 case KeyEvent.KEYCODE_RECENT_APPS: 3651 if (firstDown) { 3652 showRecentApps(false /* triggeredFromAltTab */); 3653 notifyKeyGestureCompleted(event, 3654 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS); 3655 } 3656 return true; 3657 case KeyEvent.KEYCODE_APP_SWITCH: 3658 if (!keyguardOn) { 3659 if (firstDown) { 3660 preloadRecentApps(); 3661 } else if (!down) { 3662 toggleRecentApps(); 3663 notifyKeyGestureCompleted(event, 3664 KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH); 3665 } 3666 } 3667 return true; 3668 case KeyEvent.KEYCODE_A: 3669 if (firstDown && event.isMetaPressed()) { 3670 launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, 3671 deviceId, event.getEventTime(), 3672 AssistUtils.INVOCATION_TYPE_UNKNOWN); 3673 notifyKeyGestureCompleted(event, 3674 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT); 3675 return true; 3676 } 3677 break; 3678 case KeyEvent.KEYCODE_H: 3679 case KeyEvent.KEYCODE_ENTER: 3680 if (event.isMetaPressed()) { 3681 return handleHomeShortcuts(focusedToken, event); 3682 } 3683 break; 3684 case KeyEvent.KEYCODE_I: 3685 if (firstDown && event.isMetaPressed() && isUserSetupComplete() && !keyguardOn) { 3686 showSystemSettings(); 3687 notifyKeyGestureCompleted(event, 3688 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS); 3689 return true; 3690 } 3691 break; 3692 case KeyEvent.KEYCODE_L: 3693 if (firstDown && event.isMetaPressed()) { 3694 lockNow(null /* options */); 3695 notifyKeyGestureCompleted(event, 3696 KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN); 3697 return true; 3698 } 3699 break; 3700 case KeyEvent.KEYCODE_N: 3701 if (firstDown && event.isMetaPressed()) { 3702 toggleNotificationPanel(); 3703 notifyKeyGestureCompleted(event, 3704 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL); 3705 return true; 3706 } 3707 break; 3708 case KeyEvent.KEYCODE_S: 3709 if (firstDown && event.isMetaPressed()) { 3710 interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/); 3711 notifyKeyGestureCompleted(event, 3712 KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT); 3713 return true; 3714 } 3715 break; 3716 case KeyEvent.KEYCODE_T: 3717 if (enableTalkbackAndMagnifierKeyGestures()) { 3718 if (firstDown && event.isMetaPressed() && event.isAltPressed()) { 3719 mTalkbackShortcutController.toggleTalkback(mCurrentUserId, 3720 TalkbackShortcutController.ShortcutSource.KEYBOARD); 3721 notifyKeyGestureCompleted(event, 3722 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK); 3723 return true; 3724 } 3725 } 3726 break; 3727 case KeyEvent.KEYCODE_3: 3728 if (keyboardA11yShortcutControl()) { 3729 if (firstDown && event.isMetaPressed() 3730 && event.isAltPressed()) { 3731 final boolean bounceKeysEnabled = 3732 InputSettings.isAccessibilityBounceKeysEnabled( 3733 mContext); 3734 InputSettings.setAccessibilityBounceKeysThreshold(mContext, 3735 bounceKeysEnabled ? 0 3736 : InputSettings.DEFAULT_BOUNCE_KEYS_THRESHOLD_MILLIS); 3737 notifyKeyGestureCompleted(event, 3738 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS); 3739 return true; 3740 } 3741 } 3742 break; 3743 case KeyEvent.KEYCODE_4: 3744 if (InputSettings.isAccessibilityMouseKeysFeatureFlagEnabled() 3745 && keyboardA11yShortcutControl()) { 3746 if (firstDown && event.isMetaPressed() && event.isAltPressed()) { 3747 final boolean mouseKeysEnabled = 3748 InputSettings.isAccessibilityMouseKeysEnabled( 3749 mContext); 3750 InputSettings.setAccessibilityMouseKeysEnabled(mContext, 3751 !mouseKeysEnabled); 3752 notifyKeyGestureCompleted(event, 3753 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS); 3754 return true; 3755 } 3756 } 3757 break; 3758 case KeyEvent.KEYCODE_5: 3759 if (keyboardA11yShortcutControl()) { 3760 if (firstDown && event.isMetaPressed() && event.isAltPressed()) { 3761 final boolean stickyKeysEnabled = 3762 InputSettings.isAccessibilityStickyKeysEnabled( 3763 mContext); 3764 InputSettings.setAccessibilityStickyKeysEnabled(mContext, 3765 !stickyKeysEnabled); 3766 notifyKeyGestureCompleted(event, 3767 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS); 3768 return true; 3769 } 3770 } 3771 break; 3772 case KeyEvent.KEYCODE_6: 3773 if (keyboardA11yShortcutControl()) { 3774 if (firstDown && event.isMetaPressed() && event.isAltPressed()) { 3775 final boolean slowKeysEnabled = 3776 InputSettings.isAccessibilitySlowKeysEnabled(mContext); 3777 InputSettings.setAccessibilitySlowKeysThreshold(mContext, 3778 slowKeysEnabled ? 0 3779 : InputSettings.DEFAULT_SLOW_KEYS_THRESHOLD_MILLIS); 3780 notifyKeyGestureCompleted(event, 3781 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS); 3782 return true; 3783 } 3784 } 3785 break; 3786 case KeyEvent.KEYCODE_DEL: 3787 if (newBugreportKeyboardShortcut()) { 3788 if (mEnableBugReportKeyboardShortcut && firstDown 3789 && event.isMetaPressed() && event.isCtrlPressed()) { 3790 try { 3791 if (!mActivityManagerService.launchBugReportHandlerApp()) { 3792 mActivityManagerService.requestInteractiveBugReport(); 3793 } 3794 } catch (RemoteException e) { 3795 Slog.d(TAG, "Error taking bugreport", e); 3796 } 3797 notifyKeyGestureCompleted(event, 3798 KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT); 3799 return true; 3800 } 3801 } 3802 break; 3803 case KeyEvent.KEYCODE_ESCAPE: 3804 if (firstDown && event.isMetaPressed()) { 3805 notifyKeyGestureCompleted(event, 3806 KeyGestureEvent.KEY_GESTURE_TYPE_BACK); 3807 injectBackGesture(event.getDownTime()); 3808 return true; 3809 } 3810 break; 3811 case KeyEvent.KEYCODE_DPAD_UP: 3812 if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) { 3813 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3814 if (statusbar != null) { 3815 statusbar.moveFocusedTaskToFullscreen(getTargetDisplayIdForKeyEvent(event)); 3816 notifyKeyGestureCompleted(event, 3817 KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION); 3818 return true; 3819 } 3820 } 3821 break; 3822 case KeyEvent.KEYCODE_DPAD_DOWN: 3823 if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) { 3824 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3825 if (statusbar != null) { 3826 statusbar.moveFocusedTaskToDesktop(getTargetDisplayIdForKeyEvent(event)); 3827 notifyKeyGestureCompleted(event, 3828 KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE); 3829 return true; 3830 } 3831 } 3832 break; 3833 case KeyEvent.KEYCODE_DPAD_LEFT: 3834 if (firstDown && event.isMetaPressed()) { 3835 if (event.isCtrlPressed()) { 3836 moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyEvent(event), 3837 true /* leftOrTop */); 3838 notifyKeyGestureCompleted(event, 3839 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT); 3840 } else { 3841 notifyKeyGestureCompleted(event, 3842 KeyGestureEvent.KEY_GESTURE_TYPE_BACK); 3843 injectBackGesture(event.getDownTime()); 3844 } 3845 return true; 3846 } 3847 break; 3848 case KeyEvent.KEYCODE_DPAD_RIGHT: 3849 if (firstDown && event.isMetaPressed()) { 3850 if (event.isCtrlPressed()) { 3851 moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyEvent(event), 3852 false /* leftOrTop */); 3853 notifyKeyGestureCompleted(event, 3854 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT); 3855 return true; 3856 } 3857 } 3858 break; 3859 case KeyEvent.KEYCODE_SLASH: 3860 if (firstDown && event.isMetaPressed() && !keyguardOn) { 3861 toggleKeyboardShortcutsMenu(event.getDeviceId()); 3862 notifyKeyGestureCompleted(event, 3863 KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER); 3864 return true; 3865 } 3866 break; 3867 case KeyEvent.KEYCODE_ASSIST: 3868 Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing"); 3869 return true; 3870 case KeyEvent.KEYCODE_VOICE_ASSIST: 3871 Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in" 3872 + " interceptKeyBeforeQueueing"); 3873 return true; 3874 case KeyEvent.KEYCODE_BRIGHTNESS_UP: 3875 case KeyEvent.KEYCODE_BRIGHTNESS_DOWN: 3876 if (down) { 3877 int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1; 3878 3879 changeDisplayBrightnessValue(displayId, direction); 3880 3881 int gestureType = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN 3882 ? KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN 3883 : KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP; 3884 notifyKeyGestureCompleted(event, gestureType); 3885 } 3886 return true; 3887 case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN: 3888 if (down) { 3889 mInputManagerInternal.decrementKeyboardBacklight(event.getDeviceId()); 3890 notifyKeyGestureCompleted(event, 3891 KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN); 3892 } 3893 return true; 3894 case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_UP: 3895 if (down) { 3896 mInputManagerInternal.incrementKeyboardBacklight(event.getDeviceId()); 3897 notifyKeyGestureCompleted(event, 3898 KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP); 3899 } 3900 return true; 3901 case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE: 3902 // TODO: Add logic 3903 if (!down) { 3904 notifyKeyGestureCompleted(event, 3905 KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE); 3906 } 3907 return true; 3908 case KeyEvent.KEYCODE_VOLUME_UP: 3909 case KeyEvent.KEYCODE_VOLUME_DOWN: 3910 case KeyEvent.KEYCODE_VOLUME_MUTE: 3911 if (mUseTvRouting || mHandleVolumeKeysInWM) { 3912 // On TVs or when the configuration is enabled, volume keys never 3913 // go to the foreground app. 3914 dispatchDirectAudioEvent(event); 3915 return true; 3916 } 3917 3918 // If the device is in VR mode and keys are "internal" (e.g. on the side of the 3919 // device), then drop the volume keys and don't forward it to the 3920 // application/dispatch the audio event. 3921 if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) { 3922 final InputDevice d = event.getDevice(); 3923 if (d != null && !d.isExternal()) { 3924 return true; 3925 } 3926 } 3927 break; 3928 case KeyEvent.KEYCODE_TAB: 3929 if (firstDown && !keyguardOn && isUserSetupComplete()) { 3930 if (event.isMetaPressed()) { 3931 showRecentApps(false); 3932 notifyKeyGestureCompleted(event, 3933 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS); 3934 return true; 3935 } else if (mRecentAppsHeldModifiers == 0) { 3936 final int shiftlessModifiers = 3937 event.getModifiers() & ~KeyEvent.META_SHIFT_MASK; 3938 if (KeyEvent.metaStateHasModifiers( 3939 shiftlessModifiers, KeyEvent.META_ALT_ON)) { 3940 mRecentAppsHeldModifiers = shiftlessModifiers; 3941 showRecentApps(true); 3942 notifyKeyGestureCompleted(event, 3943 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS); 3944 return true; 3945 } 3946 } 3947 } 3948 break; 3949 case KeyEvent.KEYCODE_ALL_APPS: 3950 if (firstDown) { 3951 mHandler.removeMessages(MSG_HANDLE_ALL_APPS); 3952 Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS, new KeyEvent(event)); 3953 msg.setAsynchronous(true); 3954 msg.sendToTarget(); 3955 3956 notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS); 3957 } 3958 return true; 3959 case KeyEvent.KEYCODE_NOTIFICATION: 3960 if (!down) { 3961 toggleNotificationPanel(); 3962 notifyKeyGestureCompleted(event, 3963 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL); 3964 } 3965 return true; 3966 case KeyEvent.KEYCODE_SEARCH: 3967 if (firstDown && !keyguardOn) { 3968 switch (mSearchKeyBehavior) { 3969 case SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY: { 3970 launchTargetSearchActivity(); 3971 notifyKeyGestureCompleted(event, 3972 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH); 3973 return true; 3974 } 3975 case SEARCH_KEY_BEHAVIOR_DEFAULT_SEARCH: 3976 default: 3977 break; 3978 } 3979 } 3980 break; 3981 case KeyEvent.KEYCODE_LANGUAGE_SWITCH: 3982 if (firstDown) { 3983 int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1; 3984 sendSwitchKeyboardLayout(displayId, focusedToken, direction); 3985 notifyKeyGestureCompleted(event, 3986 KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH); 3987 return true; 3988 } 3989 break; 3990 case KeyEvent.KEYCODE_META_LEFT: 3991 case KeyEvent.KEYCODE_META_RIGHT: 3992 if (down) { 3993 if (event.isAltPressed()) { 3994 mPendingCapsLockToggle = true; 3995 mPendingMetaAction = false; 3996 } else { 3997 mPendingCapsLockToggle = false; 3998 mPendingMetaAction = true; 3999 } 4000 } else { 4001 // Toggle Caps Lock on META-ALT. 4002 if (mPendingCapsLockToggle) { 4003 mInputManagerInternal.toggleCapsLock(event.getDeviceId()); 4004 mPendingCapsLockToggle = false; 4005 notifyKeyGestureCompleted(event, 4006 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK); 4007 } else if (mPendingMetaAction) { 4008 if (!canceled) { 4009 if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(), 4010 "launchAllAppsViaA11y")) { 4011 launchAllAppsAction(); 4012 } 4013 notifyKeyGestureCompleted(event, 4014 KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS); 4015 } 4016 mPendingMetaAction = false; 4017 } 4018 } 4019 return true; 4020 case KeyEvent.KEYCODE_ALT_LEFT: 4021 case KeyEvent.KEYCODE_ALT_RIGHT: 4022 if (down) { 4023 if (event.isMetaPressed()) { 4024 mPendingCapsLockToggle = true; 4025 mPendingMetaAction = false; 4026 } else { 4027 mPendingCapsLockToggle = false; 4028 } 4029 } else { 4030 // hide recent if triggered by ALT-TAB. 4031 if (mRecentAppsHeldModifiers != 0 4032 && (metaState & mRecentAppsHeldModifiers) == 0) { 4033 mRecentAppsHeldModifiers = 0; 4034 hideRecentApps(true, false); 4035 return true; 4036 } 4037 4038 // Toggle Caps Lock on META-ALT. 4039 if (mPendingCapsLockToggle) { 4040 mInputManagerInternal.toggleCapsLock(event.getDeviceId()); 4041 mPendingCapsLockToggle = false; 4042 notifyKeyGestureCompleted(event, 4043 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK); 4044 return true; 4045 } 4046 } 4047 break; 4048 case KeyEvent.KEYCODE_CAPS_LOCK: 4049 if (!down) { 4050 notifyKeyGestureCompleted(event, 4051 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK); 4052 } 4053 break; 4054 case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY: 4055 case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY: 4056 case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY: 4057 case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL: 4058 Slog.wtf(TAG, "KEYCODE_STYLUS_BUTTON_* should be handled in" 4059 + " interceptKeyBeforeQueueing"); 4060 return true; 4061 case KeyEvent.KEYCODE_SETTINGS: 4062 if (firstDown) { 4063 if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL) { 4064 toggleNotificationPanel(); 4065 notifyKeyGestureCompleted(event, 4066 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL); 4067 } else if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY) { 4068 showSystemSettings(); 4069 notifyKeyGestureCompleted(event, 4070 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS); 4071 } 4072 } 4073 return true; 4074 case KeyEvent.KEYCODE_STEM_PRIMARY: 4075 if (prepareToSendSystemKeyToApplication(focusedToken, event)) { 4076 // Send to app. 4077 return false; 4078 } else { 4079 // Intercepted. 4080 sendSystemKeyToStatusBarAsync(event); 4081 return true; 4082 } 4083 case KeyEvent.KEYCODE_SCREENSHOT: 4084 if (firstDown) { 4085 interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/); 4086 } 4087 return true; 4088 case KeyEvent.KEYCODE_DO_NOT_DISTURB: 4089 case KeyEvent.KEYCODE_LOCK: 4090 case KeyEvent.KEYCODE_FULLSCREEN: 4091 return true; 4092 } 4093 if (isValidGlobalKey(keyCode) 4094 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) { 4095 return true; 4096 } 4097 4098 // Reserve all the META modifier combos for system behavior 4099 return (metaState & KeyEvent.META_META_ON) != 0; 4100 } 4101 4102 private boolean interceptSystemKeysAndShortcutsNew(IBinder focusedToken, KeyEvent event) { 4103 final int keyCode = event.getKeyCode(); 4104 final int metaState = event.getMetaState(); 4105 4106 switch (keyCode) { 4107 case KeyEvent.KEYCODE_HOME: 4108 return handleHomeShortcuts(focusedToken, event); 4109 case KeyEvent.KEYCODE_VOLUME_UP: 4110 case KeyEvent.KEYCODE_VOLUME_DOWN: 4111 case KeyEvent.KEYCODE_VOLUME_MUTE: 4112 if (mUseTvRouting || mHandleVolumeKeysInWM) { 4113 // On TVs or when the configuration is enabled, volume keys never 4114 // go to the foreground app. 4115 dispatchDirectAudioEvent(event); 4116 return true; 4117 } 4118 4119 // If the device is in VR mode and keys are "internal" (e.g. on the side of the 4120 // device), then drop the volume keys and don't forward it to the 4121 // application/dispatch the audio event. 4122 if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) { 4123 final InputDevice d = event.getDevice(); 4124 if (d != null && !d.isExternal()) { 4125 return true; 4126 } 4127 } 4128 break; 4129 case KeyEvent.KEYCODE_STEM_PRIMARY: 4130 if (prepareToSendSystemKeyToApplication(focusedToken, event)) { 4131 // Send to app. 4132 return false; 4133 } else { 4134 // Intercepted. 4135 sendSystemKeyToStatusBarAsync(event); 4136 return true; 4137 } 4138 } 4139 if (isValidGlobalKey(keyCode) 4140 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) { 4141 return true; 4142 } 4143 4144 if (fixSearchModifierFallbacks()) { 4145 // Pass event as unhandled to give other services, e.g. InputManagerService, the 4146 // opportunity to determine if the event can be modified, e.g. generating a fallback for 4147 // meta/search events. 4148 return false; 4149 } 4150 4151 // Reserve all the META modifier combos for system behavior 4152 return (metaState & KeyEvent.META_META_ON) != 0; 4153 } 4154 4155 @SuppressLint("MissingPermission") 4156 private void initKeyGestures() { 4157 if (!useKeyGestureEventHandler()) { 4158 return; 4159 } 4160 List<Integer> supportedGestures = new ArrayList<>(List.of( 4161 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS, 4162 KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH, 4163 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT, 4164 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT, 4165 KeyGestureEvent.KEY_GESTURE_TYPE_HOME, 4166 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS, 4167 KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN, 4168 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL, 4169 KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT, 4170 KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT, 4171 KeyGestureEvent.KEY_GESTURE_TYPE_BACK, 4172 KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION, 4173 KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE, 4174 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT, 4175 KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT, 4176 KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER, 4177 KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP, 4178 KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN, 4179 KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER, 4180 KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS, 4181 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH, 4182 KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH, 4183 KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT, 4184 KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS, 4185 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION, 4186 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB, 4187 KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD, 4188 KeyGestureEvent.KEY_GESTURE_TYPE_RINGER_TOGGLE_CHORD, 4189 KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS, 4190 KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT 4191 )); 4192 if (enableTalkbackAndMagnifierKeyGestures()) { 4193 supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK); 4194 } 4195 if (enableVoiceAccessKeyGestures()) { 4196 supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS); 4197 } 4198 mInputManager.registerKeyGestureEventHandler(supportedGestures, 4199 PhoneWindowManager.this::handleKeyGestureEvent); 4200 } 4201 4202 @VisibleForTesting 4203 void handleKeyGestureEvent(KeyGestureEvent event, IBinder focusedToken) { 4204 boolean start = event.getAction() == KeyGestureEvent.ACTION_GESTURE_START; 4205 boolean complete = event.getAction() == KeyGestureEvent.ACTION_GESTURE_COMPLETE 4206 && !event.isCancelled(); 4207 int deviceId = event.getDeviceId(); 4208 int gestureType = event.getKeyGestureType(); 4209 int displayId = event.getDisplayId(); 4210 int modifierState = event.getModifierState(); 4211 boolean keyguardOn = keyguardOn(); 4212 boolean canLaunchApp = isUserSetupComplete() && !keyguardOn; 4213 if (!event.isCancelled() && Arrays.stream(event.getKeycodes()).anyMatch( 4214 (keycode) -> keycode == KeyEvent.KEYCODE_POWER)) { 4215 mPowerKeyHandled = true; 4216 } 4217 switch (gestureType) { 4218 case KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS: 4219 if (complete) { 4220 showRecentApps(false); 4221 } 4222 break; 4223 case KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH: 4224 if (!keyguardOn) { 4225 if (start) { 4226 preloadRecentApps(); 4227 } else if (complete) { 4228 toggleRecentApps(); 4229 } 4230 } 4231 break; 4232 case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT: 4233 case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT: 4234 if (complete && canLaunchApp) { 4235 launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, 4236 deviceId, SystemClock.uptimeMillis(), 4237 AssistUtils.INVOCATION_TYPE_UNKNOWN); 4238 } 4239 break; 4240 case KeyGestureEvent.KEY_GESTURE_TYPE_HOME: 4241 if (complete) { 4242 // Post to main thread to avoid blocking input pipeline. 4243 mHandler.post(() -> handleShortPressOnHome(displayId)); 4244 } 4245 break; 4246 case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS: 4247 if (complete && canLaunchApp) { 4248 showSystemSettings(); 4249 } 4250 break; 4251 case KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN: 4252 if (complete) { 4253 lockNow(null /* options */); 4254 } 4255 break; 4256 case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL: 4257 if (complete) { 4258 toggleNotificationPanel(); 4259 } 4260 break; 4261 case KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT: 4262 if (complete) { 4263 interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/); 4264 } 4265 break; 4266 case KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT: 4267 if (complete && mEnableBugReportKeyboardShortcut) { 4268 try { 4269 if (!mActivityManagerService.launchBugReportHandlerApp()) { 4270 mActivityManagerService.requestInteractiveBugReport(); 4271 } 4272 } catch (RemoteException e) { 4273 Slog.d(TAG, "Error taking bugreport", e); 4274 } 4275 } 4276 break; 4277 case KeyGestureEvent.KEY_GESTURE_TYPE_BACK: 4278 if (complete) { 4279 injectBackGesture(SystemClock.uptimeMillis()); 4280 } 4281 break; 4282 case KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION: 4283 if (complete) { 4284 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4285 if (statusbar != null) { 4286 statusbar.moveFocusedTaskToFullscreen( 4287 getTargetDisplayIdForKeyGestureEvent(event)); 4288 } 4289 } 4290 break; 4291 case KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE: 4292 if (complete) { 4293 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4294 if (statusbar != null) { 4295 statusbar.moveFocusedTaskToDesktop( 4296 getTargetDisplayIdForKeyGestureEvent(event)); 4297 } 4298 } 4299 break; 4300 case KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT: 4301 if (complete) { 4302 moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyGestureEvent(event), 4303 true /* leftOrTop */); 4304 } 4305 break; 4306 case KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT: 4307 if (complete) { 4308 moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyGestureEvent(event), 4309 false /* leftOrTop */); 4310 } 4311 break; 4312 case KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER: 4313 if (complete) { 4314 toggleKeyboardShortcutsMenu(deviceId); 4315 } 4316 break; 4317 case KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP: 4318 case KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN: 4319 if (complete) { 4320 int direction = 4321 gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP ? 1 : -1; 4322 changeDisplayBrightnessValue(displayId, direction); 4323 } 4324 break; 4325 case KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER: 4326 if (start) { 4327 showRecentApps(true); 4328 } else { 4329 hideRecentApps(true, false); 4330 } 4331 break; 4332 case KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS: 4333 if (complete && isKeyEventForCurrentUser(event.getDisplayId(), 4334 event.getKeycodes()[0], "launchAllAppsViaA11y")) { 4335 launchAllAppsAction(); 4336 } 4337 break; 4338 case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH: 4339 if (complete && canLaunchApp) { 4340 launchTargetSearchActivity(); 4341 } 4342 break; 4343 case KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH: 4344 if (complete) { 4345 int direction = (modifierState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1; 4346 sendSwitchKeyboardLayout(displayId, focusedToken, direction); 4347 } 4348 break; 4349 case KeyGestureEvent.KEY_GESTURE_TYPE_SCREENSHOT_CHORD: 4350 if (start) { 4351 // Screenshot chord is pressed: Wait for long press delay before taking 4352 // screenshot 4353 interceptScreenshotChord(SCREENSHOT_KEY_CHORD, 4354 getScreenshotChordLongPressDelay()); 4355 } else { 4356 cancelPendingScreenshotChordAction(); 4357 } 4358 break; 4359 case KeyGestureEvent.KEY_GESTURE_TYPE_RINGER_TOGGLE_CHORD: 4360 if (start) { 4361 interceptRingerToggleChord(); 4362 } else { 4363 cancelPendingRingerToggleChordAction(); 4364 } 4365 break; 4366 case KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS: 4367 if (start) { 4368 performHapticFeedback( 4369 HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON, 4370 "KEY_GESTURE_TYPE_GLOBAL_ACTIONS - Global Actions"); 4371 showGlobalActions(); 4372 } else { 4373 cancelGlobalActionsAction(); 4374 } 4375 break; 4376 case KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT: 4377 if (start) { 4378 interceptBugreportGestureTv(); 4379 } else { 4380 cancelBugreportGestureTv(); 4381 } 4382 break; 4383 case KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT: 4384 if (complete && mAccessibilityShortcutController.isAccessibilityShortcutAvailable( 4385 isKeyguardLocked())) { 4386 mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT)); 4387 } 4388 break; 4389 case KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS: 4390 if (complete) { 4391 mContext.closeSystemDialogs(); 4392 } 4393 break; 4394 case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK: 4395 if (complete) { 4396 mTalkbackShortcutController.toggleTalkback(mCurrentUserId, 4397 TalkbackShortcutController.ShortcutSource.KEYBOARD); 4398 } 4399 break; 4400 case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS: 4401 if (complete) { 4402 mVoiceAccessShortcutController.toggleVoiceAccess(mCurrentUserId); 4403 } 4404 break; 4405 case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION: 4406 AppLaunchData data = event.getAppLaunchData(); 4407 if (complete && canLaunchApp && data != null 4408 && mModifierShortcutManager.launchApplication(data)) { 4409 dismissKeyboardShortcutsMenu(); 4410 } 4411 break; 4412 case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB: 4413 NotificationManager nm = getNotificationService(); 4414 if (nm != null) { 4415 boolean isEnabled = nm.getZenMode() != Settings.Global.ZEN_MODE_OFF; 4416 nm.setZenMode(isEnabled ? Settings.Global.ZEN_MODE_OFF 4417 : Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, 4418 "Key gesture DND", true); 4419 } 4420 break; 4421 default: 4422 Log.w(TAG, "Received a key gesture " + event 4423 + " that was not registered by this handler"); 4424 break; 4425 } 4426 } 4427 4428 private void changeDisplayBrightnessValue(int displayId, int direction) { 4429 int screenDisplayId = displayId < 0 ? DEFAULT_DISPLAY : displayId; 4430 4431 float minLinearBrightness = mPowerManager.getBrightnessConstraint( 4432 screenDisplayId, PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); 4433 float maxLinearBrightness = mPowerManager.getBrightnessConstraint( 4434 screenDisplayId, PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); 4435 float linearBrightness = mDisplayManager.getBrightness(screenDisplayId); 4436 4437 float gammaBrightness = BrightnessUtils.convertLinearToGamma(linearBrightness); 4438 float adjustedGammaBrightness = gammaBrightness + 1f / BRIGHTNESS_STEPS * direction; 4439 adjustedGammaBrightness = MathUtils.constrain(adjustedGammaBrightness, 0f, 1f); 4440 float adjustedLinearBrightness = BrightnessUtils.convertGammaToLinear( 4441 adjustedGammaBrightness); 4442 adjustedLinearBrightness = MathUtils.constrain(adjustedLinearBrightness, 4443 minLinearBrightness, maxLinearBrightness); 4444 mDisplayManager.setBrightness(screenDisplayId, adjustedLinearBrightness); 4445 4446 Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG); 4447 intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION 4448 | Intent.FLAG_ACTIVITY_NO_USER_ACTION); 4449 intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true); 4450 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 4451 } 4452 4453 /** 4454 * In this function, we check whether a system key should be sent to the application. We also 4455 * detect the key gesture on this key, even if the key will be sent to the app. The gesture 4456 * action, if any, will not be executed immediately. It will be queued and execute only after 4457 * the application tells us that it didn't handle this key. 4458 * 4459 * @return true if this key should be sent to the application. This also means that the target 4460 * application has the necessary permissions to receive this key. Return false otherwise. 4461 */ 4462 private boolean prepareToSendSystemKeyToApplication(IBinder focusedToken, KeyEvent event) { 4463 final int keyCode = event.getKeyCode(); 4464 if (!event.isSystem()) { 4465 Log.wtf( 4466 TAG, 4467 "Illegal keycode provided to prepareToSendSystemKeyToApplication: " 4468 + KeyEvent.keyCodeToString(keyCode)); 4469 return false; 4470 } 4471 final boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN; 4472 if (isDown && event.getRepeatCount() == 0) { 4473 // This happens at the initial DOWN event. Check focused window permission now. 4474 final KeyInterceptionInfo info = 4475 mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken); 4476 if (info != null 4477 && mButtonOverridePermissionChecker.canAppOverrideSystemKey( 4478 mContext, info.windowOwnerUid)) { 4479 // Focused window has the permission. Pass the event to it. 4480 return true; 4481 } else { 4482 // Focused window doesn't have the permission. Intercept the event. 4483 // If the initial DOWN event is intercepted, follow-up events will be intercepted 4484 // too. So we know the gesture won't be handled by app, and can handle the gesture 4485 // in system. 4486 setDeferredKeyActionsExecutableAsync(keyCode, event.getDownTime()); 4487 return false; 4488 } 4489 } else { 4490 // This happens after the initial DOWN event. We will just reuse the initial decision. 4491 // I.e., if the initial DOWN event was dispatched, follow-up events should be 4492 // dispatched. Otherwise, follow-up events should be consumed. 4493 final Set<Integer> consumedKeys = mConsumedKeysForDevice.get(event.getDeviceId()); 4494 final boolean wasConsumed = consumedKeys != null && consumedKeys.contains(keyCode); 4495 return !wasConsumed; 4496 } 4497 } 4498 4499 private void setDeferredKeyActionsExecutableAsync(int keyCode, long downTime) { 4500 Message msg = Message.obtain(mHandler, MSG_SET_DEFERRED_KEY_ACTIONS_EXECUTABLE); 4501 msg.arg1 = keyCode; 4502 msg.obj = downTime; 4503 msg.setAsynchronous(true); 4504 msg.sendToTarget(); 4505 } 4506 4507 @SuppressLint("MissingPermission") 4508 private void injectBackGesture(long downtime) { 4509 if (mActivityTaskManagerInternal.requestBackGesture()) { 4510 return; 4511 } 4512 // Create and inject down event 4513 KeyEvent downEvent = new KeyEvent(downtime, downtime, KeyEvent.ACTION_DOWN, 4514 KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */, 4515 KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */, 4516 KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, 4517 InputDevice.SOURCE_KEYBOARD); 4518 mInputManager.injectInputEvent(downEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 4519 4520 4521 // Create and inject up event 4522 KeyEvent upEvent = KeyEvent.changeAction(downEvent, KeyEvent.ACTION_UP); 4523 mInputManager.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); 4524 4525 downEvent.recycle(); 4526 upEvent.recycle(); 4527 } 4528 4529 private boolean handleHomeShortcuts(IBinder focusedToken, KeyEvent event) { 4530 // First we always handle the home key here, so applications 4531 // can never break it, although if keyguard is on, we do let 4532 // it handle it, because that gives us the correct 5 second 4533 // timeout. 4534 DisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(event.getDisplayId()); 4535 if (handler == null) { 4536 handler = new DisplayHomeButtonHandler(event.getDisplayId()); 4537 mDisplayHomeButtonHandlers.put(event.getDisplayId(), handler); 4538 } 4539 return handler.handleHomeButton(focusedToken, event); 4540 } 4541 4542 private void toggleMicrophoneMuteFromKey() { 4543 if (mSensorPrivacyManager.supportsSensorToggle( 4544 SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, 4545 SensorPrivacyManager.Sensors.MICROPHONE)) { 4546 boolean isEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled( 4547 SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, 4548 SensorPrivacyManager.Sensors.MICROPHONE); 4549 4550 mSensorPrivacyManager.setSensorPrivacy(SensorPrivacyToggleSourceProto.OTHER, 4551 SensorPrivacyManager.Sensors.MICROPHONE, !isEnabled, mCurrentUserId); 4552 4553 int toastTextResId; 4554 if (isEnabled) { 4555 toastTextResId = R.string.mic_access_on_toast; 4556 } else { 4557 toastTextResId = R.string.mic_access_off_toast; 4558 } 4559 4560 Toast.makeText( 4561 mContext, 4562 UiThread.get().getLooper(), 4563 mContext.getString(toastTextResId), 4564 Toast.LENGTH_SHORT) 4565 .show(); 4566 } 4567 } 4568 4569 /** 4570 * TV only: recognizes a remote control gesture for capturing a bug report. 4571 */ 4572 private void interceptBugreportGestureTv() { 4573 mHandler.removeMessages(MSG_BUGREPORT_TV); 4574 // The bugreport capture chord is a long press on DPAD CENTER and BACK simultaneously. 4575 Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV); 4576 msg.setAsynchronous(true); 4577 mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS); 4578 } 4579 4580 private void cancelBugreportGestureTv() { 4581 mHandler.removeMessages(MSG_BUGREPORT_TV); 4582 } 4583 4584 /** 4585 * TV only: recognizes a remote control gesture as Accessibility shortcut. 4586 * Shortcut: Long press (BACK + DPAD_DOWN) 4587 */ 4588 private void interceptAccessibilityGestureTv() { 4589 mHandler.removeMessages(MSG_ACCESSIBILITY_TV); 4590 Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV); 4591 msg.setAsynchronous(true); 4592 mHandler.sendMessageDelayed(msg, getAccessibilityShortcutTimeout()); 4593 } 4594 private void cancelAccessibilityGestureTv() { 4595 mHandler.removeMessages(MSG_ACCESSIBILITY_TV); 4596 } 4597 4598 @VisibleForTesting 4599 void requestBugreportForTv() { 4600 try { 4601 if (!ActivityManager.getService().launchBugReportHandlerApp()) { 4602 ActivityManager.getService().requestInteractiveBugReport(); 4603 } 4604 } catch (RemoteException e) { 4605 Slog.e(TAG, "Error taking bugreport", e); 4606 } 4607 } 4608 4609 // TODO(b/117479243): handle it in InputPolicy 4610 /** {@inheritDoc} */ 4611 @Override 4612 public boolean interceptUnhandledKey(KeyEvent event, IBinder focusedToken) { 4613 // Note: This method is only called if the initial down was unhandled. 4614 if (DEBUG_INPUT) { 4615 final KeyInterceptionInfo info = 4616 mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken); 4617 final String title = info == null ? "<unknown>" : info.windowTitle; 4618 Slog.d(TAG, "Unhandled key: inputToken=" + focusedToken 4619 + ", title=" + title 4620 + ", action=" + event.getAction() 4621 + ", flags=" + event.getFlags() 4622 + ", keyCode=" + event.getKeyCode() 4623 + ", scanCode=" + event.getScanCode() 4624 + ", metaState=" + event.getMetaState() 4625 + ", repeatCount=" + event.getRepeatCount()); 4626 } 4627 4628 final int keyCode = event.getKeyCode(); 4629 final int repeatCount = event.getRepeatCount(); 4630 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 4631 final int metaState = event.getModifiers(); 4632 4633 // TODO(b/358569822): Shift to KeyGestureEvent based handling 4634 if (keyCode == KeyEvent.KEYCODE_STEM_PRIMARY) { 4635 handleUnhandledSystemKey(event); 4636 sendSystemKeyToStatusBarAsync(event); 4637 return true; 4638 } 4639 4640 if (useKeyGestureEventHandler()) { 4641 return false; 4642 } 4643 4644 switch (keyCode) { 4645 case KeyEvent.KEYCODE_SPACE: 4646 if (down && repeatCount == 0) { 4647 // Handle keyboard layout switching. (CTRL + SPACE) 4648 if (KeyEvent.metaStateHasModifiers(metaState & ~KeyEvent.META_SHIFT_MASK, 4649 KeyEvent.META_CTRL_ON)) { 4650 int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1; 4651 sendSwitchKeyboardLayout(event.getDisplayId(), focusedToken, direction); 4652 return true; 4653 } 4654 } 4655 break; 4656 case KeyEvent.KEYCODE_Z: 4657 if (down && KeyEvent.metaStateHasModifiers(metaState, 4658 KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON)) { 4659 // Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users. 4660 if (mAccessibilityShortcutController 4661 .isAccessibilityShortcutAvailable(isKeyguardLocked())) { 4662 mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT)); 4663 return true; 4664 } 4665 } 4666 break; 4667 case KeyEvent.KEYCODE_SYSRQ: 4668 if (down && repeatCount == 0) { 4669 interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/); 4670 return true; 4671 } 4672 break; 4673 case KeyEvent.KEYCODE_ESCAPE: 4674 if (down 4675 && KeyEvent.metaStateHasNoModifiers(metaState) 4676 && repeatCount == 0) { 4677 mContext.closeSystemDialogs(); 4678 return true; 4679 } 4680 break; 4681 } 4682 4683 return false; 4684 } 4685 4686 /** 4687 * Called when a system key was sent to application and was unhandled. We will execute any 4688 * queued actions associated with this key code at this point. 4689 */ 4690 private void handleUnhandledSystemKey(KeyEvent event) { 4691 if (!event.isSystem()) { 4692 Log.wtf( 4693 TAG, 4694 "Illegal keycode provided to handleUnhandledSystemKey: " 4695 + KeyEvent.keyCodeToString(event.getKeyCode())); 4696 return; 4697 } 4698 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 4699 // If the initial DOWN event is unhandled by app, follow-up events will also be 4700 // unhandled by app. So we can handle the key event in system. 4701 setDeferredKeyActionsExecutableAsync(event.getKeyCode(), event.getDownTime()); 4702 } 4703 } 4704 4705 private void sendSwitchKeyboardLayout(int displayId, @Nullable IBinder focusedToken, 4706 int direction) { 4707 SwitchKeyboardLayoutMessageObject object = 4708 new SwitchKeyboardLayoutMessageObject(displayId, focusedToken, direction); 4709 mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, object).sendToTarget(); 4710 } 4711 4712 private void handleSwitchKeyboardLayout(int displayId, int direction, IBinder focusedToken) { 4713 IBinder targetWindowToken = 4714 mWindowManagerInternal.getTargetWindowTokenFromInputToken(focusedToken); 4715 InputMethodManagerInternal.get().onSwitchKeyboardLayoutShortcut(direction, displayId, 4716 targetWindowToken); 4717 } 4718 4719 @Override 4720 public void setTopFocusedDisplay(int displayId) { 4721 mTopFocusedDisplayId = displayId; 4722 } 4723 4724 @Override 4725 public void registerDisplayFoldListener(IDisplayFoldListener listener) { 4726 if (mDisplayFoldController != null) { 4727 mDisplayFoldController.registerDisplayFoldListener(listener); 4728 } 4729 } 4730 4731 @Override 4732 public void unregisterDisplayFoldListener(IDisplayFoldListener listener) { 4733 if (mDisplayFoldController != null) { 4734 mDisplayFoldController.unregisterDisplayFoldListener(listener); 4735 } 4736 } 4737 4738 @Override 4739 public void setOverrideFoldedArea(Rect area) { 4740 if (mDisplayFoldController != null) { 4741 mDisplayFoldController.setOverrideFoldedArea(area); 4742 } 4743 } 4744 4745 @Override 4746 public Rect getFoldedArea() { 4747 if (mDisplayFoldController != null) { 4748 return mDisplayFoldController.getFoldedArea(); 4749 } 4750 return new Rect(); 4751 } 4752 4753 @Override 4754 public void onDefaultDisplayFocusChangedLw(WindowState newFocus) { 4755 if (mDisplayFoldController != null) { 4756 mDisplayFoldController.onDefaultDisplayFocusChanged( 4757 newFocus != null ? newFocus.getOwningPackage() : null); 4758 } 4759 } 4760 4761 @Override 4762 public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService) 4763 throws RemoteException { 4764 synchronized (mLock) { 4765 if (useKeyGestureEventHandler()) { 4766 mInputManagerInternal.registerShortcutKey(shortcutCode, shortcutService); 4767 return; 4768 } 4769 mModifierShortcutManager.registerShortcutKey(shortcutCode, shortcutService); 4770 } 4771 } 4772 4773 @Override 4774 public void onKeyguardOccludedChangedLw(boolean occluded) { 4775 if (mKeyguardDelegate != null) { 4776 mPendingKeyguardOccluded = occluded; 4777 mKeyguardOccludedChanged = true; 4778 } 4779 } 4780 4781 @Override 4782 public int applyKeyguardOcclusionChange() { 4783 if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded commit occluded=" 4784 + mPendingKeyguardOccluded + " changed=" + mKeyguardOccludedChanged); 4785 4786 // TODO(b/276433230): Explicitly save before/after for occlude state in each 4787 // Transition so we don't need to update SysUI every time. 4788 if (setKeyguardOccludedLw(mPendingKeyguardOccluded)) { 4789 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER; 4790 } else { 4791 return 0; 4792 } 4793 } 4794 4795 /** 4796 * Called when keyguard related app transition starts, or cancelled. 4797 * 4798 * @param startKeyguardExitAnimation Trigger IKeyguardService#startKeyguardExitAnimation to 4799 * start keyguard exit animation. 4800 * @param notifyOccluded Trigger IKeyguardService#setOccluded binder call to notify whether 4801 * the top activity can occlude the keyguard or not. 4802 * 4803 * @return Whether the flags have changed and we have to redo the layout. 4804 */ 4805 private int handleTransitionForKeyguardLw(boolean startKeyguardExitAnimation, 4806 boolean notifyOccluded) { 4807 int redoLayout = 0; 4808 if (notifyOccluded) { 4809 redoLayout = applyKeyguardOcclusionChange(); 4810 } 4811 if (startKeyguardExitAnimation) { 4812 if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation"); 4813 startKeyguardExitAnimation(SystemClock.uptimeMillis()); 4814 } 4815 return redoLayout; 4816 } 4817 4818 /** 4819 * Shows the keyguard without immediately locking the device. 4820 */ 4821 @Override 4822 public void showDismissibleKeyguard() { 4823 mKeyguardDelegate.showDismissibleKeyguard(); 4824 } 4825 4826 // There are several different flavors of "assistant" that can be launched from 4827 // various parts of the UI. 4828 4829 /** Asks the status bar to startAssist(), usually a full "assistant" interface */ 4830 private void launchAssistAction(String hint, int deviceId, long eventTime, 4831 int invocationType) { 4832 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 4833 if (!isUserSetupComplete()) { 4834 // Disable opening assist window during setup 4835 return; 4836 } 4837 4838 // Add Intent Extra data. 4839 Bundle args = null; 4840 args = new Bundle(); 4841 if (deviceId != INVALID_INPUT_DEVICE_ID) { 4842 args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, deviceId); 4843 } 4844 if (hint != null) { 4845 args.putBoolean(hint, true); 4846 } 4847 args.putLong(Intent.EXTRA_TIME, eventTime); 4848 args.putInt(AssistUtils.INVOCATION_TYPE_KEY, invocationType); 4849 4850 SearchManager searchManager = mContext.getSystemService(SearchManager.class); 4851 if (searchManager != null) { 4852 searchManager.launchAssist(args); 4853 } else { 4854 // Fallback to status bar if search manager doesn't exist (e.g. on wear). 4855 StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); 4856 if (statusBar != null) { 4857 statusBar.startAssist(args); 4858 } 4859 } 4860 } 4861 4862 /** 4863 * Launches ACTION_VOICE_ASSIST_RETAIL if in retail mode, or ACTION_VOICE_ASSIST otherwise 4864 * Does nothing on keyguard except for watches. Delegates it to keyguard if present on watch. 4865 */ 4866 private void launchVoiceAssist(boolean allowDuringSetup) { 4867 final boolean keyguardActive = 4868 mKeyguardDelegate != null && mKeyguardDelegate.isShowing(); 4869 if (!keyguardActive) { 4870 startActivityAsUser( 4871 new Intent(Intent.ACTION_VOICE_ASSIST), 4872 /* bundle= */ null, 4873 UserHandle.CURRENT_OR_SELF, 4874 allowDuringSetup); 4875 } else { 4876 mKeyguardDelegate.dismissKeyguardToLaunch(new Intent(Intent.ACTION_VOICE_ASSIST)); 4877 } 4878 } 4879 4880 private boolean isInRetailMode() { 4881 return Settings.Global.getInt(mContext.getContentResolver(), 4882 Settings.Global.DEVICE_DEMO_MODE, 0) == 1; 4883 } 4884 4885 private void startActivityAsUser(Intent intent, UserHandle handle) { 4886 startActivityAsUser(intent, null, handle); 4887 } 4888 4889 private void startActivityAsUser(Intent intent, Bundle bundle, UserHandle handle) { 4890 startActivityAsUser(intent, bundle, handle, false /* allowDuringSetup */); 4891 } 4892 4893 private void startActivityAsUser(Intent intent, Bundle bundle, UserHandle handle, 4894 boolean allowDuringSetup) { 4895 if (allowDuringSetup || isUserSetupComplete()) { 4896 mContext.startActivityAsUser(intent, bundle, handle); 4897 dismissKeyboardShortcutsMenu(); 4898 } else { 4899 Slog.i(TAG, "Not starting activity because user setup is in progress: " + intent); 4900 } 4901 } 4902 4903 private void preloadRecentApps() { 4904 mPreloadedRecentApps = true; 4905 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4906 if (statusbar != null) { 4907 statusbar.preloadRecentApps(); 4908 } 4909 } 4910 4911 private void cancelPreloadRecentApps() { 4912 if (mPreloadedRecentApps) { 4913 mPreloadedRecentApps = false; 4914 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4915 if (statusbar != null) { 4916 statusbar.cancelPreloadRecentApps(); 4917 } 4918 } 4919 } 4920 4921 private void toggleTaskbar() { 4922 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4923 if (statusbar != null) { 4924 statusbar.toggleTaskbar(); 4925 } 4926 } 4927 4928 private void toggleRecentApps() { 4929 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 4930 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4931 if (statusbar != null) { 4932 statusbar.toggleRecentApps(); 4933 } 4934 } 4935 4936 @Override 4937 public void showRecentApps() { 4938 mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS); 4939 mHandler.obtainMessage(MSG_DISPATCH_SHOW_RECENTS).sendToTarget(); 4940 } 4941 4942 private void showRecentApps(boolean triggeredFromAltTab) { 4943 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 4944 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4945 if (statusbar != null) { 4946 statusbar.showRecentApps(triggeredFromAltTab); 4947 } 4948 dismissKeyboardShortcutsMenu(); 4949 } 4950 4951 private void toggleKeyboardShortcutsMenu(int deviceId) { 4952 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4953 if (statusbar != null) { 4954 statusbar.toggleKeyboardShortcutsMenu(deviceId); 4955 } 4956 } 4957 4958 private void dismissKeyboardShortcutsMenu() { 4959 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4960 if (statusbar != null) { 4961 statusbar.dismissKeyboardShortcutsMenu(); 4962 } 4963 } 4964 4965 private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) { 4966 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 4967 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4968 if (statusbar != null) { 4969 statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome); 4970 } 4971 } 4972 4973 private void moveFocusedTaskToStageSplit(int displayId, boolean leftOrTop) { 4974 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4975 if (statusbar != null) { 4976 statusbar.moveFocusedTaskToStageSplit(displayId, leftOrTop); 4977 } 4978 } 4979 4980 void launchHomeFromHotKey(int displayId) { 4981 launchHomeFromHotKey(displayId, true /* awakenFromDreams */, true /*respectKeyguard*/); 4982 } 4983 4984 /** 4985 * A home key -> launch home action was detected. Take the appropriate action 4986 * given the situation with the keyguard. 4987 */ 4988 void launchHomeFromHotKey(int displayId, final boolean awakenFromDreams, 4989 final boolean respectKeyguard) { 4990 if (respectKeyguard) { 4991 if (isKeyguardShowingAndNotOccluded()) { 4992 // don't launch home if keyguard showing 4993 return; 4994 } 4995 4996 if (!isKeyguardOccluded() && mKeyguardDelegate.isInputRestricted()) { 4997 // when in keyguard restricted mode, must first verify unlock 4998 // before launching home 4999 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() { 5000 @Override 5001 public void onKeyguardExitResult(boolean success) { 5002 if (success) { 5003 final long origId = Binder.clearCallingIdentity(); 5004 try { 5005 startDockOrHome(displayId, true /*fromHomeKey*/, awakenFromDreams); 5006 } finally { 5007 Binder.restoreCallingIdentity(origId); 5008 } 5009 } 5010 } 5011 }); 5012 return; 5013 } 5014 } 5015 5016 // no keyguard stuff to worry about, just launch home! 5017 // If Recents is visible and the action is not from visible background users, 5018 // hide Recents and notify it to launch Home. 5019 if (mRecentsVisible 5020 && (!mVisibleBackgroundUsersEnabled || displayId == DEFAULT_DISPLAY)) { 5021 try { 5022 ActivityManager.getService().stopAppSwitches(); 5023 } catch (RemoteException e) {} 5024 5025 // Hide Recents and notify it to launch Home 5026 if (awakenFromDreams) { 5027 awakenDreams(); 5028 } 5029 hideRecentApps(false, true); 5030 } else { 5031 // Otherwise, just launch Home 5032 startDockOrHome(displayId, true /*fromHomeKey*/, awakenFromDreams); 5033 } 5034 } 5035 5036 @Override 5037 public void setRecentsVisibilityLw(boolean visible) { 5038 mRecentsVisible = visible; 5039 } 5040 5041 @Override 5042 public void setPipVisibilityLw(boolean visible) { 5043 mPictureInPictureVisible = visible; 5044 } 5045 5046 @Override 5047 public void setNavBarVirtualKeyHapticFeedbackEnabledLw(boolean enabled) { 5048 mNavBarVirtualKeyHapticFeedbackEnabled = enabled; 5049 } 5050 5051 /** 5052 * Updates the occluded state of the Keyguard immediately via {@link IKeyguardService}. 5053 * 5054 * @param isOccluded Whether the Keyguard is occluded by another window. 5055 * @return Whether the flags have changed and we have to redo the layout. 5056 */ 5057 private boolean setKeyguardOccludedLw(boolean isOccluded) { 5058 if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded); 5059 mKeyguardOccludedChanged = false; 5060 mPendingKeyguardOccluded = isOccluded; 5061 mKeyguardDelegate.setOccluded(isOccluded, true /* notify */); 5062 return mKeyguardDelegate.isShowing(); 5063 } 5064 5065 /** {@inheritDoc} */ 5066 @Override 5067 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { 5068 // lid changed state 5069 final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED; 5070 if (newLidState == mDefaultDisplayPolicy.getLidState()) { 5071 return; 5072 } 5073 5074 mDefaultDisplayPolicy.setLidState(newLidState); 5075 applyLidSwitchState(); 5076 updateRotation(true); 5077 5078 if (lidOpen) { 5079 mWindowWakeUpPolicy.wakeUpFromLid(); 5080 } else if (getLidBehavior() != LID_BEHAVIOR_SLEEP) { 5081 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 5082 } 5083 } 5084 5085 @Override 5086 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) { 5087 int lensCoverState = lensCovered ? CAMERA_LENS_COVERED : CAMERA_LENS_UNCOVERED; 5088 if (mCameraLensCoverState == lensCoverState) { 5089 return; 5090 } 5091 if (!mContext.getResources().getBoolean( 5092 R.bool.config_launchCameraOnCameraLensCoverToggle)) { 5093 return; 5094 } 5095 if (mCameraLensCoverState == CAMERA_LENS_COVERED && 5096 lensCoverState == CAMERA_LENS_UNCOVERED) { 5097 Intent intent; 5098 final boolean keyguardActive = mKeyguardDelegate == null ? false : 5099 mKeyguardDelegate.isShowing(); 5100 if (keyguardActive) { 5101 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); 5102 } else { 5103 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); 5104 } 5105 mWindowWakeUpPolicy.wakeUpFromCameraCover(whenNanos / 1000000); 5106 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 5107 } 5108 mCameraLensCoverState = lensCoverState; 5109 } 5110 5111 void initializeHdmiState() { 5112 final int oldMask = StrictMode.allowThreadDiskReadsMask(); 5113 try { 5114 initializeHdmiStateInternal(); 5115 } finally { 5116 StrictMode.setThreadPolicyMask(oldMask); 5117 } 5118 } 5119 5120 void initializeHdmiStateInternal() { 5121 boolean plugged = false; 5122 // watch for HDMI plug messages if the hdmi switch exists 5123 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) { 5124 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi"); 5125 5126 final String filename = "/sys/class/switch/hdmi/state"; 5127 FileReader reader = null; 5128 try { 5129 reader = new FileReader(filename); 5130 char[] buf = new char[15]; 5131 int n = reader.read(buf); 5132 if (n > 1) { 5133 plugged = 0 != Integer.parseInt(new String(buf, 0, n - 1)); 5134 } 5135 } catch (IOException ex) { 5136 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5137 } catch (NumberFormatException ex) { 5138 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5139 } finally { 5140 if (reader != null) { 5141 try { 5142 reader.close(); 5143 } catch (IOException ex) { 5144 } 5145 } 5146 } 5147 } else { 5148 final List<ExtconUEventObserver.ExtconInfo> extcons = 5149 ExtconUEventObserver.ExtconInfo.getExtconInfoForTypes( 5150 new String[] {ExtconUEventObserver.ExtconInfo.EXTCON_HDMI}); 5151 if (!extcons.isEmpty()) { 5152 // TODO: handle more than one HDMI 5153 HdmiVideoExtconUEventObserver observer = new HdmiVideoExtconUEventObserver(); 5154 plugged = observer.init(extcons.get(0)); 5155 mHDMIObserver = observer; 5156 } else if (localLOGV) { 5157 Slog.v(TAG, "Not observing HDMI plug state because HDMI was not found."); 5158 } 5159 } 5160 5161 // This dance forces the code in setHdmiPlugged to run. 5162 // Always do this so the sticky intent is stuck (to false) if there is no hdmi. 5163 mDefaultDisplayPolicy.setHdmiPlugged(plugged, true /* force */); 5164 } 5165 5166 // TODO(b/117479243): handle it in InputPolicy 5167 /** {@inheritDoc} */ 5168 @Override 5169 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { 5170 final int keyCode = event.getKeyCode(); 5171 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 5172 boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 5173 || event.isWakeKey(); 5174 boolean isKeyGestureTriggered = (policyFlags & FLAG_KEY_GESTURE_TRIGGERED) != 0; 5175 5176 // There are key events that perform the operation as the current user, 5177 // and these should be ignored for visible background users. 5178 if (mVisibleBackgroundUsersEnabled 5179 && !KeyEvent.isVisibleBackgroundUserAllowedKey(keyCode) 5180 && !isKeyEventForCurrentUser(event.getDisplayId(), keyCode, null)) { 5181 return 0; 5182 } 5183 5184 if (!mSystemBooted) { 5185 // If we have not yet booted, don't let key events do anything. 5186 // Exception: Wake and power key events are forwarded to PowerManager to allow it to 5187 // wake from quiescent mode during boot. On these key events we also explicitly turn on 5188 // the connected TV and switch HDMI input if we're a HDMI playback device. 5189 boolean shouldTurnOnTv = false; 5190 if (down && (keyCode == KeyEvent.KEYCODE_POWER 5191 || keyCode == KeyEvent.KEYCODE_TV_POWER)) { 5192 wakeUpFromWakeKey(event); 5193 shouldTurnOnTv = true; 5194 } else if (down && (isWakeKey || keyCode == KeyEvent.KEYCODE_WAKEUP) 5195 && isWakeKeyWhenScreenOff(keyCode)) { 5196 wakeUpFromWakeKey(event); 5197 shouldTurnOnTv = true; 5198 } 5199 if (shouldTurnOnTv) { 5200 final HdmiControl hdmiControl = getHdmiControl(); 5201 if (hdmiControl != null) { 5202 hdmiControl.turnOnTv(); 5203 } 5204 } 5205 return 0; 5206 } 5207 5208 final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; 5209 final boolean canceled = event.isCanceled(); 5210 final int displayId = event.getDisplayId(); 5211 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0; 5212 5213 if (DEBUG_INPUT) { 5214 // If screen is off then we treat the case where the keyguard is open but hidden 5215 // the same as if it were open and in front. 5216 // This will prevent any keys other than the power button from waking the screen 5217 // when the keyguard is hidden by another activity. 5218 final boolean keyguardActive = (mKeyguardDelegate != null 5219 && (interactive ? isKeyguardShowingAndNotOccluded() : 5220 mKeyguardDelegate.isShowing())); 5221 Log.d(TAG, "interceptKeyTq keycode=" + keyCode 5222 + " interactive=" + interactive + " keyguardActive=" + keyguardActive 5223 + " policyFlags=" + Integer.toHexString(policyFlags)); 5224 } 5225 5226 // Basic policy based on interactive state. 5227 int result; 5228 if (interactive || (isInjected && !isWakeKey)) { 5229 // When the device is interactive or the key is injected pass the 5230 // key to the application. 5231 result = ACTION_PASS_TO_USER; 5232 isWakeKey = false; 5233 5234 if (interactive) { 5235 // If the screen is awake, but the button pressed was the one that woke the device 5236 // then don't pass it to the application 5237 if (keyCode == mPendingWakeKey && !down) { 5238 result = 0; 5239 } 5240 // Reset the pending key 5241 mPendingWakeKey = PENDING_KEY_NULL; 5242 } 5243 } else if (shouldDispatchInputWhenNonInteractive(displayId, keyCode)) { 5244 // If we're currently dozing with the screen on and the keyguard showing, pass the key 5245 // to the application but preserve its wake key status to make sure we still move 5246 // from dozing to fully interactive if we would normally go from off to fully 5247 // interactive. 5248 result = ACTION_PASS_TO_USER; 5249 // Since we're dispatching the input, reset the pending key 5250 mPendingWakeKey = PENDING_KEY_NULL; 5251 } else { 5252 // When the screen is off and the key is not injected, determine whether 5253 // to wake the device but don't pass the key to the application. 5254 result = 0; 5255 if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) { 5256 isWakeKey = false; 5257 } 5258 // Cache the wake key on down event so we can also avoid sending the up event to the app 5259 if (isWakeKey && down) { 5260 mPendingWakeKey = keyCode; 5261 } 5262 } 5263 5264 // If the key would be handled globally, just return the result, don't worry about special 5265 // key processing. 5266 if (isValidGlobalKey(keyCode) 5267 && mGlobalKeyManager.shouldHandleGlobalKey(keyCode)) { 5268 // Dispatch if global key defined dispatchWhenNonInteractive. 5269 if (!interactive && isWakeKey && down 5270 && mGlobalKeyManager.shouldDispatchFromNonInteractive(keyCode)) { 5271 mGlobalKeyManager.setBeganFromNonInteractive(); 5272 result = ACTION_PASS_TO_USER; 5273 // Since we're dispatching the input, reset the pending key 5274 mPendingWakeKey = PENDING_KEY_NULL; 5275 } 5276 5277 if (isWakeKey) { 5278 wakeUpFromWakeKey(event); 5279 } 5280 return result; 5281 } 5282 5283 // Alternate TV power to power key for Android TV device. 5284 final HdmiControlManager hdmiControlManager = getHdmiControlManager(); 5285 if (keyCode == KeyEvent.KEYCODE_TV_POWER && mHasFeatureLeanback 5286 && (hdmiControlManager == null || !hdmiControlManager.shouldHandleTvPowerKey())) { 5287 event = KeyEvent.obtain( 5288 event.getDownTime(), event.getEventTime(), 5289 event.getAction(), KeyEvent.KEYCODE_POWER, 5290 event.getRepeatCount(), event.getMetaState(), 5291 event.getDeviceId(), event.getScanCode(), 5292 event.getFlags(), event.getSource(), event.getDisplayId(), null); 5293 return interceptKeyBeforeQueueing(event, policyFlags); 5294 } 5295 5296 // This could prevent some wrong state in multi-displays environment, 5297 // the default display may turned off but interactive is true. 5298 final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState()); 5299 final boolean isDefaultDisplayAwake = mDefaultDisplayPolicy.isAwake(); 5300 final boolean interactiveAndAwake = interactive && isDefaultDisplayAwake; 5301 if (isKeyGestureTriggered) { 5302 // If key gesture is triggered outside policy, reset gesture handlers here 5303 mSingleKeyGestureDetector.reset(); 5304 } else { 5305 if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5306 handleKeyGesture(event, interactiveAndAwake, isDefaultDisplayOn); 5307 } 5308 } 5309 5310 // Enable haptics if down and virtual key without multiple repetitions. If this is a hard 5311 // virtual key such as a navigation bar button, only vibrate if flag is enabled. 5312 final boolean isNavBarVirtKey = ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0); 5313 boolean useHapticFeedback = down 5314 && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0 5315 && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled) 5316 && event.getRepeatCount() == 0; 5317 5318 // Handle special keys. 5319 switch (keyCode) { 5320 case KeyEvent.KEYCODE_BACK: { 5321 notifyKeyGestureCompletedOnActionUp(event, 5322 KeyGestureEvent.KEY_GESTURE_TYPE_BACK); 5323 if (down) { 5324 // There may have other embedded activities on the same Task. Try to move the 5325 // focus before processing the back event. 5326 mWindowManagerInternal.moveFocusToAdjacentEmbeddedActivityIfNeeded(); 5327 mBackKeyHandled = false; 5328 } else { 5329 if (!hasLongPressOnBackBehavior()) { 5330 mBackKeyHandled |= backKeyPress(); 5331 } 5332 // Don't pass back press to app if we've already handled it via long press 5333 if (mBackKeyHandled) { 5334 result &= ~ACTION_PASS_TO_USER; 5335 } 5336 } 5337 break; 5338 } 5339 5340 case KeyEvent.KEYCODE_VOLUME_DOWN: 5341 case KeyEvent.KEYCODE_VOLUME_UP: 5342 case KeyEvent.KEYCODE_VOLUME_MUTE: { 5343 int gestureType = keyCode == KEYCODE_VOLUME_DOWN 5344 ? KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_DOWN 5345 : keyCode == KEYCODE_VOLUME_UP 5346 ? KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_UP 5347 : KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_MUTE; 5348 notifyKeyGestureCompletedOnActionDown(event, gestureType); 5349 if (down) { 5350 sendSystemKeyToStatusBarAsync(event); 5351 5352 NotificationManager nm = getNotificationService(); 5353 if (nm != null && !mHandleVolumeKeysInWM) { 5354 nm.silenceNotificationSound(); 5355 } 5356 5357 TelecomManager telecomManager = getTelecommService(); 5358 if (telecomManager != null && !mHandleVolumeKeysInWM) { 5359 // When {@link #mHandleVolumeKeysInWM} is set, volume key events 5360 // should be dispatched to WM. 5361 if (telecomManager.isRinging()) { 5362 // If an incoming call is ringing, either VOLUME key means 5363 // "silence ringer". We handle these keys here, rather than 5364 // in the InCallScreen, to make sure we'll respond to them 5365 // even if the InCallScreen hasn't come to the foreground yet. 5366 // Look for the DOWN event here, to agree with the "fallback" 5367 // behavior in the InCallScreen. 5368 Log.i(TAG, "interceptKeyBeforeQueueing:" 5369 + " VOLUME key-down while ringing: Silence ringer!"); 5370 5371 // Silence the ringer. (It's safe to call this 5372 // even if the ringer has already been silenced.) 5373 telecomManager.silenceRinger(); 5374 5375 // And *don't* pass this key thru to the current activity 5376 // (which is probably the InCallScreen.) 5377 result &= ~ACTION_PASS_TO_USER; 5378 break; 5379 } 5380 } 5381 int audioMode = AudioManager.MODE_NORMAL; 5382 try { 5383 audioMode = getAudioService().getMode(); 5384 } catch (Exception e) { 5385 Log.e(TAG, "Error getting AudioService in interceptKeyBeforeQueueing.", e); 5386 } 5387 boolean isInCall = (telecomManager != null && telecomManager.isInCall()) || 5388 audioMode == AudioManager.MODE_IN_COMMUNICATION; 5389 if (isInCall && (result & ACTION_PASS_TO_USER) == 0) { 5390 // If we are in call but we decided not to pass the key to 5391 // the application, just pass it to the session service. 5392 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 5393 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false); 5394 break; 5395 } 5396 } 5397 if (mUseTvRouting || mHandleVolumeKeysInWM) { 5398 // Defer special key handlings to 5399 // {@link interceptKeyBeforeDispatching()}. 5400 result |= ACTION_PASS_TO_USER; 5401 } else if ((result & ACTION_PASS_TO_USER) == 0) { 5402 // If we aren't passing to the user and no one else 5403 // handled it send it to the session manager to 5404 // figure out. 5405 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 5406 event, AudioManager.USE_DEFAULT_STREAM_TYPE, true); 5407 } 5408 break; 5409 } 5410 5411 case KeyEvent.KEYCODE_ENDCALL: { 5412 result &= ~ACTION_PASS_TO_USER; 5413 if (down) { 5414 TelecomManager telecomManager = getTelecommService(); 5415 boolean hungUp = false; 5416 if (telecomManager != null) { 5417 hungUp = telecomManager.endCall(); 5418 } 5419 if (interactive && !hungUp) { 5420 mEndCallKeyHandled = false; 5421 mHandler.postDelayed(mEndCallLongPress, 5422 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 5423 } else { 5424 mEndCallKeyHandled = true; 5425 } 5426 } else { 5427 if (!mEndCallKeyHandled) { 5428 mHandler.removeCallbacks(mEndCallLongPress); 5429 if (!canceled) { 5430 if ((mEndcallBehavior 5431 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) { 5432 if (goHome()) { 5433 break; 5434 } 5435 } 5436 if ((mEndcallBehavior 5437 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { 5438 sleepDefaultDisplay(event.getEventTime(), 5439 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); 5440 isWakeKey = false; 5441 } 5442 } 5443 } 5444 } 5445 break; 5446 } 5447 5448 case KeyEvent.KEYCODE_TV_POWER: { 5449 notifyKeyGestureCompletedOnActionUp(event, 5450 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER); 5451 result &= ~ACTION_PASS_TO_USER; 5452 isWakeKey = false; // wake-up will be handled separately 5453 if (down && hdmiControlManager != null) { 5454 hdmiControlManager.toggleAndFollowTvPower(); 5455 } 5456 break; 5457 } 5458 5459 case KeyEvent.KEYCODE_POWER: { 5460 notifyKeyGestureCompletedOnActionUp(event, 5461 KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER); 5462 EventLogTags.writeInterceptPower( 5463 KeyEvent.actionToString(event.getAction()), 5464 mPowerKeyHandled ? 1 : 0, 5465 mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER)); 5466 // Any activity on the power button stops the accessibility shortcut 5467 result &= ~ACTION_PASS_TO_USER; 5468 isWakeKey = false; // wake-up will be handled separately 5469 if (down) { 5470 interceptPowerKeyDown(event, interactiveAndAwake, isKeyGestureTriggered); 5471 } else { 5472 interceptPowerKeyUp(event, canceled); 5473 } 5474 break; 5475 } 5476 5477 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN: 5478 // fall through 5479 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP: 5480 // fall through 5481 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT: 5482 // fall through 5483 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: { 5484 notifyKeyGestureCompletedOnActionUp(event, 5485 KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_NAVIGATION); 5486 result &= ~ACTION_PASS_TO_USER; 5487 interceptSystemNavigationKey(event); 5488 break; 5489 } 5490 5491 case KeyEvent.KEYCODE_SLEEP: { 5492 notifyKeyGestureCompletedOnActionUp(event, 5493 KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP); 5494 result &= ~ACTION_PASS_TO_USER; 5495 isWakeKey = false; 5496 if (!mPowerManager.isInteractive()) { 5497 useHapticFeedback = false; // suppress feedback if already non-interactive 5498 } 5499 if (down) { 5500 sleepPress(); 5501 } else { 5502 sleepRelease(event.getEventTime()); 5503 } 5504 sendSystemKeyToStatusBarAsync(event); 5505 break; 5506 } 5507 5508 case KeyEvent.KEYCODE_SOFT_SLEEP: { 5509 notifyKeyGestureCompletedOnActionUp(event, 5510 KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP); 5511 result &= ~ACTION_PASS_TO_USER; 5512 isWakeKey = false; 5513 if (!down) { 5514 mPowerManagerInternal.setUserInactiveOverrideFromWindowManager(); 5515 } 5516 sendSystemKeyToStatusBarAsync(event); 5517 break; 5518 } 5519 5520 case KeyEvent.KEYCODE_WAKEUP: { 5521 notifyKeyGestureCompletedOnActionUp(event, 5522 KeyGestureEvent.KEY_GESTURE_TYPE_WAKEUP); 5523 result &= ~ACTION_PASS_TO_USER; 5524 isWakeKey = true; 5525 break; 5526 } 5527 5528 case KeyEvent.KEYCODE_MUTE: 5529 result &= ~ACTION_PASS_TO_USER; 5530 if (down && event.getRepeatCount() == 0) { 5531 notifyKeyGestureCompleted(event, 5532 KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_MUTE); 5533 toggleMicrophoneMuteFromKey(); 5534 } 5535 break; 5536 case KeyEvent.KEYCODE_MEDIA_PLAY: 5537 case KeyEvent.KEYCODE_MEDIA_PAUSE: 5538 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 5539 case KeyEvent.KEYCODE_HEADSETHOOK: 5540 case KeyEvent.KEYCODE_MEDIA_STOP: 5541 case KeyEvent.KEYCODE_MEDIA_NEXT: 5542 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 5543 case KeyEvent.KEYCODE_MEDIA_REWIND: 5544 case KeyEvent.KEYCODE_MEDIA_RECORD: 5545 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 5546 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { 5547 notifyKeyGestureCompletedOnActionUp(event, 5548 KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY); 5549 if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) { 5550 // If the global session is active pass all media keys to it 5551 // instead of the active window. 5552 result &= ~ACTION_PASS_TO_USER; 5553 } 5554 if ((result & ACTION_PASS_TO_USER) == 0) { 5555 // Only do this if we would otherwise not pass it to the user. In that 5556 // case, the PhoneWindow class will do the same thing, except it will 5557 // only do it if the showing app doesn't process the key on its own. 5558 // Note that we need to make a copy of the key event here because the 5559 // original key event will be recycled when we return. 5560 mBroadcastWakeLock.acquire(); 5561 Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK, 5562 new KeyEvent(event)); 5563 msg.setAsynchronous(true); 5564 msg.sendToTarget(); 5565 } 5566 break; 5567 } 5568 5569 case KeyEvent.KEYCODE_CALL: { 5570 if (down) { 5571 TelecomManager telecomManager = getTelecommService(); 5572 if (telecomManager != null) { 5573 if (telecomManager.isRinging()) { 5574 Log.i(TAG, "interceptKeyBeforeQueueing:" 5575 + " CALL key-down while ringing: Answer the call!"); 5576 telecomManager.acceptRingingCall(); 5577 5578 // And *don't* pass this key thru to the current activity 5579 // (which is presumably the InCallScreen.) 5580 result &= ~ACTION_PASS_TO_USER; 5581 } 5582 } 5583 } 5584 break; 5585 } 5586 case KeyEvent.KEYCODE_ASSIST: { 5587 final boolean longPressed = event.getRepeatCount() > 0; 5588 if (down && !longPressed) { 5589 Message msg = mHandler.obtainMessage(MSG_LAUNCH_ASSIST, event.getDeviceId(), 5590 0 /* unused */, event.getEventTime() /* eventTime */); 5591 msg.setAsynchronous(true); 5592 msg.sendToTarget(); 5593 notifyKeyGestureCompleted(event, 5594 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT); 5595 } 5596 result &= ~ACTION_PASS_TO_USER; 5597 break; 5598 } 5599 case KeyEvent.KEYCODE_VOICE_ASSIST: { 5600 if (!down) { 5601 mBroadcastWakeLock.acquire(); 5602 Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK); 5603 msg.setAsynchronous(true); 5604 msg.sendToTarget(); 5605 notifyKeyGestureCompleted(event, 5606 KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT); 5607 } 5608 result &= ~ACTION_PASS_TO_USER; 5609 break; 5610 } 5611 case KeyEvent.KEYCODE_WINDOW: { 5612 if (mShortPressOnWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) { 5613 if (mPictureInPictureVisible) { 5614 // Consumes the key only if picture-in-picture is visible to show 5615 // picture-in-picture control menu. This gives a chance to the foreground 5616 // activity to customize PIP key behavior. 5617 if (!down) { 5618 showPictureInPictureMenu(event); 5619 } 5620 result &= ~ACTION_PASS_TO_USER; 5621 } 5622 } 5623 break; 5624 } 5625 case KeyEvent.KEYCODE_STEM_PRIMARY: { 5626 if (down && event.getRepeatCount() == 0 && (result & ACTION_PASS_TO_USER) == 0) { 5627 // We've decided not to pass key to user at queueing stage. Make the gesture 5628 // executable. 5629 setDeferredKeyActionsExecutableAsync(keyCode, event.getDownTime()); 5630 } 5631 break; 5632 } 5633 case KeyEvent.KEYCODE_VIDEO_APP_1: 5634 case KeyEvent.KEYCODE_VIDEO_APP_2: 5635 case KeyEvent.KEYCODE_VIDEO_APP_3: 5636 case KeyEvent.KEYCODE_VIDEO_APP_4: 5637 case KeyEvent.KEYCODE_VIDEO_APP_5: 5638 case KeyEvent.KEYCODE_VIDEO_APP_6: 5639 case KeyEvent.KEYCODE_VIDEO_APP_7: 5640 case KeyEvent.KEYCODE_VIDEO_APP_8: 5641 case KeyEvent.KEYCODE_FEATURED_APP_1: 5642 case KeyEvent.KEYCODE_FEATURED_APP_2: 5643 case KeyEvent.KEYCODE_FEATURED_APP_3: 5644 case KeyEvent.KEYCODE_FEATURED_APP_4: 5645 case KeyEvent.KEYCODE_DEMO_APP_1: 5646 case KeyEvent.KEYCODE_DEMO_APP_2: 5647 case KeyEvent.KEYCODE_DEMO_APP_3: 5648 case KeyEvent.KEYCODE_DEMO_APP_4: { 5649 // Just drop if keys are not intercepted for direct key. 5650 result &= ~ACTION_PASS_TO_USER; 5651 break; 5652 } 5653 case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY: 5654 case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY: 5655 case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY: 5656 case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL: { 5657 Slog.i(TAG, "Stylus buttons event: " + keyCode + " received. Should handle event? " 5658 + mStylusButtonsEnabled); 5659 if (mStylusButtonsEnabled) { 5660 sendSystemKeyToStatusBarAsync(event); 5661 } 5662 result &= ~ACTION_PASS_TO_USER; 5663 break; 5664 } 5665 case KeyEvent.KEYCODE_MACRO_1: 5666 case KeyEvent.KEYCODE_MACRO_2: 5667 case KeyEvent.KEYCODE_MACRO_3: 5668 case KeyEvent.KEYCODE_MACRO_4: 5669 result &= ~ACTION_PASS_TO_USER; 5670 break; 5671 case KeyEvent.KEYCODE_DICTATE: 5672 case KeyEvent.KEYCODE_NEW: 5673 case KeyEvent.KEYCODE_CLOSE: 5674 case KeyEvent.KEYCODE_PRINT: 5675 case KeyEvent.KEYCODE_F13: 5676 case KeyEvent.KEYCODE_F14: 5677 case KeyEvent.KEYCODE_F15: 5678 case KeyEvent.KEYCODE_F16: 5679 case KeyEvent.KEYCODE_F17: 5680 case KeyEvent.KEYCODE_F18: 5681 case KeyEvent.KEYCODE_F19: 5682 case KeyEvent.KEYCODE_F20: 5683 case KeyEvent.KEYCODE_F21: 5684 case KeyEvent.KEYCODE_F22: 5685 case KeyEvent.KEYCODE_F23: 5686 case KeyEvent.KEYCODE_F24: 5687 if (!enableNew25q2Keycodes()) { 5688 result &= ~ACTION_PASS_TO_USER; 5689 } 5690 break; 5691 } 5692 5693 if (useHapticFeedback) { 5694 performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, "Virtual Key - Press"); 5695 } 5696 5697 if (isWakeKey) { 5698 wakeUpFromWakeKey(event); 5699 } 5700 5701 // If the key event is targeted to a specific display, then the user is interacting with 5702 // that display. Therefore, try to give focus to the display that the user is interacting 5703 // with. 5704 if ((result & ACTION_PASS_TO_USER) != 0 && displayId != INVALID_DISPLAY 5705 && displayId != mTopFocusedDisplayId) { 5706 // An event is targeting a non-focused display. Move the display to top so that 5707 // it can become the focused display to interact with the user. 5708 // This should be done asynchronously, once the focus logic is fully moved to input 5709 // from windowmanager. Currently, we need to ensure the setInputWindows completes, 5710 // which would force the focus event to be queued before the current key event. 5711 // TODO(b/70668286): post call to 'moveDisplayToTop' to mHandler instead 5712 Log.i(TAG, "Attempting to move non-focused display " + displayId + " to top " 5713 + "because a key is targeting it"); 5714 mWindowManagerFuncs.moveDisplayToTopIfAllowed(displayId); 5715 } 5716 5717 return result; 5718 } 5719 5720 private void handleKeyGesture(KeyEvent event, boolean interactive, boolean defaultDisplayOn) { 5721 if (!InputSettings.doesKeyGestureEventHandlerSupportMultiKeyGestures() 5722 && mKeyCombinationManager.interceptKey(event, interactive)) { 5723 // handled by combo keys manager. 5724 mSingleKeyGestureDetector.reset(); 5725 return; 5726 } 5727 5728 if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) { 5729 mPowerKeyHandled = handleCameraGesture(event, interactive); 5730 if (mPowerKeyHandled) { 5731 // handled by camera gesture. 5732 mSingleKeyGestureDetector.reset(); 5733 return; 5734 } 5735 } 5736 5737 mSingleKeyGestureDetector.interceptKey(event, interactive, defaultDisplayOn); 5738 } 5739 5740 // The camera gesture will be detected by GestureLauncherService. 5741 private boolean handleCameraGesture(KeyEvent event, boolean interactive) { 5742 // camera gesture. 5743 if (mGestureLauncherService == null) { 5744 return false; 5745 } 5746 mPowerButtonLaunchGestureTriggered = false; 5747 final MutableBoolean outLaunched = new MutableBoolean(false); 5748 final boolean intercept = 5749 mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched); 5750 if (!outLaunched.value) { 5751 // If GestureLauncherService intercepted the power key, but didn't launch camera app, 5752 // we should still return the intercept result. This prevents the single key gesture 5753 // detector from processing the power key later on. 5754 return intercept; 5755 } 5756 mPowerButtonLaunchGestureTriggered = true; 5757 if (mRequestedOrSleepingDefaultDisplay) { 5758 mPowerButtonLaunchGestureTriggeredDuringGoingToSleep = true; 5759 // Wake device up early to prevent display doing redundant turning off/on stuff. 5760 mWindowWakeUpPolicy.wakeUpFromPowerKeyCameraGesture(); 5761 } 5762 return true; 5763 } 5764 5765 /** 5766 * Handle statusbar expansion events. 5767 * @param event 5768 */ 5769 private void interceptSystemNavigationKey(KeyEvent event) { 5770 if (event.getAction() == KeyEvent.ACTION_UP) { 5771 if (!mAccessibilityManager.isEnabled() 5772 || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) { 5773 if (mSystemNavigationKeysEnabled) { 5774 sendSystemKeyToStatusBarAsync(event); 5775 } 5776 } 5777 } 5778 } 5779 5780 /** 5781 * Notify the StatusBar that a system key was pressed. 5782 */ 5783 private void sendSystemKeyToStatusBar(KeyEvent key) { 5784 if (!isKeyEventForCurrentUser(key.getDisplayId(), key.getKeyCode(), "handleSystemKey")) { 5785 return; 5786 } 5787 IStatusBarService statusBar = getStatusBarService(); 5788 if (statusBar != null) { 5789 try { 5790 statusBar.handleSystemKey(key); 5791 } catch (RemoteException e) { 5792 // Oh well. 5793 } 5794 } 5795 } 5796 5797 /** 5798 * Notify the StatusBar that a system key was pressed without blocking the current thread. 5799 */ 5800 private void sendSystemKeyToStatusBarAsync(KeyEvent keyEvent) { 5801 // Make a copy because the event may be recycled. 5802 Message message = mHandler.obtainMessage(MSG_SYSTEM_KEY_PRESS, KeyEvent.obtain(keyEvent)); 5803 message.setAsynchronous(true); 5804 mHandler.sendMessage(message); 5805 } 5806 5807 /** 5808 * Returns true if the key can have global actions attached to it. 5809 * We reserve all power management keys for the system since they require 5810 * very careful handling. 5811 */ 5812 private static boolean isValidGlobalKey(int keyCode) { 5813 switch (keyCode) { 5814 case KeyEvent.KEYCODE_POWER: 5815 case KeyEvent.KEYCODE_WAKEUP: 5816 case KeyEvent.KEYCODE_SLEEP: 5817 return false; 5818 default: 5819 return true; 5820 } 5821 } 5822 5823 /** 5824 * When the screen is off we ignore some keys that might otherwise typically 5825 * be considered wake keys. We filter them out here. 5826 * 5827 * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it 5828 * is always considered a wake key. 5829 */ 5830 private boolean isWakeKeyWhenScreenOff(int keyCode) { 5831 switch (keyCode) { 5832 case KeyEvent.KEYCODE_DPAD_UP: 5833 case KeyEvent.KEYCODE_DPAD_DOWN: 5834 case KeyEvent.KEYCODE_DPAD_LEFT: 5835 case KeyEvent.KEYCODE_DPAD_RIGHT: 5836 case KeyEvent.KEYCODE_DPAD_CENTER: 5837 return mWakeOnDpadKeyPress; 5838 5839 case KeyEvent.KEYCODE_ASSIST: 5840 return mWakeOnAssistKeyPress; 5841 5842 case KeyEvent.KEYCODE_BACK: 5843 return mWakeOnBackKeyPress; 5844 5845 case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY: 5846 case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY: 5847 case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY: 5848 case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL: 5849 return mStylusButtonsEnabled; 5850 } 5851 5852 return true; 5853 } 5854 5855 // TODO(b/117479243): handle it in InputPolicy 5856 /** {@inheritDoc} */ 5857 @Override 5858 public int interceptMotionBeforeQueueingNonInteractive(int displayId, int source, int action, 5859 long whenNanos, int policyFlags) { 5860 if ((policyFlags & FLAG_WAKE) != 0) { 5861 if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source, 5862 action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) { 5863 // Woke up. Pass motion events to user. 5864 return ACTION_PASS_TO_USER; 5865 } 5866 } 5867 5868 if (shouldDispatchInputWhenNonInteractive(displayId, KEYCODE_UNKNOWN)) { 5869 return ACTION_PASS_TO_USER; 5870 } 5871 5872 // If we have not passed the action up and we are in theater mode without dreaming, 5873 // there will be no dream to intercept the touch and wake into ambient. The device should 5874 // wake up in this case. 5875 if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) { 5876 if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source, 5877 action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) { 5878 // Woke up. Pass motion events to user. 5879 return ACTION_PASS_TO_USER; 5880 } 5881 } 5882 5883 return 0; 5884 } 5885 5886 private boolean shouldDispatchInputWhenNonInteractive(int displayId, int keyCode) { 5887 // Apply the default display policy to unknown displays as well. 5888 final boolean isDefaultDisplay = displayId == DEFAULT_DISPLAY 5889 || displayId == INVALID_DISPLAY; 5890 final Display display = isDefaultDisplay 5891 ? mDefaultDisplay 5892 : mDisplayManager.getDisplay(displayId); 5893 final boolean displayOff = (display == null 5894 || display.getState() == STATE_OFF); 5895 5896 if (displayOff) { 5897 return false; 5898 } 5899 5900 // Send events to keyguard while the screen is on and it's showing. 5901 if (isKeyguardShowingAndNotOccluded()) { 5902 return true; 5903 } 5904 5905 // TODO(b/123372519): Refine when dream can support multi display. 5906 if (isDefaultDisplay) { 5907 // Send events to a dozing dream since the dream is in control of the state of the 5908 // screen. 5909 IDreamManager dreamManager = getDreamManager(); 5910 5911 try { 5912 if (dreamManager != null && dreamManager.isDreaming()) { 5913 return true; 5914 } 5915 } catch (RemoteException e) { 5916 Slog.e(TAG, "RemoteException when checking if dreaming", e); 5917 } 5918 } 5919 5920 // Otherwise, consume events since the user can't see what is being 5921 // interacted with. 5922 return false; 5923 } 5924 5925 // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, 5926 // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE 5927 private void dispatchDirectAudioEvent(KeyEvent event) { 5928 // When System Audio Mode is off, volume keys received by AVR can be either consumed by AVR 5929 // or forwarded to the TV. It's up to Amplifier manufacturer’s implementation. 5930 HdmiControlManager hdmiControlManager = getHdmiControlManager(); 5931 if (null != hdmiControlManager 5932 && !hdmiControlManager.getSystemAudioMode() 5933 && shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff()) { 5934 HdmiAudioSystemClient audioSystemClient = hdmiControlManager.getAudioSystemClient(); 5935 if (audioSystemClient != null) { 5936 audioSystemClient.sendKeyEvent( 5937 event.getKeyCode(), event.getAction() == KeyEvent.ACTION_DOWN); 5938 return; 5939 } 5940 } 5941 try { 5942 getAudioService().handleVolumeKey(event, mUseTvRouting, 5943 mContext.getOpPackageName(), TAG); 5944 } catch (Exception e) { 5945 Log.e(TAG, "Error dispatching volume key in handleVolumeKey for event:" 5946 + event, e); 5947 } 5948 } 5949 5950 @Nullable 5951 private HdmiControlManager getHdmiControlManager() { 5952 if (!mHasFeatureHdmiCec) { 5953 return null; 5954 } 5955 return (HdmiControlManager) mContext.getSystemService(HdmiControlManager.class); 5956 } 5957 5958 private boolean shouldCecAudioDeviceForwardVolumeKeysSystemAudioModeOff() { 5959 return RoSystemProperties.CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF; 5960 } 5961 5962 void dispatchMediaKeyWithWakeLock(KeyEvent event) { 5963 if (DEBUG_INPUT) { 5964 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event); 5965 } 5966 5967 if (mHavePendingMediaKeyRepeatWithWakeLock) { 5968 if (DEBUG_INPUT) { 5969 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat"); 5970 } 5971 5972 mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK); 5973 mHavePendingMediaKeyRepeatWithWakeLock = false; 5974 mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock 5975 } 5976 5977 dispatchMediaKeyWithWakeLockToAudioService(event); 5978 5979 if (event.getAction() == KeyEvent.ACTION_DOWN 5980 && event.getRepeatCount() == 0) { 5981 mHavePendingMediaKeyRepeatWithWakeLock = true; 5982 5983 Message msg = mHandler.obtainMessage( 5984 MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event); 5985 msg.setAsynchronous(true); 5986 mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout()); 5987 } else { 5988 mBroadcastWakeLock.release(); 5989 } 5990 } 5991 5992 void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) { 5993 mHavePendingMediaKeyRepeatWithWakeLock = false; 5994 5995 KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event, 5996 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS); 5997 if (DEBUG_INPUT) { 5998 Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent); 5999 } 6000 6001 dispatchMediaKeyWithWakeLockToAudioService(repeatEvent); 6002 mBroadcastWakeLock.release(); 6003 } 6004 6005 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) { 6006 if (mActivityManagerInternal.isSystemReady()) { 6007 MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true); 6008 } 6009 } 6010 6011 void launchVoiceAssistWithWakeLock() { 6012 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 6013 6014 final Intent voiceIntent; 6015 if (!keyguardOn()) { 6016 voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH); 6017 } else { 6018 DeviceIdleManager dim = mContext.getSystemService(DeviceIdleManager.class); 6019 if (dim != null) { 6020 dim.endIdle("voice-search"); 6021 } 6022 voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 6023 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true); 6024 } 6025 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 6026 mBroadcastWakeLock.release(); 6027 } 6028 6029 BroadcastReceiver mDockReceiver = new BroadcastReceiver() { 6030 @Override 6031 public void onReceive(Context context, Intent intent) { 6032 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 6033 mDefaultDisplayPolicy.setDockMode(intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 6034 Intent.EXTRA_DOCK_STATE_UNDOCKED)); 6035 } else { 6036 try { 6037 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface( 6038 ServiceManager.getService(Context.UI_MODE_SERVICE)); 6039 mUiMode = uiModeService.getCurrentModeType(); 6040 } catch (RemoteException e) { 6041 } 6042 } 6043 updateRotation(true); 6044 mDefaultDisplayRotation.updateOrientationListener(); 6045 } 6046 }; 6047 6048 BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() { 6049 @Override 6050 public void onReceive(Context context, Intent intent) { 6051 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 6052 // tickle the settings observer: this first ensures that we're 6053 // observing the relevant settings for the newly-active user, 6054 // and then updates our own bookkeeping based on the now- 6055 // current user. 6056 mSettingsObserver.onChange(false); 6057 mDefaultDisplayRotation.onUserSwitch(); 6058 mWindowManagerFuncs.onUserSwitched(); 6059 } 6060 } 6061 }; 6062 6063 @Override 6064 public void startedWakingUpGlobal(@WakeReason int reason) { 6065 6066 } 6067 6068 @Override 6069 public void finishedWakingUpGlobal(@WakeReason int reason) { 6070 6071 } 6072 6073 @Override 6074 public void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) { 6075 mDeviceGoingToSleep = true; 6076 } 6077 6078 @Override 6079 public void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) { 6080 mDeviceGoingToSleep = false; 6081 } 6082 6083 // Called on the PowerManager's Notifier thread. 6084 @Override 6085 public void startedGoingToSleep(int displayGroupId, 6086 @PowerManager.GoToSleepReason int pmSleepReason) { 6087 if (DEBUG_WAKEUP) { 6088 Slog.i(TAG, "Started going to sleep... (groupId=" + displayGroupId + " why=" 6089 + WindowManagerPolicyConstants.offReasonToString( 6090 WindowManagerPolicyConstants.translateSleepReasonToOffReason( 6091 pmSleepReason)) + ")"); 6092 } 6093 if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) { 6094 return; 6095 } 6096 6097 mRequestedOrSleepingDefaultDisplay = true; 6098 mIsGoingToSleepDefaultDisplay = true; 6099 6100 if (mKeyguardDelegate != null) { 6101 mKeyguardDelegate.onStartedGoingToSleep(pmSleepReason); 6102 } 6103 } 6104 6105 // Called on the PowerManager's Notifier thread. 6106 @Override 6107 public void finishedGoingToSleep(int displayGroupId, 6108 @PowerManager.GoToSleepReason int pmSleepReason) { 6109 if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) { 6110 return; 6111 } 6112 EventLogTags.writeScreenToggled(0); 6113 if (DEBUG_WAKEUP) { 6114 Slog.i(TAG, "Finished going to sleep... (groupId=" + displayGroupId + " why=" 6115 + WindowManagerPolicyConstants.offReasonToString( 6116 WindowManagerPolicyConstants.translateSleepReasonToOffReason( 6117 pmSleepReason)) + ")"); 6118 } 6119 MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000); 6120 6121 mRequestedOrSleepingDefaultDisplay = false; 6122 mIsGoingToSleepDefaultDisplay = false; 6123 mDefaultDisplayPolicy.setAwake(false); 6124 6125 // We must get this work done here because the power manager will drop 6126 // the wake lock and let the system suspend once this function returns. 6127 synchronized (mLock) { 6128 updateWakeGestureListenerLp(); 6129 updateLockScreenTimeout(); 6130 } 6131 mDefaultDisplayRotation.updateOrientationListener(); 6132 6133 if (mKeyguardDelegate != null) { 6134 mKeyguardDelegate.onFinishedGoingToSleep(pmSleepReason, 6135 mPowerButtonLaunchGestureTriggeredDuringGoingToSleep); 6136 } 6137 if (mDisplayFoldController != null) { 6138 mDisplayFoldController.finishedGoingToSleep(); 6139 } 6140 mPowerButtonLaunchGestureTriggeredDuringGoingToSleep = false; 6141 mPowerButtonLaunchGestureTriggered = false; 6142 } 6143 6144 // Called on the PowerManager's Notifier thread. 6145 @Override 6146 public void startedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) { 6147 if (DEBUG_WAKEUP) { 6148 Slog.i(TAG, "Started waking up... (groupId=" + displayGroupId + " why=" 6149 + WindowManagerPolicyConstants.onReasonToString( 6150 WindowManagerPolicyConstants.translateWakeReasonToOnReason( 6151 pmWakeReason)) + ")"); 6152 } 6153 if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) { 6154 return; 6155 } 6156 EventLogTags.writeScreenToggled(1); 6157 6158 mIsGoingToSleepDefaultDisplay = false; 6159 mDefaultDisplayPolicy.setAwake(true); 6160 6161 // Since goToSleep performs these functions synchronously, we must 6162 // do the same here. We cannot post this work to a handler because 6163 // that might cause it to become reordered with respect to what 6164 // may happen in a future call to goToSleep. 6165 synchronized (mLock) { 6166 updateWakeGestureListenerLp(); 6167 updateLockScreenTimeout(); 6168 } 6169 mDefaultDisplayRotation.updateOrientationListener(); 6170 6171 if (mKeyguardDelegate != null) { 6172 mKeyguardDelegate.onStartedWakingUp(pmWakeReason, mPowerButtonLaunchGestureTriggered); 6173 } 6174 6175 mPowerButtonLaunchGestureTriggered = false; 6176 } 6177 6178 // Called on the PowerManager's Notifier thread. 6179 @Override 6180 public void finishedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) { 6181 if (DEBUG_WAKEUP) { 6182 Slog.i(TAG, "Finished waking up... (groupId=" + displayGroupId + " why=" 6183 + WindowManagerPolicyConstants.onReasonToString( 6184 WindowManagerPolicyConstants.translateWakeReasonToOnReason( 6185 pmWakeReason)) + ")"); 6186 } 6187 if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) { 6188 return; 6189 } 6190 6191 if (mKeyguardDelegate != null) { 6192 mKeyguardDelegate.onFinishedWakingUp(); 6193 } 6194 if (mDisplayFoldController != null) { 6195 mDisplayFoldController.finishedWakingUp(); 6196 } 6197 } 6198 6199 private boolean shouldWakeUpWithHomeIntent() { 6200 if (mWakeUpToLastStateTimeout <= 0) { 6201 return false; 6202 } 6203 6204 final long sleepDurationRealtime = 6205 mPowerManagerInternal.getLastWakeup().sleepDurationRealtime; 6206 if (DEBUG_WAKEUP) { 6207 Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDurationRealtime= " + sleepDurationRealtime 6208 + " mWakeUpToLastStateTimeout= " + mWakeUpToLastStateTimeout); 6209 } 6210 return sleepDurationRealtime > mWakeUpToLastStateTimeout; 6211 } 6212 6213 private void wakeUpFromWakeKey(KeyEvent event) { 6214 if (!isKeyEventForCurrentUser( 6215 event.getDisplayId(), event.getKeyCode(), "wakeUpFromWakeKey")) { 6216 return; 6217 } 6218 wakeUpFromWakeKey( 6219 event.getEventTime(), 6220 event.getKeyCode(), 6221 event.getAction() == KeyEvent.ACTION_DOWN); 6222 } 6223 6224 private void wakeUpFromWakeKey(long eventTime, int keyCode, boolean isDown) { 6225 if (mWindowWakeUpPolicy.wakeUpFromKey(DEFAULT_DISPLAY, eventTime, keyCode, isDown)) { 6226 final boolean keyCanLaunchHome = keyCode == KEYCODE_HOME || keyCode == KEYCODE_POWER; 6227 // Start HOME with "reason" extra if sleeping for more than mWakeUpToLastStateTimeout 6228 if (shouldWakeUpWithHomeIntent() && keyCanLaunchHome) { 6229 startDockOrHome( 6230 DEFAULT_DISPLAY, 6231 /*fromHomeKey*/ keyCode == KEYCODE_HOME, 6232 /*wakenFromDreams*/ true, 6233 "Wake from " + KeyEvent. keyCodeToString(keyCode)); 6234 } 6235 } 6236 } 6237 6238 private void finishKeyguardDrawn() { 6239 if (!mDefaultDisplayPolicy.finishKeyguardDrawn()) { 6240 return; 6241 } 6242 6243 synchronized (mLock) { 6244 if (mKeyguardDelegate != null) { 6245 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6246 } 6247 } 6248 6249 // ... eventually calls finishWindowsDrawn which will finalize our screen turn on 6250 // as well as enabling the orientation change logic/sensor. 6251 Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, 6252 TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD, INVALID_DISPLAY /* cookie */); 6253 mWindowManagerInternal.waitForAllWindowsDrawn(mHandler.obtainMessage( 6254 MSG_WINDOW_MANAGER_DRAWN_COMPLETE, INVALID_DISPLAY, 0), 6255 WAITING_FOR_DRAWN_TIMEOUT, INVALID_DISPLAY); 6256 } 6257 6258 // Called on the DisplayManager's DisplayPowerController thread. 6259 @Override 6260 public void screenTurnedOff(int displayId, boolean isSwappingDisplay) { 6261 if (DEBUG_WAKEUP) Slog.i(TAG, "Display" + displayId + " turned off..."); 6262 6263 if (displayId == DEFAULT_DISPLAY) { 6264 final boolean acquireSleepToken = !isSwappingDisplay || mIsGoingToSleepDefaultDisplay; 6265 mRequestedOrSleepingDefaultDisplay = false; 6266 mDefaultDisplayPolicy.screenTurnedOff(acquireSleepToken); 6267 synchronized (mLock) { 6268 if (mKeyguardDelegate != null) { 6269 mKeyguardDelegate.onScreenTurnedOff(); 6270 } 6271 } 6272 mDefaultDisplayRotation.updateOrientationListener(); 6273 reportScreenStateToVrManager(false); 6274 } 6275 } 6276 6277 @Override 6278 public void onDisplaySwitchStart(int displayId) { 6279 if (displayId == DEFAULT_DISPLAY) { 6280 mDefaultDisplayPolicy.onDisplaySwitchStart(); 6281 } 6282 } 6283 6284 private long getKeyguardDrawnTimeout() { 6285 final boolean bootCompleted = 6286 LocalServices.getService(SystemServiceManager.class).isBootCompleted(); 6287 // Set longer timeout if it has not booted yet to prevent showing empty window. 6288 return bootCompleted ? mKeyguardDrawnTimeout : 5000; 6289 } 6290 6291 @Nullable 6292 private WallpaperManagerInternal getWallpaperManagerInternal() { 6293 if (mWallpaperManagerInternal == null) { 6294 mWallpaperManagerInternal = LocalServices.getService(WallpaperManagerInternal.class); 6295 } 6296 return mWallpaperManagerInternal; 6297 } 6298 6299 private void reportScreenTurningOnToWallpaper(int displayId) { 6300 WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal(); 6301 if (wallpaperManagerInternal != null) { 6302 wallpaperManagerInternal.onScreenTurningOn(displayId); 6303 } 6304 } 6305 6306 private void reportScreenTurnedOnToWallpaper(int displayId) { 6307 WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal(); 6308 if (wallpaperManagerInternal != null) { 6309 wallpaperManagerInternal.onScreenTurnedOn(displayId); 6310 } 6311 } 6312 6313 // Called on the DisplayManager's DisplayPowerController thread. 6314 @Override 6315 public void screenTurningOn(int displayId, final ScreenOnListener screenOnListener) { 6316 if (DEBUG_WAKEUP) Slog.i(TAG, "Display " + displayId + " turning on..."); 6317 6318 reportScreenTurningOnToWallpaper(displayId); 6319 if (displayId == DEFAULT_DISPLAY) { 6320 Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 6321 0 /* cookie */); 6322 mDefaultDisplayPolicy.screenTurningOn(screenOnListener); 6323 mBootAnimationDismissable = false; 6324 6325 synchronized (mLock) { 6326 if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) { 6327 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6328 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 6329 getKeyguardDrawnTimeout()); 6330 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); 6331 } else { 6332 if (DEBUG_WAKEUP) Slog.d(TAG, 6333 "null mKeyguardDelegate: setting mKeyguardDrawComplete."); 6334 mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE); 6335 } 6336 } 6337 } else { 6338 mScreenOnListeners.put(displayId, screenOnListener); 6339 6340 Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, 6341 TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD, displayId /* cookie */); 6342 mWindowManagerInternal.waitForAllWindowsDrawn(mHandler.obtainMessage( 6343 MSG_WINDOW_MANAGER_DRAWN_COMPLETE, displayId, 0), 6344 WAITING_FOR_DRAWN_TIMEOUT, displayId); 6345 } 6346 } 6347 6348 // Called on the DisplayManager's DisplayPowerController thread. 6349 @Override 6350 public void screenTurnedOn(int displayId) { 6351 if (DEBUG_WAKEUP) Slog.i(TAG, "Display " + displayId + " turned on..."); 6352 6353 reportScreenTurnedOnToWallpaper(displayId); 6354 6355 if (displayId != DEFAULT_DISPLAY) { 6356 return; 6357 } 6358 6359 synchronized (mLock) { 6360 if (mKeyguardDelegate != null) { 6361 mKeyguardDelegate.onScreenTurnedOn(); 6362 } 6363 } 6364 mDefaultDisplayPolicy.screenTurnedOn(); 6365 reportScreenStateToVrManager(true); 6366 } 6367 6368 @Override 6369 public void screenTurningOff(int displayId, ScreenOffListener screenOffListener) { 6370 mWindowManagerFuncs.screenTurningOff(displayId, screenOffListener); 6371 if (displayId != DEFAULT_DISPLAY) { 6372 return; 6373 } 6374 6375 mRequestedOrSleepingDefaultDisplay = true; 6376 synchronized (mLock) { 6377 if (mKeyguardDelegate != null) { 6378 mKeyguardDelegate.onScreenTurningOff(); 6379 } 6380 } 6381 } 6382 6383 private void reportScreenStateToVrManager(boolean isScreenOn) { 6384 if (mVrManagerInternal == null) { 6385 return; 6386 } 6387 mVrManagerInternal.onScreenStateChanged(isScreenOn); 6388 } 6389 6390 private void finishWindowsDrawn(int displayId) { 6391 if (displayId != DEFAULT_DISPLAY && displayId != INVALID_DISPLAY) { 6392 final ScreenOnListener screenOnListener = mScreenOnListeners.removeReturnOld(displayId); 6393 if (screenOnListener != null) { 6394 screenOnListener.onScreenOn(); 6395 } 6396 return; 6397 } 6398 6399 if (!mDefaultDisplayPolicy.finishWindowsDrawn()) { 6400 return; 6401 } 6402 6403 finishScreenTurningOn(); 6404 } 6405 6406 private void finishScreenTurningOn() { 6407 // We have just finished drawing screen content. Since the orientation listener 6408 // gets only installed when all windows are drawn, we try to install it again. 6409 mDefaultDisplayRotation.updateOrientationListener(); 6410 6411 final ScreenOnListener listener = mDefaultDisplayPolicy.getScreenOnListener(); 6412 if (!mDefaultDisplayPolicy.finishScreenTurningOn()) { 6413 return; // Spurious or not ready yet. 6414 } 6415 Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */); 6416 6417 enableScreen(listener, true /* report */); 6418 } 6419 6420 private void enableScreen(ScreenOnListener listener, boolean report) { 6421 final boolean enableScreen; 6422 final boolean awake = mDefaultDisplayPolicy.isAwake(); 6423 synchronized (mLock) { 6424 // Remember the first time we draw the keyguard so we know when we're done with 6425 // the main part of booting and can enable the screen and hide boot messages. 6426 if (!mKeyguardDrawnOnce && awake) { 6427 mKeyguardDrawnOnce = true; 6428 enableScreen = true; 6429 if (mBootMessageNeedsHiding) { 6430 mBootMessageNeedsHiding = false; 6431 hideBootMessages(); 6432 } 6433 } else { 6434 enableScreen = false; 6435 } 6436 } 6437 6438 if (report) { 6439 if (listener != null) { 6440 listener.onScreenOn(); 6441 } 6442 } 6443 6444 if (enableScreen) { 6445 mWindowManagerFuncs.enableScreenIfNeeded(); 6446 } 6447 } 6448 6449 private void handleHideBootMessage() { 6450 synchronized (mLock) { 6451 if (!mKeyguardDrawnOnce) { 6452 mBootMessageNeedsHiding = true; 6453 return; // keyguard hasn't drawn the first time yet, not done booting 6454 } 6455 } 6456 6457 if (mBootMsgDialog != null) { 6458 if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing"); 6459 mBootMsgDialog.dismiss(); 6460 mBootMsgDialog = null; 6461 } 6462 } 6463 6464 @Override 6465 public boolean isScreenOn() { 6466 return mDefaultDisplayPolicy.isScreenOnEarly(); 6467 } 6468 6469 @Override 6470 public boolean okToAnimate(boolean ignoreScreenOn) { 6471 return (ignoreScreenOn || isScreenOn()) && !mDeviceGoingToSleep; 6472 } 6473 6474 /** {@inheritDoc} */ 6475 @Override 6476 public void enableKeyguard(boolean enabled) { 6477 if (mKeyguardDelegate != null) { 6478 mKeyguardDelegate.setKeyguardEnabled(enabled); 6479 } 6480 } 6481 6482 /** {@inheritDoc} */ 6483 @Override 6484 public void exitKeyguardSecurely(OnKeyguardExitResult callback) { 6485 if (mKeyguardDelegate != null) { 6486 mKeyguardDelegate.verifyUnlock(callback); 6487 } 6488 } 6489 6490 @Override 6491 public boolean isKeyguardShowing() { 6492 if (mKeyguardDelegate == null) return false; 6493 return mKeyguardDelegate.isShowing(); 6494 } 6495 6496 @Override 6497 public boolean isKeyguardShowingAndNotOccluded() { 6498 if (mKeyguardDelegate == null) return false; 6499 return mKeyguardDelegate.isShowing() && !isKeyguardOccluded(); 6500 } 6501 6502 @Override 6503 public boolean isKeyguardTrustedLw() { 6504 if (mKeyguardDelegate == null) return false; 6505 return mKeyguardDelegate.isTrusted(); 6506 } 6507 6508 /** {@inheritDoc} */ 6509 @Override 6510 public boolean isKeyguardLocked() { 6511 return keyguardOn(); 6512 } 6513 6514 /** {@inheritDoc} */ 6515 @Override 6516 public boolean isKeyguardSecure(int userId) { 6517 if (mKeyguardDelegate == null) return false; 6518 return mKeyguardDelegate.isSecure(userId); 6519 } 6520 6521 /** {@inheritDoc} */ 6522 @Override 6523 public boolean isKeyguardOccluded() { 6524 if (mKeyguardDelegate == null) return false; 6525 return mKeyguardDelegate.isOccluded(); 6526 } 6527 6528 /** {@inheritDoc} */ 6529 @Override 6530 public boolean inKeyguardRestrictedKeyInputMode() { 6531 if (mKeyguardDelegate == null) return false; 6532 return mKeyguardDelegate.isInputRestricted(); 6533 } 6534 6535 @Override 6536 public void dismissKeyguardLw(IKeyguardDismissCallback callback, CharSequence message) { 6537 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 6538 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw"); 6539 6540 // ask the keyguard to prompt the user to authenticate if necessary 6541 mKeyguardDelegate.dismiss(callback, message); 6542 } else if (callback != null) { 6543 try { 6544 callback.onDismissError(); 6545 } catch (RemoteException e) { 6546 Slog.w(TAG, "Failed to call callback", e); 6547 } 6548 } 6549 } 6550 6551 @Override 6552 public boolean isKeyguardDrawnLw() { 6553 synchronized (mLock) { 6554 return mKeyguardDrawnOnce; 6555 } 6556 } 6557 6558 @Override 6559 public void startKeyguardExitAnimation(long startTime) { 6560 if (mKeyguardDelegate != null) { 6561 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation"); 6562 mKeyguardDelegate.startKeyguardExitAnimation(startTime); 6563 } 6564 } 6565 6566 void sendCloseSystemWindows() { 6567 PhoneWindow.sendCloseSystemWindows(mContext, null); 6568 } 6569 6570 void sendCloseSystemWindows(String reason) { 6571 PhoneWindow.sendCloseSystemWindows(mContext, reason); 6572 } 6573 6574 @Override 6575 public void setSafeMode(boolean safeMode) { 6576 mSafeMode = safeMode; 6577 if (safeMode) { 6578 performHapticFeedback( 6579 HapticFeedbackConstants.SAFE_MODE_ENABLED, 6580 "Safe Mode Enabled" /* reason */, 6581 HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); 6582 } 6583 } 6584 6585 private void bindKeyguard() { 6586 synchronized (mLock) { 6587 if (mKeyguardBound) { 6588 return; 6589 } 6590 mKeyguardBound = true; 6591 } 6592 mKeyguardDelegate.bindService(mContext); 6593 } 6594 6595 @Override 6596 public void onSystemUiStarted() { 6597 bindKeyguard(); 6598 } 6599 6600 /** {@inheritDoc} */ 6601 @Override 6602 public void systemReady() { 6603 // In normal flow, systemReady is called before other system services are ready. 6604 // So it is better not to bind keyguard here. 6605 mKeyguardDelegate.onSystemReady(); 6606 mModifierShortcutManager.onSystemReady(); 6607 6608 mVrManagerInternal = LocalServices.getService(VrManagerInternal.class); 6609 if (mVrManagerInternal != null) { 6610 mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); 6611 } 6612 6613 mDockObserverInternal = LocalServices.getService(DockObserverInternal.class); 6614 if (mDockObserverInternal != null) { 6615 // Get initial state from DockObserverInternal, DockObserver starts after WM. 6616 int dockMode = mDockObserverInternal.getActualDockState(); 6617 mDefaultDisplayPolicy.setDockMode(dockMode); 6618 } 6619 6620 readCameraLensCoverState(); 6621 updateUiMode(); 6622 mDefaultDisplayRotation.updateOrientationListener(); 6623 synchronized (mLock) { 6624 mSystemReady = true; 6625 updateSettings(mHandler); 6626 // If this happens, for whatever reason, systemReady came later than systemBooted. 6627 // And keyguard should be already bound from systemBooted 6628 if (mSystemBooted) { 6629 mKeyguardDelegate.onBootCompleted(); 6630 } 6631 } 6632 6633 mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class); 6634 mGestureLauncherService = LocalServices.getService(GestureLauncherService.class); 6635 } 6636 6637 /** {@inheritDoc} */ 6638 @Override 6639 public void systemBooted() { 6640 bindKeyguard(); 6641 synchronized (mLock) { 6642 mSystemBooted = true; 6643 if (mSystemReady) { 6644 mKeyguardDelegate.onBootCompleted(); 6645 } 6646 } 6647 mSideFpsEventHandler.onFingerprintSensorReady(); 6648 startedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN); 6649 finishedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN); 6650 6651 int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState(); 6652 boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON; 6653 boolean defaultScreenTurningOn = mDefaultDisplayPolicy.getScreenOnListener() != null; 6654 if (defaultDisplayOn || defaultScreenTurningOn) { 6655 // Now that system is booted, wait for keyguard and windows to be drawn before 6656 // updating the orientation listener, stopping the boot animation and enabling screen. 6657 screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener()); 6658 screenTurnedOn(DEFAULT_DISPLAY); 6659 } else { 6660 // We're not turning the screen on, so don't wait for keyguard to be drawn 6661 // to dismiss the boot animation and finish booting 6662 mBootAnimationDismissable = true; 6663 enableScreen(null, false /* report */); 6664 } 6665 } 6666 6667 @Override 6668 public boolean canDismissBootAnimation() { 6669 // Allow to dismiss the boot animation if the keyguard has finished drawing, 6670 // or mBootAnimationDismissable has been set 6671 return mDefaultDisplayPolicy.isKeyguardDrawComplete() || mBootAnimationDismissable; 6672 } 6673 6674 ProgressDialog mBootMsgDialog = null; 6675 6676 /** {@inheritDoc} */ 6677 @Override 6678 public void showBootMessage(final CharSequence msg, final boolean always) { 6679 mHandler.post(new Runnable() { 6680 @Override public void run() { 6681 if (mBootMsgDialog == null) { 6682 int theme; 6683 if (mPackageManager.hasSystemFeature(FEATURE_LEANBACK)) { 6684 theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert; 6685 } else { 6686 theme = 0; 6687 } 6688 6689 mBootMsgDialog = new ProgressDialog(mContext, theme) { 6690 // This dialog will consume all events coming in to 6691 // it, to avoid it trying to do things too early in boot. 6692 @Override public boolean dispatchKeyEvent(KeyEvent event) { 6693 return true; 6694 } 6695 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { 6696 return true; 6697 } 6698 @Override public boolean dispatchTouchEvent(MotionEvent ev) { 6699 return true; 6700 } 6701 @Override public boolean dispatchTrackballEvent(MotionEvent ev) { 6702 return true; 6703 } 6704 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) { 6705 return true; 6706 } 6707 @Override public boolean dispatchPopulateAccessibilityEvent( 6708 AccessibilityEvent event) { 6709 return true; 6710 } 6711 }; 6712 if (mPackageManager.isDeviceUpgrading()) { 6713 mBootMsgDialog.setTitle(R.string.android_upgrading_title); 6714 } else { 6715 mBootMsgDialog.setTitle(R.string.android_start_title); 6716 } 6717 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 6718 mBootMsgDialog.setIndeterminate(true); 6719 mBootMsgDialog.getWindow().setType( 6720 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS); 6721 mBootMsgDialog.getWindow().addFlags( 6722 WindowManager.LayoutParams.FLAG_DIM_BEHIND 6723 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 6724 mBootMsgDialog.getWindow().setDimAmount(1); 6725 WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes(); 6726 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 6727 lp.setFitInsetsTypes(0 /* types */); 6728 mBootMsgDialog.getWindow().setAttributes(lp); 6729 mBootMsgDialog.setCancelable(false); 6730 mBootMsgDialog.show(); 6731 } 6732 mBootMsgDialog.setMessage(msg); 6733 } 6734 }); 6735 } 6736 6737 /** {@inheritDoc} */ 6738 @Override 6739 public void hideBootMessages() { 6740 mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE); 6741 } 6742 6743 /** {@inheritDoc} */ 6744 @Override 6745 public void userActivity(int displayGroupId, int event) { 6746 if (displayGroupId == DEFAULT_DISPLAY && event == PowerManager.USER_ACTIVITY_EVENT_TOUCH) { 6747 mDefaultDisplayPolicy.onUserActivityEventTouch(); 6748 } 6749 synchronized (mScreenLockTimeout) { 6750 if (mLockScreenTimerActive) { 6751 // reset the timer 6752 mHandler.removeCallbacks(mScreenLockTimeout); 6753 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 6754 } 6755 } 6756 } 6757 6758 class ScreenLockTimeout implements Runnable { 6759 Bundle options; 6760 6761 @Override 6762 public void run() { 6763 synchronized (this) { 6764 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard"); 6765 if (mKeyguardDelegate != null) { 6766 mKeyguardDelegate.doKeyguardTimeout(options); 6767 } 6768 mLockScreenTimerActive = false; 6769 mLockNowPending = false; 6770 options = null; 6771 } 6772 } 6773 6774 public void setLockOptions(Bundle options) { 6775 this.options = options; 6776 } 6777 } 6778 6779 final ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout(); 6780 6781 @Override 6782 public void lockNow(Bundle options) { 6783 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 6784 mHandler.removeCallbacks(mScreenLockTimeout); 6785 if (options != null) { 6786 // In case multiple calls are made to lockNow, we don't wipe out the options 6787 // until the runnable actually executes. 6788 mScreenLockTimeout.setLockOptions(options); 6789 } 6790 mHandler.post(mScreenLockTimeout); 6791 synchronized (mScreenLockTimeout) { 6792 mLockNowPending = true; 6793 } 6794 } 6795 6796 // TODO (b/113840485): Move this logic to DisplayPolicy when lockscreen supports multi-display. 6797 @Override 6798 public void setAllowLockscreenWhenOn(int displayId, boolean allow) { 6799 // We should ignore this operation for visible background users 6800 // until lockscreen supports multi-display. 6801 if (mVisibleBackgroundUsersEnabled 6802 && mUserManagerInternal.getUserAssignedToDisplay(displayId) != mCurrentUserId) { 6803 return; 6804 } 6805 if (allow) { 6806 mAllowLockscreenWhenOnDisplays.add(displayId); 6807 } else { 6808 mAllowLockscreenWhenOnDisplays.remove(displayId); 6809 } 6810 updateLockScreenTimeout(); 6811 } 6812 6813 private void updateLockScreenTimeout() { 6814 synchronized (mScreenLockTimeout) { 6815 if (mLockNowPending) { 6816 Log.w(TAG, "lockNow pending, ignore updating lockscreen timeout"); 6817 return; 6818 } 6819 final boolean enable = !mAllowLockscreenWhenOnDisplays.isEmpty() 6820 && mDefaultDisplayPolicy.isAwake() 6821 && mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId); 6822 if (mLockScreenTimerActive != enable) { 6823 if (enable) { 6824 if (localLOGV) Log.v(TAG, "setting lockscreen timer"); 6825 mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests 6826 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 6827 } else { 6828 if (localLOGV) Log.v(TAG, "clearing lockscreen timer"); 6829 mHandler.removeCallbacks(mScreenLockTimeout); 6830 } 6831 mLockScreenTimerActive = enable; 6832 } 6833 } 6834 } 6835 6836 /** {@inheritDoc} */ 6837 @Override 6838 public void enableScreenAfterBoot() { 6839 readLidState(); 6840 applyLidSwitchState(); 6841 updateRotation(true); 6842 } 6843 6844 private void applyLidSwitchState() { 6845 final int lidState = mDefaultDisplayPolicy.getLidState(); 6846 if (lidState == LID_CLOSED) { 6847 int lidBehavior = getLidBehavior(); 6848 switch (lidBehavior) { 6849 case LID_BEHAVIOR_LOCK: 6850 mWindowManagerFuncs.lockDeviceNow(); 6851 break; 6852 case LID_BEHAVIOR_SLEEP: 6853 sleepDefaultDisplay(SystemClock.uptimeMillis(), 6854 PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH, 6855 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 6856 break; 6857 case LID_BEHAVIOR_NONE: 6858 // fall through 6859 default: 6860 break; 6861 } 6862 } 6863 6864 synchronized (mLock) { 6865 updateWakeGestureListenerLp(); 6866 } 6867 } 6868 6869 void updateUiMode() { 6870 if (mUiModeManager == null) { 6871 mUiModeManager = IUiModeManager.Stub.asInterface( 6872 ServiceManager.getService(Context.UI_MODE_SERVICE)); 6873 } 6874 try { 6875 mUiMode = mUiModeManager.getCurrentModeType(); 6876 } catch (RemoteException e) { 6877 } 6878 } 6879 6880 @Override 6881 public int getUiMode() { 6882 return mUiMode; 6883 } 6884 6885 void updateRotation(boolean alwaysSendConfiguration) { 6886 mWindowManagerFuncs.updateRotation(alwaysSendConfiguration, false /* forceRelayout */); 6887 } 6888 6889 /** 6890 * Return an Intent to launch the currently active dock app as home. Returns 6891 * null if the standard home should be launched, which is the case if any of the following is 6892 * true: 6893 * <ul> 6894 * <li>The device is not in either car mode or desk mode 6895 * <li>The device is in car mode but mEnableCarDockHomeCapture is false 6896 * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false 6897 * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME 6898 * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME 6899 * </ul> 6900 * @return A dock intent. 6901 */ 6902 Intent createHomeDockIntent() { 6903 Intent intent = null; 6904 6905 // What home does is based on the mode, not the dock state. That 6906 // is, when in car mode you should be taken to car home regardless 6907 // of whether we are actually in a car dock. 6908 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) { 6909 if (mEnableCarDockHomeCapture) { 6910 intent = mCarDockIntent; 6911 } 6912 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) { 6913 if (ENABLE_DESK_DOCK_HOME_CAPTURE) { 6914 intent = mDeskDockIntent; 6915 } 6916 } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH) { 6917 final int dockMode = mDefaultDisplayPolicy.getDockMode(); 6918 if (dockMode == Intent.EXTRA_DOCK_STATE_DESK 6919 || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK 6920 || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK) { 6921 // Always launch dock home from home when watch is docked, if it exists. 6922 intent = mDeskDockIntent; 6923 } 6924 } else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) { 6925 if (ENABLE_VR_HEADSET_HOME_CAPTURE) { 6926 intent = mVrHeadsetHomeIntent; 6927 } 6928 } 6929 6930 if (intent == null) { 6931 return null; 6932 } 6933 6934 ActivityInfo ai = null; 6935 ResolveInfo info = mPackageManager.resolveActivityAsUser( 6936 intent, 6937 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, 6938 mCurrentUserId); 6939 if (info != null) { 6940 ai = info.activityInfo; 6941 } 6942 if (ai != null 6943 && ai.metaData != null 6944 && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) { 6945 intent = new Intent(intent); 6946 intent.setClassName(ai.packageName, ai.name); 6947 return intent; 6948 } 6949 6950 return null; 6951 } 6952 6953 void startDockOrHome(int displayId, boolean fromHomeKey, boolean awakenFromDreams, 6954 String startReason) { 6955 try { 6956 ActivityManager.getService().stopAppSwitches(); 6957 } catch (RemoteException e) {} 6958 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 6959 6960 if (awakenFromDreams) { 6961 awakenDreams(); 6962 } 6963 6964 if (!mHasFeatureAuto && !isUserSetupComplete()) { 6965 Slog.i(TAG, "Not going home because user setup is in progress."); 6966 return; 6967 } 6968 6969 // Start dock. 6970 Intent dock = createHomeDockIntent(); 6971 if (dock != null) { 6972 try { 6973 if (fromHomeKey) { 6974 dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 6975 } 6976 startActivityAsUser(dock, UserHandle.CURRENT); 6977 return; 6978 } catch (ActivityNotFoundException e) { 6979 } 6980 } 6981 6982 if (DEBUG_WAKEUP) { 6983 Log.d(TAG, "startDockOrHome: startReason= " + startReason); 6984 } 6985 6986 int userId = mUserManagerInternal.getUserAssignedToDisplay(displayId); 6987 // Start home. 6988 mActivityTaskManagerInternal.startHomeOnDisplay(userId, startReason, 6989 displayId, true /* allowInstrumenting */, fromHomeKey); 6990 } 6991 6992 void startDockOrHome(int displayId, boolean fromHomeKey, boolean awakenFromDreams) { 6993 startDockOrHome(displayId, fromHomeKey, awakenFromDreams, /*startReason*/ 6994 "startDockOrHome"); 6995 } 6996 6997 /** 6998 * goes to the home screen 6999 * @return whether it did anything 7000 */ 7001 boolean goHome() { 7002 if (!isUserSetupComplete()) { 7003 Slog.i(TAG, "Not going home because user setup is in progress."); 7004 return false; 7005 } 7006 if (false) { 7007 // This code always brings home to the front. 7008 startDockOrHome(DEFAULT_DISPLAY, false /*fromHomeKey*/, true /* awakenFromDreams */); 7009 } else { 7010 // This code brings home to the front or, if it is already 7011 // at the front, puts the device to sleep. 7012 try { 7013 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) { 7014 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry. 7015 Log.d(TAG, "UTS-TEST-MODE"); 7016 } else { 7017 ActivityManager.getService().stopAppSwitches(); 7018 sendCloseSystemWindows(); 7019 final Intent dock = createHomeDockIntent(); 7020 if (dock != null) { 7021 int result = ActivityTaskManager.getService() 7022 .startActivityAsUser(null, mContext.getOpPackageName(), 7023 mContext.getAttributionTag(), dock, 7024 dock.resolveTypeIfNeeded(mContext.getContentResolver()), 7025 null, null, 0, 7026 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7027 null, null, UserHandle.USER_CURRENT); 7028 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7029 return false; 7030 } 7031 } 7032 } 7033 int result = ActivityTaskManager.getService() 7034 .startActivityAsUser(null, mContext.getOpPackageName(), 7035 mContext.getAttributionTag(), mHomeIntent, 7036 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()), 7037 null, null, 0, 7038 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7039 null, null, UserHandle.USER_CURRENT); 7040 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7041 return false; 7042 } 7043 } catch (RemoteException ex) { 7044 // bummer, the activity manager, which is in this process, is dead 7045 } 7046 } 7047 return true; 7048 } 7049 7050 private boolean isTheaterModeEnabled() { 7051 return Settings.Global.getInt(mContext.getContentResolver(), 7052 Settings.Global.THEATER_MODE_ON, 0) == 1; 7053 } 7054 7055 private void performHapticFeedback(int effectId, String reason) { 7056 performHapticFeedback(effectId, reason, 0 /* flags */); 7057 } 7058 7059 private void performHapticFeedback( 7060 int effectId, String reason, @HapticFeedbackConstants.Flags int flags) { 7061 mVibrator.performHapticFeedback(effectId, reason, flags, 0 /* privFlags */); 7062 } 7063 7064 @Override 7065 public boolean isGlobalKey(int keyCode) { 7066 return mGlobalKeyManager.shouldHandleGlobalKey(keyCode); 7067 } 7068 7069 7070 @Override 7071 public void keepScreenOnStartedLw() { 7072 } 7073 7074 @Override 7075 public void keepScreenOnStoppedLw() { 7076 if (isKeyguardShowingAndNotOccluded()) { 7077 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 7078 } 7079 } 7080 7081 // Use this instead of checking config_showNavigationBar so that it can be consistently 7082 // overridden by qemu.hw.mainkeys in the emulator. 7083 @Override 7084 public boolean hasNavigationBar() { 7085 return mDefaultDisplayPolicy.hasNavigationBar(); 7086 } 7087 7088 @Override 7089 public void setDismissImeOnBackKeyPressed(boolean newValue) { 7090 mDismissImeOnBackKeyPressed = newValue; 7091 } 7092 7093 @Override 7094 public void setCurrentUserLw(int newUserId) { 7095 mCurrentUserId = newUserId; 7096 if (mKeyguardDelegate != null) { 7097 mKeyguardDelegate.setCurrentUser(newUserId); 7098 } 7099 if (mAccessibilityShortcutController != null) { 7100 mAccessibilityShortcutController.setCurrentUser(newUserId); 7101 } 7102 StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); 7103 if (statusBar != null) { 7104 statusBar.setCurrentUser(newUserId); 7105 } 7106 if (modifierShortcutManagerMultiuser()) { 7107 mModifierShortcutManager.setCurrentUser(UserHandle.of(newUserId)); 7108 } 7109 if (!inputManagerLifecycleSupport()) { 7110 mInputManagerInternal.setCurrentUser(newUserId); 7111 } 7112 } 7113 7114 @Override 7115 public void setSwitchingUser(boolean switching) { 7116 mKeyguardDelegate.setSwitchingUser(switching); 7117 if (switching) { 7118 dismissKeyboardShortcutsMenu(); 7119 } 7120 } 7121 7122 @Override 7123 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 7124 final long token = proto.start(fieldId); 7125 proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode()); 7126 proto.write(ROTATION, mDefaultDisplayRotation.getUserRotation()); 7127 proto.write(ORIENTATION, mDefaultDisplayRotation.getCurrentAppOrientation()); 7128 proto.write(SCREEN_ON_FULLY, mDefaultDisplayPolicy.isScreenOnFully()); 7129 proto.write(KEYGUARD_DRAW_COMPLETE, mDefaultDisplayPolicy.isKeyguardDrawComplete()); 7130 proto.write(WINDOW_MANAGER_DRAW_COMPLETE, 7131 mDefaultDisplayPolicy.isWindowManagerDrawComplete()); 7132 proto.write(KEYGUARD_OCCLUDED, isKeyguardOccluded()); 7133 proto.write(KEYGUARD_OCCLUDED_CHANGED, mKeyguardOccludedChanged); 7134 proto.write(KEYGUARD_OCCLUDED_PENDING, mPendingKeyguardOccluded); 7135 if (mKeyguardDelegate != null) { 7136 mKeyguardDelegate.dumpDebug(proto, KEYGUARD_DELEGATE); 7137 } 7138 proto.end(token); 7139 } 7140 7141 @Override 7142 public void dump(String prefix, PrintWriter pw, String[] args) { 7143 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode); 7144 pw.print(" mSystemReady="); pw.print(mSystemReady); 7145 pw.print(" mSystemBooted="); pw.println(mSystemBooted); 7146 pw.print(prefix); pw.print("mCameraLensCoverState="); 7147 pw.println(WindowManagerFuncs.cameraLensStateToString(mCameraLensCoverState)); 7148 pw.print(prefix); pw.print("mWakeGestureEnabledSetting="); 7149 pw.println(mWakeGestureEnabledSetting); 7150 7151 pw.print(prefix); 7152 pw.print("mUiMode="); 7153 pw.print(Configuration.uiModeToString(mUiMode)); 7154 pw.print("mEnableCarDockHomeCapture="); pw.println(mEnableCarDockHomeCapture); 7155 pw.print(prefix); pw.print("mLidKeyboardAccessibility="); 7156 pw.print(mLidKeyboardAccessibility); 7157 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility); 7158 pw.print(" getLidBehavior="); pw.println(lidBehaviorToString(getLidBehavior())); 7159 pw.print(prefix); 7160 pw.print("mLongPressOnBackBehavior="); 7161 pw.println(longPressOnBackBehaviorToString(mLongPressOnBackBehavior)); 7162 pw.print(prefix); 7163 pw.print("mLongPressOnHomeBehavior="); 7164 pw.println(longPressOnHomeBehaviorToString(mLongPressOnHomeBehavior)); 7165 pw.print(prefix); 7166 pw.print("mDoubleTapOnHomeBehavior="); 7167 pw.println(doubleTapOnHomeBehaviorToString(mDoubleTapOnHomeBehavior)); 7168 pw.print(prefix); 7169 pw.print("mShortPressOnPowerBehavior="); 7170 pw.println(shortPressOnPowerBehaviorToString(mShortPressOnPowerBehavior)); 7171 pw.print(prefix); 7172 pw.print("mLongPressOnPowerBehavior="); 7173 pw.println(longPressOnPowerBehaviorToString(mLongPressOnPowerBehavior)); 7174 pw.print(prefix); 7175 pw.print("mSettingsKeyBehavior="); 7176 pw.println(settingsKeyBehaviorToString(mSettingsKeyBehavior)); 7177 pw.print(prefix); 7178 pw.print("mLongPressOnPowerAssistantTimeoutMs="); 7179 pw.println(mLongPressOnPowerAssistantTimeoutMs); 7180 pw.print(prefix); 7181 pw.print("mVeryLongPressOnPowerBehavior="); 7182 pw.println(veryLongPressOnPowerBehaviorToString(mVeryLongPressOnPowerBehavior)); 7183 pw.print(prefix); 7184 pw.print("mDoublePressOnPowerBehavior="); 7185 pw.println(multiPressOnPowerBehaviorToString(mDoublePressOnPowerBehavior)); 7186 pw.print(prefix); 7187 pw.print("mTriplePressOnPowerBehavior="); 7188 pw.println(multiPressOnPowerBehaviorToString(mTriplePressOnPowerBehavior)); 7189 pw.print(prefix); 7190 pw.print("mSupportShortPressPowerWhenDefaultDisplayOn="); 7191 pw.println(mSupportShortPressPowerWhenDefaultDisplayOn); 7192 pw.print(prefix); 7193 pw.print("mPowerVolUpBehavior="); 7194 pw.println(powerVolumeUpBehaviorToString(mPowerVolUpBehavior)); 7195 pw.print(prefix); 7196 pw.print("mShortPressOnSleepBehavior="); 7197 pw.println(shortPressOnSleepBehaviorToString(mShortPressOnSleepBehavior)); 7198 pw.print(prefix); 7199 pw.print("mShortPressOnWindowBehavior="); 7200 pw.println(shortPressOnWindowBehaviorToString(mShortPressOnWindowBehavior)); 7201 pw.print(prefix); 7202 pw.print("mShortPressOnStemPrimaryBehavior="); 7203 pw.println(shortPressOnStemPrimaryBehaviorToString( 7204 mShortPressOnStemPrimaryBehavior)); 7205 pw.print(prefix); 7206 pw.print("mDoublePressOnStemPrimaryBehavior="); 7207 pw.println(doublePressOnStemPrimaryBehaviorToString( 7208 mDoublePressOnStemPrimaryBehavior)); 7209 pw.print(prefix); 7210 pw.print("mTriplePressOnStemPrimaryBehavior="); 7211 pw.println(triplePressOnStemPrimaryBehaviorToString( 7212 mTriplePressOnStemPrimaryBehavior)); 7213 pw.print(prefix); 7214 pw.print("mLongPressOnStemPrimaryBehavior="); 7215 pw.println(longPressOnStemPrimaryBehaviorToString( 7216 mLongPressOnStemPrimaryBehavior)); 7217 pw.print(prefix); 7218 pw.print("mAllowStartActivityForLongPressOnPowerDuringSetup="); 7219 pw.println(mAllowStartActivityForLongPressOnPowerDuringSetup); 7220 pw.print(prefix); 7221 pw.print("mHasSoftInput="); pw.println(mHasSoftInput); 7222 pw.print(prefix); 7223 pw.print("mDismissImeOnBackKeyPressed="); pw.print(mDismissImeOnBackKeyPressed); 7224 pw.print(" mIncallPowerBehavior="); 7225 pw.println(incallPowerBehaviorToString(mIncallPowerBehavior)); 7226 pw.print(prefix); 7227 pw.print("mIncallBackBehavior="); 7228 pw.print(incallBackBehaviorToString(mIncallBackBehavior)); 7229 pw.print(" mEndcallBehavior="); 7230 pw.println(endcallBehaviorToString(mEndcallBehavior)); 7231 pw.print(prefix); 7232 // TODO(b/117479243): handle it in InputPolicy 7233 pw.println("mDisplayHomeButtonHandlers="); 7234 for (int i = 0; i < mDisplayHomeButtonHandlers.size(); i++) { 7235 final int key = mDisplayHomeButtonHandlers.keyAt(i); 7236 pw.print(prefix); pw.print(" "); pw.println(mDisplayHomeButtonHandlers.get(key)); 7237 } 7238 pw.print(prefix); pw.print("mKeyguardOccluded="); pw.print(isKeyguardOccluded()); 7239 pw.print(" mKeyguardOccludedChanged="); pw.print(mKeyguardOccludedChanged); 7240 pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded); 7241 pw.print(prefix); pw.print("mAllowLockscreenWhenOnDisplays="); 7242 pw.print(!mAllowLockscreenWhenOnDisplays.isEmpty()); 7243 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout); 7244 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive); 7245 pw.print(prefix); pw.print("mKidsModeEnabled="); pw.println(mKidsModeEnabled); 7246 7247 mGlobalKeyManager.dump(prefix, pw); 7248 mKeyCombinationManager.dump(prefix, pw); 7249 mSingleKeyGestureDetector.dump(prefix, pw); 7250 mDeferredKeyActionExecutor.dump(prefix, pw); 7251 7252 if (mWakeGestureListener != null) { 7253 mWakeGestureListener.dump(pw, prefix); 7254 } 7255 if (mBurnInProtectionHelper != null) { 7256 mBurnInProtectionHelper.dump(prefix, pw); 7257 } 7258 if (mKeyguardDelegate != null) { 7259 mKeyguardDelegate.dump(prefix, pw); 7260 } 7261 7262 pw.print(prefix); pw.println("Looper state:"); 7263 mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " "); 7264 if (modifierShortcutDump()) { 7265 mModifierShortcutManager.dump(prefix, pw); 7266 } 7267 } 7268 7269 private static String endcallBehaviorToString(int behavior) { 7270 StringBuilder sb = new StringBuilder(); 7271 if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0 ) { 7272 sb.append("home|"); 7273 } 7274 if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { 7275 sb.append("sleep|"); 7276 } 7277 7278 final int N = sb.length(); 7279 if (N == 0) { 7280 return "<nothing>"; 7281 } else { 7282 // Chop off the trailing '|' 7283 return sb.substring(0, N - 1); 7284 } 7285 } 7286 7287 private static String incallPowerBehaviorToString(int behavior) { 7288 if ((behavior & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0) { 7289 return "hangup"; 7290 } else { 7291 return "sleep"; 7292 } 7293 } 7294 7295 private static String incallBackBehaviorToString(int behavior) { 7296 if ((behavior & Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_HANGUP) != 0) { 7297 return "hangup"; 7298 } else { 7299 return "<nothing>"; 7300 } 7301 } 7302 7303 private static String longPressOnBackBehaviorToString(int behavior) { 7304 switch (behavior) { 7305 case LONG_PRESS_BACK_NOTHING: 7306 return "LONG_PRESS_BACK_NOTHING"; 7307 case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST: 7308 return "LONG_PRESS_BACK_GO_TO_VOICE_ASSIST"; 7309 default: 7310 return Integer.toString(behavior); 7311 } 7312 } 7313 7314 private static String longPressOnHomeBehaviorToString(int behavior) { 7315 switch (behavior) { 7316 case LONG_PRESS_HOME_NOTHING: 7317 return "LONG_PRESS_HOME_NOTHING"; 7318 case LONG_PRESS_HOME_ALL_APPS: 7319 return "LONG_PRESS_HOME_ALL_APPS"; 7320 case LONG_PRESS_HOME_ASSIST: 7321 return "LONG_PRESS_HOME_ASSIST"; 7322 case LONG_PRESS_HOME_NOTIFICATION_PANEL: 7323 return "LONG_PRESS_HOME_NOTIFICATION_PANEL"; 7324 default: 7325 return Integer.toString(behavior); 7326 } 7327 } 7328 7329 private static String doubleTapOnHomeBehaviorToString(int behavior) { 7330 switch (behavior) { 7331 case DOUBLE_TAP_HOME_NOTHING: 7332 return "DOUBLE_TAP_HOME_NOTHING"; 7333 case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI: 7334 return "DOUBLE_TAP_HOME_RECENT_SYSTEM_UI"; 7335 case DOUBLE_TAP_HOME_PIP_MENU: 7336 return "DOUBLE_TAP_HOME_PIP_MENU"; 7337 default: 7338 return Integer.toString(behavior); 7339 } 7340 } 7341 7342 private static String shortPressOnPowerBehaviorToString(int behavior) { 7343 switch (behavior) { 7344 case SHORT_PRESS_POWER_NOTHING: 7345 return "SHORT_PRESS_POWER_NOTHING"; 7346 case SHORT_PRESS_POWER_GO_TO_SLEEP: 7347 return "SHORT_PRESS_POWER_GO_TO_SLEEP"; 7348 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: 7349 return "SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP"; 7350 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME: 7351 return "SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME"; 7352 case SHORT_PRESS_POWER_GO_HOME: 7353 return "SHORT_PRESS_POWER_GO_HOME"; 7354 case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: 7355 return "SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME"; 7356 default: 7357 return Integer.toString(behavior); 7358 } 7359 } 7360 7361 private static String longPressOnPowerBehaviorToString(int behavior) { 7362 switch (behavior) { 7363 case LONG_PRESS_POWER_NOTHING: 7364 return "LONG_PRESS_POWER_NOTHING"; 7365 case LONG_PRESS_POWER_GLOBAL_ACTIONS: 7366 return "LONG_PRESS_POWER_GLOBAL_ACTIONS"; 7367 case LONG_PRESS_POWER_SHUT_OFF: 7368 return "LONG_PRESS_POWER_SHUT_OFF"; 7369 case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM: 7370 return "LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM"; 7371 case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST: 7372 return "LONG_PRESS_POWER_GO_TO_VOICE_ASSIST"; 7373 case LONG_PRESS_POWER_ASSISTANT: 7374 return "LONG_PRESS_POWER_ASSISTANT"; 7375 default: 7376 return Integer.toString(behavior); 7377 } 7378 } 7379 7380 private static String settingsKeyBehaviorToString(int behavior) { 7381 switch (behavior) { 7382 case SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY: 7383 return "SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY"; 7384 case SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL: 7385 return "SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL"; 7386 case SETTINGS_KEY_BEHAVIOR_NOTHING: 7387 return "SETTINGS_KEY_BEHAVIOR_NOTHING"; 7388 default: 7389 return Integer.toString(behavior); 7390 } 7391 } 7392 7393 private static String veryLongPressOnPowerBehaviorToString(int behavior) { 7394 switch (behavior) { 7395 case VERY_LONG_PRESS_POWER_NOTHING: 7396 return "VERY_LONG_PRESS_POWER_NOTHING"; 7397 case VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS: 7398 return "VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS"; 7399 default: 7400 return Integer.toString(behavior); 7401 } 7402 } 7403 7404 private static String powerVolumeUpBehaviorToString(int behavior) { 7405 switch (behavior) { 7406 case POWER_VOLUME_UP_BEHAVIOR_NOTHING: 7407 return "POWER_VOLUME_UP_BEHAVIOR_NOTHING"; 7408 case POWER_VOLUME_UP_BEHAVIOR_MUTE: 7409 return "POWER_VOLUME_UP_BEHAVIOR_MUTE"; 7410 case POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS: 7411 return "POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS"; 7412 default: 7413 return Integer.toString(behavior); 7414 } 7415 } 7416 7417 private static String multiPressOnPowerBehaviorToString(int behavior) { 7418 switch (behavior) { 7419 case MULTI_PRESS_POWER_NOTHING: 7420 return "MULTI_PRESS_POWER_NOTHING"; 7421 case MULTI_PRESS_POWER_THEATER_MODE: 7422 return "MULTI_PRESS_POWER_THEATER_MODE"; 7423 case MULTI_PRESS_POWER_BRIGHTNESS_BOOST: 7424 return "MULTI_PRESS_POWER_BRIGHTNESS_BOOST"; 7425 case MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY: 7426 return "MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY"; 7427 default: 7428 return Integer.toString(behavior); 7429 } 7430 } 7431 7432 private static String shortPressOnSleepBehaviorToString(int behavior) { 7433 switch (behavior) { 7434 case SHORT_PRESS_SLEEP_GO_TO_SLEEP: 7435 return "SHORT_PRESS_SLEEP_GO_TO_SLEEP"; 7436 case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME: 7437 return "SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME"; 7438 default: 7439 return Integer.toString(behavior); 7440 } 7441 } 7442 7443 private static String shortPressOnWindowBehaviorToString(int behavior) { 7444 switch (behavior) { 7445 case SHORT_PRESS_WINDOW_NOTHING: 7446 return "SHORT_PRESS_WINDOW_NOTHING"; 7447 case SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE: 7448 return "SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE"; 7449 default: 7450 return Integer.toString(behavior); 7451 } 7452 } 7453 7454 private static String shortPressOnStemPrimaryBehaviorToString(int behavior) { 7455 switch (behavior) { 7456 case SHORT_PRESS_PRIMARY_NOTHING: 7457 return "SHORT_PRESS_PRIMARY_NOTHING"; 7458 case SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS: 7459 return "SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS"; 7460 case SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY: 7461 return "SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY"; 7462 default: 7463 return Integer.toString(behavior); 7464 } 7465 } 7466 7467 private static String doublePressOnStemPrimaryBehaviorToString(int behavior) { 7468 switch (behavior) { 7469 case DOUBLE_PRESS_PRIMARY_NOTHING: 7470 return "DOUBLE_PRESS_PRIMARY_NOTHING"; 7471 case DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP: 7472 return "DOUBLE_PRESS_PRIMARY_SWITCH_RECENT_APP"; 7473 case DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP: 7474 return "DOUBLE_PRESS_PRIMARY_LAUNCH_DEFAULT_FITNESS_APP"; 7475 default: 7476 return Integer.toString(behavior); 7477 } 7478 } 7479 7480 private static String triplePressOnStemPrimaryBehaviorToString(int behavior) { 7481 switch (behavior) { 7482 case TRIPLE_PRESS_PRIMARY_NOTHING: 7483 return "TRIPLE_PRESS_PRIMARY_NOTHING"; 7484 case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY: 7485 return "TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY"; 7486 default: 7487 return Integer.toString(behavior); 7488 } 7489 } 7490 7491 private static String longPressOnStemPrimaryBehaviorToString(int behavior) { 7492 switch (behavior) { 7493 case LONG_PRESS_PRIMARY_NOTHING: 7494 return "LONG_PRESS_PRIMARY_NOTHING"; 7495 case LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT: 7496 return "LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT"; 7497 default: 7498 return Integer.toString(behavior); 7499 } 7500 } 7501 7502 private static String lidBehaviorToString(int behavior) { 7503 switch (behavior) { 7504 case LID_BEHAVIOR_LOCK: 7505 return "LID_BEHAVIOR_LOCK"; 7506 case LID_BEHAVIOR_SLEEP: 7507 return "LID_BEHAVIOR_SLEEP"; 7508 case LID_BEHAVIOR_NONE: 7509 return "LID_BEHAVIOR_NONE"; 7510 default: 7511 return Integer.toString(behavior); 7512 } 7513 } 7514 7515 public static boolean isLongPressToAssistantEnabled(Context context) { 7516 ContentResolver resolver = context.getContentResolver(); 7517 int longPressToAssistant = Settings.System.getIntForUser(resolver, 7518 Settings.Global.Wearable.CLOCKWORK_LONG_PRESS_TO_ASSISTANT_ENABLED, 7519 /* def= */ 1, 7520 UserHandle.USER_CURRENT); 7521 if(Log.isLoggable(TAG, Log.DEBUG)) { 7522 Log.d(TAG, "longPressToAssistant = " + longPressToAssistant); 7523 } 7524 return (longPressToAssistant == 1); 7525 } 7526 7527 private class HdmiVideoExtconUEventObserver extends ExtconStateObserver<Boolean> { 7528 private static final String HDMI_EXIST = "HDMI=1"; 7529 private static final String DP_EXIST = "DP=1"; 7530 private static final String NAME = "hdmi"; 7531 7532 private boolean init(ExtconInfo hdmi) { 7533 boolean plugged = false; 7534 try { 7535 plugged = parseStateFromFile(hdmi); 7536 } catch (FileNotFoundException e) { 7537 Slog.w(TAG, 7538 hdmi.getStatePath() 7539 + " not found while attempting to determine initial state", 7540 e); 7541 } catch (IOException e) { 7542 Slog.e(TAG, 7543 "Error reading " + hdmi.getStatePath() 7544 + " while attempting to determine initial state", 7545 e); 7546 } 7547 startObserving(hdmi); 7548 return plugged; 7549 } 7550 7551 @Override 7552 public void updateState(ExtconInfo extconInfo, String eventName, Boolean state) { 7553 mDefaultDisplayPolicy.setHdmiPlugged(state); 7554 } 7555 7556 @Override 7557 public Boolean parseState(ExtconInfo extconIfno, String state) { 7558 // extcon event state changes from kernel4.9 7559 // new state will be like STATE=HDMI=1 7560 // or like STATE=DP=1 for newer kernel 7561 return state.contains(HDMI_EXIST) || state.contains(DP_EXIST); 7562 } 7563 } 7564 7565 private void launchTargetSearchActivity() { 7566 Intent intent; 7567 if (mSearchKeyTargetActivity != null) { 7568 intent = new Intent(); 7569 intent.setComponent(mSearchKeyTargetActivity); 7570 } else { 7571 intent = new Intent(Intent.ACTION_WEB_SEARCH); 7572 } 7573 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 7574 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 7575 try { 7576 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 7577 } catch (ActivityNotFoundException ignore) { 7578 Slog.e(TAG, "Could not resolve activity with : " 7579 + intent.getComponent().flattenToString() 7580 + " name."); 7581 } 7582 } 7583 7584 /** A helper class to check button override permission. */ 7585 static class ButtonOverridePermissionChecker { 7586 boolean canAppOverrideSystemKey(Context context, int uid) { 7587 return PermissionChecker.checkPermissionForDataDelivery( 7588 context, 7589 OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW, 7590 PID_UNKNOWN, 7591 uid, 7592 null, 7593 null, 7594 null) 7595 == PERMISSION_GRANTED; 7596 } 7597 } 7598 7599 private int getTargetDisplayIdForKeyEvent(KeyEvent event) { 7600 if (event.getDisplayId() != INVALID_DISPLAY) { 7601 return event.getDisplayId(); 7602 } 7603 if (mTopFocusedDisplayId != INVALID_DISPLAY) { 7604 return mTopFocusedDisplayId; 7605 } 7606 return DEFAULT_DISPLAY; 7607 } 7608 7609 private int getTargetDisplayIdForKeyGestureEvent(KeyGestureEvent event) { 7610 if (event.getDisplayId() != INVALID_DISPLAY) { 7611 return event.getDisplayId(); 7612 } 7613 if (mTopFocusedDisplayId != INVALID_DISPLAY) { 7614 return mTopFocusedDisplayId; 7615 } 7616 return DEFAULT_DISPLAY; 7617 } 7618 7619 /** 7620 * This method is intended to prevent key events for visible background users 7621 * from interfering with the current user's experience in MUMD environment. 7622 * 7623 * @param displayId the displayId of the key event. 7624 * @param keyCode the key code of the event. 7625 * 7626 * @return false if the key event is for a visible background user. 7627 */ 7628 private boolean isKeyEventForCurrentUser(int displayId, int keyCode, @Nullable String purpose) { 7629 if (!mVisibleBackgroundUsersEnabled) { 7630 return true; 7631 } 7632 int assignedUser = mUserManagerInternal.getUserAssignedToDisplay(displayId); 7633 if (assignedUser == mCurrentUserId) { 7634 return true; 7635 } 7636 if (DEBUG_INPUT) { 7637 Slog.w(TAG, "Cannot handle " + KeyEvent.keyCodeToString(keyCode) 7638 + (purpose != null ? " to " + purpose : "") 7639 + " for visible background user(u" + assignedUser + ")"); 7640 } 7641 return false; 7642 } 7643 } 7644