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