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