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