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