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