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