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