PhoneWindowManager.java revision 2dc47c1dd55818a0bd68847215adccfe39d6dd88
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 17package com.android.server.policy; 18 19import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 20import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; 21import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 22import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 23import static android.app.ActivityManager.StackId.HOME_STACK_ID; 24import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; 25import static android.app.AppOpsManager.OP_TOAST_WINDOW; 26import static android.content.Context.DISPLAY_SERVICE; 27import static android.content.Context.WINDOW_SERVICE; 28import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; 29import static android.content.pm.PackageManager.FEATURE_LEANBACK; 30import static android.content.pm.PackageManager.FEATURE_WATCH; 31import static android.content.pm.PackageManager.PERMISSION_GRANTED; 32import static android.content.res.Configuration.EMPTY; 33import static android.content.res.Configuration.UI_MODE_TYPE_CAR; 34import static android.content.res.Configuration.UI_MODE_TYPE_MASK; 35import static android.os.Build.VERSION_CODES.M; 36import static android.os.Build.VERSION_CODES.O; 37import static android.view.WindowManager.DOCKED_LEFT; 38import static android.view.WindowManager.DOCKED_RIGHT; 39import static android.view.WindowManager.DOCKED_TOP; 40import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; 41import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; 42import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 43import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; 44import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 45import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; 46import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN; 47import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; 48import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; 49import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 50import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN; 51import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 52import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 53import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 54import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 55import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 56import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 57import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW; 58import static android.view.WindowManager.LayoutParams.MATCH_PARENT; 59import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND; 60import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT; 61import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 62import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 63import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT; 64import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR; 65import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; 66import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT; 67import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE; 68import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS; 69import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; 70import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 71import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; 72import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 73import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 74import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 75import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; 76import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY; 77import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 78import static android.view.WindowManager.LayoutParams.TYPE_DREAM; 79import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER; 80import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 81import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; 82import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; 83import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 84import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; 85import static android.view.WindowManager.LayoutParams.TYPE_PHONE; 86import static android.view.WindowManager.LayoutParams.TYPE_POINTER; 87import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; 88import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE; 89import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; 90import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; 91import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; 92import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR; 93import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 94import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; 95import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL; 96import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; 97import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; 98import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; 99import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; 100import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 101import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 102import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; 103import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING; 104import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; 105import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 106import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; 107import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; 108import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION; 109import static android.view.WindowManagerGlobal.ADD_OKAY; 110import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED; 111import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED; 112import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT; 113import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED; 114import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT; 115import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED; 116import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN; 117 118import android.annotation.Nullable; 119import android.app.ActivityManager; 120import android.app.ActivityManager.StackId; 121import android.app.ActivityManagerInternal; 122import android.app.ActivityManagerInternal.SleepToken; 123import android.app.AppOpsManager; 124import android.app.IUiModeManager; 125import android.app.ProgressDialog; 126import android.app.SearchManager; 127import android.app.StatusBarManager; 128import android.app.UiModeManager; 129import android.content.ActivityNotFoundException; 130import android.content.BroadcastReceiver; 131import android.content.ComponentName; 132import android.content.ContentResolver; 133import android.content.Context; 134import android.content.Intent; 135import android.content.IntentFilter; 136import android.content.ServiceConnection; 137import android.content.pm.ActivityInfo; 138import android.content.pm.ApplicationInfo; 139import android.content.pm.PackageManager; 140import android.content.pm.ResolveInfo; 141import android.content.res.CompatibilityInfo; 142import android.content.res.Configuration; 143import android.content.res.Resources; 144import android.content.res.TypedArray; 145import android.database.ContentObserver; 146import android.graphics.PixelFormat; 147import android.graphics.Rect; 148import android.graphics.drawable.Drawable; 149import android.hardware.display.DisplayManager; 150import android.hardware.hdmi.HdmiControlManager; 151import android.hardware.hdmi.HdmiPlaybackClient; 152import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback; 153import android.hardware.input.InputManager; 154import android.hardware.input.InputManagerInternal; 155import android.hardware.power.V1_0.PowerHint; 156import android.media.AudioAttributes; 157import android.media.AudioManager; 158import android.media.AudioSystem; 159import android.media.IAudioService; 160import android.media.session.MediaSessionLegacyHelper; 161import android.os.Binder; 162import android.os.Build; 163import android.os.Bundle; 164import android.os.FactoryTest; 165import android.os.Handler; 166import android.os.IBinder; 167import android.os.IDeviceIdleController; 168import android.os.Looper; 169import android.os.Message; 170import android.os.Messenger; 171import android.os.PowerManager; 172import android.os.PowerManagerInternal; 173import android.os.Process; 174import android.os.RemoteException; 175import android.os.ServiceManager; 176import android.os.SystemClock; 177import android.os.SystemProperties; 178import android.os.UEventObserver; 179import android.os.UserHandle; 180import android.os.Vibrator; 181import android.os.VibrationEffect; 182import android.provider.MediaStore; 183import android.provider.Settings; 184import android.service.dreams.DreamManagerInternal; 185import android.service.dreams.DreamService; 186import android.service.dreams.IDreamManager; 187import android.service.vr.IPersistentVrStateCallbacks; 188import android.speech.RecognizerIntent; 189import android.telecom.TelecomManager; 190import android.util.DisplayMetrics; 191import android.util.EventLog; 192import android.util.Log; 193import android.util.LongSparseArray; 194import android.util.MutableBoolean; 195import android.util.Slog; 196import android.util.SparseArray; 197import android.view.Display; 198import android.view.Gravity; 199import android.view.HapticFeedbackConstants; 200import android.view.IApplicationToken; 201import android.view.IWindowManager; 202import android.view.InputChannel; 203import android.view.InputDevice; 204import android.view.InputEvent; 205import android.view.InputEventReceiver; 206import android.view.KeyCharacterMap; 207import android.view.KeyCharacterMap.FallbackAction; 208import android.view.KeyEvent; 209import android.view.MotionEvent; 210import android.view.PointerIcon; 211import android.view.Surface; 212import android.view.View; 213import android.view.ViewConfiguration; 214import android.view.WindowManager; 215import android.view.WindowManager.LayoutParams; 216import android.view.WindowManagerGlobal; 217import android.view.WindowManagerInternal; 218import android.view.WindowManagerInternal.AppTransitionListener; 219import android.view.WindowManagerPolicy; 220import android.view.accessibility.AccessibilityEvent; 221import android.view.accessibility.AccessibilityManager; 222import android.view.animation.Animation; 223import android.view.animation.AnimationSet; 224import android.view.animation.AnimationUtils; 225import android.view.inputmethod.InputMethodManagerInternal; 226 227import com.android.internal.R; 228import com.android.internal.logging.MetricsLogger; 229import com.android.internal.policy.IKeyguardDismissCallback; 230import com.android.internal.policy.IShortcutService; 231import com.android.internal.policy.PhoneWindow; 232import com.android.internal.statusbar.IStatusBarService; 233import com.android.internal.util.ScreenShapeHelper; 234import com.android.internal.widget.PointerLocationView; 235import com.android.server.GestureLauncherService; 236import com.android.server.LocalServices; 237import com.android.server.policy.keyguard.KeyguardServiceDelegate; 238import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener; 239import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback; 240import com.android.server.statusbar.StatusBarManagerInternal; 241import com.android.server.wm.AppTransition; 242import com.android.server.vr.VrManagerInternal; 243 244import java.io.File; 245import java.io.FileReader; 246import java.io.IOException; 247import java.io.PrintWriter; 248import java.util.List; 249 250/** 251 * WindowManagerPolicy implementation for the Android phone UI. This 252 * introduces a new method suffix, Lp, for an internal lock of the 253 * PhoneWindowManager. This is used to protect some internal state, and 254 * can be acquired with either the Lw and Li lock held, so has the restrictions 255 * of both of those when held. 256 */ 257public class PhoneWindowManager implements WindowManagerPolicy { 258 static final String TAG = "WindowManager"; 259 static final boolean DEBUG = false; 260 static final boolean localLOGV = false; 261 static final boolean DEBUG_INPUT = false; 262 static final boolean DEBUG_KEYGUARD = false; 263 static final boolean DEBUG_LAYOUT = false; 264 static final boolean DEBUG_SPLASH_SCREEN = false; 265 static final boolean DEBUG_WAKEUP = false; 266 static final boolean SHOW_SPLASH_SCREENS = true; 267 268 // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key. 269 // No longer recommended for desk docks; 270 static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false; 271 272 // Whether to allow devices placed in vr headset viewers to have an alternative Home intent. 273 static final boolean ENABLE_VR_HEADSET_HOME_CAPTURE = true; 274 275 static final boolean ALTERNATE_CAR_MODE_NAV_SIZE = false; 276 277 static final int SHORT_PRESS_POWER_NOTHING = 0; 278 static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1; 279 static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2; 280 static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3; 281 static final int SHORT_PRESS_POWER_GO_HOME = 4; 282 static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5; 283 284 static final int LONG_PRESS_POWER_NOTHING = 0; 285 static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; 286 static final int LONG_PRESS_POWER_SHUT_OFF = 2; 287 static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3; 288 289 static final int LONG_PRESS_BACK_NOTHING = 0; 290 static final int LONG_PRESS_BACK_GO_TO_VOICE_ASSIST = 1; 291 292 static final int MULTI_PRESS_POWER_NOTHING = 0; 293 static final int MULTI_PRESS_POWER_THEATER_MODE = 1; 294 static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2; 295 296 // Number of presses needed before we induce panic press behavior on the back button 297 static final int PANIC_PRESS_BACK_COUNT = 4; 298 static final int PANIC_PRESS_BACK_NOTHING = 0; 299 static final int PANIC_PRESS_BACK_HOME = 1; 300 301 // These need to match the documentation/constant in 302 // core/res/res/values/config.xml 303 static final int LONG_PRESS_HOME_NOTHING = 0; 304 static final int LONG_PRESS_HOME_ALL_APPS = 1; 305 static final int LONG_PRESS_HOME_ASSIST = 2; 306 static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_ASSIST; 307 308 static final int DOUBLE_TAP_HOME_NOTHING = 0; 309 static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1; 310 311 static final int SHORT_PRESS_WINDOW_NOTHING = 0; 312 static final int SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE = 1; 313 314 static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0; 315 static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1; 316 317 static final int PENDING_KEY_NULL = -1; 318 319 // Controls navigation bar opacity depending on which workspace stacks are currently 320 // visible. 321 // Nav bar is always opaque when either the freeform stack or docked stack is visible. 322 static final int NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED = 0; 323 // Nav bar is always translucent when the freeform stack is visible, otherwise always opaque. 324 static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1; 325 326 static public final String SYSTEM_DIALOG_REASON_KEY = "reason"; 327 static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; 328 static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; 329 static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; 330 static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist"; 331 332 /** 333 * These are the system UI flags that, when changing, can cause the layout 334 * of the screen to change. 335 */ 336 static final int SYSTEM_UI_CHANGING_LAYOUT = 337 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 338 | View.SYSTEM_UI_FLAG_FULLSCREEN 339 | View.STATUS_BAR_TRANSLUCENT 340 | View.NAVIGATION_BAR_TRANSLUCENT 341 | View.STATUS_BAR_TRANSPARENT 342 | View.NAVIGATION_BAR_TRANSPARENT; 343 344 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() 345 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 346 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 347 .build(); 348 349 // The panic gesture may become active only after the keyguard is dismissed and the immersive 350 // app shows again. If that doesn't happen for 30s we drop the gesture. 351 private static final long PANIC_GESTURE_EXPIRATION = 30000; 352 353 private static final String SYSUI_PACKAGE = "com.android.systemui"; 354 private static final String SYSUI_SCREENSHOT_SERVICE = 355 "com.android.systemui.screenshot.TakeScreenshotService"; 356 private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER = 357 "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver"; 358 359 private static final int NAV_BAR_BOTTOM = 0; 360 private static final int NAV_BAR_RIGHT = 1; 361 private static final int NAV_BAR_LEFT = 2; 362 363 /** 364 * Keyguard stuff 365 */ 366 private boolean mKeyguardDrawnOnce; 367 368 /* Table of Application Launch keys. Maps from key codes to intent categories. 369 * 370 * These are special keys that are used to launch particular kinds of applications, 371 * such as a web browser. HID defines nearly a hundred of them in the Consumer (0x0C) 372 * usage page. We don't support quite that many yet... 373 */ 374 static SparseArray<String> sApplicationLaunchKeyCategories; 375 static { 376 sApplicationLaunchKeyCategories = new SparseArray<String>(); 377 sApplicationLaunchKeyCategories.append( 378 KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER); 379 sApplicationLaunchKeyCategories.append( 380 KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL); 381 sApplicationLaunchKeyCategories.append( 382 KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS); 383 sApplicationLaunchKeyCategories.append( 384 KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR); 385 sApplicationLaunchKeyCategories.append( 386 KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC); 387 sApplicationLaunchKeyCategories.append( 388 KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR); 389 } 390 391 /** Amount of time (in milliseconds) to wait for windows drawn before powering on. */ 392 static final int WAITING_FOR_DRAWN_TIMEOUT = 1000; 393 394 /** Amount of time (in milliseconds) a toast window can be shown. */ 395 public static final int TOAST_WINDOW_TIMEOUT = 3500; // 3.5 seconds 396 397 /** 398 * Lock protecting internal state. Must not call out into window 399 * manager with lock held. (This lock will be acquired in places 400 * where the window manager is calling in with its own lock held.) 401 */ 402 private final Object mLock = new Object(); 403 404 Context mContext; 405 IWindowManager mWindowManager; 406 WindowManagerFuncs mWindowManagerFuncs; 407 WindowManagerInternal mWindowManagerInternal; 408 PowerManager mPowerManager; 409 ActivityManagerInternal mActivityManagerInternal; 410 InputManagerInternal mInputManagerInternal; 411 InputMethodManagerInternal mInputMethodManagerInternal; 412 DreamManagerInternal mDreamManagerInternal; 413 PowerManagerInternal mPowerManagerInternal; 414 IStatusBarService mStatusBarService; 415 StatusBarManagerInternal mStatusBarManagerInternal; 416 boolean mPreloadedRecentApps; 417 final Object mServiceAquireLock = new Object(); 418 Vibrator mVibrator; // Vibrator for giving feedback of orientation changes 419 SearchManager mSearchManager; 420 AccessibilityManager mAccessibilityManager; 421 BurnInProtectionHelper mBurnInProtectionHelper; 422 AppOpsManager mAppOpsManager; 423 private boolean mHasFeatureWatch; 424 private boolean mHasFeatureLeanback; 425 426 // Assigned on main thread, accessed on UI thread 427 volatile VrManagerInternal mVrManagerInternal; 428 429 // Vibrator pattern for haptic feedback of a long press. 430 long[] mLongPressVibePattern; 431 432 // Vibrator pattern for haptic feedback of virtual key press. 433 long[] mVirtualKeyVibePattern; 434 435 // Vibrator pattern for a short vibration. 436 long[] mKeyboardTapVibePattern; 437 438 // Vibrator pattern for a short vibration when tapping on an hour/minute tick of a Clock. 439 long[] mClockTickVibePattern; 440 441 // Vibrator pattern for a short vibration when tapping on a day/month/year date of a Calendar. 442 long[] mCalendarDateVibePattern; 443 444 // Vibrator pattern for haptic feedback during boot when safe mode is disabled. 445 long[] mSafeModeDisabledVibePattern; 446 447 // Vibrator pattern for haptic feedback during boot when safe mode is enabled. 448 long[] mSafeModeEnabledVibePattern; 449 450 // Vibrator pattern for haptic feedback of a context click. 451 long[] mContextClickVibePattern; 452 453 /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */ 454 boolean mEnableShiftMenuBugReports = false; 455 456 /** Controller that supports enabling an AccessibilityService by holding down the volume keys */ 457 private AccessibilityShortcutController mAccessibilityShortcutController; 458 459 boolean mSafeMode; 460 WindowState mStatusBar = null; 461 int mStatusBarHeight; 462 WindowState mNavigationBar = null; 463 boolean mHasNavigationBar = false; 464 boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side? 465 int mNavigationBarPosition = NAV_BAR_BOTTOM; 466 int[] mNavigationBarHeightForRotationDefault = new int[4]; 467 int[] mNavigationBarWidthForRotationDefault = new int[4]; 468 int[] mNavigationBarHeightForRotationInCarMode = new int[4]; 469 int[] mNavigationBarWidthForRotationInCarMode = new int[4]; 470 471 private LongSparseArray<IShortcutService> mShortcutKeyServices = new LongSparseArray<>(); 472 473 // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key. 474 // This is for car dock and this is updated from resource. 475 private boolean mEnableCarDockHomeCapture = true; 476 477 boolean mBootMessageNeedsHiding; 478 KeyguardServiceDelegate mKeyguardDelegate; 479 final Runnable mWindowManagerDrawCallback = new Runnable() { 480 @Override 481 public void run() { 482 if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!"); 483 mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE); 484 } 485 }; 486 final DrawnListener mKeyguardDrawnCallback = new DrawnListener() { 487 @Override 488 public void onDrawn() { 489 if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn."); 490 mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE); 491 } 492 }; 493 494 GlobalActions mGlobalActions; 495 Handler mHandler; 496 WindowState mLastInputMethodWindow = null; 497 WindowState mLastInputMethodTargetWindow = null; 498 499 // FIXME This state is shared between the input reader and handler thread. 500 // Technically it's broken and buggy but it has been like this for many years 501 // and we have not yet seen any problems. Someday we'll rewrite this logic 502 // so that only one thread is involved in handling input policy. Unfortunately 503 // it's on a critical path for power management so we can't just post the work to the 504 // handler thread. We'll need to resolve this someday by teaching the input dispatcher 505 // to hold wakelocks during dispatch and eliminating the critical path. 506 volatile boolean mPowerKeyHandled; 507 volatile boolean mBackKeyHandled; 508 volatile boolean mBeganFromNonInteractive; 509 volatile int mPowerKeyPressCounter; 510 volatile int mBackKeyPressCounter; 511 volatile boolean mEndCallKeyHandled; 512 volatile boolean mCameraGestureTriggeredDuringGoingToSleep; 513 volatile boolean mGoingToSleep; 514 volatile boolean mRecentsVisible; 515 volatile boolean mPictureInPictureVisible; 516 // Written by vr manager thread, only read in this class. 517 volatile private boolean mPersistentVrModeEnabled; 518 volatile private boolean mDismissImeOnBackKeyPressed; 519 520 // Used to hold the last user key used to wake the device. This helps us prevent up events 521 // from being passed to the foregrounded app without a corresponding down event 522 volatile int mPendingWakeKey = PENDING_KEY_NULL; 523 524 int mRecentAppsHeldModifiers; 525 boolean mLanguageSwitchKeyPressed; 526 527 int mLidState = LID_ABSENT; 528 int mCameraLensCoverState = CAMERA_LENS_COVER_ABSENT; 529 boolean mHaveBuiltInKeyboard; 530 531 boolean mSystemReady; 532 boolean mSystemBooted; 533 private boolean mDeferBindKeyguard; 534 boolean mHdmiPlugged; 535 HdmiControl mHdmiControl; 536 IUiModeManager mUiModeManager; 537 int mUiMode; 538 int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED; 539 int mLidOpenRotation; 540 int mCarDockRotation; 541 int mDeskDockRotation; 542 int mUndockedHdmiRotation; 543 int mDemoHdmiRotation; 544 boolean mDemoHdmiRotationLock; 545 int mDemoRotation; 546 boolean mDemoRotationLock; 547 548 boolean mWakeGestureEnabledSetting; 549 MyWakeGestureListener mWakeGestureListener; 550 551 // Default display does not rotate, apps that require non-default orientation will have to 552 // have the orientation emulated. 553 private boolean mForceDefaultOrientation = false; 554 555 int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE; 556 int mUserRotation = Surface.ROTATION_0; 557 boolean mAccelerometerDefault; 558 559 boolean mSupportAutoRotation; 560 int mAllowAllRotations = -1; 561 boolean mCarDockEnablesAccelerometer; 562 boolean mDeskDockEnablesAccelerometer; 563 int mLidKeyboardAccessibility; 564 int mLidNavigationAccessibility; 565 boolean mLidControlsScreenLock; 566 boolean mLidControlsSleep; 567 int mShortPressOnPowerBehavior; 568 int mLongPressOnPowerBehavior; 569 int mDoublePressOnPowerBehavior; 570 int mTriplePressOnPowerBehavior; 571 int mLongPressOnBackBehavior; 572 int mPanicPressOnBackBehavior; 573 int mShortPressOnSleepBehavior; 574 int mShortPressWindowBehavior; 575 boolean mAwake; 576 boolean mScreenOnEarly; 577 boolean mScreenOnFully; 578 ScreenOnListener mScreenOnListener; 579 boolean mKeyguardDrawComplete; 580 boolean mWindowManagerDrawComplete; 581 boolean mOrientationSensorEnabled = false; 582 int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 583 boolean mHasSoftInput = false; 584 boolean mTranslucentDecorEnabled = true; 585 boolean mUseTvRouting; 586 587 int mPointerLocationMode = 0; // guarded by mLock 588 589 // The last window we were told about in focusChanged. 590 WindowState mFocusedWindow; 591 IApplicationToken mFocusedApp; 592 593 PointerLocationView mPointerLocationView; 594 595 // The current size of the screen; really; extends into the overscan area of 596 // the screen and doesn't account for any system elements like the status bar. 597 int mOverscanScreenLeft, mOverscanScreenTop; 598 int mOverscanScreenWidth, mOverscanScreenHeight; 599 // The current visible size of the screen; really; (ir)regardless of whether the status 600 // bar can be hidden but not extending into the overscan area. 601 int mUnrestrictedScreenLeft, mUnrestrictedScreenTop; 602 int mUnrestrictedScreenWidth, mUnrestrictedScreenHeight; 603 // Like mOverscanScreen*, but allowed to move into the overscan region where appropriate. 604 int mRestrictedOverscanScreenLeft, mRestrictedOverscanScreenTop; 605 int mRestrictedOverscanScreenWidth, mRestrictedOverscanScreenHeight; 606 // The current size of the screen; these may be different than (0,0)-(dw,dh) 607 // if the status bar can't be hidden; in that case it effectively carves out 608 // that area of the display from all other windows. 609 int mRestrictedScreenLeft, mRestrictedScreenTop; 610 int mRestrictedScreenWidth, mRestrictedScreenHeight; 611 // During layout, the current screen borders accounting for any currently 612 // visible system UI elements. 613 int mSystemLeft, mSystemTop, mSystemRight, mSystemBottom; 614 // For applications requesting stable content insets, these are them. 615 int mStableLeft, mStableTop, mStableRight, mStableBottom; 616 // For applications requesting stable content insets but have also set the 617 // fullscreen window flag, these are the stable dimensions without the status bar. 618 int mStableFullscreenLeft, mStableFullscreenTop; 619 int mStableFullscreenRight, mStableFullscreenBottom; 620 // During layout, the current screen borders with all outer decoration 621 // (status bar, input method dock) accounted for. 622 int mCurLeft, mCurTop, mCurRight, mCurBottom; 623 // During layout, the frame in which content should be displayed 624 // to the user, accounting for all screen decoration except for any 625 // space they deem as available for other content. This is usually 626 // the same as mCur*, but may be larger if the screen decor has supplied 627 // content insets. 628 int mContentLeft, mContentTop, mContentRight, mContentBottom; 629 // During layout, the frame in which voice content should be displayed 630 // to the user, accounting for all screen decoration except for any 631 // space they deem as available for other content. 632 int mVoiceContentLeft, mVoiceContentTop, mVoiceContentRight, mVoiceContentBottom; 633 // During layout, the current screen borders along which input method 634 // windows are placed. 635 int mDockLeft, mDockTop, mDockRight, mDockBottom; 636 // During layout, the layer at which the doc window is placed. 637 int mDockLayer; 638 // During layout, this is the layer of the status bar. 639 int mStatusBarLayer; 640 int mLastSystemUiFlags; 641 // Bits that we are in the process of clearing, so we want to prevent 642 // them from being set by applications until everything has been updated 643 // to have them clear. 644 int mResettingSystemUiFlags = 0; 645 // Bits that we are currently always keeping cleared. 646 int mForceClearedSystemUiFlags = 0; 647 int mLastFullscreenStackSysUiFlags; 648 int mLastDockedStackSysUiFlags; 649 final Rect mNonDockedStackBounds = new Rect(); 650 final Rect mDockedStackBounds = new Rect(); 651 final Rect mLastNonDockedStackBounds = new Rect(); 652 final Rect mLastDockedStackBounds = new Rect(); 653 654 // What we last reported to system UI about whether the compatibility 655 // menu needs to be displayed. 656 boolean mLastFocusNeedsMenu = false; 657 // If nonzero, a panic gesture was performed at that time in uptime millis and is still pending. 658 private long mPendingPanicGestureUptime; 659 660 InputConsumer mInputConsumer = null; 661 662 static final Rect mTmpParentFrame = new Rect(); 663 static final Rect mTmpDisplayFrame = new Rect(); 664 static final Rect mTmpOverscanFrame = new Rect(); 665 static final Rect mTmpContentFrame = new Rect(); 666 static final Rect mTmpVisibleFrame = new Rect(); 667 static final Rect mTmpDecorFrame = new Rect(); 668 static final Rect mTmpStableFrame = new Rect(); 669 static final Rect mTmpNavigationFrame = new Rect(); 670 static final Rect mTmpOutsetFrame = new Rect(); 671 private static final Rect mTmpRect = new Rect(); 672 673 WindowState mTopFullscreenOpaqueWindowState; 674 WindowState mTopFullscreenOpaqueOrDimmingWindowState; 675 WindowState mTopDockedOpaqueWindowState; 676 WindowState mTopDockedOpaqueOrDimmingWindowState; 677 boolean mTopIsFullscreen; 678 boolean mForceStatusBar; 679 boolean mForceStatusBarFromKeyguard; 680 private boolean mForceStatusBarTransparent; 681 int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED; 682 boolean mForcingShowNavBar; 683 int mForcingShowNavBarLayer; 684 685 private boolean mPendingKeyguardOccluded; 686 private boolean mKeyguardOccludedChanged; 687 688 boolean mShowingDream; 689 private boolean mLastShowingDream; 690 boolean mDreamingLockscreen; 691 boolean mDreamingSleepTokenNeeded; 692 SleepToken mDreamingSleepToken; 693 SleepToken mScreenOffSleepToken; 694 volatile boolean mKeyguardOccluded; 695 boolean mHomePressed; 696 boolean mHomeConsumed; 697 boolean mHomeDoubleTapPending; 698 Intent mHomeIntent; 699 Intent mCarDockIntent; 700 Intent mDeskDockIntent; 701 Intent mVrHeadsetHomeIntent; 702 boolean mSearchKeyShortcutPending; 703 boolean mConsumeSearchKeyUp; 704 boolean mAssistKeyLongPressed; 705 boolean mPendingMetaAction; 706 boolean mPendingCapsLockToggle; 707 int mMetaState; 708 int mInitialMetaState; 709 boolean mForceShowSystemBars; 710 711 // support for activating the lock screen while the screen is on 712 boolean mAllowLockscreenWhenOn; 713 int mLockScreenTimeout; 714 boolean mLockScreenTimerActive; 715 716 // Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.) 717 int mEndcallBehavior; 718 719 // Behavior of POWER button while in-call and screen on. 720 // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.) 721 int mIncallPowerBehavior; 722 723 // Behavior of Back button while in-call and screen on 724 int mIncallBackBehavior; 725 726 Display mDisplay; 727 728 private int mDisplayRotation; 729 730 int mLandscapeRotation = 0; // default landscape rotation 731 int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation 732 int mPortraitRotation = 0; // default portrait rotation 733 int mUpsideDownRotation = 0; // "other" portrait rotation 734 735 int mOverscanLeft = 0; 736 int mOverscanTop = 0; 737 int mOverscanRight = 0; 738 int mOverscanBottom = 0; 739 740 // What we do when the user long presses on home 741 private int mLongPressOnHomeBehavior; 742 743 // What we do when the user double-taps on home 744 private int mDoubleTapOnHomeBehavior; 745 746 // Allowed theater mode wake actions 747 private boolean mAllowTheaterModeWakeFromKey; 748 private boolean mAllowTheaterModeWakeFromPowerKey; 749 private boolean mAllowTheaterModeWakeFromMotion; 750 private boolean mAllowTheaterModeWakeFromMotionWhenNotDreaming; 751 private boolean mAllowTheaterModeWakeFromCameraLens; 752 private boolean mAllowTheaterModeWakeFromLidSwitch; 753 private boolean mAllowTheaterModeWakeFromWakeGesture; 754 755 // Whether to support long press from power button in non-interactive mode 756 private boolean mSupportLongPressPowerWhenNonInteractive; 757 758 // Whether to go to sleep entering theater mode from power button 759 private boolean mGoToSleepOnButtonPressTheaterMode; 760 761 // Screenshot trigger states 762 // Time to volume and power must be pressed within this interval of each other. 763 private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150; 764 // Increase the chord delay when taking a screenshot from the keyguard 765 private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f; 766 private boolean mScreenshotChordEnabled; 767 private boolean mScreenshotChordVolumeDownKeyTriggered; 768 private long mScreenshotChordVolumeDownKeyTime; 769 private boolean mScreenshotChordVolumeDownKeyConsumed; 770 private boolean mA11yShortcutChordVolumeUpKeyTriggered; 771 private long mA11yShortcutChordVolumeUpKeyTime; 772 private boolean mA11yShortcutChordVolumeUpKeyConsumed; 773 774 private boolean mScreenshotChordPowerKeyTriggered; 775 private long mScreenshotChordPowerKeyTime; 776 777 private static final long BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS = 1000; 778 779 private boolean mBugreportTvKey1Pressed; 780 private boolean mBugreportTvKey2Pressed; 781 private boolean mBugreportTvScheduled; 782 783 /* The number of steps between min and max brightness */ 784 private static final int BRIGHTNESS_STEPS = 10; 785 786 SettingsObserver mSettingsObserver; 787 ShortcutManager mShortcutManager; 788 PowerManager.WakeLock mBroadcastWakeLock; 789 PowerManager.WakeLock mPowerKeyWakeLock; 790 boolean mHavePendingMediaKeyRepeatWithWakeLock; 791 792 private int mCurrentUserId; 793 794 // Maps global key codes to the components that will handle them. 795 private GlobalKeyManager mGlobalKeyManager; 796 797 // Fallback actions by key code. 798 private final SparseArray<KeyCharacterMap.FallbackAction> mFallbackActions = 799 new SparseArray<KeyCharacterMap.FallbackAction>(); 800 801 private final LogDecelerateInterpolator mLogDecelerateInterpolator 802 = new LogDecelerateInterpolator(100, 0); 803 804 private final MutableBoolean mTmpBoolean = new MutableBoolean(false); 805 806 private static final int MSG_ENABLE_POINTER_LOCATION = 1; 807 private static final int MSG_DISABLE_POINTER_LOCATION = 2; 808 private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3; 809 private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4; 810 private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5; 811 private static final int MSG_KEYGUARD_DRAWN_TIMEOUT = 6; 812 private static final int MSG_WINDOW_MANAGER_DRAWN_COMPLETE = 7; 813 private static final int MSG_DISPATCH_SHOW_RECENTS = 9; 814 private static final int MSG_DISPATCH_SHOW_GLOBAL_ACTIONS = 10; 815 private static final int MSG_HIDE_BOOT_MESSAGE = 11; 816 private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12; 817 private static final int MSG_POWER_DELAYED_PRESS = 13; 818 private static final int MSG_POWER_LONG_PRESS = 14; 819 private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 15; 820 private static final int MSG_REQUEST_TRANSIENT_BARS = 16; 821 private static final int MSG_SHOW_PICTURE_IN_PICTURE_MENU = 17; 822 private static final int MSG_BACK_LONG_PRESS = 18; 823 private static final int MSG_DISPOSE_INPUT_CONSUMER = 19; 824 private static final int MSG_BACK_DELAYED_PRESS = 20; 825 private static final int MSG_ACCESSIBILITY_SHORTCUT = 21; 826 private static final int MSG_BUGREPORT_TV = 22; 827 828 private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0; 829 private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1; 830 831 private class PolicyHandler extends Handler { 832 @Override 833 public void handleMessage(Message msg) { 834 switch (msg.what) { 835 case MSG_ENABLE_POINTER_LOCATION: 836 enablePointerLocation(); 837 break; 838 case MSG_DISABLE_POINTER_LOCATION: 839 disablePointerLocation(); 840 break; 841 case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK: 842 dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj); 843 break; 844 case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK: 845 dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj); 846 break; 847 case MSG_DISPATCH_SHOW_RECENTS: 848 showRecentApps(false, msg.arg1 != 0); 849 break; 850 case MSG_DISPATCH_SHOW_GLOBAL_ACTIONS: 851 showGlobalActionsInternal(); 852 break; 853 case MSG_KEYGUARD_DRAWN_COMPLETE: 854 if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete"); 855 finishKeyguardDrawn(); 856 break; 857 case MSG_KEYGUARD_DRAWN_TIMEOUT: 858 Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete"); 859 finishKeyguardDrawn(); 860 break; 861 case MSG_WINDOW_MANAGER_DRAWN_COMPLETE: 862 if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete"); 863 finishWindowsDrawn(); 864 break; 865 case MSG_HIDE_BOOT_MESSAGE: 866 handleHideBootMessage(); 867 break; 868 case MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK: 869 launchVoiceAssistWithWakeLock(msg.arg1 != 0); 870 break; 871 case MSG_POWER_DELAYED_PRESS: 872 powerPress((Long)msg.obj, msg.arg1 != 0, msg.arg2); 873 finishPowerKeyPress(); 874 break; 875 case MSG_POWER_LONG_PRESS: 876 powerLongPress(); 877 break; 878 case MSG_UPDATE_DREAMING_SLEEP_TOKEN: 879 updateDreamingSleepToken(msg.arg1 != 0); 880 break; 881 case MSG_REQUEST_TRANSIENT_BARS: 882 WindowState targetBar = (msg.arg1 == MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS) ? 883 mStatusBar : mNavigationBar; 884 if (targetBar != null) { 885 requestTransientBars(targetBar); 886 } 887 break; 888 case MSG_SHOW_PICTURE_IN_PICTURE_MENU: 889 showPictureInPictureMenuInternal(); 890 break; 891 case MSG_BACK_LONG_PRESS: 892 backLongPress(); 893 finishBackKeyPress(); 894 break; 895 case MSG_DISPOSE_INPUT_CONSUMER: 896 disposeInputConsumer((InputConsumer) msg.obj); 897 break; 898 case MSG_BACK_DELAYED_PRESS: 899 backMultiPressAction((Long) msg.obj, msg.arg1); 900 finishBackKeyPress(); 901 break; 902 case MSG_ACCESSIBILITY_SHORTCUT: 903 accessibilityShortcutActivated(); 904 break; 905 case MSG_BUGREPORT_TV: 906 takeBugreport(); 907 break; 908 } 909 } 910 } 911 912 private UEventObserver mHDMIObserver = new UEventObserver() { 913 @Override 914 public void onUEvent(UEventObserver.UEvent event) { 915 setHdmiPlugged("1".equals(event.get("SWITCH_STATE"))); 916 } 917 }; 918 919 class SettingsObserver extends ContentObserver { 920 SettingsObserver(Handler handler) { 921 super(handler); 922 } 923 924 void observe() { 925 // Observe all users' changes 926 ContentResolver resolver = mContext.getContentResolver(); 927 resolver.registerContentObserver(Settings.System.getUriFor( 928 Settings.System.END_BUTTON_BEHAVIOR), false, this, 929 UserHandle.USER_ALL); 930 resolver.registerContentObserver(Settings.Secure.getUriFor( 931 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this, 932 UserHandle.USER_ALL); 933 resolver.registerContentObserver(Settings.Secure.getUriFor( 934 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR), false, this, 935 UserHandle.USER_ALL); 936 resolver.registerContentObserver(Settings.Secure.getUriFor( 937 Settings.Secure.WAKE_GESTURE_ENABLED), false, this, 938 UserHandle.USER_ALL); 939 resolver.registerContentObserver(Settings.System.getUriFor( 940 Settings.System.ACCELEROMETER_ROTATION), false, this, 941 UserHandle.USER_ALL); 942 resolver.registerContentObserver(Settings.System.getUriFor( 943 Settings.System.USER_ROTATION), false, this, 944 UserHandle.USER_ALL); 945 resolver.registerContentObserver(Settings.System.getUriFor( 946 Settings.System.SCREEN_OFF_TIMEOUT), false, this, 947 UserHandle.USER_ALL); 948 resolver.registerContentObserver(Settings.System.getUriFor( 949 Settings.System.POINTER_LOCATION), false, this, 950 UserHandle.USER_ALL); 951 resolver.registerContentObserver(Settings.Secure.getUriFor( 952 Settings.Secure.DEFAULT_INPUT_METHOD), false, this, 953 UserHandle.USER_ALL); 954 resolver.registerContentObserver(Settings.Secure.getUriFor( 955 Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this, 956 UserHandle.USER_ALL); 957 resolver.registerContentObserver(Settings.Global.getUriFor( 958 Settings.Global.POLICY_CONTROL), false, this, 959 UserHandle.USER_ALL); 960 updateSettings(); 961 } 962 963 @Override public void onChange(boolean selfChange) { 964 updateSettings(); 965 updateRotation(false); 966 } 967 } 968 969 class MyWakeGestureListener extends WakeGestureListener { 970 MyWakeGestureListener(Context context, Handler handler) { 971 super(context, handler); 972 } 973 974 @Override 975 public void onWakeUp() { 976 synchronized (mLock) { 977 if (shouldEnableWakeGestureLp()) { 978 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); 979 wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture, 980 "android.policy:GESTURE"); 981 } 982 } 983 } 984 } 985 986 class MyOrientationListener extends WindowOrientationListener { 987 private final Runnable mUpdateRotationRunnable = new Runnable() { 988 @Override 989 public void run() { 990 // send interaction hint to improve redraw performance 991 mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0); 992 updateRotation(false); 993 } 994 }; 995 996 MyOrientationListener(Context context, Handler handler) { 997 super(context, handler); 998 } 999 1000 @Override 1001 public void onProposedRotationChanged(int rotation) { 1002 if (localLOGV) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation); 1003 mHandler.post(mUpdateRotationRunnable); 1004 } 1005 } 1006 MyOrientationListener mOrientationListener; 1007 1008 final IPersistentVrStateCallbacks mPersistentVrModeListener = 1009 new IPersistentVrStateCallbacks.Stub() { 1010 @Override 1011 public void onPersistentVrStateChanged(boolean enabled) { 1012 mPersistentVrModeEnabled = enabled; 1013 } 1014 }; 1015 1016 private final StatusBarController mStatusBarController = new StatusBarController(); 1017 1018 private final BarController mNavigationBarController = new BarController("NavigationBar", 1019 View.NAVIGATION_BAR_TRANSIENT, 1020 View.NAVIGATION_BAR_UNHIDE, 1021 View.NAVIGATION_BAR_TRANSLUCENT, 1022 StatusBarManager.WINDOW_NAVIGATION_BAR, 1023 WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, 1024 View.NAVIGATION_BAR_TRANSPARENT); 1025 1026 private final BarController.OnBarVisibilityChangedListener mNavBarVisibilityListener = 1027 new BarController.OnBarVisibilityChangedListener() { 1028 @Override 1029 public void onBarVisibilityChanged(boolean visible) { 1030 mAccessibilityManager.notifyAccessibilityButtonAvailabilityChanged(visible); 1031 } 1032 }; 1033 1034 private ImmersiveModeConfirmation mImmersiveModeConfirmation; 1035 1036 private SystemGesturesPointerEventListener mSystemGestures; 1037 1038 IStatusBarService getStatusBarService() { 1039 synchronized (mServiceAquireLock) { 1040 if (mStatusBarService == null) { 1041 mStatusBarService = IStatusBarService.Stub.asInterface( 1042 ServiceManager.getService("statusbar")); 1043 } 1044 return mStatusBarService; 1045 } 1046 } 1047 1048 StatusBarManagerInternal getStatusBarManagerInternal() { 1049 synchronized (mServiceAquireLock) { 1050 if (mStatusBarManagerInternal == null) { 1051 mStatusBarManagerInternal = 1052 LocalServices.getService(StatusBarManagerInternal.class); 1053 } 1054 return mStatusBarManagerInternal; 1055 } 1056 } 1057 1058 /* 1059 * We always let the sensor be switched on by default except when 1060 * the user has explicitly disabled sensor based rotation or when the 1061 * screen is switched off. 1062 */ 1063 boolean needSensorRunningLp() { 1064 if (mSupportAutoRotation) { 1065 if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR 1066 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 1067 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT 1068 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) { 1069 // If the application has explicitly requested to follow the 1070 // orientation, then we need to turn the sensor on. 1071 return true; 1072 } 1073 } 1074 if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) || 1075 (mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK 1076 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK 1077 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) { 1078 // enable accelerometer if we are docked in a dock that enables accelerometer 1079 // orientation management, 1080 return true; 1081 } 1082 if (mUserRotationMode == USER_ROTATION_LOCKED) { 1083 // If the setting for using the sensor by default is enabled, then 1084 // we will always leave it on. Note that the user could go to 1085 // a window that forces an orientation that does not use the 1086 // sensor and in theory we could turn it off... however, when next 1087 // turning it on we won't have a good value for the current 1088 // orientation for a little bit, which can cause orientation 1089 // changes to lag, so we'd like to keep it always on. (It will 1090 // still be turned off when the screen is off.) 1091 return false; 1092 } 1093 return mSupportAutoRotation; 1094 } 1095 1096 /* 1097 * Various use cases for invoking this function 1098 * screen turning off, should always disable listeners if already enabled 1099 * screen turned on and current app has sensor based orientation, enable listeners 1100 * if not already enabled 1101 * screen turned on and current app does not have sensor orientation, disable listeners if 1102 * already enabled 1103 * screen turning on and current app has sensor based orientation, enable listeners if needed 1104 * screen turning on and current app has nosensor based orientation, do nothing 1105 */ 1106 void updateOrientationListenerLp() { 1107 if (!mOrientationListener.canDetectOrientation()) { 1108 // If sensor is turned off or nonexistent for some reason 1109 return; 1110 } 1111 // Could have been invoked due to screen turning on or off or 1112 // change of the currently visible window's orientation. 1113 if (localLOGV) Slog.v(TAG, "mScreenOnEarly=" + mScreenOnEarly 1114 + ", mAwake=" + mAwake + ", mCurrentAppOrientation=" + mCurrentAppOrientation 1115 + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled 1116 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete 1117 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); 1118 boolean disable = true; 1119 // Note: We postpone the rotating of the screen until the keyguard as well as the 1120 // window manager have reported a draw complete. 1121 if (mScreenOnEarly && mAwake && 1122 mKeyguardDrawComplete && mWindowManagerDrawComplete) { 1123 if (needSensorRunningLp()) { 1124 disable = false; 1125 //enable listener if not already enabled 1126 if (!mOrientationSensorEnabled) { 1127 mOrientationListener.enable(); 1128 if(localLOGV) Slog.v(TAG, "Enabling listeners"); 1129 mOrientationSensorEnabled = true; 1130 } 1131 } 1132 } 1133 //check if sensors need to be disabled 1134 if (disable && mOrientationSensorEnabled) { 1135 mOrientationListener.disable(); 1136 if(localLOGV) Slog.v(TAG, "Disabling listeners"); 1137 mOrientationSensorEnabled = false; 1138 } 1139 } 1140 1141 private void interceptBackKeyDown() { 1142 MetricsLogger.count(mContext, "key_back_down", 1); 1143 // Reset back key state for long press 1144 mBackKeyHandled = false; 1145 1146 // Cancel multi-press detection timeout. 1147 if (hasPanicPressOnBackBehavior()) { 1148 if (mBackKeyPressCounter != 0 1149 && mBackKeyPressCounter < PANIC_PRESS_BACK_COUNT) { 1150 mHandler.removeMessages(MSG_BACK_DELAYED_PRESS); 1151 } 1152 } 1153 1154 if (hasLongPressOnBackBehavior()) { 1155 Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS); 1156 msg.setAsynchronous(true); 1157 mHandler.sendMessageDelayed(msg, 1158 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 1159 } 1160 } 1161 1162 // returns true if the key was handled and should not be passed to the user 1163 private boolean interceptBackKeyUp(KeyEvent event) { 1164 // Cache handled state 1165 boolean handled = mBackKeyHandled; 1166 1167 if (hasPanicPressOnBackBehavior()) { 1168 // Check for back key panic press 1169 ++mBackKeyPressCounter; 1170 1171 final long eventTime = event.getDownTime(); 1172 1173 if (mBackKeyPressCounter <= PANIC_PRESS_BACK_COUNT) { 1174 // This could be a multi-press. Wait a little bit longer to confirm. 1175 Message msg = mHandler.obtainMessage(MSG_BACK_DELAYED_PRESS, 1176 mBackKeyPressCounter, 0, eventTime); 1177 msg.setAsynchronous(true); 1178 mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout()); 1179 } 1180 } 1181 1182 // Reset back long press state 1183 cancelPendingBackKeyAction(); 1184 1185 if (mHasFeatureWatch) { 1186 TelecomManager telecomManager = getTelecommService(); 1187 1188 if (telecomManager != null) { 1189 if (telecomManager.isRinging()) { 1190 // Pressing back while there's a ringing incoming 1191 // call should silence the ringer. 1192 telecomManager.silenceRinger(); 1193 1194 // It should not prevent navigating away 1195 return false; 1196 } else if ( 1197 (mIncallBackBehavior & Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_HANGUP) != 0 1198 && telecomManager.isInCall()) { 1199 // Otherwise, if "Back button ends call" is enabled, 1200 // the Back button will hang up any current active call. 1201 return telecomManager.endCall(); 1202 } 1203 } 1204 } 1205 1206 return handled; 1207 } 1208 1209 private void interceptPowerKeyDown(KeyEvent event, boolean interactive) { 1210 // Hold a wake lock until the power key is released. 1211 if (!mPowerKeyWakeLock.isHeld()) { 1212 mPowerKeyWakeLock.acquire(); 1213 } 1214 1215 // Cancel multi-press detection timeout. 1216 if (mPowerKeyPressCounter != 0) { 1217 mHandler.removeMessages(MSG_POWER_DELAYED_PRESS); 1218 } 1219 1220 // Detect user pressing the power button in panic when an application has 1221 // taken over the whole screen. 1222 boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive, 1223 SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags), 1224 isNavBarEmpty(mLastSystemUiFlags)); 1225 if (panic) { 1226 mHandler.post(mHiddenNavPanic); 1227 } 1228 1229 // Latch power key state to detect screenshot chord. 1230 if (interactive && !mScreenshotChordPowerKeyTriggered 1231 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 1232 mScreenshotChordPowerKeyTriggered = true; 1233 mScreenshotChordPowerKeyTime = event.getDownTime(); 1234 interceptScreenshotChord(); 1235 } 1236 1237 // Stop ringing or end call if configured to do so when power is pressed. 1238 TelecomManager telecomManager = getTelecommService(); 1239 boolean hungUp = false; 1240 if (telecomManager != null) { 1241 if (telecomManager.isRinging()) { 1242 // Pressing Power while there's a ringing incoming 1243 // call should silence the ringer. 1244 telecomManager.silenceRinger(); 1245 } else if ((mIncallPowerBehavior 1246 & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0 1247 && telecomManager.isInCall() && interactive) { 1248 // Otherwise, if "Power button ends call" is enabled, 1249 // the Power button will hang up any current active call. 1250 hungUp = telecomManager.endCall(); 1251 } 1252 } 1253 1254 GestureLauncherService gestureService = LocalServices.getService( 1255 GestureLauncherService.class); 1256 boolean gesturedServiceIntercepted = false; 1257 if (gestureService != null) { 1258 gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive, 1259 mTmpBoolean); 1260 if (mTmpBoolean.value && mGoingToSleep) { 1261 mCameraGestureTriggeredDuringGoingToSleep = true; 1262 } 1263 } 1264 1265 // If the power key has still not yet been handled, then detect short 1266 // press, long press, or multi press and decide what to do. 1267 mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered 1268 || mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted; 1269 if (!mPowerKeyHandled) { 1270 if (interactive) { 1271 // When interactive, we're already awake. 1272 // Wait for a long press or for the button to be released to decide what to do. 1273 if (hasLongPressOnPowerBehavior()) { 1274 Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS); 1275 msg.setAsynchronous(true); 1276 mHandler.sendMessageDelayed(msg, 1277 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 1278 } 1279 } else { 1280 wakeUpFromPowerKey(event.getDownTime()); 1281 1282 if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) { 1283 Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS); 1284 msg.setAsynchronous(true); 1285 mHandler.sendMessageDelayed(msg, 1286 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 1287 mBeganFromNonInteractive = true; 1288 } else { 1289 final int maxCount = getMaxMultiPressPowerCount(); 1290 1291 if (maxCount <= 1) { 1292 mPowerKeyHandled = true; 1293 } else { 1294 mBeganFromNonInteractive = true; 1295 } 1296 } 1297 } 1298 } 1299 } 1300 1301 private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) { 1302 final boolean handled = canceled || mPowerKeyHandled; 1303 mScreenshotChordPowerKeyTriggered = false; 1304 cancelPendingScreenshotChordAction(); 1305 cancelPendingPowerKeyAction(); 1306 1307 if (!handled) { 1308 // Figure out how to handle the key now that it has been released. 1309 mPowerKeyPressCounter += 1; 1310 1311 final int maxCount = getMaxMultiPressPowerCount(); 1312 final long eventTime = event.getDownTime(); 1313 if (mPowerKeyPressCounter < maxCount) { 1314 // This could be a multi-press. Wait a little bit longer to confirm. 1315 // Continue holding the wake lock. 1316 Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS, 1317 interactive ? 1 : 0, mPowerKeyPressCounter, eventTime); 1318 msg.setAsynchronous(true); 1319 mHandler.sendMessageDelayed(msg, ViewConfiguration.getDoubleTapTimeout()); 1320 return; 1321 } 1322 1323 // No other actions. Handle it immediately. 1324 powerPress(eventTime, interactive, mPowerKeyPressCounter); 1325 } 1326 1327 // Done. Reset our state. 1328 finishPowerKeyPress(); 1329 } 1330 1331 private void finishPowerKeyPress() { 1332 mBeganFromNonInteractive = false; 1333 mPowerKeyPressCounter = 0; 1334 if (mPowerKeyWakeLock.isHeld()) { 1335 mPowerKeyWakeLock.release(); 1336 } 1337 } 1338 1339 private void finishBackKeyPress() { 1340 mBackKeyPressCounter = 0; 1341 } 1342 1343 private void cancelPendingPowerKeyAction() { 1344 if (!mPowerKeyHandled) { 1345 mPowerKeyHandled = true; 1346 mHandler.removeMessages(MSG_POWER_LONG_PRESS); 1347 } 1348 } 1349 1350 private void cancelPendingBackKeyAction() { 1351 if (!mBackKeyHandled) { 1352 mBackKeyHandled = true; 1353 mHandler.removeMessages(MSG_BACK_LONG_PRESS); 1354 } 1355 } 1356 1357 private void backMultiPressAction(long eventTime, int count) { 1358 if (count >= PANIC_PRESS_BACK_COUNT) { 1359 switch (mPanicPressOnBackBehavior) { 1360 case PANIC_PRESS_BACK_NOTHING: 1361 break; 1362 case PANIC_PRESS_BACK_HOME: 1363 launchHomeFromHotKey(); 1364 break; 1365 } 1366 } 1367 } 1368 1369 private void powerPress(long eventTime, boolean interactive, int count) { 1370 if (mScreenOnEarly && !mScreenOnFully) { 1371 Slog.i(TAG, "Suppressed redundant power key press while " 1372 + "already in the process of turning the screen on."); 1373 return; 1374 } 1375 1376 if (count == 2) { 1377 powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior); 1378 } else if (count == 3) { 1379 powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior); 1380 } else if (interactive && !mBeganFromNonInteractive) { 1381 switch (mShortPressOnPowerBehavior) { 1382 case SHORT_PRESS_POWER_NOTHING: 1383 break; 1384 case SHORT_PRESS_POWER_GO_TO_SLEEP: 1385 mPowerManager.goToSleep(eventTime, 1386 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); 1387 break; 1388 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: 1389 mPowerManager.goToSleep(eventTime, 1390 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 1391 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 1392 break; 1393 case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME: 1394 mPowerManager.goToSleep(eventTime, 1395 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 1396 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 1397 launchHomeFromHotKey(); 1398 break; 1399 case SHORT_PRESS_POWER_GO_HOME: 1400 launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/); 1401 break; 1402 case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: { 1403 if (mDismissImeOnBackKeyPressed) { 1404 if (mInputMethodManagerInternal == null) { 1405 mInputMethodManagerInternal = 1406 LocalServices.getService(InputMethodManagerInternal.class); 1407 } 1408 if (mInputMethodManagerInternal != null) { 1409 mInputMethodManagerInternal.hideCurrentInputMethod(); 1410 } 1411 } else { 1412 launchHomeFromHotKey(true /* awakenFromDreams */, 1413 false /*respectKeyguard*/); 1414 } 1415 break; 1416 } 1417 } 1418 } 1419 } 1420 1421 private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) { 1422 switch (behavior) { 1423 case MULTI_PRESS_POWER_NOTHING: 1424 break; 1425 case MULTI_PRESS_POWER_THEATER_MODE: 1426 if (!isUserSetupComplete()) { 1427 Slog.i(TAG, "Ignoring toggling theater mode - device not setup."); 1428 break; 1429 } 1430 1431 if (isTheaterModeEnabled()) { 1432 Slog.i(TAG, "Toggling theater mode off."); 1433 Settings.Global.putInt(mContext.getContentResolver(), 1434 Settings.Global.THEATER_MODE_ON, 0); 1435 if (!interactive) { 1436 wakeUpFromPowerKey(eventTime); 1437 } 1438 } else { 1439 Slog.i(TAG, "Toggling theater mode on."); 1440 Settings.Global.putInt(mContext.getContentResolver(), 1441 Settings.Global.THEATER_MODE_ON, 1); 1442 1443 if (mGoToSleepOnButtonPressTheaterMode && interactive) { 1444 mPowerManager.goToSleep(eventTime, 1445 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); 1446 } 1447 } 1448 break; 1449 case MULTI_PRESS_POWER_BRIGHTNESS_BOOST: 1450 Slog.i(TAG, "Starting brightness boost."); 1451 if (!interactive) { 1452 wakeUpFromPowerKey(eventTime); 1453 } 1454 mPowerManager.boostScreenBrightness(eventTime); 1455 break; 1456 } 1457 } 1458 1459 private int getMaxMultiPressPowerCount() { 1460 if (mTriplePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) { 1461 return 3; 1462 } 1463 if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) { 1464 return 2; 1465 } 1466 return 1; 1467 } 1468 1469 private void powerLongPress() { 1470 final int behavior = getResolvedLongPressOnPowerBehavior(); 1471 switch (behavior) { 1472 case LONG_PRESS_POWER_NOTHING: 1473 break; 1474 case LONG_PRESS_POWER_GLOBAL_ACTIONS: 1475 mPowerKeyHandled = true; 1476 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); 1477 showGlobalActionsInternal(); 1478 break; 1479 case LONG_PRESS_POWER_SHUT_OFF: 1480 case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM: 1481 mPowerKeyHandled = true; 1482 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); 1483 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); 1484 mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF); 1485 break; 1486 } 1487 } 1488 1489 private void backLongPress() { 1490 mBackKeyHandled = true; 1491 1492 switch (mLongPressOnBackBehavior) { 1493 case LONG_PRESS_BACK_NOTHING: 1494 break; 1495 case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST: 1496 final boolean keyguardActive = mKeyguardDelegate == null 1497 ? false 1498 : mKeyguardDelegate.isShowing(); 1499 if (!keyguardActive) { 1500 Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST); 1501 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 1502 } 1503 break; 1504 } 1505 } 1506 1507 private void accessibilityShortcutActivated() { 1508 mAccessibilityShortcutController.performAccessibilityShortcut(); 1509 } 1510 1511 private void disposeInputConsumer(InputConsumer inputConsumer) { 1512 if (inputConsumer != null) { 1513 inputConsumer.dismiss(); 1514 } 1515 } 1516 1517 private void sleepPress(long eventTime) { 1518 if (mShortPressOnSleepBehavior == SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME) { 1519 launchHomeFromHotKey(false /* awakenDreams */, true /*respectKeyguard*/); 1520 } 1521 } 1522 1523 private void sleepRelease(long eventTime) { 1524 switch (mShortPressOnSleepBehavior) { 1525 case SHORT_PRESS_SLEEP_GO_TO_SLEEP: 1526 case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME: 1527 Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)"); 1528 mPowerManager.goToSleep(eventTime, 1529 PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); 1530 break; 1531 } 1532 } 1533 1534 private int getResolvedLongPressOnPowerBehavior() { 1535 if (FactoryTest.isLongPressOnPowerOffEnabled()) { 1536 return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM; 1537 } 1538 return mLongPressOnPowerBehavior; 1539 } 1540 1541 private boolean hasLongPressOnPowerBehavior() { 1542 return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING; 1543 } 1544 1545 private boolean hasLongPressOnBackBehavior() { 1546 return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING; 1547 } 1548 1549 private boolean hasPanicPressOnBackBehavior() { 1550 return mPanicPressOnBackBehavior != PANIC_PRESS_BACK_NOTHING; 1551 } 1552 1553 private void interceptScreenshotChord() { 1554 if (mScreenshotChordEnabled 1555 && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered 1556 && !mA11yShortcutChordVolumeUpKeyTriggered) { 1557 final long now = SystemClock.uptimeMillis(); 1558 if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS 1559 && now <= mScreenshotChordPowerKeyTime 1560 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) { 1561 mScreenshotChordVolumeDownKeyConsumed = true; 1562 cancelPendingPowerKeyAction(); 1563 mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN); 1564 mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay()); 1565 } 1566 } 1567 } 1568 1569 private void interceptAccessibilityShortcutChord() { 1570 if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked()) 1571 && mScreenshotChordVolumeDownKeyTriggered && mA11yShortcutChordVolumeUpKeyTriggered 1572 && !mScreenshotChordPowerKeyTriggered) { 1573 final long now = SystemClock.uptimeMillis(); 1574 if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS 1575 && now <= mA11yShortcutChordVolumeUpKeyTime 1576 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) { 1577 mScreenshotChordVolumeDownKeyConsumed = true; 1578 mA11yShortcutChordVolumeUpKeyConsumed = true; 1579 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT), 1580 ViewConfiguration.get(mContext).getAccessibilityShortcutKeyTimeout()); 1581 } 1582 } 1583 } 1584 1585 private long getScreenshotChordLongPressDelay() { 1586 if (mKeyguardDelegate.isShowing()) { 1587 // Double the time it takes to take a screenshot from the keyguard 1588 return (long) (KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER * 1589 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 1590 } 1591 return ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout(); 1592 } 1593 1594 private void cancelPendingScreenshotChordAction() { 1595 mHandler.removeCallbacks(mScreenshotRunnable); 1596 } 1597 1598 private void cancelPendingAccessibilityShortcutAction() { 1599 mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT); 1600 } 1601 1602 private final Runnable mEndCallLongPress = new Runnable() { 1603 @Override 1604 public void run() { 1605 mEndCallKeyHandled = true; 1606 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); 1607 showGlobalActionsInternal(); 1608 } 1609 }; 1610 1611 private class ScreenshotRunnable implements Runnable { 1612 private int mScreenshotType = TAKE_SCREENSHOT_FULLSCREEN; 1613 1614 public void setScreenshotType(int screenshotType) { 1615 mScreenshotType = screenshotType; 1616 } 1617 1618 @Override 1619 public void run() { 1620 takeScreenshot(mScreenshotType); 1621 } 1622 } 1623 1624 private final ScreenshotRunnable mScreenshotRunnable = new ScreenshotRunnable(); 1625 1626 @Override 1627 public void showGlobalActions() { 1628 mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS); 1629 mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS); 1630 } 1631 1632 void showGlobalActionsInternal() { 1633 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); 1634 if (mGlobalActions == null) { 1635 mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs); 1636 } 1637 final boolean keyguardShowing = isKeyguardShowingAndNotOccluded(); 1638 mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); 1639 if (keyguardShowing) { 1640 // since it took two seconds of long press to bring this up, 1641 // poke the wake lock so they have some time to see the dialog. 1642 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 1643 } 1644 } 1645 1646 boolean isDeviceProvisioned() { 1647 return Settings.Global.getInt( 1648 mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0; 1649 } 1650 1651 boolean isUserSetupComplete() { 1652 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 1653 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; 1654 } 1655 1656 private void handleShortPressOnHome() { 1657 // Turn on the connected TV and switch HDMI input if we're a HDMI playback device. 1658 final HdmiControl hdmiControl = getHdmiControl(); 1659 if (hdmiControl != null) { 1660 hdmiControl.turnOnTv(); 1661 } 1662 1663 // If there's a dream running then use home to escape the dream 1664 // but don't actually go home. 1665 if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) { 1666 mDreamManagerInternal.stopDream(false /*immediate*/); 1667 return; 1668 } 1669 1670 // Go home! 1671 launchHomeFromHotKey(); 1672 } 1673 1674 /** 1675 * Creates an accessor to HDMI control service that performs the operation of 1676 * turning on TV (optional) and switching input to us. If HDMI control service 1677 * is not available or we're not a HDMI playback device, the operation is no-op. 1678 * @return {@link HdmiControl} instance if available, null otherwise. 1679 */ 1680 private HdmiControl getHdmiControl() { 1681 if (null == mHdmiControl) { 1682 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { 1683 return null; 1684 } 1685 HdmiControlManager manager = (HdmiControlManager) mContext.getSystemService( 1686 Context.HDMI_CONTROL_SERVICE); 1687 HdmiPlaybackClient client = null; 1688 if (manager != null) { 1689 client = manager.getPlaybackClient(); 1690 } 1691 mHdmiControl = new HdmiControl(client); 1692 } 1693 return mHdmiControl; 1694 } 1695 1696 private static class HdmiControl { 1697 private final HdmiPlaybackClient mClient; 1698 1699 private HdmiControl(HdmiPlaybackClient client) { 1700 mClient = client; 1701 } 1702 1703 public void turnOnTv() { 1704 if (mClient == null) { 1705 return; 1706 } 1707 mClient.oneTouchPlay(new OneTouchPlayCallback() { 1708 @Override 1709 public void onComplete(int result) { 1710 if (result != HdmiControlManager.RESULT_SUCCESS) { 1711 Log.w(TAG, "One touch play failed: " + result); 1712 } 1713 } 1714 }); 1715 } 1716 } 1717 1718 private void handleLongPressOnHome(int deviceId) { 1719 if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_NOTHING) { 1720 return; 1721 } 1722 mHomeConsumed = true; 1723 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); 1724 switch (mLongPressOnHomeBehavior) { 1725 case LONG_PRESS_HOME_ALL_APPS: 1726 launchAllAppsAction(); 1727 break; 1728 case LONG_PRESS_HOME_ASSIST: 1729 launchAssistAction(null, deviceId); 1730 break; 1731 default: 1732 Log.w(TAG, "Undefined home long press behavior: " + mLongPressOnHomeBehavior); 1733 break; 1734 } 1735 } 1736 1737 private void launchAllAppsAction() { 1738 Intent intent = new Intent(Intent.ACTION_ALL_APPS); 1739 startActivityAsUser(intent, UserHandle.CURRENT); 1740 } 1741 1742 private void handleDoubleTapOnHome() { 1743 if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) { 1744 mHomeConsumed = true; 1745 toggleRecentApps(); 1746 } 1747 } 1748 1749 private void showPictureInPictureMenu(KeyEvent event) { 1750 if (DEBUG_INPUT) Log.d(TAG, "showPictureInPictureMenu event=" + event); 1751 mHandler.removeMessages(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 1752 Message msg = mHandler.obtainMessage(MSG_SHOW_PICTURE_IN_PICTURE_MENU); 1753 msg.setAsynchronous(true); 1754 msg.sendToTarget(); 1755 } 1756 1757 private void showPictureInPictureMenuInternal() { 1758 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 1759 if (statusbar != null) { 1760 statusbar.showPictureInPictureMenu(); 1761 } 1762 } 1763 1764 private final Runnable mHomeDoubleTapTimeoutRunnable = new Runnable() { 1765 @Override 1766 public void run() { 1767 if (mHomeDoubleTapPending) { 1768 mHomeDoubleTapPending = false; 1769 handleShortPressOnHome(); 1770 } 1771 } 1772 }; 1773 1774 private boolean isRoundWindow() { 1775 return mContext.getResources().getConfiguration().isScreenRound(); 1776 } 1777 1778 /** {@inheritDoc} */ 1779 @Override 1780 public void init(Context context, IWindowManager windowManager, 1781 WindowManagerFuncs windowManagerFuncs) { 1782 mContext = context; 1783 mWindowManager = windowManager; 1784 mWindowManagerFuncs = windowManagerFuncs; 1785 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); 1786 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 1787 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 1788 mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); 1789 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 1790 mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 1791 mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH); 1792 mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK); 1793 mAccessibilityShortcutController = 1794 new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId); 1795 // Init display burn-in protection 1796 boolean burnInProtectionEnabled = context.getResources().getBoolean( 1797 com.android.internal.R.bool.config_enableBurnInProtection); 1798 // Allow a system property to override this. Used by developer settings. 1799 boolean burnInProtectionDevMode = 1800 SystemProperties.getBoolean("persist.debug.force_burn_in", false); 1801 if (burnInProtectionEnabled || burnInProtectionDevMode) { 1802 final int minHorizontal; 1803 final int maxHorizontal; 1804 final int minVertical; 1805 final int maxVertical; 1806 final int maxRadius; 1807 if (burnInProtectionDevMode) { 1808 minHorizontal = -8; 1809 maxHorizontal = 8; 1810 minVertical = -8; 1811 maxVertical = -4; 1812 maxRadius = (isRoundWindow()) ? 6 : -1; 1813 } else { 1814 Resources resources = context.getResources(); 1815 minHorizontal = resources.getInteger( 1816 com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset); 1817 maxHorizontal = resources.getInteger( 1818 com.android.internal.R.integer.config_burnInProtectionMaxHorizontalOffset); 1819 minVertical = resources.getInteger( 1820 com.android.internal.R.integer.config_burnInProtectionMinVerticalOffset); 1821 maxVertical = resources.getInteger( 1822 com.android.internal.R.integer.config_burnInProtectionMaxVerticalOffset); 1823 maxRadius = resources.getInteger( 1824 com.android.internal.R.integer.config_burnInProtectionMaxRadius); 1825 } 1826 mBurnInProtectionHelper = new BurnInProtectionHelper( 1827 context, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius); 1828 } 1829 1830 mHandler = new PolicyHandler(); 1831 mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler); 1832 mOrientationListener = new MyOrientationListener(mContext, mHandler); 1833 try { 1834 mOrientationListener.setCurrentRotation(windowManager.getDefaultDisplayRotation()); 1835 } catch (RemoteException ex) { } 1836 mSettingsObserver = new SettingsObserver(mHandler); 1837 mSettingsObserver.observe(); 1838 mShortcutManager = new ShortcutManager(context); 1839 mUiMode = context.getResources().getInteger( 1840 com.android.internal.R.integer.config_defaultUiModeType); 1841 mHomeIntent = new Intent(Intent.ACTION_MAIN, null); 1842 mHomeIntent.addCategory(Intent.CATEGORY_HOME); 1843 mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1844 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1845 mEnableCarDockHomeCapture = context.getResources().getBoolean( 1846 com.android.internal.R.bool.config_enableCarDockHomeLaunch); 1847 mCarDockIntent = new Intent(Intent.ACTION_MAIN, null); 1848 mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK); 1849 mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1850 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1851 mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null); 1852 mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK); 1853 mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1854 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1855 mVrHeadsetHomeIntent = new Intent(Intent.ACTION_MAIN, null); 1856 mVrHeadsetHomeIntent.addCategory(Intent.CATEGORY_VR_HOME); 1857 mVrHeadsetHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1858 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1859 1860 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1861 mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1862 "PhoneWindowManager.mBroadcastWakeLock"); 1863 mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 1864 "PhoneWindowManager.mPowerKeyWakeLock"); 1865 mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable")); 1866 mSupportAutoRotation = mContext.getResources().getBoolean( 1867 com.android.internal.R.bool.config_supportAutoRotation); 1868 mLidOpenRotation = readRotation( 1869 com.android.internal.R.integer.config_lidOpenRotation); 1870 mCarDockRotation = readRotation( 1871 com.android.internal.R.integer.config_carDockRotation); 1872 mDeskDockRotation = readRotation( 1873 com.android.internal.R.integer.config_deskDockRotation); 1874 mUndockedHdmiRotation = readRotation( 1875 com.android.internal.R.integer.config_undockedHdmiRotation); 1876 mCarDockEnablesAccelerometer = mContext.getResources().getBoolean( 1877 com.android.internal.R.bool.config_carDockEnablesAccelerometer); 1878 mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean( 1879 com.android.internal.R.bool.config_deskDockEnablesAccelerometer); 1880 mLidKeyboardAccessibility = mContext.getResources().getInteger( 1881 com.android.internal.R.integer.config_lidKeyboardAccessibility); 1882 mLidNavigationAccessibility = mContext.getResources().getInteger( 1883 com.android.internal.R.integer.config_lidNavigationAccessibility); 1884 mLidControlsScreenLock = mContext.getResources().getBoolean( 1885 com.android.internal.R.bool.config_lidControlsScreenLock); 1886 mLidControlsSleep = mContext.getResources().getBoolean( 1887 com.android.internal.R.bool.config_lidControlsSleep); 1888 mTranslucentDecorEnabled = mContext.getResources().getBoolean( 1889 com.android.internal.R.bool.config_enableTranslucentDecor); 1890 1891 mAllowTheaterModeWakeFromKey = mContext.getResources().getBoolean( 1892 com.android.internal.R.bool.config_allowTheaterModeWakeFromKey); 1893 mAllowTheaterModeWakeFromPowerKey = mAllowTheaterModeWakeFromKey 1894 || mContext.getResources().getBoolean( 1895 com.android.internal.R.bool.config_allowTheaterModeWakeFromPowerKey); 1896 mAllowTheaterModeWakeFromMotion = mContext.getResources().getBoolean( 1897 com.android.internal.R.bool.config_allowTheaterModeWakeFromMotion); 1898 mAllowTheaterModeWakeFromMotionWhenNotDreaming = mContext.getResources().getBoolean( 1899 com.android.internal.R.bool.config_allowTheaterModeWakeFromMotionWhenNotDreaming); 1900 mAllowTheaterModeWakeFromCameraLens = mContext.getResources().getBoolean( 1901 com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraLens); 1902 mAllowTheaterModeWakeFromLidSwitch = mContext.getResources().getBoolean( 1903 com.android.internal.R.bool.config_allowTheaterModeWakeFromLidSwitch); 1904 mAllowTheaterModeWakeFromWakeGesture = mContext.getResources().getBoolean( 1905 com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture); 1906 1907 mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean( 1908 com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode); 1909 1910 mSupportLongPressPowerWhenNonInteractive = mContext.getResources().getBoolean( 1911 com.android.internal.R.bool.config_supportLongPressPowerWhenNonInteractive); 1912 1913 mLongPressOnBackBehavior = mContext.getResources().getInteger( 1914 com.android.internal.R.integer.config_longPressOnBackBehavior); 1915 mPanicPressOnBackBehavior = mContext.getResources().getInteger( 1916 com.android.internal.R.integer.config_backPanicBehavior); 1917 1918 mShortPressOnPowerBehavior = mContext.getResources().getInteger( 1919 com.android.internal.R.integer.config_shortPressOnPowerBehavior); 1920 mLongPressOnPowerBehavior = mContext.getResources().getInteger( 1921 com.android.internal.R.integer.config_longPressOnPowerBehavior); 1922 mDoublePressOnPowerBehavior = mContext.getResources().getInteger( 1923 com.android.internal.R.integer.config_doublePressOnPowerBehavior); 1924 mTriplePressOnPowerBehavior = mContext.getResources().getInteger( 1925 com.android.internal.R.integer.config_triplePressOnPowerBehavior); 1926 mShortPressOnSleepBehavior = mContext.getResources().getInteger( 1927 com.android.internal.R.integer.config_shortPressOnSleepBehavior); 1928 1929 mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION; 1930 1931 readConfigurationDependentBehaviors(); 1932 1933 mAccessibilityManager = (AccessibilityManager) context.getSystemService( 1934 Context.ACCESSIBILITY_SERVICE); 1935 1936 // register for dock events 1937 IntentFilter filter = new IntentFilter(); 1938 filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE); 1939 filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE); 1940 filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE); 1941 filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE); 1942 filter.addAction(Intent.ACTION_DOCK_EVENT); 1943 Intent intent = context.registerReceiver(mDockReceiver, filter); 1944 if (intent != null) { 1945 // Retrieve current sticky dock event broadcast. 1946 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 1947 Intent.EXTRA_DOCK_STATE_UNDOCKED); 1948 } 1949 1950 // register for dream-related broadcasts 1951 filter = new IntentFilter(); 1952 filter.addAction(Intent.ACTION_DREAMING_STARTED); 1953 filter.addAction(Intent.ACTION_DREAMING_STOPPED); 1954 context.registerReceiver(mDreamReceiver, filter); 1955 1956 // register for multiuser-relevant broadcasts 1957 filter = new IntentFilter(Intent.ACTION_USER_SWITCHED); 1958 context.registerReceiver(mMultiuserReceiver, filter); 1959 1960 // monitor for system gestures 1961 mSystemGestures = new SystemGesturesPointerEventListener(context, 1962 new SystemGesturesPointerEventListener.Callbacks() { 1963 @Override 1964 public void onSwipeFromTop() { 1965 if (mStatusBar != null) { 1966 requestTransientBars(mStatusBar); 1967 } 1968 } 1969 @Override 1970 public void onSwipeFromBottom() { 1971 if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) { 1972 requestTransientBars(mNavigationBar); 1973 } 1974 } 1975 @Override 1976 public void onSwipeFromRight() { 1977 if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) { 1978 requestTransientBars(mNavigationBar); 1979 } 1980 } 1981 @Override 1982 public void onSwipeFromLeft() { 1983 if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) { 1984 requestTransientBars(mNavigationBar); 1985 } 1986 } 1987 @Override 1988 public void onFling(int duration) { 1989 if (mPowerManagerInternal != null) { 1990 mPowerManagerInternal.powerHint( 1991 PowerHint.INTERACTION, duration); 1992 } 1993 } 1994 @Override 1995 public void onDebug() { 1996 // no-op 1997 } 1998 @Override 1999 public void onDown() { 2000 mOrientationListener.onTouchStart(); 2001 } 2002 @Override 2003 public void onUpOrCancel() { 2004 mOrientationListener.onTouchEnd(); 2005 } 2006 @Override 2007 public void onMouseHoverAtTop() { 2008 mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); 2009 Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); 2010 msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS; 2011 mHandler.sendMessageDelayed(msg, 500); 2012 } 2013 @Override 2014 public void onMouseHoverAtBottom() { 2015 mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); 2016 Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); 2017 msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION; 2018 mHandler.sendMessageDelayed(msg, 500); 2019 } 2020 @Override 2021 public void onMouseLeaveFromEdge() { 2022 mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); 2023 } 2024 }); 2025 mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext); 2026 mWindowManagerFuncs.registerPointerEventListener(mSystemGestures); 2027 2028 mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE); 2029 mLongPressVibePattern = getLongIntArray(mContext.getResources(), 2030 com.android.internal.R.array.config_longPressVibePattern); 2031 mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(), 2032 com.android.internal.R.array.config_virtualKeyVibePattern); 2033 mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(), 2034 com.android.internal.R.array.config_keyboardTapVibePattern); 2035 mClockTickVibePattern = getLongIntArray(mContext.getResources(), 2036 com.android.internal.R.array.config_clockTickVibePattern); 2037 mCalendarDateVibePattern = getLongIntArray(mContext.getResources(), 2038 com.android.internal.R.array.config_calendarDateVibePattern); 2039 mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(), 2040 com.android.internal.R.array.config_safeModeDisabledVibePattern); 2041 mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(), 2042 com.android.internal.R.array.config_safeModeEnabledVibePattern); 2043 mContextClickVibePattern = getLongIntArray(mContext.getResources(), 2044 com.android.internal.R.array.config_contextClickVibePattern); 2045 2046 mScreenshotChordEnabled = mContext.getResources().getBoolean( 2047 com.android.internal.R.bool.config_enableScreenshotChord); 2048 2049 mGlobalKeyManager = new GlobalKeyManager(mContext); 2050 2051 // Controls rotation and the like. 2052 initializeHdmiState(); 2053 2054 // Match current screen state. 2055 if (!mPowerManager.isInteractive()) { 2056 startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER); 2057 finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER); 2058 } 2059 2060 mWindowManagerInternal.registerAppTransitionListener( 2061 mStatusBarController.getAppTransitionListener()); 2062 mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() { 2063 @Override 2064 public int onAppTransitionStartingLocked(int transit, IBinder openToken, 2065 IBinder closeToken, 2066 Animation openAnimation, Animation closeAnimation) { 2067 return handleStartTransitionForKeyguardLw(transit, openAnimation); 2068 } 2069 2070 @Override 2071 public void onAppTransitionCancelledLocked(int transit) { 2072 handleStartTransitionForKeyguardLw(transit, null /* transit */); 2073 } 2074 }); 2075 } 2076 2077 /** 2078 * Read values from config.xml that may be overridden depending on 2079 * the configuration of the device. 2080 * eg. Disable long press on home goes to recents on sw600dp. 2081 */ 2082 private void readConfigurationDependentBehaviors() { 2083 final Resources res = mContext.getResources(); 2084 2085 mLongPressOnHomeBehavior = res.getInteger( 2086 com.android.internal.R.integer.config_longPressOnHomeBehavior); 2087 if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING || 2088 mLongPressOnHomeBehavior > LAST_LONG_PRESS_HOME_BEHAVIOR) { 2089 mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING; 2090 } 2091 2092 mDoubleTapOnHomeBehavior = res.getInteger( 2093 com.android.internal.R.integer.config_doubleTapOnHomeBehavior); 2094 if (mDoubleTapOnHomeBehavior < DOUBLE_TAP_HOME_NOTHING || 2095 mDoubleTapOnHomeBehavior > DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) { 2096 mDoubleTapOnHomeBehavior = LONG_PRESS_HOME_NOTHING; 2097 } 2098 2099 mShortPressWindowBehavior = SHORT_PRESS_WINDOW_NOTHING; 2100 if (mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { 2101 mShortPressWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE; 2102 } 2103 2104 mNavBarOpacityMode = res.getInteger( 2105 com.android.internal.R.integer.config_navBarOpacityMode); 2106 } 2107 2108 @Override 2109 public void setInitialDisplaySize(Display display, int width, int height, int density) { 2110 // This method might be called before the policy has been fully initialized 2111 // or for other displays we don't care about. 2112 // TODO(multi-display): Define policy for secondary displays. 2113 if (mContext == null || display.getDisplayId() != Display.DEFAULT_DISPLAY) { 2114 return; 2115 } 2116 mDisplay = display; 2117 2118 final Resources res = mContext.getResources(); 2119 int shortSize, longSize; 2120 if (width > height) { 2121 shortSize = height; 2122 longSize = width; 2123 mLandscapeRotation = Surface.ROTATION_0; 2124 mSeascapeRotation = Surface.ROTATION_180; 2125 if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) { 2126 mPortraitRotation = Surface.ROTATION_90; 2127 mUpsideDownRotation = Surface.ROTATION_270; 2128 } else { 2129 mPortraitRotation = Surface.ROTATION_270; 2130 mUpsideDownRotation = Surface.ROTATION_90; 2131 } 2132 } else { 2133 shortSize = width; 2134 longSize = height; 2135 mPortraitRotation = Surface.ROTATION_0; 2136 mUpsideDownRotation = Surface.ROTATION_180; 2137 if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) { 2138 mLandscapeRotation = Surface.ROTATION_270; 2139 mSeascapeRotation = Surface.ROTATION_90; 2140 } else { 2141 mLandscapeRotation = Surface.ROTATION_90; 2142 mSeascapeRotation = Surface.ROTATION_270; 2143 } 2144 } 2145 2146 // SystemUI (status bar) layout policy 2147 int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density; 2148 int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density; 2149 2150 // Allow the navigation bar to move on non-square small devices (phones). 2151 mNavigationBarCanMove = width != height && shortSizeDp < 600; 2152 2153 mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar); 2154 2155 // Allow a system property to override this. Used by the emulator. 2156 // See also hasNavigationBar(). 2157 String navBarOverride = SystemProperties.get("qemu.hw.mainkeys"); 2158 if ("1".equals(navBarOverride)) { 2159 mHasNavigationBar = false; 2160 } else if ("0".equals(navBarOverride)) { 2161 mHasNavigationBar = true; 2162 } 2163 2164 // For demo purposes, allow the rotation of the HDMI display to be controlled. 2165 // By default, HDMI locks rotation to landscape. 2166 if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) { 2167 mDemoHdmiRotation = mPortraitRotation; 2168 } else { 2169 mDemoHdmiRotation = mLandscapeRotation; 2170 } 2171 mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false); 2172 2173 // For demo purposes, allow the rotation of the remote display to be controlled. 2174 // By default, remote display locks rotation to landscape. 2175 if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) { 2176 mDemoRotation = mPortraitRotation; 2177 } else { 2178 mDemoRotation = mLandscapeRotation; 2179 } 2180 mDemoRotationLock = SystemProperties.getBoolean( 2181 "persist.demo.rotationlock", false); 2182 2183 // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per 2184 // http://developer.android.com/guide/practices/screens_support.html#range 2185 mForceDefaultOrientation = longSizeDp >= 960 && shortSizeDp >= 720 && 2186 res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) && 2187 // For debug purposes the next line turns this feature off with: 2188 // $ adb shell setprop config.override_forced_orient true 2189 // $ adb shell wm size reset 2190 !"true".equals(SystemProperties.get("config.override_forced_orient")); 2191 } 2192 2193 /** 2194 * @return whether the navigation bar can be hidden, e.g. the device has a 2195 * navigation bar and touch exploration is not enabled 2196 */ 2197 private boolean canHideNavigationBar() { 2198 return mHasNavigationBar; 2199 } 2200 2201 @Override 2202 public boolean isDefaultOrientationForced() { 2203 return mForceDefaultOrientation; 2204 } 2205 2206 @Override 2207 public void setDisplayOverscan(Display display, int left, int top, int right, int bottom) { 2208 // TODO(multi-display): Define policy for secondary displays. 2209 if (display.getDisplayId() == Display.DEFAULT_DISPLAY) { 2210 mOverscanLeft = left; 2211 mOverscanTop = top; 2212 mOverscanRight = right; 2213 mOverscanBottom = bottom; 2214 } 2215 } 2216 2217 public void updateSettings() { 2218 ContentResolver resolver = mContext.getContentResolver(); 2219 boolean updateRotation = false; 2220 synchronized (mLock) { 2221 mEndcallBehavior = Settings.System.getIntForUser(resolver, 2222 Settings.System.END_BUTTON_BEHAVIOR, 2223 Settings.System.END_BUTTON_BEHAVIOR_DEFAULT, 2224 UserHandle.USER_CURRENT); 2225 mIncallPowerBehavior = Settings.Secure.getIntForUser(resolver, 2226 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 2227 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT, 2228 UserHandle.USER_CURRENT); 2229 mIncallBackBehavior = Settings.Secure.getIntForUser(resolver, 2230 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR, 2231 Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_DEFAULT, 2232 UserHandle.USER_CURRENT); 2233 2234 // Configure wake gesture. 2235 boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver, 2236 Settings.Secure.WAKE_GESTURE_ENABLED, 0, 2237 UserHandle.USER_CURRENT) != 0; 2238 if (mWakeGestureEnabledSetting != wakeGestureEnabledSetting) { 2239 mWakeGestureEnabledSetting = wakeGestureEnabledSetting; 2240 updateWakeGestureListenerLp(); 2241 } 2242 2243 // Configure rotation lock. 2244 int userRotation = Settings.System.getIntForUser(resolver, 2245 Settings.System.USER_ROTATION, Surface.ROTATION_0, 2246 UserHandle.USER_CURRENT); 2247 if (mUserRotation != userRotation) { 2248 mUserRotation = userRotation; 2249 updateRotation = true; 2250 } 2251 int userRotationMode = Settings.System.getIntForUser(resolver, 2252 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ? 2253 WindowManagerPolicy.USER_ROTATION_FREE : 2254 WindowManagerPolicy.USER_ROTATION_LOCKED; 2255 if (mUserRotationMode != userRotationMode) { 2256 mUserRotationMode = userRotationMode; 2257 updateRotation = true; 2258 updateOrientationListenerLp(); 2259 } 2260 2261 if (mSystemReady) { 2262 int pointerLocation = Settings.System.getIntForUser(resolver, 2263 Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT); 2264 if (mPointerLocationMode != pointerLocation) { 2265 mPointerLocationMode = pointerLocation; 2266 mHandler.sendEmptyMessage(pointerLocation != 0 ? 2267 MSG_ENABLE_POINTER_LOCATION : MSG_DISABLE_POINTER_LOCATION); 2268 } 2269 } 2270 // use screen off timeout setting as the timeout for the lockscreen 2271 mLockScreenTimeout = Settings.System.getIntForUser(resolver, 2272 Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT); 2273 String imId = Settings.Secure.getStringForUser(resolver, 2274 Settings.Secure.DEFAULT_INPUT_METHOD, UserHandle.USER_CURRENT); 2275 boolean hasSoftInput = imId != null && imId.length() > 0; 2276 if (mHasSoftInput != hasSoftInput) { 2277 mHasSoftInput = hasSoftInput; 2278 updateRotation = true; 2279 } 2280 if (mImmersiveModeConfirmation != null) { 2281 mImmersiveModeConfirmation.loadSetting(mCurrentUserId); 2282 } 2283 } 2284 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 2285 PolicyControl.reloadFromSetting(mContext); 2286 } 2287 if (updateRotation) { 2288 updateRotation(true); 2289 } 2290 } 2291 2292 private void updateWakeGestureListenerLp() { 2293 if (shouldEnableWakeGestureLp()) { 2294 mWakeGestureListener.requestWakeUpTrigger(); 2295 } else { 2296 mWakeGestureListener.cancelWakeUpTrigger(); 2297 } 2298 } 2299 2300 private boolean shouldEnableWakeGestureLp() { 2301 return mWakeGestureEnabledSetting && !mAwake 2302 && (!mLidControlsSleep || mLidState != LID_CLOSED) 2303 && mWakeGestureListener.isSupported(); 2304 } 2305 2306 private void enablePointerLocation() { 2307 if (mPointerLocationView == null) { 2308 mPointerLocationView = new PointerLocationView(mContext); 2309 mPointerLocationView.setPrintCoords(false); 2310 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 2311 WindowManager.LayoutParams.MATCH_PARENT, 2312 WindowManager.LayoutParams.MATCH_PARENT); 2313 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 2314 lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN 2315 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 2316 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 2317 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 2318 if (ActivityManager.isHighEndGfx()) { 2319 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 2320 lp.privateFlags |= 2321 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; 2322 } 2323 lp.format = PixelFormat.TRANSLUCENT; 2324 lp.setTitle("PointerLocation"); 2325 WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE); 2326 lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL; 2327 wm.addView(mPointerLocationView, lp); 2328 mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView); 2329 } 2330 } 2331 2332 private void disablePointerLocation() { 2333 if (mPointerLocationView != null) { 2334 mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView); 2335 WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE); 2336 wm.removeView(mPointerLocationView); 2337 mPointerLocationView = null; 2338 } 2339 } 2340 2341 private int readRotation(int resID) { 2342 try { 2343 int rotation = mContext.getResources().getInteger(resID); 2344 switch (rotation) { 2345 case 0: 2346 return Surface.ROTATION_0; 2347 case 90: 2348 return Surface.ROTATION_90; 2349 case 180: 2350 return Surface.ROTATION_180; 2351 case 270: 2352 return Surface.ROTATION_270; 2353 } 2354 } catch (Resources.NotFoundException e) { 2355 // fall through 2356 } 2357 return -1; 2358 } 2359 2360 /** {@inheritDoc} */ 2361 @Override 2362 public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) { 2363 int type = attrs.type; 2364 2365 outAppOp[0] = AppOpsManager.OP_NONE; 2366 2367 if (!((type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) 2368 || (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) 2369 || (type >= FIRST_SYSTEM_WINDOW && type <= LAST_SYSTEM_WINDOW))) { 2370 return WindowManagerGlobal.ADD_INVALID_TYPE; 2371 } 2372 2373 if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) { 2374 // Window manager will make sure these are okay. 2375 return ADD_OKAY; 2376 } 2377 2378 if (!isSystemAlertWindowType(type)) { 2379 switch (type) { 2380 case TYPE_TOAST: 2381 // Only apps that target older than O SDK can add window without a token, after 2382 // that we require a token so apps cannot add toasts directly as the token is 2383 // added by the notification system. 2384 // Window manager does the checking for this. 2385 outAppOp[0] = OP_TOAST_WINDOW; 2386 return ADD_OKAY; 2387 case TYPE_DREAM: 2388 case TYPE_INPUT_METHOD: 2389 case TYPE_WALLPAPER: 2390 case TYPE_PRESENTATION: 2391 case TYPE_PRIVATE_PRESENTATION: 2392 case TYPE_VOICE_INTERACTION: 2393 case TYPE_ACCESSIBILITY_OVERLAY: 2394 case TYPE_QS_DIALOG: 2395 // The window manager will check these. 2396 return ADD_OKAY; 2397 } 2398 return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) 2399 == PERMISSION_GRANTED ? ADD_OKAY : ADD_PERMISSION_DENIED; 2400 } 2401 2402 // Things get a little more interesting for alert windows... 2403 outAppOp[0] = OP_SYSTEM_ALERT_WINDOW; 2404 2405 final int callingUid = Binder.getCallingUid(); 2406 // system processes will be automatically granted privilege to draw 2407 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 2408 return ADD_OKAY; 2409 } 2410 2411 ApplicationInfo appInfo; 2412 try { 2413 appInfo = mContext.getPackageManager().getApplicationInfoAsUser( 2414 attrs.packageName, 2415 0 /* flags */, 2416 UserHandle.getUserId(callingUid)); 2417 } catch (PackageManager.NameNotFoundException e) { 2418 appInfo = null; 2419 } 2420 2421 if (appInfo == null || (type != TYPE_APPLICATION_OVERLAY && appInfo.targetSdkVersion >= O)) { 2422 /** 2423 * Apps targeting >= {@link Build.VERSION_CODES#O} are required to hold 2424 * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} (system signature apps) 2425 * permission to add alert windows that aren't 2426 * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}. 2427 */ 2428 return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) 2429 == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED; 2430 } 2431 2432 // check if user has enabled this operation. SecurityException will be thrown if this app 2433 // has not been allowed by the user 2434 final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid, attrs.packageName); 2435 switch (mode) { 2436 case AppOpsManager.MODE_ALLOWED: 2437 case AppOpsManager.MODE_IGNORED: 2438 // although we return ADD_OKAY for MODE_IGNORED, the added window will 2439 // actually be hidden in WindowManagerService 2440 return ADD_OKAY; 2441 case AppOpsManager.MODE_ERRORED: 2442 // Don't crash legacy apps 2443 if (appInfo.targetSdkVersion < M) { 2444 return ADD_OKAY; 2445 } 2446 return ADD_PERMISSION_DENIED; 2447 default: 2448 // in the default mode, we will make a decision here based on 2449 // checkCallingPermission() 2450 return (mContext.checkCallingOrSelfPermission(SYSTEM_ALERT_WINDOW) 2451 == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED; 2452 } 2453 } 2454 2455 @Override 2456 public boolean checkShowToOwnerOnly(WindowManager.LayoutParams attrs) { 2457 2458 // If this switch statement is modified, modify the comment in the declarations of 2459 // the type in {@link WindowManager.LayoutParams} as well. 2460 switch (attrs.type) { 2461 default: 2462 // These are the windows that by default are shown only to the user that created 2463 // them. If this needs to be overridden, set 2464 // {@link WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS} in 2465 // {@link WindowManager.LayoutParams}. Note that permission 2466 // {@link android.Manifest.permission.INTERNAL_SYSTEM_WINDOW} is required as well. 2467 if ((attrs.privateFlags & PRIVATE_FLAG_SHOW_FOR_ALL_USERS) == 0) { 2468 return true; 2469 } 2470 break; 2471 2472 // These are the windows that by default are shown to all users. However, to 2473 // protect against spoofing, check permissions below. 2474 case TYPE_APPLICATION_STARTING: 2475 case TYPE_BOOT_PROGRESS: 2476 case TYPE_DISPLAY_OVERLAY: 2477 case TYPE_INPUT_CONSUMER: 2478 case TYPE_KEYGUARD_DIALOG: 2479 case TYPE_MAGNIFICATION_OVERLAY: 2480 case TYPE_NAVIGATION_BAR: 2481 case TYPE_NAVIGATION_BAR_PANEL: 2482 case TYPE_PHONE: 2483 case TYPE_POINTER: 2484 case TYPE_PRIORITY_PHONE: 2485 case TYPE_SEARCH_BAR: 2486 case TYPE_STATUS_BAR: 2487 case TYPE_STATUS_BAR_PANEL: 2488 case TYPE_STATUS_BAR_SUB_PANEL: 2489 case TYPE_SYSTEM_DIALOG: 2490 case TYPE_VOLUME_OVERLAY: 2491 case TYPE_PRESENTATION: 2492 case TYPE_PRIVATE_PRESENTATION: 2493 case TYPE_DOCK_DIVIDER: 2494 break; 2495 } 2496 2497 // Check if third party app has set window to system window type. 2498 return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED; 2499 } 2500 2501 @Override 2502 public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) { 2503 switch (attrs.type) { 2504 case TYPE_SYSTEM_OVERLAY: 2505 case TYPE_SECURE_SYSTEM_OVERLAY: 2506 // These types of windows can't receive input events. 2507 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 2508 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 2509 attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 2510 break; 2511 case TYPE_STATUS_BAR: 2512 2513 // If the Keyguard is in a hidden state (occluded by another window), we force to 2514 // remove the wallpaper and keyguard flag so that any change in-flight after setting 2515 // the keyguard as occluded wouldn't set these flags again. 2516 // See {@link #processKeyguardSetHiddenResultLw}. 2517 if (mKeyguardOccluded) { 2518 attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 2519 attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 2520 } 2521 break; 2522 2523 case TYPE_SCREENSHOT: 2524 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 2525 break; 2526 2527 case TYPE_TOAST: 2528 // While apps should use the dedicated toast APIs to add such windows 2529 // it possible legacy apps to add the window directly. Therefore, we 2530 // make windows added directly by the app behave as a toast as much 2531 // as possible in terms of timeout and animation. 2532 if (attrs.hideTimeoutMilliseconds < 0 2533 || attrs.hideTimeoutMilliseconds > TOAST_WINDOW_TIMEOUT) { 2534 attrs.hideTimeoutMilliseconds = TOAST_WINDOW_TIMEOUT; 2535 } 2536 attrs.windowAnimations = com.android.internal.R.style.Animation_Toast; 2537 break; 2538 } 2539 2540 if (attrs.type != TYPE_STATUS_BAR) { 2541 // The status bar is the only window allowed to exhibit keyguard behavior. 2542 attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 2543 } 2544 2545 if (ActivityManager.isHighEndGfx()) { 2546 if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) { 2547 attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; 2548 } 2549 final boolean forceWindowDrawsStatusBarBackground = 2550 (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) 2551 != 0; 2552 if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 2553 || forceWindowDrawsStatusBarBackground 2554 && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT) { 2555 attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; 2556 } 2557 } 2558 } 2559 2560 void readLidState() { 2561 mLidState = mWindowManagerFuncs.getLidState(); 2562 } 2563 2564 private void readCameraLensCoverState() { 2565 mCameraLensCoverState = mWindowManagerFuncs.getCameraLensCoverState(); 2566 } 2567 2568 private boolean isHidden(int accessibilityMode) { 2569 switch (accessibilityMode) { 2570 case 1: 2571 return mLidState == LID_CLOSED; 2572 case 2: 2573 return mLidState == LID_OPEN; 2574 default: 2575 return false; 2576 } 2577 } 2578 2579 /** {@inheritDoc} */ 2580 @Override 2581 public void adjustConfigurationLw(Configuration config, int keyboardPresence, 2582 int navigationPresence) { 2583 mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0; 2584 2585 readConfigurationDependentBehaviors(); 2586 readLidState(); 2587 2588 if (config.keyboard == Configuration.KEYBOARD_NOKEYS 2589 || (keyboardPresence == PRESENCE_INTERNAL 2590 && isHidden(mLidKeyboardAccessibility))) { 2591 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES; 2592 if (!mHasSoftInput) { 2593 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES; 2594 } 2595 } 2596 2597 if (config.navigation == Configuration.NAVIGATION_NONAV 2598 || (navigationPresence == PRESENCE_INTERNAL 2599 && isHidden(mLidNavigationAccessibility))) { 2600 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES; 2601 } 2602 } 2603 2604 @Override 2605 public void onConfigurationChanged() { 2606 // TODO(multi-display): Define policy for secondary displays. 2607 final Resources res = mContext.getResources(); 2608 2609 mStatusBarHeight = 2610 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); 2611 2612 // Height of the navigation bar when presented horizontally at bottom 2613 mNavigationBarHeightForRotationDefault[mPortraitRotation] = 2614 mNavigationBarHeightForRotationDefault[mUpsideDownRotation] = 2615 res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height); 2616 mNavigationBarHeightForRotationDefault[mLandscapeRotation] = 2617 mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize( 2618 com.android.internal.R.dimen.navigation_bar_height_landscape); 2619 2620 // Width of the navigation bar when presented vertically along one side 2621 mNavigationBarWidthForRotationDefault[mPortraitRotation] = 2622 mNavigationBarWidthForRotationDefault[mUpsideDownRotation] = 2623 mNavigationBarWidthForRotationDefault[mLandscapeRotation] = 2624 mNavigationBarWidthForRotationDefault[mSeascapeRotation] = 2625 res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width); 2626 2627 if (ALTERNATE_CAR_MODE_NAV_SIZE) { 2628 // Height of the navigation bar when presented horizontally at bottom 2629 mNavigationBarHeightForRotationInCarMode[mPortraitRotation] = 2630 mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] = 2631 res.getDimensionPixelSize( 2632 com.android.internal.R.dimen.navigation_bar_height_car_mode); 2633 mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] = 2634 mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize( 2635 com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode); 2636 2637 // Width of the navigation bar when presented vertically along one side 2638 mNavigationBarWidthForRotationInCarMode[mPortraitRotation] = 2639 mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] = 2640 mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] = 2641 mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] = 2642 res.getDimensionPixelSize( 2643 com.android.internal.R.dimen.navigation_bar_width_car_mode); 2644 } 2645 } 2646 2647 @Override 2648 public int getMaxWallpaperLayer() { 2649 return getWindowLayerFromTypeLw(TYPE_STATUS_BAR); 2650 } 2651 2652 private int getNavigationBarWidth(int rotation, int uiMode) { 2653 if (ALTERNATE_CAR_MODE_NAV_SIZE && (uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_CAR) { 2654 return mNavigationBarWidthForRotationInCarMode[rotation]; 2655 } else { 2656 return mNavigationBarWidthForRotationDefault[rotation]; 2657 } 2658 } 2659 2660 @Override 2661 public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode, 2662 int displayId) { 2663 // TODO(multi-display): Support navigation bar on secondary displays. 2664 if (displayId == Display.DEFAULT_DISPLAY && mHasNavigationBar) { 2665 // For a basic navigation bar, when we are in landscape mode we place 2666 // the navigation bar to the side. 2667 if (mNavigationBarCanMove && fullWidth > fullHeight) { 2668 return fullWidth - getNavigationBarWidth(rotation, uiMode); 2669 } 2670 } 2671 return fullWidth; 2672 } 2673 2674 private int getNavigationBarHeight(int rotation, int uiMode) { 2675 if (ALTERNATE_CAR_MODE_NAV_SIZE && (uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_CAR) { 2676 return mNavigationBarHeightForRotationInCarMode[rotation]; 2677 } else { 2678 return mNavigationBarHeightForRotationDefault[rotation]; 2679 } 2680 } 2681 2682 @Override 2683 public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode, 2684 int displayId) { 2685 // TODO(multi-display): Support navigation bar on secondary displays. 2686 if (displayId == Display.DEFAULT_DISPLAY && mHasNavigationBar) { 2687 // For a basic navigation bar, when we are in portrait mode we place 2688 // the navigation bar to the bottom. 2689 if (!mNavigationBarCanMove || fullWidth < fullHeight) { 2690 return fullHeight - getNavigationBarHeight(rotation, uiMode); 2691 } 2692 } 2693 return fullHeight; 2694 } 2695 2696 @Override 2697 public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode, 2698 int displayId) { 2699 return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayId); 2700 } 2701 2702 @Override 2703 public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode, 2704 int displayId) { 2705 // There is a separate status bar at the top of the display. We don't count that as part 2706 // of the fixed decor, since it can hide; however, for purposes of configurations, 2707 // we do want to exclude it since applications can't generally use that part 2708 // of the screen. 2709 // TODO(multi-display): Support status bars on secondary displays. 2710 if (displayId == Display.DEFAULT_DISPLAY) { 2711 return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId) 2712 - mStatusBarHeight; 2713 } 2714 return fullHeight; 2715 } 2716 2717 @Override 2718 public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) { 2719 return attrs.type == TYPE_STATUS_BAR; 2720 } 2721 2722 @Override 2723 public boolean canBeHiddenByKeyguardLw(WindowState win) { 2724 switch (win.getAttrs().type) { 2725 case TYPE_STATUS_BAR: 2726 case TYPE_NAVIGATION_BAR: 2727 case TYPE_WALLPAPER: 2728 case TYPE_DREAM: 2729 return false; 2730 default: 2731 // Hide only windows below the keyguard host window. 2732 return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_STATUS_BAR); 2733 } 2734 } 2735 2736 private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) { 2737 2738 // Keyguard visibility of window from activities are determined over activity visibility. 2739 if (win.getAppToken() != null) { 2740 return false; 2741 } 2742 2743 final LayoutParams attrs = win.getAttrs(); 2744 final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleLw() && 2745 ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0 2746 || !canBeHiddenByKeyguardLw(imeTarget)); 2747 2748 // Show IME over the keyguard if the target allows it 2749 boolean allowWhenLocked = (win.isInputMethodWindow() || imeTarget == this) 2750 && showImeOverKeyguard;; 2751 2752 if (isKeyguardLocked() && isKeyguardOccluded()) { 2753 // Show SHOW_WHEN_LOCKED windows if Keyguard is occluded. 2754 allowWhenLocked |= (attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 2755 // Show error dialogs over apps that are shown on lockscreen 2756 || (attrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0; 2757 } 2758 2759 boolean keyguardLocked = isKeyguardLocked(); 2760 boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER 2761 && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID); 2762 return (keyguardLocked && !allowWhenLocked && win.getDisplayId() == Display.DEFAULT_DISPLAY) 2763 || hideDockDivider; 2764 } 2765 2766 /** {@inheritDoc} */ 2767 @Override 2768 public StartingSurface addSplashScreen(IBinder appToken, String packageName, int theme, 2769 CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon, 2770 int logo, int windowFlags, Configuration overrideConfig, int displayId) { 2771 if (!SHOW_SPLASH_SCREENS) { 2772 return null; 2773 } 2774 if (packageName == null) { 2775 return null; 2776 } 2777 2778 WindowManager wm = null; 2779 View view = null; 2780 2781 try { 2782 Context context = mContext; 2783 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "addSplashScreen " + packageName 2784 + ": nonLocalizedLabel=" + nonLocalizedLabel + " theme=" 2785 + Integer.toHexString(theme)); 2786 2787 // Obtain proper context to launch on the right display. 2788 final Context displayContext = getDisplayContext(context, displayId); 2789 if (displayContext == null) { 2790 // Can't show splash screen on requested display, so skip showing at all. 2791 return null; 2792 } 2793 context = displayContext; 2794 2795 if (theme != context.getThemeResId() || labelRes != 0) { 2796 try { 2797 context = context.createPackageContext(packageName, 0); 2798 context.setTheme(theme); 2799 } catch (PackageManager.NameNotFoundException e) { 2800 // Ignore 2801 } 2802 } 2803 2804 if (overrideConfig != null && !overrideConfig.equals(EMPTY)) { 2805 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "addSplashScreen: creating context based" 2806 + " on overrideConfig" + overrideConfig + " for splash screen"); 2807 final Context overrideContext = context.createConfigurationContext(overrideConfig); 2808 overrideContext.setTheme(theme); 2809 final TypedArray typedArray = overrideContext.obtainStyledAttributes( 2810 com.android.internal.R.styleable.Window); 2811 final int resId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0); 2812 if (resId != 0 && overrideContext.getDrawable(resId) != null) { 2813 // We want to use the windowBackground for the override context if it is 2814 // available, otherwise we use the default one to make sure a themed starting 2815 // window is displayed for the app. 2816 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "addSplashScreen: apply overrideConfig" 2817 + overrideConfig + " to starting window resId=" + resId); 2818 context = overrideContext; 2819 } 2820 typedArray.recycle(); 2821 } 2822 2823 final PhoneWindow win = new PhoneWindow(context); 2824 win.setIsStartingWindow(true); 2825 2826 CharSequence label = context.getResources().getText(labelRes, null); 2827 // Only change the accessibility title if the label is localized 2828 if (label != null) { 2829 win.setTitle(label, true); 2830 } else { 2831 win.setTitle(nonLocalizedLabel, false); 2832 } 2833 2834 win.setType( 2835 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING); 2836 2837 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 2838 // Assumes it's safe to show starting windows of launched apps while 2839 // the keyguard is being hidden. This is okay because starting windows never show 2840 // secret information. 2841 if (mKeyguardOccluded) { 2842 windowFlags |= FLAG_SHOW_WHEN_LOCKED; 2843 } 2844 } 2845 2846 // Force the window flags: this is a fake window, so it is not really 2847 // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM 2848 // flag because we do know that the next window will take input 2849 // focus, so we want to get the IME window up on top of us right away. 2850 win.setFlags( 2851 windowFlags| 2852 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| 2853 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| 2854 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, 2855 windowFlags| 2856 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| 2857 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| 2858 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2859 2860 win.setDefaultIcon(icon); 2861 win.setDefaultLogo(logo); 2862 2863 win.setLayout(WindowManager.LayoutParams.MATCH_PARENT, 2864 WindowManager.LayoutParams.MATCH_PARENT); 2865 2866 final WindowManager.LayoutParams params = win.getAttributes(); 2867 params.token = appToken; 2868 params.packageName = packageName; 2869 params.windowAnimations = win.getWindowStyle().getResourceId( 2870 com.android.internal.R.styleable.Window_windowAnimationStyle, 0); 2871 params.privateFlags |= 2872 WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED; 2873 params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 2874 2875 if (!compatInfo.supportsScreen()) { 2876 params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 2877 } 2878 2879 params.setTitle("Splash Screen " + packageName); 2880 addSplashscreenContent(win, context); 2881 2882 wm = (WindowManager) context.getSystemService(WINDOW_SERVICE); 2883 view = win.getDecorView(); 2884 2885 if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "Adding splash screen window for " 2886 + packageName + " / " + appToken + ": " + (view.getParent() != null ? view : null)); 2887 2888 wm.addView(view, params); 2889 2890 // Only return the view if it was successfully added to the 2891 // window manager... which we can tell by it having a parent. 2892 return view.getParent() != null ? new SplashScreenSurface(view, appToken) : null; 2893 } catch (WindowManager.BadTokenException e) { 2894 // ignore 2895 Log.w(TAG, appToken + " already running, starting window not displayed. " + 2896 e.getMessage()); 2897 } catch (RuntimeException e) { 2898 // don't crash if something else bad happens, for example a 2899 // failure loading resources because we are loading from an app 2900 // on external storage that has been unmounted. 2901 Log.w(TAG, appToken + " failed creating starting window", e); 2902 } finally { 2903 if (view != null && view.getParent() == null) { 2904 Log.w(TAG, "view not successfully added to wm, removing view"); 2905 wm.removeViewImmediate(view); 2906 } 2907 } 2908 2909 return null; 2910 } 2911 2912 private void addSplashscreenContent(PhoneWindow win, Context ctx) { 2913 final TypedArray a = ctx.obtainStyledAttributes(R.styleable.Window); 2914 final int resId = a.getResourceId(R.styleable.Window_windowSplashscreenContent, 0); 2915 a.recycle(); 2916 if (resId == 0) { 2917 return; 2918 } 2919 final Drawable drawable = ctx.getDrawable(resId); 2920 if (drawable == null) { 2921 return; 2922 } 2923 2924 // We wrap this into a view so the system insets get applied to the drawable. 2925 final View v = new View(ctx); 2926 v.setBackground(drawable); 2927 win.setContentView(v); 2928 } 2929 2930 /** Obtain proper context for showing splash screen on the provided display. */ 2931 private Context getDisplayContext(Context context, int displayId) { 2932 if (displayId == Display.DEFAULT_DISPLAY) { 2933 // The default context fits. 2934 return context; 2935 } 2936 2937 final DisplayManager dm = (DisplayManager) context.getSystemService(DISPLAY_SERVICE); 2938 final Display targetDisplay = dm.getDisplay(displayId); 2939 if (targetDisplay == null) { 2940 // Failed to obtain the non-default display where splash screen should be shown, 2941 // lets not show at all. 2942 return null; 2943 } 2944 2945 return context.createDisplayContext(targetDisplay); 2946 } 2947 2948 /** 2949 * Preflight adding a window to the system. 2950 * 2951 * Currently enforces that three window types are singletons: 2952 * <ul> 2953 * <li>STATUS_BAR_TYPE</li> 2954 * <li>KEYGUARD_TYPE</li> 2955 * </ul> 2956 * 2957 * @param win The window to be added 2958 * @param attrs Information about the window to be added 2959 * 2960 * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons, 2961 * WindowManagerImpl.ADD_MULTIPLE_SINGLETON 2962 */ 2963 @Override 2964 public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) { 2965 switch (attrs.type) { 2966 case TYPE_STATUS_BAR: 2967 mContext.enforceCallingOrSelfPermission( 2968 android.Manifest.permission.STATUS_BAR_SERVICE, 2969 "PhoneWindowManager"); 2970 if (mStatusBar != null) { 2971 if (mStatusBar.isAlive()) { 2972 return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; 2973 } 2974 } 2975 mStatusBar = win; 2976 mStatusBarController.setWindow(win); 2977 setKeyguardOccludedLw(mKeyguardOccluded, true /* force */); 2978 break; 2979 case TYPE_NAVIGATION_BAR: 2980 mContext.enforceCallingOrSelfPermission( 2981 android.Manifest.permission.STATUS_BAR_SERVICE, 2982 "PhoneWindowManager"); 2983 if (mNavigationBar != null) { 2984 if (mNavigationBar.isAlive()) { 2985 return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; 2986 } 2987 } 2988 mNavigationBar = win; 2989 mNavigationBarController.setWindow(win); 2990 mNavigationBarController.setOnBarVisibilityChangedListener( 2991 mNavBarVisibilityListener); 2992 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar); 2993 break; 2994 case TYPE_NAVIGATION_BAR_PANEL: 2995 case TYPE_STATUS_BAR_PANEL: 2996 case TYPE_STATUS_BAR_SUB_PANEL: 2997 case TYPE_VOICE_INTERACTION_STARTING: 2998 mContext.enforceCallingOrSelfPermission( 2999 android.Manifest.permission.STATUS_BAR_SERVICE, 3000 "PhoneWindowManager"); 3001 break; 3002 } 3003 return ADD_OKAY; 3004 } 3005 3006 /** {@inheritDoc} */ 3007 @Override 3008 public void removeWindowLw(WindowState win) { 3009 if (mStatusBar == win) { 3010 mStatusBar = null; 3011 mStatusBarController.setWindow(null); 3012 } else if (mNavigationBar == win) { 3013 mNavigationBar = null; 3014 mNavigationBarController.setWindow(null); 3015 } 3016 } 3017 3018 static final boolean PRINT_ANIM = false; 3019 3020 /** {@inheritDoc} */ 3021 @Override 3022 public int selectAnimationLw(WindowState win, int transit) { 3023 if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win 3024 + ": transit=" + transit); 3025 if (win == mStatusBar) { 3026 boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; 3027 if (transit == TRANSIT_EXIT 3028 || transit == TRANSIT_HIDE) { 3029 return isKeyguard ? -1 : R.anim.dock_top_exit; 3030 } else if (transit == TRANSIT_ENTER 3031 || transit == TRANSIT_SHOW) { 3032 return isKeyguard ? -1 : R.anim.dock_top_enter; 3033 } 3034 } else if (win == mNavigationBar) { 3035 if (win.getAttrs().windowAnimations != 0) { 3036 return 0; 3037 } 3038 // This can be on either the bottom or the right or the left. 3039 if (mNavigationBarPosition == NAV_BAR_BOTTOM) { 3040 if (transit == TRANSIT_EXIT 3041 || transit == TRANSIT_HIDE) { 3042 if (isKeyguardShowingAndNotOccluded()) { 3043 return R.anim.dock_bottom_exit_keyguard; 3044 } else { 3045 return R.anim.dock_bottom_exit; 3046 } 3047 } else if (transit == TRANSIT_ENTER 3048 || transit == TRANSIT_SHOW) { 3049 return R.anim.dock_bottom_enter; 3050 } 3051 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) { 3052 if (transit == TRANSIT_EXIT 3053 || transit == TRANSIT_HIDE) { 3054 return R.anim.dock_right_exit; 3055 } else if (transit == TRANSIT_ENTER 3056 || transit == TRANSIT_SHOW) { 3057 return R.anim.dock_right_enter; 3058 } 3059 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 3060 if (transit == TRANSIT_EXIT 3061 || transit == TRANSIT_HIDE) { 3062 return R.anim.dock_left_exit; 3063 } else if (transit == TRANSIT_ENTER 3064 || transit == TRANSIT_SHOW) { 3065 return R.anim.dock_left_enter; 3066 } 3067 } 3068 } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) { 3069 return selectDockedDividerAnimationLw(win, transit); 3070 } 3071 3072 if (transit == TRANSIT_PREVIEW_DONE) { 3073 if (win.hasAppShownWindows()) { 3074 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT"); 3075 return com.android.internal.R.anim.app_starting_exit; 3076 } 3077 } else if (win.getAttrs().type == TYPE_DREAM && mDreamingLockscreen 3078 && transit == TRANSIT_ENTER) { 3079 // Special case: we are animating in a dream, while the keyguard 3080 // is shown. We don't want an animation on the dream, because 3081 // we need it shown immediately with the keyguard animating away 3082 // to reveal it. 3083 return -1; 3084 } 3085 3086 return 0; 3087 } 3088 3089 private int selectDockedDividerAnimationLw(WindowState win, int transit) { 3090 int insets = mWindowManagerFuncs.getDockedDividerInsetsLw(); 3091 3092 // If the divider is behind the navigation bar, don't animate. 3093 final Rect frame = win.getFrameLw(); 3094 final boolean behindNavBar = mNavigationBar != null 3095 && ((mNavigationBarPosition == NAV_BAR_BOTTOM 3096 && frame.top + insets >= mNavigationBar.getFrameLw().top) 3097 || (mNavigationBarPosition == NAV_BAR_RIGHT 3098 && frame.left + insets >= mNavigationBar.getFrameLw().left) 3099 || (mNavigationBarPosition == NAV_BAR_LEFT 3100 && frame.right - insets <= mNavigationBar.getFrameLw().right)); 3101 final boolean landscape = frame.height() > frame.width(); 3102 final boolean offscreenLandscape = landscape && (frame.right - insets <= 0 3103 || frame.left + insets >= win.getDisplayFrameLw().right); 3104 final boolean offscreenPortrait = !landscape && (frame.top - insets <= 0 3105 || frame.bottom + insets >= win.getDisplayFrameLw().bottom); 3106 final boolean offscreen = offscreenLandscape || offscreenPortrait; 3107 if (behindNavBar || offscreen) { 3108 return 0; 3109 } 3110 if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) { 3111 return R.anim.fade_in; 3112 } else if (transit == TRANSIT_EXIT) { 3113 return R.anim.fade_out; 3114 } else { 3115 return 0; 3116 } 3117 } 3118 3119 @Override 3120 public void selectRotationAnimationLw(int anim[]) { 3121 if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen=" 3122 + mTopFullscreenOpaqueWindowState + " rotationAnimation=" 3123 + (mTopFullscreenOpaqueWindowState == null ? 3124 "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation)); 3125 if (mTopFullscreenOpaqueWindowState != null) { 3126 int animationHint = mTopFullscreenOpaqueWindowState.getRotationAnimationHint(); 3127 if (animationHint < 0 && mTopIsFullscreen) { 3128 animationHint = mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation; 3129 } 3130 switch (animationHint) { 3131 case ROTATION_ANIMATION_CROSSFADE: 3132 case ROTATION_ANIMATION_SEAMLESS: // Crossfade is fallback for seamless. 3133 anim[0] = R.anim.rotation_animation_xfade_exit; 3134 anim[1] = R.anim.rotation_animation_enter; 3135 break; 3136 case ROTATION_ANIMATION_JUMPCUT: 3137 anim[0] = R.anim.rotation_animation_jump_exit; 3138 anim[1] = R.anim.rotation_animation_enter; 3139 break; 3140 case ROTATION_ANIMATION_ROTATE: 3141 default: 3142 anim[0] = anim[1] = 0; 3143 break; 3144 } 3145 } else { 3146 anim[0] = anim[1] = 0; 3147 } 3148 } 3149 3150 @Override 3151 public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId, 3152 boolean forceDefault) { 3153 switch (exitAnimId) { 3154 case R.anim.rotation_animation_xfade_exit: 3155 case R.anim.rotation_animation_jump_exit: 3156 // These are the only cases that matter. 3157 if (forceDefault) { 3158 return false; 3159 } 3160 int anim[] = new int[2]; 3161 selectRotationAnimationLw(anim); 3162 return (exitAnimId == anim[0] && enterAnimId == anim[1]); 3163 default: 3164 return true; 3165 } 3166 } 3167 3168 @Override 3169 public Animation createHiddenByKeyguardExit(boolean onWallpaper, 3170 boolean goingToNotificationShade) { 3171 if (goingToNotificationShade) { 3172 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in); 3173 } 3174 3175 AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ? 3176 R.anim.lock_screen_behind_enter_wallpaper : 3177 R.anim.lock_screen_behind_enter); 3178 3179 // TODO: Use XML interpolators when we have log interpolators available in XML. 3180 final List<Animation> animations = set.getAnimations(); 3181 for (int i = animations.size() - 1; i >= 0; --i) { 3182 animations.get(i).setInterpolator(mLogDecelerateInterpolator); 3183 } 3184 3185 return set; 3186 } 3187 3188 3189 @Override 3190 public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) { 3191 if (goingToNotificationShade) { 3192 return null; 3193 } else { 3194 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit); 3195 } 3196 } 3197 3198 private static void awakenDreams() { 3199 IDreamManager dreamManager = getDreamManager(); 3200 if (dreamManager != null) { 3201 try { 3202 dreamManager.awaken(); 3203 } catch (RemoteException e) { 3204 // fine, stay asleep then 3205 } 3206 } 3207 } 3208 3209 static IDreamManager getDreamManager() { 3210 return IDreamManager.Stub.asInterface( 3211 ServiceManager.checkService(DreamService.DREAM_SERVICE)); 3212 } 3213 3214 TelecomManager getTelecommService() { 3215 return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 3216 } 3217 3218 static IAudioService getAudioService() { 3219 IAudioService audioService = IAudioService.Stub.asInterface( 3220 ServiceManager.checkService(Context.AUDIO_SERVICE)); 3221 if (audioService == null) { 3222 Log.w(TAG, "Unable to find IAudioService interface."); 3223 } 3224 return audioService; 3225 } 3226 3227 boolean keyguardOn() { 3228 return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode(); 3229 } 3230 3231 private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = { 3232 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 3233 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, 3234 }; 3235 3236 /** {@inheritDoc} */ 3237 @Override 3238 public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) { 3239 final boolean keyguardOn = keyguardOn(); 3240 final int keyCode = event.getKeyCode(); 3241 final int repeatCount = event.getRepeatCount(); 3242 final int metaState = event.getMetaState(); 3243 final int flags = event.getFlags(); 3244 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 3245 final boolean canceled = event.isCanceled(); 3246 3247 if (DEBUG_INPUT) { 3248 Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount=" 3249 + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed 3250 + " canceled=" + canceled); 3251 } 3252 3253 // If we think we might have a volume down & power key chord on the way 3254 // but we're not sure, then tell the dispatcher to wait a little while and 3255 // try again later before dispatching. 3256 if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) { 3257 if (mScreenshotChordVolumeDownKeyTriggered && !mScreenshotChordPowerKeyTriggered) { 3258 final long now = SystemClock.uptimeMillis(); 3259 final long timeoutTime = mScreenshotChordVolumeDownKeyTime 3260 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS; 3261 if (now < timeoutTime) { 3262 return timeoutTime - now; 3263 } 3264 } 3265 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 3266 && mScreenshotChordVolumeDownKeyConsumed) { 3267 if (!down) { 3268 mScreenshotChordVolumeDownKeyConsumed = false; 3269 } 3270 return -1; 3271 } 3272 } 3273 3274 // If an accessibility shortcut might be partially complete, hold off dispatching until we 3275 // know if it is complete or not 3276 if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false) 3277 && (flags & KeyEvent.FLAG_FALLBACK) == 0) { 3278 if (mScreenshotChordVolumeDownKeyTriggered ^ mA11yShortcutChordVolumeUpKeyTriggered) { 3279 final long now = SystemClock.uptimeMillis(); 3280 final long timeoutTime = (mScreenshotChordVolumeDownKeyTriggered 3281 ? mScreenshotChordVolumeDownKeyTime : mA11yShortcutChordVolumeUpKeyTime) 3282 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS; 3283 if (now < timeoutTime) { 3284 return timeoutTime - now; 3285 } 3286 } 3287 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mScreenshotChordVolumeDownKeyConsumed) { 3288 if (!down) { 3289 mScreenshotChordVolumeDownKeyConsumed = false; 3290 } 3291 return -1; 3292 } 3293 if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mA11yShortcutChordVolumeUpKeyConsumed) { 3294 if (!down) { 3295 mA11yShortcutChordVolumeUpKeyConsumed = false; 3296 } 3297 return -1; 3298 } 3299 } 3300 3301 // Cancel any pending meta actions if we see any other keys being pressed between the down 3302 // of the meta key and its corresponding up. 3303 if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) { 3304 mPendingMetaAction = false; 3305 } 3306 // Any key that is not Alt or Meta cancels Caps Lock combo tracking. 3307 if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) { 3308 mPendingCapsLockToggle = false; 3309 } 3310 3311 // First we always handle the home key here, so applications 3312 // can never break it, although if keyguard is on, we do let 3313 // it handle it, because that gives us the correct 5 second 3314 // timeout. 3315 if (keyCode == KeyEvent.KEYCODE_HOME) { 3316 3317 // If we have released the home key, and didn't do anything else 3318 // while it was pressed, then it is time to go home! 3319 if (!down) { 3320 cancelPreloadRecentApps(); 3321 3322 mHomePressed = false; 3323 if (mHomeConsumed) { 3324 mHomeConsumed = false; 3325 return -1; 3326 } 3327 3328 if (canceled) { 3329 Log.i(TAG, "Ignoring HOME; event canceled."); 3330 return -1; 3331 } 3332 3333 // Delay handling home if a double-tap is possible. 3334 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) { 3335 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case 3336 mHomeDoubleTapPending = true; 3337 mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable, 3338 ViewConfiguration.getDoubleTapTimeout()); 3339 return -1; 3340 } 3341 3342 handleShortPressOnHome(); 3343 return -1; 3344 } 3345 3346 // If a system window has focus, then it doesn't make sense 3347 // right now to interact with applications. 3348 WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null; 3349 if (attrs != null) { 3350 final int type = attrs.type; 3351 if (type == TYPE_KEYGUARD_DIALOG 3352 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 3353 // the "app" is keyguard, so give it the key 3354 return 0; 3355 } 3356 final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length; 3357 for (int i=0; i<typeCount; i++) { 3358 if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) { 3359 // don't do anything, but also don't pass it to the app 3360 return -1; 3361 } 3362 } 3363 } 3364 3365 // Remember that home is pressed and handle special actions. 3366 if (repeatCount == 0) { 3367 mHomePressed = true; 3368 if (mHomeDoubleTapPending) { 3369 mHomeDoubleTapPending = false; 3370 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); 3371 handleDoubleTapOnHome(); 3372 } else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) { 3373 preloadRecentApps(); 3374 } 3375 } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) { 3376 if (!keyguardOn) { 3377 handleLongPressOnHome(event.getDeviceId()); 3378 } 3379 } 3380 return -1; 3381 } else if (keyCode == KeyEvent.KEYCODE_MENU) { 3382 // Hijack modified menu keys for debugging features 3383 final int chordBug = KeyEvent.META_SHIFT_ON; 3384 3385 if (down && repeatCount == 0) { 3386 if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) { 3387 Intent intent = new Intent(Intent.ACTION_BUG_REPORT); 3388 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, 3389 null, null, null, 0, null, null); 3390 return -1; 3391 } 3392 } 3393 } else if (keyCode == KeyEvent.KEYCODE_SEARCH) { 3394 if (down) { 3395 if (repeatCount == 0) { 3396 mSearchKeyShortcutPending = true; 3397 mConsumeSearchKeyUp = false; 3398 } 3399 } else { 3400 mSearchKeyShortcutPending = false; 3401 if (mConsumeSearchKeyUp) { 3402 mConsumeSearchKeyUp = false; 3403 return -1; 3404 } 3405 } 3406 return 0; 3407 } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) { 3408 if (!keyguardOn) { 3409 if (down && repeatCount == 0) { 3410 preloadRecentApps(); 3411 } else if (!down) { 3412 toggleRecentApps(); 3413 } 3414 } 3415 return -1; 3416 } else if (keyCode == KeyEvent.KEYCODE_N && event.isMetaPressed()) { 3417 if (down) { 3418 IStatusBarService service = getStatusBarService(); 3419 if (service != null) { 3420 try { 3421 service.expandNotificationsPanel(); 3422 } catch (RemoteException e) { 3423 // do nothing. 3424 } 3425 } 3426 } 3427 } else if (keyCode == KeyEvent.KEYCODE_S && event.isMetaPressed() 3428 && event.isCtrlPressed()) { 3429 if (down && repeatCount == 0) { 3430 int type = event.isShiftPressed() ? TAKE_SCREENSHOT_SELECTED_REGION 3431 : TAKE_SCREENSHOT_FULLSCREEN; 3432 mScreenshotRunnable.setScreenshotType(type); 3433 mHandler.post(mScreenshotRunnable); 3434 return -1; 3435 } 3436 } else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) { 3437 if (down && repeatCount == 0 && !isKeyguardLocked()) { 3438 toggleKeyboardShortcutsMenu(event.getDeviceId()); 3439 } 3440 } else if (keyCode == KeyEvent.KEYCODE_ASSIST) { 3441 if (down) { 3442 if (repeatCount == 0) { 3443 mAssistKeyLongPressed = false; 3444 } else if (repeatCount == 1) { 3445 mAssistKeyLongPressed = true; 3446 if (!keyguardOn) { 3447 launchAssistLongPressAction(); 3448 } 3449 } 3450 } else { 3451 if (mAssistKeyLongPressed) { 3452 mAssistKeyLongPressed = false; 3453 } else { 3454 if (!keyguardOn) { 3455 launchAssistAction(null, event.getDeviceId()); 3456 } 3457 } 3458 } 3459 return -1; 3460 } else if (keyCode == KeyEvent.KEYCODE_VOICE_ASSIST) { 3461 if (!down) { 3462 Intent voiceIntent; 3463 if (!keyguardOn) { 3464 voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH); 3465 } else { 3466 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface( 3467 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 3468 if (dic != null) { 3469 try { 3470 dic.exitIdle("voice-search"); 3471 } catch (RemoteException e) { 3472 } 3473 } 3474 voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 3475 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true); 3476 } 3477 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 3478 } 3479 } else if (keyCode == KeyEvent.KEYCODE_SYSRQ) { 3480 if (down && repeatCount == 0) { 3481 mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN); 3482 mHandler.post(mScreenshotRunnable); 3483 } 3484 return -1; 3485 } else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP 3486 || keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) { 3487 if (down) { 3488 int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1; 3489 3490 // Disable autobrightness if it's on 3491 int auto = Settings.System.getIntForUser( 3492 mContext.getContentResolver(), 3493 Settings.System.SCREEN_BRIGHTNESS_MODE, 3494 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, 3495 UserHandle.USER_CURRENT_OR_SELF); 3496 if (auto != 0) { 3497 Settings.System.putIntForUser(mContext.getContentResolver(), 3498 Settings.System.SCREEN_BRIGHTNESS_MODE, 3499 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, 3500 UserHandle.USER_CURRENT_OR_SELF); 3501 } 3502 3503 int min = mPowerManager.getMinimumScreenBrightnessSetting(); 3504 int max = mPowerManager.getMaximumScreenBrightnessSetting(); 3505 int step = (max - min + BRIGHTNESS_STEPS - 1) / BRIGHTNESS_STEPS * direction; 3506 int brightness = Settings.System.getIntForUser(mContext.getContentResolver(), 3507 Settings.System.SCREEN_BRIGHTNESS, 3508 mPowerManager.getDefaultScreenBrightnessSetting(), 3509 UserHandle.USER_CURRENT_OR_SELF); 3510 brightness += step; 3511 // Make sure we don't go beyond the limits. 3512 brightness = Math.min(max, brightness); 3513 brightness = Math.max(min, brightness); 3514 3515 Settings.System.putIntForUser(mContext.getContentResolver(), 3516 Settings.System.SCREEN_BRIGHTNESS, brightness, 3517 UserHandle.USER_CURRENT_OR_SELF); 3518 startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG), 3519 UserHandle.CURRENT_OR_SELF); 3520 } 3521 return -1; 3522 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP 3523 || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 3524 || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) { 3525 if (mUseTvRouting) { 3526 // On TVs volume keys never go to the foreground app. 3527 dispatchDirectAudioEvent(event); 3528 return -1; 3529 } 3530 } else if (keyCode == KeyEvent.KEYCODE_TAB && event.isMetaPressed()) { 3531 // Pass through keyboard navigation keys. 3532 return 0; 3533 } else if (mHasFeatureLeanback && interceptBugreportGestureTv(keyCode, down)) { 3534 return -1; 3535 } 3536 3537 // Toggle Caps Lock on META-ALT. 3538 boolean actionTriggered = false; 3539 if (KeyEvent.isModifierKey(keyCode)) { 3540 if (!mPendingCapsLockToggle) { 3541 // Start tracking meta state for combo. 3542 mInitialMetaState = mMetaState; 3543 mPendingCapsLockToggle = true; 3544 } else if (event.getAction() == KeyEvent.ACTION_UP) { 3545 int altOnMask = mMetaState & KeyEvent.META_ALT_MASK; 3546 int metaOnMask = mMetaState & KeyEvent.META_META_MASK; 3547 3548 // Check for Caps Lock toggle 3549 if ((metaOnMask != 0) && (altOnMask != 0)) { 3550 // Check if nothing else is pressed 3551 if (mInitialMetaState == (mMetaState ^ (altOnMask | metaOnMask))) { 3552 // Handle Caps Lock Toggle 3553 mInputManagerInternal.toggleCapsLock(event.getDeviceId()); 3554 actionTriggered = true; 3555 } 3556 } 3557 3558 // Always stop tracking when key goes up. 3559 mPendingCapsLockToggle = false; 3560 } 3561 } 3562 // Store current meta state to be able to evaluate it later. 3563 mMetaState = metaState; 3564 3565 if (actionTriggered) { 3566 return -1; 3567 } 3568 3569 if (KeyEvent.isMetaKey(keyCode)) { 3570 if (down) { 3571 mPendingMetaAction = true; 3572 } else if (mPendingMetaAction) { 3573 launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, event.getDeviceId()); 3574 } 3575 return -1; 3576 } 3577 3578 // Shortcuts are invoked through Search+key, so intercept those here 3579 // Any printing key that is chorded with Search should be consumed 3580 // even if no shortcut was invoked. This prevents text from being 3581 // inadvertently inserted when using a keyboard that has built-in macro 3582 // shortcut keys (that emit Search+x) and some of them are not registered. 3583 if (mSearchKeyShortcutPending) { 3584 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3585 if (kcm.isPrintingKey(keyCode)) { 3586 mConsumeSearchKeyUp = true; 3587 mSearchKeyShortcutPending = false; 3588 if (down && repeatCount == 0 && !keyguardOn) { 3589 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState); 3590 if (shortcutIntent != null) { 3591 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3592 try { 3593 startActivityAsUser(shortcutIntent, UserHandle.CURRENT); 3594 dismissKeyboardShortcutsMenu(); 3595 } catch (ActivityNotFoundException ex) { 3596 Slog.w(TAG, "Dropping shortcut key combination because " 3597 + "the activity to which it is registered was not found: " 3598 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex); 3599 } 3600 } else { 3601 Slog.i(TAG, "Dropping unregistered shortcut key combination: " 3602 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode)); 3603 } 3604 } 3605 return -1; 3606 } 3607 } 3608 3609 // Invoke shortcuts using Meta. 3610 if (down && repeatCount == 0 && !keyguardOn 3611 && (metaState & KeyEvent.META_META_ON) != 0) { 3612 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3613 if (kcm.isPrintingKey(keyCode)) { 3614 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, 3615 metaState & ~(KeyEvent.META_META_ON 3616 | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON)); 3617 if (shortcutIntent != null) { 3618 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3619 try { 3620 startActivityAsUser(shortcutIntent, UserHandle.CURRENT); 3621 dismissKeyboardShortcutsMenu(); 3622 } catch (ActivityNotFoundException ex) { 3623 Slog.w(TAG, "Dropping shortcut key combination because " 3624 + "the activity to which it is registered was not found: " 3625 + "META+" + KeyEvent.keyCodeToString(keyCode), ex); 3626 } 3627 return -1; 3628 } 3629 } 3630 } 3631 3632 // Handle application launch keys. 3633 if (down && repeatCount == 0 && !keyguardOn) { 3634 String category = sApplicationLaunchKeyCategories.get(keyCode); 3635 if (category != null) { 3636 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category); 3637 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3638 try { 3639 startActivityAsUser(intent, UserHandle.CURRENT); 3640 dismissKeyboardShortcutsMenu(); 3641 } catch (ActivityNotFoundException ex) { 3642 Slog.w(TAG, "Dropping application launch key because " 3643 + "the activity to which it is registered was not found: " 3644 + "keyCode=" + keyCode + ", category=" + category, ex); 3645 } 3646 return -1; 3647 } 3648 } 3649 3650 // Display task switcher for ALT-TAB. 3651 if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) { 3652 if (mRecentAppsHeldModifiers == 0 && !keyguardOn && isUserSetupComplete()) { 3653 final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK; 3654 if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)) { 3655 mRecentAppsHeldModifiers = shiftlessModifiers; 3656 showRecentApps(true, false); 3657 return -1; 3658 } 3659 } 3660 } else if (!down && mRecentAppsHeldModifiers != 0 3661 && (metaState & mRecentAppsHeldModifiers) == 0) { 3662 mRecentAppsHeldModifiers = 0; 3663 hideRecentApps(true, false); 3664 } 3665 3666 // Handle input method switching. 3667 if (down && repeatCount == 0 3668 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH 3669 || (keyCode == KeyEvent.KEYCODE_SPACE 3670 && (metaState & KeyEvent.META_META_MASK) != 0))) { 3671 final boolean forwardDirection = (metaState & KeyEvent.META_SHIFT_MASK) == 0; 3672 mWindowManagerFuncs.switchInputMethod(forwardDirection); 3673 return -1; 3674 } 3675 if (mLanguageSwitchKeyPressed && !down 3676 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH 3677 || keyCode == KeyEvent.KEYCODE_SPACE)) { 3678 mLanguageSwitchKeyPressed = false; 3679 return -1; 3680 } 3681 3682 if (isValidGlobalKey(keyCode) 3683 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) { 3684 return -1; 3685 } 3686 3687 if (down) { 3688 long shortcutCode = keyCode; 3689 if (event.isCtrlPressed()) { 3690 shortcutCode |= ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE; 3691 } 3692 3693 if (event.isAltPressed()) { 3694 shortcutCode |= ((long) KeyEvent.META_ALT_ON) << Integer.SIZE; 3695 } 3696 3697 if (event.isShiftPressed()) { 3698 shortcutCode |= ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE; 3699 } 3700 3701 if (event.isMetaPressed()) { 3702 shortcutCode |= ((long) KeyEvent.META_META_ON) << Integer.SIZE; 3703 } 3704 3705 IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode); 3706 if (shortcutService != null) { 3707 try { 3708 if (isUserSetupComplete()) { 3709 shortcutService.notifyShortcutKeyPressed(shortcutCode); 3710 } 3711 } catch (RemoteException e) { 3712 mShortcutKeyServices.delete(shortcutCode); 3713 } 3714 return -1; 3715 } 3716 } 3717 3718 // Reserve all the META modifier combos for system behavior 3719 if ((metaState & KeyEvent.META_META_ON) != 0) { 3720 return -1; 3721 } 3722 3723 // Let the application handle the key. 3724 return 0; 3725 } 3726 3727 /** 3728 * TV only: recognizes a remote control gesture for capturing a bug report. 3729 */ 3730 private boolean interceptBugreportGestureTv(int keyCode, boolean down) { 3731 // The bugreport capture chord is a long press on DPAD CENTER and BACK simultaneously. 3732 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 3733 mBugreportTvKey1Pressed = down; 3734 } else if (keyCode == KeyEvent.KEYCODE_BACK) { 3735 mBugreportTvKey2Pressed = down; 3736 } 3737 3738 if (mBugreportTvKey1Pressed && mBugreportTvKey2Pressed) { 3739 if (!mBugreportTvScheduled) { 3740 mBugreportTvScheduled = true; 3741 Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV); 3742 msg.setAsynchronous(true); 3743 mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS); 3744 } 3745 } else if (mBugreportTvScheduled) { 3746 mHandler.removeMessages(MSG_BUGREPORT_TV); 3747 mBugreportTvScheduled = false; 3748 } 3749 3750 return mBugreportTvScheduled; 3751 } 3752 3753 private void takeBugreport() { 3754 if ("1".equals(SystemProperties.get("ro.debuggable")) 3755 || Settings.Global.getInt(mContext.getContentResolver(), 3756 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) { 3757 try { 3758 ActivityManager.getService() 3759 .requestBugReport(ActivityManager.BUGREPORT_OPTION_INTERACTIVE); 3760 } catch (RemoteException e) { 3761 Slog.e(TAG, "Error taking bugreport", e); 3762 } 3763 } 3764 } 3765 3766 /** {@inheritDoc} */ 3767 @Override 3768 public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) { 3769 // Note: This method is only called if the initial down was unhandled. 3770 if (DEBUG_INPUT) { 3771 Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction() 3772 + ", flags=" + event.getFlags() 3773 + ", keyCode=" + event.getKeyCode() 3774 + ", scanCode=" + event.getScanCode() 3775 + ", metaState=" + event.getMetaState() 3776 + ", repeatCount=" + event.getRepeatCount() 3777 + ", policyFlags=" + policyFlags); 3778 } 3779 3780 KeyEvent fallbackEvent = null; 3781 if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 3782 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3783 final int keyCode = event.getKeyCode(); 3784 final int metaState = event.getMetaState(); 3785 final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN 3786 && event.getRepeatCount() == 0; 3787 3788 // Check for fallback actions specified by the key character map. 3789 final FallbackAction fallbackAction; 3790 if (initialDown) { 3791 fallbackAction = kcm.getFallbackAction(keyCode, metaState); 3792 } else { 3793 fallbackAction = mFallbackActions.get(keyCode); 3794 } 3795 3796 if (fallbackAction != null) { 3797 if (DEBUG_INPUT) { 3798 Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode 3799 + " metaState=" + Integer.toHexString(fallbackAction.metaState)); 3800 } 3801 3802 final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK; 3803 fallbackEvent = KeyEvent.obtain( 3804 event.getDownTime(), event.getEventTime(), 3805 event.getAction(), fallbackAction.keyCode, 3806 event.getRepeatCount(), fallbackAction.metaState, 3807 event.getDeviceId(), event.getScanCode(), 3808 flags, event.getSource(), null); 3809 3810 if (!interceptFallback(win, fallbackEvent, policyFlags)) { 3811 fallbackEvent.recycle(); 3812 fallbackEvent = null; 3813 } 3814 3815 if (initialDown) { 3816 mFallbackActions.put(keyCode, fallbackAction); 3817 } else if (event.getAction() == KeyEvent.ACTION_UP) { 3818 mFallbackActions.remove(keyCode); 3819 fallbackAction.recycle(); 3820 } 3821 } 3822 } 3823 3824 if (DEBUG_INPUT) { 3825 if (fallbackEvent == null) { 3826 Slog.d(TAG, "No fallback."); 3827 } else { 3828 Slog.d(TAG, "Performing fallback: " + fallbackEvent); 3829 } 3830 } 3831 return fallbackEvent; 3832 } 3833 3834 private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) { 3835 int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags); 3836 if ((actions & ACTION_PASS_TO_USER) != 0) { 3837 long delayMillis = interceptKeyBeforeDispatching( 3838 win, fallbackEvent, policyFlags); 3839 if (delayMillis == 0) { 3840 return true; 3841 } 3842 } 3843 return false; 3844 } 3845 3846 @Override 3847 public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService) 3848 throws RemoteException { 3849 synchronized (mLock) { 3850 IShortcutService service = mShortcutKeyServices.get(shortcutCode); 3851 if (service != null && service.asBinder().pingBinder()) { 3852 throw new RemoteException("Key already exists."); 3853 } 3854 3855 mShortcutKeyServices.put(shortcutCode, shortcutService); 3856 } 3857 } 3858 3859 @Override 3860 public void onKeyguardOccludedChangedLw(boolean occluded) { 3861 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 3862 mPendingKeyguardOccluded = occluded; 3863 mKeyguardOccludedChanged = true; 3864 } else { 3865 setKeyguardOccludedLw(occluded, false /* force */); 3866 } 3867 } 3868 3869 private int handleStartTransitionForKeyguardLw(int transit, @Nullable Animation anim) { 3870 if (mKeyguardOccludedChanged) { 3871 if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded=" 3872 + mPendingKeyguardOccluded); 3873 mKeyguardOccludedChanged = false; 3874 if (setKeyguardOccludedLw(mPendingKeyguardOccluded, false /* force */)) { 3875 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER; 3876 } 3877 } 3878 if (AppTransition.isKeyguardGoingAwayTransit(transit)) { 3879 if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation"); 3880 final long startTime = anim != null 3881 ? SystemClock.uptimeMillis() + anim.getStartOffset() 3882 : SystemClock.uptimeMillis(); 3883 final long duration = anim != null 3884 ? anim.getDuration() 3885 : 0; 3886 startKeyguardExitAnimation(startTime, duration); 3887 } 3888 return 0; 3889 } 3890 3891 private void launchAssistLongPressAction() { 3892 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); 3893 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 3894 3895 // launch the search activity 3896 Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); 3897 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3898 try { 3899 // TODO: This only stops the factory-installed search manager. 3900 // Need to formalize an API to handle others 3901 SearchManager searchManager = getSearchManager(); 3902 if (searchManager != null) { 3903 searchManager.stopSearch(); 3904 } 3905 startActivityAsUser(intent, UserHandle.CURRENT); 3906 } catch (ActivityNotFoundException e) { 3907 Slog.w(TAG, "No activity to handle assist long press action.", e); 3908 } 3909 } 3910 3911 private void launchAssistAction(String hint, int deviceId) { 3912 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 3913 if (!isUserSetupComplete()) { 3914 // Disable opening assist window during setup 3915 return; 3916 } 3917 Bundle args = null; 3918 if (deviceId > Integer.MIN_VALUE) { 3919 args = new Bundle(); 3920 args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, deviceId); 3921 } 3922 if ((mContext.getResources().getConfiguration().uiMode 3923 & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) { 3924 // On TV, use legacy handling until assistants are implemented in the proper way. 3925 ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 3926 .launchLegacyAssist(hint, UserHandle.myUserId(), args); 3927 } else { 3928 if (hint != null) { 3929 if (args == null) { 3930 args = new Bundle(); 3931 } 3932 args.putBoolean(hint, true); 3933 } 3934 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3935 if (statusbar != null) { 3936 statusbar.startAssist(args); 3937 } 3938 } 3939 } 3940 3941 private void startActivityAsUser(Intent intent, UserHandle handle) { 3942 if (isUserSetupComplete()) { 3943 mContext.startActivityAsUser(intent, handle); 3944 } else { 3945 Slog.i(TAG, "Not starting activity because user setup is in progress: " + intent); 3946 } 3947 } 3948 3949 private SearchManager getSearchManager() { 3950 if (mSearchManager == null) { 3951 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 3952 } 3953 return mSearchManager; 3954 } 3955 3956 private void preloadRecentApps() { 3957 mPreloadedRecentApps = true; 3958 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3959 if (statusbar != null) { 3960 statusbar.preloadRecentApps(); 3961 } 3962 } 3963 3964 private void cancelPreloadRecentApps() { 3965 if (mPreloadedRecentApps) { 3966 mPreloadedRecentApps = false; 3967 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3968 if (statusbar != null) { 3969 statusbar.cancelPreloadRecentApps(); 3970 } 3971 } 3972 } 3973 3974 private void toggleRecentApps() { 3975 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 3976 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3977 if (statusbar != null) { 3978 statusbar.toggleRecentApps(); 3979 } 3980 } 3981 3982 @Override 3983 public void showRecentApps(boolean fromHome) { 3984 mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS); 3985 mHandler.obtainMessage(MSG_DISPATCH_SHOW_RECENTS, fromHome ? 1 : 0, 0).sendToTarget(); 3986 } 3987 3988 private void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) { 3989 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 3990 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3991 if (statusbar != null) { 3992 statusbar.showRecentApps(triggeredFromAltTab, fromHome); 3993 } 3994 } 3995 3996 private void toggleKeyboardShortcutsMenu(int deviceId) { 3997 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3998 if (statusbar != null) { 3999 statusbar.toggleKeyboardShortcutsMenu(deviceId); 4000 } 4001 } 4002 4003 private void dismissKeyboardShortcutsMenu() { 4004 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4005 if (statusbar != null) { 4006 statusbar.dismissKeyboardShortcutsMenu(); 4007 } 4008 } 4009 4010 private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) { 4011 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 4012 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4013 if (statusbar != null) { 4014 statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome); 4015 } 4016 } 4017 4018 void launchHomeFromHotKey() { 4019 launchHomeFromHotKey(true /* awakenFromDreams */, true /*respectKeyguard*/); 4020 } 4021 4022 /** 4023 * A home key -> launch home action was detected. Take the appropriate action 4024 * given the situation with the keyguard. 4025 */ 4026 void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) { 4027 if (respectKeyguard) { 4028 if (isKeyguardShowingAndNotOccluded()) { 4029 // don't launch home if keyguard showing 4030 return; 4031 } 4032 4033 if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) { 4034 // when in keyguard restricted mode, must first verify unlock 4035 // before launching home 4036 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() { 4037 @Override 4038 public void onKeyguardExitResult(boolean success) { 4039 if (success) { 4040 try { 4041 ActivityManager.getService().stopAppSwitches(); 4042 } catch (RemoteException e) { 4043 } 4044 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 4045 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); 4046 } 4047 } 4048 }); 4049 return; 4050 } 4051 } 4052 4053 // no keyguard stuff to worry about, just launch home! 4054 try { 4055 ActivityManager.getService().stopAppSwitches(); 4056 } catch (RemoteException e) { 4057 } 4058 if (mRecentsVisible) { 4059 // Hide Recents and notify it to launch Home 4060 if (awakenFromDreams) { 4061 awakenDreams(); 4062 } 4063 hideRecentApps(false, true); 4064 } else { 4065 // Otherwise, just launch Home 4066 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 4067 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); 4068 } 4069 } 4070 4071 private final Runnable mClearHideNavigationFlag = new Runnable() { 4072 @Override 4073 public void run() { 4074 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 4075 // Clear flags. 4076 mForceClearedSystemUiFlags &= 4077 ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 4078 } 4079 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 4080 } 4081 }; 4082 4083 /** 4084 * Input handler used while nav bar is hidden. Captures any touch on the screen, 4085 * to determine when the nav bar should be shown and prevent applications from 4086 * receiving those touches. 4087 */ 4088 final class HideNavInputEventReceiver extends InputEventReceiver { 4089 public HideNavInputEventReceiver(InputChannel inputChannel, Looper looper) { 4090 super(inputChannel, looper); 4091 } 4092 4093 @Override 4094 public void onInputEvent(InputEvent event) { 4095 boolean handled = false; 4096 try { 4097 if (event instanceof MotionEvent 4098 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { 4099 final MotionEvent motionEvent = (MotionEvent)event; 4100 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 4101 // When the user taps down, we re-show the nav bar. 4102 boolean changed = false; 4103 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 4104 if (mInputConsumer == null) { 4105 return; 4106 } 4107 // Any user activity always causes us to show the 4108 // navigation controls, if they had been hidden. 4109 // We also clear the low profile and only content 4110 // flags so that tapping on the screen will atomically 4111 // restore all currently hidden screen decorations. 4112 int newVal = mResettingSystemUiFlags | 4113 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 4114 View.SYSTEM_UI_FLAG_LOW_PROFILE | 4115 View.SYSTEM_UI_FLAG_FULLSCREEN; 4116 if (mResettingSystemUiFlags != newVal) { 4117 mResettingSystemUiFlags = newVal; 4118 changed = true; 4119 } 4120 // We don't allow the system's nav bar to be hidden 4121 // again for 1 second, to prevent applications from 4122 // spamming us and keeping it from being shown. 4123 newVal = mForceClearedSystemUiFlags | 4124 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 4125 if (mForceClearedSystemUiFlags != newVal) { 4126 mForceClearedSystemUiFlags = newVal; 4127 changed = true; 4128 mHandler.postDelayed(mClearHideNavigationFlag, 1000); 4129 } 4130 } 4131 if (changed) { 4132 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 4133 } 4134 } 4135 } 4136 } finally { 4137 finishInputEvent(event, handled); 4138 } 4139 } 4140 } 4141 4142 @Override 4143 public void setRecentsVisibilityLw(boolean visible) { 4144 mRecentsVisible = visible; 4145 } 4146 4147 @Override 4148 public void setPipVisibilityLw(boolean visible) { 4149 mPictureInPictureVisible = visible; 4150 } 4151 4152 @Override 4153 public int adjustSystemUiVisibilityLw(int visibility) { 4154 mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); 4155 mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); 4156 4157 // Reset any bits in mForceClearingStatusBarVisibility that 4158 // are now clear. 4159 mResettingSystemUiFlags &= visibility; 4160 // Clear any bits in the new visibility that are currently being 4161 // force cleared, before reporting it. 4162 return visibility & ~mResettingSystemUiFlags 4163 & ~mForceClearedSystemUiFlags; 4164 } 4165 4166 @Override 4167 public boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds, 4168 int displayRotation, int displayWidth, int displayHeight, Rect outContentInsets, 4169 Rect outStableInsets, Rect outOutsets) { 4170 final int fl = PolicyControl.getWindowFlags(null, attrs); 4171 final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs); 4172 final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility); 4173 4174 final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl); 4175 if (useOutsets) { 4176 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); 4177 if (outset > 0) { 4178 if (displayRotation == Surface.ROTATION_0) { 4179 outOutsets.bottom += outset; 4180 } else if (displayRotation == Surface.ROTATION_90) { 4181 outOutsets.right += outset; 4182 } else if (displayRotation == Surface.ROTATION_180) { 4183 outOutsets.top += outset; 4184 } else if (displayRotation == Surface.ROTATION_270) { 4185 outOutsets.left += outset; 4186 } 4187 } 4188 } 4189 4190 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) 4191 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { 4192 int availRight, availBottom; 4193 if (canHideNavigationBar() && 4194 (systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { 4195 availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4196 availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4197 } else { 4198 availRight = mRestrictedScreenLeft + mRestrictedScreenWidth; 4199 availBottom = mRestrictedScreenTop + mRestrictedScreenHeight; 4200 } 4201 if ((systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 4202 if ((fl & FLAG_FULLSCREEN) != 0) { 4203 outContentInsets.set(mStableFullscreenLeft, mStableFullscreenTop, 4204 availRight - mStableFullscreenRight, 4205 availBottom - mStableFullscreenBottom); 4206 } else { 4207 outContentInsets.set(mStableLeft, mStableTop, 4208 availRight - mStableRight, availBottom - mStableBottom); 4209 } 4210 } else if ((fl & FLAG_FULLSCREEN) != 0 || (fl & FLAG_LAYOUT_IN_OVERSCAN) != 0) { 4211 outContentInsets.setEmpty(); 4212 } else if ((systemUiVisibility & (View.SYSTEM_UI_FLAG_FULLSCREEN 4213 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)) == 0) { 4214 outContentInsets.set(mCurLeft, mCurTop, 4215 availRight - mCurRight, availBottom - mCurBottom); 4216 } else { 4217 outContentInsets.set(mCurLeft, mCurTop, 4218 availRight - mCurRight, availBottom - mCurBottom); 4219 } 4220 4221 outStableInsets.set(mStableLeft, mStableTop, 4222 availRight - mStableRight, availBottom - mStableBottom); 4223 if (taskBounds != null) { 4224 calculateRelevantTaskInsets(taskBounds, outContentInsets, 4225 displayWidth, displayHeight); 4226 calculateRelevantTaskInsets(taskBounds, outStableInsets, 4227 displayWidth, displayHeight); 4228 } 4229 return mForceShowSystemBars; 4230 } 4231 outContentInsets.setEmpty(); 4232 outStableInsets.setEmpty(); 4233 return mForceShowSystemBars; 4234 } 4235 4236 /** 4237 * For any given task bounds, the insets relevant for these bounds given the insets relevant 4238 * for the entire display. 4239 */ 4240 private void calculateRelevantTaskInsets(Rect taskBounds, Rect inOutInsets, int displayWidth, 4241 int displayHeight) { 4242 mTmpRect.set(0, 0, displayWidth, displayHeight); 4243 mTmpRect.inset(inOutInsets); 4244 mTmpRect.intersect(taskBounds); 4245 int leftInset = mTmpRect.left - taskBounds.left; 4246 int topInset = mTmpRect.top - taskBounds.top; 4247 int rightInset = taskBounds.right - mTmpRect.right; 4248 int bottomInset = taskBounds.bottom - mTmpRect.bottom; 4249 inOutInsets.set(leftInset, topInset, rightInset, bottomInset); 4250 } 4251 4252 private boolean shouldUseOutsets(WindowManager.LayoutParams attrs, int fl) { 4253 return attrs.type == TYPE_WALLPAPER || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN 4254 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0; 4255 } 4256 4257 /** {@inheritDoc} */ 4258 @Override 4259 public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight, 4260 int displayRotation, int uiMode) { 4261 mDisplayRotation = displayRotation; 4262 final int overscanLeft, overscanTop, overscanRight, overscanBottom; 4263 if (isDefaultDisplay) { 4264 switch (displayRotation) { 4265 case Surface.ROTATION_90: 4266 overscanLeft = mOverscanTop; 4267 overscanTop = mOverscanRight; 4268 overscanRight = mOverscanBottom; 4269 overscanBottom = mOverscanLeft; 4270 break; 4271 case Surface.ROTATION_180: 4272 overscanLeft = mOverscanRight; 4273 overscanTop = mOverscanBottom; 4274 overscanRight = mOverscanLeft; 4275 overscanBottom = mOverscanTop; 4276 break; 4277 case Surface.ROTATION_270: 4278 overscanLeft = mOverscanBottom; 4279 overscanTop = mOverscanLeft; 4280 overscanRight = mOverscanTop; 4281 overscanBottom = mOverscanRight; 4282 break; 4283 default: 4284 overscanLeft = mOverscanLeft; 4285 overscanTop = mOverscanTop; 4286 overscanRight = mOverscanRight; 4287 overscanBottom = mOverscanBottom; 4288 break; 4289 } 4290 } else { 4291 overscanLeft = 0; 4292 overscanTop = 0; 4293 overscanRight = 0; 4294 overscanBottom = 0; 4295 } 4296 mOverscanScreenLeft = mRestrictedOverscanScreenLeft = 0; 4297 mOverscanScreenTop = mRestrictedOverscanScreenTop = 0; 4298 mOverscanScreenWidth = mRestrictedOverscanScreenWidth = displayWidth; 4299 mOverscanScreenHeight = mRestrictedOverscanScreenHeight = displayHeight; 4300 mSystemLeft = 0; 4301 mSystemTop = 0; 4302 mSystemRight = displayWidth; 4303 mSystemBottom = displayHeight; 4304 mUnrestrictedScreenLeft = overscanLeft; 4305 mUnrestrictedScreenTop = overscanTop; 4306 mUnrestrictedScreenWidth = displayWidth - overscanLeft - overscanRight; 4307 mUnrestrictedScreenHeight = displayHeight - overscanTop - overscanBottom; 4308 mRestrictedScreenLeft = mUnrestrictedScreenLeft; 4309 mRestrictedScreenTop = mUnrestrictedScreenTop; 4310 mRestrictedScreenWidth = mSystemGestures.screenWidth = mUnrestrictedScreenWidth; 4311 mRestrictedScreenHeight = mSystemGestures.screenHeight = mUnrestrictedScreenHeight; 4312 mDockLeft = mContentLeft = mVoiceContentLeft = mStableLeft = mStableFullscreenLeft 4313 = mCurLeft = mUnrestrictedScreenLeft; 4314 mDockTop = mContentTop = mVoiceContentTop = mStableTop = mStableFullscreenTop 4315 = mCurTop = mUnrestrictedScreenTop; 4316 mDockRight = mContentRight = mVoiceContentRight = mStableRight = mStableFullscreenRight 4317 = mCurRight = displayWidth - overscanRight; 4318 mDockBottom = mContentBottom = mVoiceContentBottom = mStableBottom = mStableFullscreenBottom 4319 = mCurBottom = displayHeight - overscanBottom; 4320 mDockLayer = 0x10000000; 4321 mStatusBarLayer = -1; 4322 4323 // start with the current dock rect, which will be (0,0,displayWidth,displayHeight) 4324 final Rect pf = mTmpParentFrame; 4325 final Rect df = mTmpDisplayFrame; 4326 final Rect of = mTmpOverscanFrame; 4327 final Rect vf = mTmpVisibleFrame; 4328 final Rect dcf = mTmpDecorFrame; 4329 pf.left = df.left = of.left = vf.left = mDockLeft; 4330 pf.top = df.top = of.top = vf.top = mDockTop; 4331 pf.right = df.right = of.right = vf.right = mDockRight; 4332 pf.bottom = df.bottom = of.bottom = vf.bottom = mDockBottom; 4333 dcf.setEmpty(); // Decor frame N/A for system bars. 4334 4335 if (isDefaultDisplay) { 4336 // For purposes of putting out fake window up to steal focus, we will 4337 // drive nav being hidden only by whether it is requested. 4338 final int sysui = mLastSystemUiFlags; 4339 boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; 4340 boolean navTranslucent = (sysui 4341 & (View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT)) != 0; 4342 boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; 4343 boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 4344 boolean navAllowedHidden = immersive || immersiveSticky; 4345 navTranslucent &= !immersiveSticky; // transient trumps translucent 4346 boolean isKeyguardShowing = isStatusBarKeyguard() && !mKeyguardOccluded; 4347 if (!isKeyguardShowing) { 4348 navTranslucent &= areTranslucentBarsAllowed(); 4349 } 4350 boolean statusBarExpandedNotKeyguard = !isKeyguardShowing && mStatusBar != null 4351 && mStatusBar.getAttrs().height == MATCH_PARENT 4352 && mStatusBar.getAttrs().width == MATCH_PARENT; 4353 4354 // When the navigation bar isn't visible, we put up a fake 4355 // input window to catch all touch events. This way we can 4356 // detect when the user presses anywhere to bring back the nav 4357 // bar and ensure the application doesn't see the event. 4358 if (navVisible || navAllowedHidden) { 4359 if (mInputConsumer != null) { 4360 mHandler.sendMessage( 4361 mHandler.obtainMessage(MSG_DISPOSE_INPUT_CONSUMER, mInputConsumer)); 4362 mInputConsumer = null; 4363 } 4364 } else if (mInputConsumer == null) { 4365 mInputConsumer = mWindowManagerFuncs.createInputConsumer(mHandler.getLooper(), 4366 INPUT_CONSUMER_NAVIGATION, 4367 (channel, looper) -> new HideNavInputEventReceiver(channel, looper)); 4368 // As long as mInputConsumer is active, hover events are not dispatched to the app 4369 // and the pointer icon is likely to become stale. Hide it to avoid confusion. 4370 InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_NULL); 4371 } 4372 4373 // For purposes of positioning and showing the nav bar, if we have 4374 // decided that it can't be hidden (because of the screen aspect ratio), 4375 // then take that into account. 4376 navVisible |= !canHideNavigationBar(); 4377 4378 boolean updateSysUiVisibility = layoutNavigationBar(displayWidth, displayHeight, 4379 displayRotation, uiMode, overscanLeft, overscanRight, overscanBottom, dcf, navVisible, navTranslucent, 4380 navAllowedHidden, statusBarExpandedNotKeyguard); 4381 if (DEBUG_LAYOUT) Slog.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)", 4382 mDockLeft, mDockTop, mDockRight, mDockBottom)); 4383 updateSysUiVisibility |= layoutStatusBar(pf, df, of, vf, dcf, sysui, isKeyguardShowing); 4384 if (updateSysUiVisibility) { 4385 updateSystemUiVisibilityLw(); 4386 } 4387 } 4388 } 4389 4390 private boolean layoutStatusBar(Rect pf, Rect df, Rect of, Rect vf, Rect dcf, int sysui, 4391 boolean isKeyguardShowing) { 4392 // decide where the status bar goes ahead of time 4393 if (mStatusBar != null) { 4394 // apply any navigation bar insets 4395 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4396 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4397 pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft; 4398 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight 4399 + mUnrestrictedScreenTop; 4400 vf.left = mStableLeft; 4401 vf.top = mStableTop; 4402 vf.right = mStableRight; 4403 vf.bottom = mStableBottom; 4404 4405 mStatusBarLayer = mStatusBar.getSurfaceLayer(); 4406 4407 // Let the status bar determine its size. 4408 mStatusBar.computeFrameLw(pf /* parentFrame */, df /* displayFrame */, 4409 vf /* overlayFrame */, vf /* contentFrame */, vf /* visibleFrame */, 4410 dcf /* decorFrame */, vf /* stableFrame */, vf /* outsetFrame */); 4411 4412 // For layout, the status bar is always at the top with our fixed height. 4413 mStableTop = mUnrestrictedScreenTop + mStatusBarHeight; 4414 4415 boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0; 4416 boolean statusBarTranslucent = (sysui 4417 & (View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT)) != 0; 4418 if (!isKeyguardShowing) { 4419 statusBarTranslucent &= areTranslucentBarsAllowed(); 4420 } 4421 4422 // If the status bar is hidden, we don't want to cause 4423 // windows behind it to scroll. 4424 if (mStatusBar.isVisibleLw() && !statusBarTransient) { 4425 // Status bar may go away, so the screen area it occupies 4426 // is available to apps but just covering them when the 4427 // status bar is visible. 4428 mDockTop = mUnrestrictedScreenTop + mStatusBarHeight; 4429 4430 mContentTop = mVoiceContentTop = mCurTop = mDockTop; 4431 mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; 4432 mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; 4433 mContentRight = mVoiceContentRight = mCurRight = mDockRight; 4434 4435 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " + 4436 String.format( 4437 "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]", 4438 mDockLeft, mDockTop, mDockRight, mDockBottom, 4439 mContentLeft, mContentTop, mContentRight, mContentBottom, 4440 mCurLeft, mCurTop, mCurRight, mCurBottom)); 4441 } 4442 if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw() 4443 && !statusBarTransient && !statusBarTranslucent 4444 && !mStatusBarController.wasRecentlyTranslucent()) { 4445 // If the opaque status bar is currently requested to be visible, 4446 // and not in the process of animating on or off, then 4447 // we can tell the app that it is covered by it. 4448 mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight; 4449 } 4450 if (mStatusBarController.checkHiddenLw()) { 4451 return true; 4452 } 4453 } 4454 return false; 4455 } 4456 4457 private boolean layoutNavigationBar(int displayWidth, int displayHeight, int displayRotation, 4458 int uiMode, int overscanLeft, int overscanRight, int overscanBottom, Rect dcf, 4459 boolean navVisible, boolean navTranslucent, boolean navAllowedHidden, 4460 boolean statusBarExpandedNotKeyguard) { 4461 if (mNavigationBar != null) { 4462 boolean transientNavBarShowing = mNavigationBarController.isTransientShowing(); 4463 // Force the navigation bar to its appropriate place and 4464 // size. We need to do this directly, instead of relying on 4465 // it to bubble up from the nav bar, because this needs to 4466 // change atomically with screen rotations. 4467 mNavigationBarPosition = navigationBarPosition(displayWidth, displayHeight, 4468 displayRotation); 4469 if (mNavigationBarPosition == NAV_BAR_BOTTOM) { 4470 // It's a system nav bar or a portrait screen; nav bar goes on bottom. 4471 int top = displayHeight - overscanBottom 4472 - getNavigationBarHeight(displayRotation, uiMode); 4473 mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom); 4474 mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top; 4475 if (transientNavBarShowing) { 4476 mNavigationBarController.setBarShowingLw(true); 4477 } else if (navVisible) { 4478 mNavigationBarController.setBarShowingLw(true); 4479 mDockBottom = mTmpNavigationFrame.top; 4480 mRestrictedScreenHeight = mDockBottom - mRestrictedScreenTop; 4481 mRestrictedOverscanScreenHeight = mDockBottom - mRestrictedOverscanScreenTop; 4482 } else { 4483 // We currently want to hide the navigation UI - unless we expanded the status 4484 // bar. 4485 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4486 } 4487 if (navVisible && !navTranslucent && !navAllowedHidden 4488 && !mNavigationBar.isAnimatingLw() 4489 && !mNavigationBarController.wasRecentlyTranslucent()) { 4490 // If the opaque nav bar is currently requested to be visible, 4491 // and not in the process of animating on or off, then 4492 // we can tell the app that it is covered by it. 4493 mSystemBottom = mTmpNavigationFrame.top; 4494 } 4495 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) { 4496 // Landscape screen; nav bar goes to the right. 4497 int left = displayWidth - overscanRight 4498 - getNavigationBarWidth(displayRotation, uiMode); 4499 mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight); 4500 mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left; 4501 if (transientNavBarShowing) { 4502 mNavigationBarController.setBarShowingLw(true); 4503 } else if (navVisible) { 4504 mNavigationBarController.setBarShowingLw(true); 4505 mDockRight = mTmpNavigationFrame.left; 4506 mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft; 4507 mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft; 4508 } else { 4509 // We currently want to hide the navigation UI - unless we expanded the status 4510 // bar. 4511 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4512 } 4513 if (navVisible && !navTranslucent && !navAllowedHidden 4514 && !mNavigationBar.isAnimatingLw() 4515 && !mNavigationBarController.wasRecentlyTranslucent()) { 4516 // If the nav bar is currently requested to be visible, 4517 // and not in the process of animating on or off, then 4518 // we can tell the app that it is covered by it. 4519 mSystemRight = mTmpNavigationFrame.left; 4520 } 4521 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 4522 // Seascape screen; nav bar goes to the left. 4523 int right = overscanLeft + getNavigationBarWidth(displayRotation, uiMode); 4524 mTmpNavigationFrame.set(overscanLeft, 0, right, displayHeight); 4525 mStableLeft = mStableFullscreenLeft = mTmpNavigationFrame.right; 4526 if (transientNavBarShowing) { 4527 mNavigationBarController.setBarShowingLw(true); 4528 } else if (navVisible) { 4529 mNavigationBarController.setBarShowingLw(true); 4530 mDockLeft = mTmpNavigationFrame.right; 4531 // TODO: not so sure about those: 4532 mRestrictedScreenLeft = mRestrictedOverscanScreenLeft = mDockLeft; 4533 mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft; 4534 mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft; 4535 } else { 4536 // We currently want to hide the navigation UI - unless we expanded the status 4537 // bar. 4538 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4539 } 4540 if (navVisible && !navTranslucent && !navAllowedHidden 4541 && !mNavigationBar.isAnimatingLw() 4542 && !mNavigationBarController.wasRecentlyTranslucent()) { 4543 // If the nav bar is currently requested to be visible, 4544 // and not in the process of animating on or off, then 4545 // we can tell the app that it is covered by it. 4546 mSystemLeft = mTmpNavigationFrame.right; 4547 } 4548 } 4549 // Make sure the content and current rectangles are updated to 4550 // account for the restrictions from the navigation bar. 4551 mContentTop = mVoiceContentTop = mCurTop = mDockTop; 4552 mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; 4553 mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; 4554 mContentRight = mVoiceContentRight = mCurRight = mDockRight; 4555 mStatusBarLayer = mNavigationBar.getSurfaceLayer(); 4556 // And compute the final frame. 4557 mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, 4558 mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf, 4559 mTmpNavigationFrame, mTmpNavigationFrame); 4560 if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame); 4561 if (mNavigationBarController.checkHiddenLw()) { 4562 return true; 4563 } 4564 } 4565 return false; 4566 } 4567 4568 private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) { 4569 if (mNavigationBarCanMove && displayWidth > displayHeight) { 4570 if (displayRotation == Surface.ROTATION_270) { 4571 return NAV_BAR_LEFT; 4572 } else { 4573 return NAV_BAR_RIGHT; 4574 } 4575 } 4576 return NAV_BAR_BOTTOM; 4577 } 4578 4579 /** {@inheritDoc} */ 4580 @Override 4581 public int getSystemDecorLayerLw() { 4582 if (mStatusBar != null && mStatusBar.isVisibleLw()) { 4583 return mStatusBar.getSurfaceLayer(); 4584 } 4585 4586 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) { 4587 return mNavigationBar.getSurfaceLayer(); 4588 } 4589 4590 return 0; 4591 } 4592 4593 @Override 4594 public void getContentRectLw(Rect r) { 4595 r.set(mContentLeft, mContentTop, mContentRight, mContentBottom); 4596 } 4597 4598 void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached, 4599 boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf) { 4600 if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { 4601 // Here's a special case: if this attached window is a panel that is 4602 // above the dock window, and the window it is attached to is below 4603 // the dock window, then the frames we computed for the window it is 4604 // attached to can not be used because the dock is effectively part 4605 // of the underlying window and the attached window is floating on top 4606 // of the whole thing. So, we ignore the attached window and explicitly 4607 // compute the frames that would be appropriate without the dock. 4608 df.left = of.left = cf.left = vf.left = mDockLeft; 4609 df.top = of.top = cf.top = vf.top = mDockTop; 4610 df.right = of.right = cf.right = vf.right = mDockRight; 4611 df.bottom = of.bottom = cf.bottom = vf.bottom = mDockBottom; 4612 } else { 4613 // The effective display frame of the attached window depends on 4614 // whether it is taking care of insetting its content. If not, 4615 // we need to use the parent's content frame so that the entire 4616 // window is positioned within that content. Otherwise we can use 4617 // the overscan frame and let the attached window take care of 4618 // positioning its content appropriately. 4619 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4620 // Set the content frame of the attached window to the parent's decor frame 4621 // (same as content frame when IME isn't present) if specifically requested by 4622 // setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag. 4623 // Otherwise, use the overscan frame. 4624 cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0 4625 ? attached.getContentFrameLw() : attached.getOverscanFrameLw()); 4626 } else { 4627 // If the window is resizing, then we want to base the content 4628 // frame on our attached content frame to resize... however, 4629 // things can be tricky if the attached window is NOT in resize 4630 // mode, in which case its content frame will be larger. 4631 // Ungh. So to deal with that, make sure the content frame 4632 // we end up using is not covering the IM dock. 4633 cf.set(attached.getContentFrameLw()); 4634 if (attached.isVoiceInteraction()) { 4635 if (cf.left < mVoiceContentLeft) cf.left = mVoiceContentLeft; 4636 if (cf.top < mVoiceContentTop) cf.top = mVoiceContentTop; 4637 if (cf.right > mVoiceContentRight) cf.right = mVoiceContentRight; 4638 if (cf.bottom > mVoiceContentBottom) cf.bottom = mVoiceContentBottom; 4639 } else if (attached.getSurfaceLayer() < mDockLayer) { 4640 if (cf.left < mContentLeft) cf.left = mContentLeft; 4641 if (cf.top < mContentTop) cf.top = mContentTop; 4642 if (cf.right > mContentRight) cf.right = mContentRight; 4643 if (cf.bottom > mContentBottom) cf.bottom = mContentBottom; 4644 } 4645 } 4646 df.set(insetDecors ? attached.getDisplayFrameLw() : cf); 4647 of.set(insetDecors ? attached.getOverscanFrameLw() : cf); 4648 vf.set(attached.getVisibleFrameLw()); 4649 } 4650 // The LAYOUT_IN_SCREEN flag is used to determine whether the attached 4651 // window should be positioned relative to its parent or the entire 4652 // screen. 4653 pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 4654 ? attached.getFrameLw() : df); 4655 } 4656 4657 private void applyStableConstraints(int sysui, int fl, Rect r) { 4658 if ((sysui & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 4659 // If app is requesting a stable layout, don't let the 4660 // content insets go below the stable values. 4661 if ((fl & FLAG_FULLSCREEN) != 0) { 4662 if (r.left < mStableFullscreenLeft) r.left = mStableFullscreenLeft; 4663 if (r.top < mStableFullscreenTop) r.top = mStableFullscreenTop; 4664 if (r.right > mStableFullscreenRight) r.right = mStableFullscreenRight; 4665 if (r.bottom > mStableFullscreenBottom) r.bottom = mStableFullscreenBottom; 4666 } else { 4667 if (r.left < mStableLeft) r.left = mStableLeft; 4668 if (r.top < mStableTop) r.top = mStableTop; 4669 if (r.right > mStableRight) r.right = mStableRight; 4670 if (r.bottom > mStableBottom) r.bottom = mStableBottom; 4671 } 4672 } 4673 } 4674 4675 private boolean canReceiveInput(WindowState win) { 4676 boolean notFocusable = 4677 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0; 4678 boolean altFocusableIm = 4679 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0; 4680 boolean notFocusableForIm = notFocusable ^ altFocusableIm; 4681 return !notFocusableForIm; 4682 } 4683 4684 /** {@inheritDoc} */ 4685 @Override 4686 public void layoutWindowLw(WindowState win, WindowState attached) { 4687 // We've already done the navigation bar and status bar. If the status bar can receive 4688 // input, we need to layout it again to accomodate for the IME window. 4689 if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar) { 4690 return; 4691 } 4692 final WindowManager.LayoutParams attrs = win.getAttrs(); 4693 final boolean isDefaultDisplay = win.isDefaultDisplay(); 4694 final boolean needsToOffsetInputMethodTarget = isDefaultDisplay && 4695 (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null); 4696 if (needsToOffsetInputMethodTarget) { 4697 if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state"); 4698 offsetInputMethodWindowLw(mLastInputMethodWindow); 4699 } 4700 4701 final int fl = PolicyControl.getWindowFlags(win, attrs); 4702 final int pfl = attrs.privateFlags; 4703 final int sim = attrs.softInputMode; 4704 final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null); 4705 4706 final Rect pf = mTmpParentFrame; 4707 final Rect df = mTmpDisplayFrame; 4708 final Rect of = mTmpOverscanFrame; 4709 final Rect cf = mTmpContentFrame; 4710 final Rect vf = mTmpVisibleFrame; 4711 final Rect dcf = mTmpDecorFrame; 4712 final Rect sf = mTmpStableFrame; 4713 Rect osf = null; 4714 dcf.setEmpty(); 4715 4716 final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar 4717 && mNavigationBar != null && mNavigationBar.isVisibleLw()); 4718 4719 final int adjust = sim & SOFT_INPUT_MASK_ADJUST; 4720 4721 if (isDefaultDisplay) { 4722 sf.set(mStableLeft, mStableTop, mStableRight, mStableBottom); 4723 } else { 4724 sf.set(mOverscanLeft, mOverscanTop, mOverscanRight, mOverscanBottom); 4725 } 4726 4727 if (!isDefaultDisplay) { 4728 if (attached != null) { 4729 // If this window is attached to another, our display 4730 // frame is the same as the one we are attached to. 4731 setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf); 4732 } else { 4733 // Give the window full screen. 4734 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 4735 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 4736 pf.right = df.right = of.right = cf.right 4737 = mOverscanScreenLeft + mOverscanScreenWidth; 4738 pf.bottom = df.bottom = of.bottom = cf.bottom 4739 = mOverscanScreenTop + mOverscanScreenHeight; 4740 } 4741 } else if (attrs.type == TYPE_INPUT_METHOD) { 4742 pf.left = df.left = of.left = cf.left = vf.left = mDockLeft; 4743 pf.top = df.top = of.top = cf.top = vf.top = mDockTop; 4744 pf.right = df.right = of.right = cf.right = vf.right = mDockRight; 4745 // IM dock windows layout below the nav bar... 4746 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4747 // ...with content insets above the nav bar 4748 cf.bottom = vf.bottom = mStableBottom; 4749 if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) { 4750 // The status bar forces the navigation bar while it's visible. Make sure the IME 4751 // avoids the navigation bar in that case. 4752 if (mNavigationBarPosition == NAV_BAR_RIGHT) { 4753 pf.right = df.right = of.right = cf.right = vf.right = mStableRight; 4754 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 4755 pf.left = df.left = of.left = cf.left = vf.left = mStableLeft; 4756 } 4757 } 4758 // IM dock windows always go to the bottom of the screen. 4759 attrs.gravity = Gravity.BOTTOM; 4760 mDockLayer = win.getSurfaceLayer(); 4761 } else if (attrs.type == TYPE_VOICE_INTERACTION) { 4762 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4763 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4764 pf.right = df.right = of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4765 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4766 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4767 cf.left = mDockLeft; 4768 cf.top = mDockTop; 4769 cf.right = mDockRight; 4770 cf.bottom = mDockBottom; 4771 } else { 4772 cf.left = mContentLeft; 4773 cf.top = mContentTop; 4774 cf.right = mContentRight; 4775 cf.bottom = mContentBottom; 4776 } 4777 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 4778 vf.left = mCurLeft; 4779 vf.top = mCurTop; 4780 vf.right = mCurRight; 4781 vf.bottom = mCurBottom; 4782 } else { 4783 vf.set(cf); 4784 } 4785 } else if (attrs.type == TYPE_WALLPAPER) { 4786 layoutWallpaper(win, pf, df, of, cf); 4787 } else if (win == mStatusBar) { 4788 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4789 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4790 pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft; 4791 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight + mUnrestrictedScreenTop; 4792 cf.left = vf.left = mStableLeft; 4793 cf.top = vf.top = mStableTop; 4794 cf.right = vf.right = mStableRight; 4795 vf.bottom = mStableBottom; 4796 4797 if (adjust == SOFT_INPUT_ADJUST_RESIZE) { 4798 cf.bottom = mContentBottom; 4799 } else { 4800 cf.bottom = mDockBottom; 4801 vf.bottom = mContentBottom; 4802 } 4803 } else { 4804 4805 // Default policy decor for the default display 4806 dcf.left = mSystemLeft; 4807 dcf.top = mSystemTop; 4808 dcf.right = mSystemRight; 4809 dcf.bottom = mSystemBottom; 4810 final boolean inheritTranslucentDecor = (attrs.privateFlags 4811 & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) != 0; 4812 final boolean isAppWindow = 4813 attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && 4814 attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 4815 final boolean topAtRest = 4816 win == mTopFullscreenOpaqueWindowState && !win.isAnimatingLw(); 4817 if (isAppWindow && !inheritTranslucentDecor && !topAtRest) { 4818 if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 4819 && (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0 4820 && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0 4821 && (fl & WindowManager.LayoutParams. 4822 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0 4823 && (pfl & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) == 0) { 4824 // Ensure policy decor includes status bar 4825 dcf.top = mStableTop; 4826 } 4827 if ((fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == 0 4828 && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 4829 && (fl & WindowManager.LayoutParams. 4830 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) { 4831 // Ensure policy decor includes navigation bar 4832 dcf.bottom = mStableBottom; 4833 dcf.right = mStableRight; 4834 } 4835 } 4836 4837 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) 4838 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { 4839 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() 4840 + "): IN_SCREEN, INSET_DECOR"); 4841 // This is the case for a normal activity window: we want it 4842 // to cover all of the screen space, and it can take care of 4843 // moving its contents to account for screen decorations that 4844 // intrude into that space. 4845 if (attached != null) { 4846 // If this window is attached to another, our display 4847 // frame is the same as the one we are attached to. 4848 setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf); 4849 } else { 4850 if (attrs.type == TYPE_STATUS_BAR_PANEL 4851 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) { 4852 // Status bar panels are the only windows who can go on top of 4853 // the status bar. They are protected by the STATUS_BAR_SERVICE 4854 // permission, so they have the same privileges as the status 4855 // bar itself. 4856 // 4857 // However, they should still dodge the navigation bar if it exists. 4858 4859 pf.left = df.left = of.left = hasNavBar 4860 ? mDockLeft : mUnrestrictedScreenLeft; 4861 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4862 pf.right = df.right = of.right = hasNavBar 4863 ? mRestrictedScreenLeft+mRestrictedScreenWidth 4864 : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4865 pf.bottom = df.bottom = of.bottom = hasNavBar 4866 ? mRestrictedScreenTop+mRestrictedScreenHeight 4867 : mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4868 4869 if (DEBUG_LAYOUT) Slog.v(TAG, String.format( 4870 "Laying out status bar window: (%d,%d - %d,%d)", 4871 pf.left, pf.top, pf.right, pf.bottom)); 4872 } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0 4873 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 4874 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 4875 // Asking to layout into the overscan region, so give it that pure 4876 // unrestricted area. 4877 pf.left = df.left = of.left = mOverscanScreenLeft; 4878 pf.top = df.top = of.top = mOverscanScreenTop; 4879 pf.right = df.right = of.right = mOverscanScreenLeft + mOverscanScreenWidth; 4880 pf.bottom = df.bottom = of.bottom = mOverscanScreenTop 4881 + mOverscanScreenHeight; 4882 } else if (canHideNavigationBar() 4883 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 4884 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 4885 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 4886 // Asking for layout as if the nav bar is hidden, lets the 4887 // application extend into the unrestricted overscan screen area. We 4888 // only do this for application windows to ensure no window that 4889 // can be above the nav bar can do this. 4890 pf.left = df.left = mOverscanScreenLeft; 4891 pf.top = df.top = mOverscanScreenTop; 4892 pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; 4893 pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; 4894 // We need to tell the app about where the frame inside the overscan 4895 // is, so it can inset its content by that amount -- it didn't ask 4896 // to actually extend itself into the overscan region. 4897 of.left = mUnrestrictedScreenLeft; 4898 of.top = mUnrestrictedScreenTop; 4899 of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4900 of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4901 } else { 4902 pf.left = df.left = mRestrictedOverscanScreenLeft; 4903 pf.top = df.top = mRestrictedOverscanScreenTop; 4904 pf.right = df.right = mRestrictedOverscanScreenLeft 4905 + mRestrictedOverscanScreenWidth; 4906 pf.bottom = df.bottom = mRestrictedOverscanScreenTop 4907 + mRestrictedOverscanScreenHeight; 4908 // We need to tell the app about where the frame inside the overscan 4909 // is, so it can inset its content by that amount -- it didn't ask 4910 // to actually extend itself into the overscan region. 4911 of.left = mUnrestrictedScreenLeft; 4912 of.top = mUnrestrictedScreenTop; 4913 of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4914 of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4915 } 4916 4917 if ((fl & FLAG_FULLSCREEN) == 0) { 4918 if (win.isVoiceInteraction()) { 4919 cf.left = mVoiceContentLeft; 4920 cf.top = mVoiceContentTop; 4921 cf.right = mVoiceContentRight; 4922 cf.bottom = mVoiceContentBottom; 4923 } else { 4924 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4925 cf.left = mDockLeft; 4926 cf.top = mDockTop; 4927 cf.right = mDockRight; 4928 cf.bottom = mDockBottom; 4929 } else { 4930 cf.left = mContentLeft; 4931 cf.top = mContentTop; 4932 cf.right = mContentRight; 4933 cf.bottom = mContentBottom; 4934 } 4935 } 4936 } else { 4937 // Full screen windows are always given a layout that is as if the 4938 // status bar and other transient decors are gone. This is to avoid 4939 // bad states when moving from a window that is not hding the 4940 // status bar to one that is. 4941 cf.left = mRestrictedScreenLeft; 4942 cf.top = mRestrictedScreenTop; 4943 cf.right = mRestrictedScreenLeft + mRestrictedScreenWidth; 4944 cf.bottom = mRestrictedScreenTop + mRestrictedScreenHeight; 4945 } 4946 applyStableConstraints(sysUiFl, fl, cf); 4947 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 4948 vf.left = mCurLeft; 4949 vf.top = mCurTop; 4950 vf.right = mCurRight; 4951 vf.bottom = mCurBottom; 4952 } else { 4953 vf.set(cf); 4954 } 4955 } 4956 } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0 || (sysUiFl 4957 & (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 4958 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) { 4959 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 4960 "): IN_SCREEN"); 4961 // A window that has requested to fill the entire screen just 4962 // gets everything, period. 4963 if (attrs.type == TYPE_STATUS_BAR_PANEL 4964 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL 4965 || attrs.type == TYPE_VOLUME_OVERLAY) { 4966 pf.left = df.left = of.left = cf.left = hasNavBar 4967 ? mDockLeft : mUnrestrictedScreenLeft; 4968 pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; 4969 pf.right = df.right = of.right = cf.right = hasNavBar 4970 ? mRestrictedScreenLeft+mRestrictedScreenWidth 4971 : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4972 pf.bottom = df.bottom = of.bottom = cf.bottom = hasNavBar 4973 ? mRestrictedScreenTop+mRestrictedScreenHeight 4974 : mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4975 if (DEBUG_LAYOUT) Slog.v(TAG, String.format( 4976 "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)", 4977 pf.left, pf.top, pf.right, pf.bottom)); 4978 } else if (attrs.type == TYPE_NAVIGATION_BAR 4979 || attrs.type == TYPE_NAVIGATION_BAR_PANEL) { 4980 // The navigation bar has Real Ultimate Power. 4981 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4982 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4983 pf.right = df.right = of.right = mUnrestrictedScreenLeft 4984 + mUnrestrictedScreenWidth; 4985 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop 4986 + mUnrestrictedScreenHeight; 4987 if (DEBUG_LAYOUT) Slog.v(TAG, String.format( 4988 "Laying out navigation bar window: (%d,%d - %d,%d)", 4989 pf.left, pf.top, pf.right, pf.bottom)); 4990 } else if ((attrs.type == TYPE_SECURE_SYSTEM_OVERLAY 4991 || attrs.type == TYPE_BOOT_PROGRESS 4992 || attrs.type == TYPE_SCREENSHOT) 4993 && ((fl & FLAG_FULLSCREEN) != 0)) { 4994 // Fullscreen secure system overlays get what they ask for. Screenshot region 4995 // selection overlay should also expand to full screen. 4996 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 4997 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 4998 pf.right = df.right = of.right = cf.right = mOverscanScreenLeft 4999 + mOverscanScreenWidth; 5000 pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop 5001 + mOverscanScreenHeight; 5002 } else if (attrs.type == TYPE_BOOT_PROGRESS) { 5003 // Boot progress screen always covers entire display. 5004 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 5005 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 5006 pf.right = df.right = of.right = cf.right = mOverscanScreenLeft 5007 + mOverscanScreenWidth; 5008 pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop 5009 + mOverscanScreenHeight; 5010 } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0 5011 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 5012 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 5013 // Asking to layout into the overscan region, so give it that pure 5014 // unrestricted area. 5015 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 5016 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 5017 pf.right = df.right = of.right = cf.right 5018 = mOverscanScreenLeft + mOverscanScreenWidth; 5019 pf.bottom = df.bottom = of.bottom = cf.bottom 5020 = mOverscanScreenTop + mOverscanScreenHeight; 5021 } else if (canHideNavigationBar() 5022 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 5023 && (attrs.type == TYPE_STATUS_BAR 5024 || attrs.type == TYPE_TOAST 5025 || attrs.type == TYPE_DOCK_DIVIDER 5026 || attrs.type == TYPE_VOICE_INTERACTION_STARTING 5027 || (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 5028 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) { 5029 // Asking for layout as if the nav bar is hidden, lets the 5030 // application extend into the unrestricted screen area. We 5031 // only do this for application windows (or toasts) to ensure no window that 5032 // can be above the nav bar can do this. 5033 // XXX This assumes that an app asking for this will also 5034 // ask for layout in only content. We can't currently figure out 5035 // what the screen would be if only laying out to hide the nav bar. 5036 pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft; 5037 pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; 5038 pf.right = df.right = of.right = cf.right = mUnrestrictedScreenLeft 5039 + mUnrestrictedScreenWidth; 5040 pf.bottom = df.bottom = of.bottom = cf.bottom = mUnrestrictedScreenTop 5041 + mUnrestrictedScreenHeight; 5042 } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) { 5043 pf.left = df.left = of.left = mRestrictedScreenLeft; 5044 pf.top = df.top = of.top = mRestrictedScreenTop; 5045 pf.right = df.right = of.right = mRestrictedScreenLeft + mRestrictedScreenWidth; 5046 pf.bottom = df.bottom = of.bottom = mRestrictedScreenTop 5047 + mRestrictedScreenHeight; 5048 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 5049 cf.left = mDockLeft; 5050 cf.top = mDockTop; 5051 cf.right = mDockRight; 5052 cf.bottom = mDockBottom; 5053 } else { 5054 cf.left = mContentLeft; 5055 cf.top = mContentTop; 5056 cf.right = mContentRight; 5057 cf.bottom = mContentBottom; 5058 } 5059 } else { 5060 pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; 5061 pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; 5062 pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft 5063 + mRestrictedScreenWidth; 5064 pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop 5065 + mRestrictedScreenHeight; 5066 } 5067 5068 applyStableConstraints(sysUiFl, fl, cf); 5069 5070 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 5071 vf.left = mCurLeft; 5072 vf.top = mCurTop; 5073 vf.right = mCurRight; 5074 vf.bottom = mCurBottom; 5075 } else { 5076 vf.set(cf); 5077 } 5078 } else if (attached != null) { 5079 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 5080 "): attached to " + attached); 5081 // A child window should be placed inside of the same visible 5082 // frame that its parent had. 5083 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, of, cf, vf); 5084 } else { 5085 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 5086 "): normal window"); 5087 // Otherwise, a normal window must be placed inside the content 5088 // of all screen decorations. 5089 if (attrs.type == TYPE_STATUS_BAR_PANEL || attrs.type == TYPE_VOLUME_OVERLAY) { 5090 // Status bar panels and the volume dialog are the only windows who can go on 5091 // top of the status bar. They are protected by the STATUS_BAR_SERVICE 5092 // permission, so they have the same privileges as the status 5093 // bar itself. 5094 pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; 5095 pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; 5096 pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft 5097 + mRestrictedScreenWidth; 5098 pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop 5099 + mRestrictedScreenHeight; 5100 } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT) { 5101 // These dialogs are stable to interim decor changes. 5102 pf.left = df.left = of.left = cf.left = mStableLeft; 5103 pf.top = df.top = of.top = cf.top = mStableTop; 5104 pf.right = df.right = of.right = cf.right = mStableRight; 5105 pf.bottom = df.bottom = of.bottom = cf.bottom = mStableBottom; 5106 } else { 5107 pf.left = mContentLeft; 5108 pf.top = mContentTop; 5109 pf.right = mContentRight; 5110 pf.bottom = mContentBottom; 5111 if (win.isVoiceInteraction()) { 5112 df.left = of.left = cf.left = mVoiceContentLeft; 5113 df.top = of.top = cf.top = mVoiceContentTop; 5114 df.right = of.right = cf.right = mVoiceContentRight; 5115 df.bottom = of.bottom = cf.bottom = mVoiceContentBottom; 5116 } else if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 5117 df.left = of.left = cf.left = mDockLeft; 5118 df.top = of.top = cf.top = mDockTop; 5119 df.right = of.right = cf.right = mDockRight; 5120 df.bottom = of.bottom = cf.bottom = mDockBottom; 5121 } else { 5122 df.left = of.left = cf.left = mContentLeft; 5123 df.top = of.top = cf.top = mContentTop; 5124 df.right = of.right = cf.right = mContentRight; 5125 df.bottom = of.bottom = cf.bottom = mContentBottom; 5126 } 5127 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 5128 vf.left = mCurLeft; 5129 vf.top = mCurTop; 5130 vf.right = mCurRight; 5131 vf.bottom = mCurBottom; 5132 } else { 5133 vf.set(cf); 5134 } 5135 } 5136 } 5137 } 5138 5139 // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it. 5140 // Also, we don't allow windows in multi-window mode to extend out of the screen. 5141 if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR 5142 && !win.isInMultiWindowMode()) { 5143 df.left = df.top = -10000; 5144 df.right = df.bottom = 10000; 5145 if (attrs.type != TYPE_WALLPAPER) { 5146 of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000; 5147 of.right = of.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000; 5148 } 5149 } 5150 5151 // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we 5152 // need to provide information to the clients that want to pretend that you can draw there. 5153 // We only want to apply outsets to certain types of windows. For example, we never want to 5154 // apply the outsets to floating dialogs, because they wouldn't make sense there. 5155 final boolean useOutsets = shouldUseOutsets(attrs, fl); 5156 if (isDefaultDisplay && useOutsets) { 5157 osf = mTmpOutsetFrame; 5158 osf.set(cf.left, cf.top, cf.right, cf.bottom); 5159 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); 5160 if (outset > 0) { 5161 int rotation = mDisplayRotation; 5162 if (rotation == Surface.ROTATION_0) { 5163 osf.bottom += outset; 5164 } else if (rotation == Surface.ROTATION_90) { 5165 osf.right += outset; 5166 } else if (rotation == Surface.ROTATION_180) { 5167 osf.top -= outset; 5168 } else if (rotation == Surface.ROTATION_270) { 5169 osf.left -= outset; 5170 } 5171 if (DEBUG_LAYOUT) Slog.v(TAG, "applying bottom outset of " + outset 5172 + " with rotation " + rotation + ", result: " + osf); 5173 } 5174 } 5175 5176 if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle() 5177 + ": sim=#" + Integer.toHexString(sim) 5178 + " attach=" + attached + " type=" + attrs.type 5179 + String.format(" flags=0x%08x", fl) 5180 + " pf=" + pf.toShortString() + " df=" + df.toShortString() 5181 + " of=" + of.toShortString() 5182 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString() 5183 + " dcf=" + dcf.toShortString() 5184 + " sf=" + sf.toShortString() 5185 + " osf=" + (osf == null ? "null" : osf.toShortString())); 5186 5187 win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf); 5188 5189 // Dock windows carve out the bottom of the screen, so normal windows 5190 // can't appear underneath them. 5191 if (attrs.type == TYPE_INPUT_METHOD && win.isVisibleLw() 5192 && !win.getGivenInsetsPendingLw()) { 5193 setLastInputMethodWindowLw(null, null); 5194 offsetInputMethodWindowLw(win); 5195 } 5196 if (attrs.type == TYPE_VOICE_INTERACTION && win.isVisibleLw() 5197 && !win.getGivenInsetsPendingLw()) { 5198 offsetVoiceInputWindowLw(win); 5199 } 5200 } 5201 5202 private void layoutWallpaper(WindowState win, Rect pf, Rect df, Rect of, Rect cf) { 5203 5204 // The wallpaper also has Real Ultimate Power, but we want to tell 5205 // it about the overscan area. 5206 pf.left = df.left = mOverscanScreenLeft; 5207 pf.top = df.top = mOverscanScreenTop; 5208 pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; 5209 pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; 5210 of.left = cf.left = mUnrestrictedScreenLeft; 5211 of.top = cf.top = mUnrestrictedScreenTop; 5212 of.right = cf.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 5213 of.bottom = cf.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 5214 } 5215 5216 private void offsetInputMethodWindowLw(WindowState win) { 5217 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top); 5218 top += win.getGivenContentInsetsLw().top; 5219 if (mContentBottom > top) { 5220 mContentBottom = top; 5221 } 5222 if (mVoiceContentBottom > top) { 5223 mVoiceContentBottom = top; 5224 } 5225 top = win.getVisibleFrameLw().top; 5226 top += win.getGivenVisibleInsetsLw().top; 5227 if (mCurBottom > top) { 5228 mCurBottom = top; 5229 } 5230 if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom=" 5231 + mDockBottom + " mContentBottom=" 5232 + mContentBottom + " mCurBottom=" + mCurBottom); 5233 } 5234 5235 private void offsetVoiceInputWindowLw(WindowState win) { 5236 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top); 5237 top += win.getGivenContentInsetsLw().top; 5238 if (mVoiceContentBottom > top) { 5239 mVoiceContentBottom = top; 5240 } 5241 } 5242 5243 /** {@inheritDoc} */ 5244 @Override 5245 public void finishLayoutLw() { 5246 return; 5247 } 5248 5249 /** {@inheritDoc} */ 5250 @Override 5251 public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { 5252 mTopFullscreenOpaqueWindowState = null; 5253 mTopFullscreenOpaqueOrDimmingWindowState = null; 5254 mTopDockedOpaqueWindowState = null; 5255 mTopDockedOpaqueOrDimmingWindowState = null; 5256 mForceStatusBar = false; 5257 mForceStatusBarFromKeyguard = false; 5258 mForceStatusBarTransparent = false; 5259 mForcingShowNavBar = false; 5260 mForcingShowNavBarLayer = -1; 5261 5262 mAllowLockscreenWhenOn = false; 5263 mShowingDream = false; 5264 } 5265 5266 /** {@inheritDoc} */ 5267 @Override 5268 public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs, 5269 WindowState attached, WindowState imeTarget) { 5270 final boolean visible = !win.isGoneForLayoutLw() && win.getAttrs().alpha > 0f; 5271 if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisible=" + visible); 5272 applyKeyguardPolicyLw(win, imeTarget); 5273 final int fl = PolicyControl.getWindowFlags(win, attrs); 5274 if (mTopFullscreenOpaqueWindowState == null && visible && attrs.type == TYPE_INPUT_METHOD) { 5275 mForcingShowNavBar = true; 5276 mForcingShowNavBarLayer = win.getSurfaceLayer(); 5277 } 5278 if (attrs.type == TYPE_STATUS_BAR) { 5279 if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 5280 mForceStatusBarFromKeyguard = true; 5281 } 5282 if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) { 5283 mForceStatusBarTransparent = true; 5284 } 5285 } 5286 5287 boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW 5288 && attrs.type < FIRST_SYSTEM_WINDOW; 5289 final int stackId = win.getStackId(); 5290 if (mTopFullscreenOpaqueWindowState == null && visible) { 5291 if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) { 5292 mForceStatusBar = true; 5293 } 5294 if (attrs.type == TYPE_DREAM) { 5295 // If the lockscreen was showing when the dream started then wait 5296 // for the dream to draw before hiding the lockscreen. 5297 if (!mDreamingLockscreen 5298 || (win.isVisibleLw() && win.hasDrawnLw())) { 5299 mShowingDream = true; 5300 appWindow = true; 5301 } 5302 } 5303 5304 // For app windows that are not attached, we decide if all windows in the app they 5305 // represent should be hidden or if we should hide the lockscreen. For attached app 5306 // windows we defer the decision to the window it is attached to. 5307 if (appWindow && attached == null) { 5308 if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) { 5309 if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win); 5310 mTopFullscreenOpaqueWindowState = win; 5311 if (mTopFullscreenOpaqueOrDimmingWindowState == null) { 5312 mTopFullscreenOpaqueOrDimmingWindowState = win; 5313 } 5314 if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { 5315 mAllowLockscreenWhenOn = true; 5316 } 5317 } 5318 } 5319 } 5320 5321 // Voice interaction overrides both top fullscreen and top docked. 5322 if (visible && win.getAttrs().type == TYPE_VOICE_INTERACTION) { 5323 if (mTopFullscreenOpaqueWindowState == null) { 5324 mTopFullscreenOpaqueWindowState = win; 5325 if (mTopFullscreenOpaqueOrDimmingWindowState == null) { 5326 mTopFullscreenOpaqueOrDimmingWindowState = win; 5327 } 5328 } 5329 if (mTopDockedOpaqueWindowState == null) { 5330 mTopDockedOpaqueWindowState = win; 5331 if (mTopDockedOpaqueOrDimmingWindowState == null) { 5332 mTopDockedOpaqueOrDimmingWindowState = win; 5333 } 5334 } 5335 } 5336 5337 // Keep track of the window if it's dimming but not necessarily fullscreen. 5338 if (mTopFullscreenOpaqueOrDimmingWindowState == null && visible 5339 && win.isDimming() && StackId.normallyFullscreenWindows(stackId)) { 5340 mTopFullscreenOpaqueOrDimmingWindowState = win; 5341 } 5342 5343 // We need to keep track of the top "fullscreen" opaque window for the docked stack 5344 // separately, because both the "real fullscreen" opaque window and the one for the docked 5345 // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR. 5346 if (mTopDockedOpaqueWindowState == null && visible && appWindow && attached == null 5347 && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) { 5348 mTopDockedOpaqueWindowState = win; 5349 if (mTopDockedOpaqueOrDimmingWindowState == null) { 5350 mTopDockedOpaqueOrDimmingWindowState = win; 5351 } 5352 } 5353 5354 // Also keep track of any windows that are dimming but not necessarily fullscreen in the 5355 // docked stack. 5356 if (mTopDockedOpaqueOrDimmingWindowState == null && visible && win.isDimming() 5357 && stackId == DOCKED_STACK_ID) { 5358 mTopDockedOpaqueOrDimmingWindowState = win; 5359 } 5360 } 5361 5362 private void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget) { 5363 if (canBeHiddenByKeyguardLw(win)) { 5364 if (shouldBeHiddenByKeyguard(win, imeTarget)) { 5365 win.hideLw(false /* doAnimation */); 5366 } else { 5367 win.showLw(false /* doAnimation */); 5368 } 5369 } 5370 } 5371 5372 private boolean isFullscreen(WindowManager.LayoutParams attrs) { 5373 return attrs.x == 0 && attrs.y == 0 5374 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT 5375 && attrs.height == WindowManager.LayoutParams.MATCH_PARENT; 5376 } 5377 5378 /** {@inheritDoc} */ 5379 @Override 5380 public int finishPostLayoutPolicyLw() { 5381 int changes = 0; 5382 boolean topIsFullscreen = false; 5383 5384 final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null) 5385 ? mTopFullscreenOpaqueWindowState.getAttrs() 5386 : null; 5387 5388 // If we are not currently showing a dream then remember the current 5389 // lockscreen state. We will use this to determine whether the dream 5390 // started while the lockscreen was showing and remember this state 5391 // while the dream is showing. 5392 if (!mShowingDream) { 5393 mDreamingLockscreen = isKeyguardShowingAndNotOccluded(); 5394 if (mDreamingSleepTokenNeeded) { 5395 mDreamingSleepTokenNeeded = false; 5396 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget(); 5397 } 5398 } else { 5399 if (!mDreamingSleepTokenNeeded) { 5400 mDreamingSleepTokenNeeded = true; 5401 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 1, 1).sendToTarget(); 5402 } 5403 } 5404 5405 if (mStatusBar != null) { 5406 if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar 5407 + " forcefkg=" + mForceStatusBarFromKeyguard 5408 + " top=" + mTopFullscreenOpaqueWindowState); 5409 boolean shouldBeTransparent = mForceStatusBarTransparent 5410 && !mForceStatusBar 5411 && !mForceStatusBarFromKeyguard; 5412 if (!shouldBeTransparent) { 5413 mStatusBarController.setShowTransparent(false /* transparent */); 5414 } else if (!mStatusBar.isVisibleLw()) { 5415 mStatusBarController.setShowTransparent(true /* transparent */); 5416 } 5417 5418 WindowManager.LayoutParams statusBarAttrs = mStatusBar.getAttrs(); 5419 boolean statusBarExpanded = statusBarAttrs.height == MATCH_PARENT 5420 && statusBarAttrs.width == MATCH_PARENT; 5421 if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent 5422 || statusBarExpanded) { 5423 if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced"); 5424 if (mStatusBarController.setBarShowingLw(true)) { 5425 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5426 } 5427 // Maintain fullscreen layout until incoming animation is complete. 5428 topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw(); 5429 // Transient status bar on the lockscreen is not allowed 5430 if ((mForceStatusBarFromKeyguard || statusBarExpanded) 5431 && mStatusBarController.isTransientShowing()) { 5432 mStatusBarController.updateVisibilityLw(false /*transientAllowed*/, 5433 mLastSystemUiFlags, mLastSystemUiFlags); 5434 } 5435 if (statusBarExpanded && mNavigationBar != null) { 5436 if (mNavigationBarController.setBarShowingLw(true)) { 5437 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5438 } 5439 } 5440 } else if (mTopFullscreenOpaqueWindowState != null) { 5441 final int fl = PolicyControl.getWindowFlags(null, lp); 5442 if (localLOGV) { 5443 Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() 5444 + " shown position: " 5445 + mTopFullscreenOpaqueWindowState.getShownPositionLw()); 5446 Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs() 5447 + " lp.flags=0x" + Integer.toHexString(fl)); 5448 } 5449 topIsFullscreen = (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0 5450 || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 5451 // The subtle difference between the window for mTopFullscreenOpaqueWindowState 5452 // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window 5453 // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the 5454 // case though. 5455 if (mStatusBarController.isTransientShowing()) { 5456 if (mStatusBarController.setBarShowingLw(true)) { 5457 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5458 } 5459 } else if (topIsFullscreen 5460 && !mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID) 5461 && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID)) { 5462 if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar"); 5463 if (mStatusBarController.setBarShowingLw(false)) { 5464 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5465 } else { 5466 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding"); 5467 } 5468 } else { 5469 if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen"); 5470 if (mStatusBarController.setBarShowingLw(true)) { 5471 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5472 } 5473 } 5474 } 5475 } 5476 5477 if (mTopIsFullscreen != topIsFullscreen) { 5478 if (!topIsFullscreen) { 5479 // Force another layout when status bar becomes fully shown. 5480 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5481 } 5482 mTopIsFullscreen = topIsFullscreen; 5483 } 5484 5485 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5486 // If the navigation bar has been hidden or shown, we need to do another 5487 // layout pass to update that window. 5488 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5489 } 5490 5491 if (mShowingDream != mLastShowingDream) { 5492 mLastShowingDream = mShowingDream; 5493 mWindowManagerFuncs.notifyShowingDreamChanged(); 5494 } 5495 5496 // update since mAllowLockscreenWhenOn might have changed 5497 updateLockScreenTimeout(); 5498 return changes; 5499 } 5500 5501 /** 5502 * Updates the occluded state of the Keyguard. 5503 * 5504 * @return Whether the flags have changed and we have to redo the layout. 5505 */ 5506 private boolean setKeyguardOccludedLw(boolean isOccluded, boolean force) { 5507 if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded); 5508 final boolean wasOccluded = mKeyguardOccluded; 5509 final boolean showing = mKeyguardDelegate.isShowing(); 5510 final boolean changed = wasOccluded != isOccluded || force; 5511 if (!isOccluded && changed && showing) { 5512 mKeyguardOccluded = false; 5513 mKeyguardDelegate.setOccluded(false, true /* animate */); 5514 if (mStatusBar != null) { 5515 mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD; 5516 if (!mKeyguardDelegate.hasLockscreenWallpaper()) { 5517 mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER; 5518 } 5519 } 5520 return true; 5521 } else if (isOccluded && changed && showing) { 5522 mKeyguardOccluded = true; 5523 mKeyguardDelegate.setOccluded(true, false /* animate */); 5524 if (mStatusBar != null) { 5525 mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD; 5526 mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER; 5527 } 5528 return true; 5529 } else if (changed) { 5530 mKeyguardOccluded = isOccluded; 5531 mKeyguardDelegate.setOccluded(isOccluded, false /* animate */); 5532 return false; 5533 } else { 5534 return false; 5535 } 5536 } 5537 5538 private boolean isStatusBarKeyguard() { 5539 return mStatusBar != null 5540 && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; 5541 } 5542 5543 @Override 5544 public boolean allowAppAnimationsLw() { 5545 if (mShowingDream) { 5546 // If keyguard or dreams is currently visible, no reason to animate behind it. 5547 return false; 5548 } 5549 return true; 5550 } 5551 5552 @Override 5553 public int focusChangedLw(WindowState lastFocus, WindowState newFocus) { 5554 mFocusedWindow = newFocus; 5555 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5556 // If the navigation bar has been hidden or shown, we need to do another 5557 // layout pass to update that window. 5558 return FINISH_LAYOUT_REDO_LAYOUT; 5559 } 5560 return 0; 5561 } 5562 5563 /** {@inheritDoc} */ 5564 @Override 5565 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { 5566 // lid changed state 5567 final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED; 5568 if (newLidState == mLidState) { 5569 return; 5570 } 5571 5572 mLidState = newLidState; 5573 applyLidSwitchState(); 5574 updateRotation(true); 5575 5576 if (lidOpen) { 5577 wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch, 5578 "android.policy:LID"); 5579 } else if (!mLidControlsSleep) { 5580 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 5581 } 5582 } 5583 5584 @Override 5585 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) { 5586 int lensCoverState = lensCovered ? CAMERA_LENS_COVERED : CAMERA_LENS_UNCOVERED; 5587 if (mCameraLensCoverState == lensCoverState) { 5588 return; 5589 } 5590 if (mCameraLensCoverState == CAMERA_LENS_COVERED && 5591 lensCoverState == CAMERA_LENS_UNCOVERED) { 5592 Intent intent; 5593 final boolean keyguardActive = mKeyguardDelegate == null ? false : 5594 mKeyguardDelegate.isShowing(); 5595 if (keyguardActive) { 5596 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); 5597 } else { 5598 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); 5599 } 5600 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens, 5601 "android.policy:CAMERA_COVER"); 5602 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 5603 } 5604 mCameraLensCoverState = lensCoverState; 5605 } 5606 5607 void setHdmiPlugged(boolean plugged) { 5608 if (mHdmiPlugged != plugged) { 5609 mHdmiPlugged = plugged; 5610 updateRotation(true, true); 5611 Intent intent = new Intent(ACTION_HDMI_PLUGGED); 5612 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 5613 intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged); 5614 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 5615 } 5616 } 5617 5618 void initializeHdmiState() { 5619 boolean plugged = false; 5620 // watch for HDMI plug messages if the hdmi switch exists 5621 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) { 5622 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi"); 5623 5624 final String filename = "/sys/class/switch/hdmi/state"; 5625 FileReader reader = null; 5626 try { 5627 reader = new FileReader(filename); 5628 char[] buf = new char[15]; 5629 int n = reader.read(buf); 5630 if (n > 1) { 5631 plugged = 0 != Integer.parseInt(new String(buf, 0, n-1)); 5632 } 5633 } catch (IOException ex) { 5634 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5635 } catch (NumberFormatException ex) { 5636 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5637 } finally { 5638 if (reader != null) { 5639 try { 5640 reader.close(); 5641 } catch (IOException ex) { 5642 } 5643 } 5644 } 5645 } 5646 // This dance forces the code in setHdmiPlugged to run. 5647 // Always do this so the sticky intent is stuck (to false) if there is no hdmi. 5648 mHdmiPlugged = !plugged; 5649 setHdmiPlugged(!mHdmiPlugged); 5650 } 5651 5652 final Object mScreenshotLock = new Object(); 5653 ServiceConnection mScreenshotConnection = null; 5654 5655 final Runnable mScreenshotTimeout = new Runnable() { 5656 @Override public void run() { 5657 synchronized (mScreenshotLock) { 5658 if (mScreenshotConnection != null) { 5659 mContext.unbindService(mScreenshotConnection); 5660 mScreenshotConnection = null; 5661 notifyScreenshotError(); 5662 } 5663 } 5664 } 5665 }; 5666 5667 // Assume this is called from the Handler thread. 5668 private void takeScreenshot(final int screenshotType) { 5669 synchronized (mScreenshotLock) { 5670 if (mScreenshotConnection != null) { 5671 return; 5672 } 5673 final ComponentName serviceComponent = new ComponentName(SYSUI_PACKAGE, 5674 SYSUI_SCREENSHOT_SERVICE); 5675 final Intent serviceIntent = new Intent(); 5676 serviceIntent.setComponent(serviceComponent); 5677 ServiceConnection conn = new ServiceConnection() { 5678 @Override 5679 public void onServiceConnected(ComponentName name, IBinder service) { 5680 synchronized (mScreenshotLock) { 5681 if (mScreenshotConnection != this) { 5682 return; 5683 } 5684 Messenger messenger = new Messenger(service); 5685 Message msg = Message.obtain(null, screenshotType); 5686 final ServiceConnection myConn = this; 5687 Handler h = new Handler(mHandler.getLooper()) { 5688 @Override 5689 public void handleMessage(Message msg) { 5690 synchronized (mScreenshotLock) { 5691 if (mScreenshotConnection == myConn) { 5692 mContext.unbindService(mScreenshotConnection); 5693 mScreenshotConnection = null; 5694 mHandler.removeCallbacks(mScreenshotTimeout); 5695 } 5696 } 5697 } 5698 }; 5699 msg.replyTo = new Messenger(h); 5700 msg.arg1 = msg.arg2 = 0; 5701 if (mStatusBar != null && mStatusBar.isVisibleLw()) 5702 msg.arg1 = 1; 5703 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) 5704 msg.arg2 = 1; 5705 try { 5706 messenger.send(msg); 5707 } catch (RemoteException e) { 5708 } 5709 } 5710 } 5711 5712 @Override 5713 public void onServiceDisconnected(ComponentName name) { 5714 synchronized (mScreenshotLock) { 5715 if (mScreenshotConnection != null) { 5716 mContext.unbindService(mScreenshotConnection); 5717 mScreenshotConnection = null; 5718 mHandler.removeCallbacks(mScreenshotTimeout); 5719 notifyScreenshotError(); 5720 } 5721 } 5722 } 5723 }; 5724 if (mContext.bindServiceAsUser(serviceIntent, conn, 5725 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, 5726 UserHandle.CURRENT)) { 5727 mScreenshotConnection = conn; 5728 mHandler.postDelayed(mScreenshotTimeout, 10000); 5729 } 5730 } 5731 } 5732 5733 /** 5734 * Notifies the screenshot service to show an error. 5735 */ 5736 private void notifyScreenshotError() { 5737 // If the service process is killed, then ask it to clean up after itself 5738 final ComponentName errorComponent = new ComponentName(SYSUI_PACKAGE, 5739 SYSUI_SCREENSHOT_ERROR_RECEIVER); 5740 Intent errorIntent = new Intent(Intent.ACTION_USER_PRESENT); 5741 errorIntent.setComponent(errorComponent); 5742 errorIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | 5743 Intent.FLAG_RECEIVER_FOREGROUND); 5744 mContext.sendBroadcastAsUser(errorIntent, UserHandle.CURRENT); 5745 } 5746 5747 /** {@inheritDoc} */ 5748 @Override 5749 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { 5750 if (!mSystemBooted) { 5751 // If we have not yet booted, don't let key events do anything. 5752 return 0; 5753 } 5754 5755 final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; 5756 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 5757 final boolean canceled = event.isCanceled(); 5758 final int keyCode = event.getKeyCode(); 5759 5760 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0; 5761 5762 // If screen is off then we treat the case where the keyguard is open but hidden 5763 // the same as if it were open and in front. 5764 // This will prevent any keys other than the power button from waking the screen 5765 // when the keyguard is hidden by another activity. 5766 final boolean keyguardActive = (mKeyguardDelegate == null ? false : 5767 (interactive ? 5768 isKeyguardShowingAndNotOccluded() : 5769 mKeyguardDelegate.isShowing())); 5770 5771 if (DEBUG_INPUT) { 5772 Log.d(TAG, "interceptKeyTq keycode=" + keyCode 5773 + " interactive=" + interactive + " keyguardActive=" + keyguardActive 5774 + " policyFlags=" + Integer.toHexString(policyFlags)); 5775 } 5776 5777 // Basic policy based on interactive state. 5778 int result; 5779 boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 5780 || event.isWakeKey(); 5781 if (interactive || (isInjected && !isWakeKey)) { 5782 // When the device is interactive or the key is injected pass the 5783 // key to the application. 5784 result = ACTION_PASS_TO_USER; 5785 isWakeKey = false; 5786 5787 if (interactive) { 5788 // If the screen is awake, but the button pressed was the one that woke the device 5789 // then don't pass it to the application 5790 if (keyCode == mPendingWakeKey && !down) { 5791 result = 0; 5792 } 5793 // Reset the pending key 5794 mPendingWakeKey = PENDING_KEY_NULL; 5795 } 5796 } else if (!interactive && shouldDispatchInputWhenNonInteractive(event)) { 5797 // If we're currently dozing with the screen on and the keyguard showing, pass the key 5798 // to the application but preserve its wake key status to make sure we still move 5799 // from dozing to fully interactive if we would normally go from off to fully 5800 // interactive. 5801 result = ACTION_PASS_TO_USER; 5802 // Since we're dispatching the input, reset the pending key 5803 mPendingWakeKey = PENDING_KEY_NULL; 5804 } else { 5805 // When the screen is off and the key is not injected, determine whether 5806 // to wake the device but don't pass the key to the application. 5807 result = 0; 5808 if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) { 5809 isWakeKey = false; 5810 } 5811 // Cache the wake key on down event so we can also avoid sending the up event to the app 5812 if (isWakeKey && down) { 5813 mPendingWakeKey = keyCode; 5814 } 5815 } 5816 5817 // If the key would be handled globally, just return the result, don't worry about special 5818 // key processing. 5819 if (isValidGlobalKey(keyCode) 5820 && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) { 5821 if (isWakeKey) { 5822 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 5823 } 5824 return result; 5825 } 5826 5827 boolean useHapticFeedback = down 5828 && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0 5829 && event.getRepeatCount() == 0; 5830 5831 // Handle special keys. 5832 switch (keyCode) { 5833 case KeyEvent.KEYCODE_BACK: { 5834 if (down) { 5835 interceptBackKeyDown(); 5836 } else { 5837 boolean handled = interceptBackKeyUp(event); 5838 5839 // Don't pass back press to app if we've already handled it via long press 5840 if (handled) { 5841 result &= ~ACTION_PASS_TO_USER; 5842 } 5843 } 5844 break; 5845 } 5846 5847 case KeyEvent.KEYCODE_VOLUME_DOWN: 5848 case KeyEvent.KEYCODE_VOLUME_UP: 5849 case KeyEvent.KEYCODE_VOLUME_MUTE: { 5850 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 5851 if (down) { 5852 if (interactive && !mScreenshotChordVolumeDownKeyTriggered 5853 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5854 mScreenshotChordVolumeDownKeyTriggered = true; 5855 mScreenshotChordVolumeDownKeyTime = event.getDownTime(); 5856 mScreenshotChordVolumeDownKeyConsumed = false; 5857 cancelPendingPowerKeyAction(); 5858 interceptScreenshotChord(); 5859 interceptAccessibilityShortcutChord(); 5860 } 5861 } else { 5862 mScreenshotChordVolumeDownKeyTriggered = false; 5863 cancelPendingScreenshotChordAction(); 5864 cancelPendingAccessibilityShortcutAction(); 5865 } 5866 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 5867 if (down) { 5868 if (interactive && !mA11yShortcutChordVolumeUpKeyTriggered 5869 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5870 mA11yShortcutChordVolumeUpKeyTriggered = true; 5871 mA11yShortcutChordVolumeUpKeyTime = event.getDownTime(); 5872 mA11yShortcutChordVolumeUpKeyConsumed = false; 5873 cancelPendingPowerKeyAction(); 5874 cancelPendingScreenshotChordAction(); 5875 interceptAccessibilityShortcutChord(); 5876 } 5877 } else { 5878 mA11yShortcutChordVolumeUpKeyTriggered = false; 5879 cancelPendingScreenshotChordAction(); 5880 cancelPendingAccessibilityShortcutAction(); 5881 } 5882 } 5883 if (down) { 5884 TelecomManager telecomManager = getTelecommService(); 5885 if (telecomManager != null) { 5886 if (telecomManager.isRinging()) { 5887 // If an incoming call is ringing, either VOLUME key means 5888 // "silence ringer". We handle these keys here, rather than 5889 // in the InCallScreen, to make sure we'll respond to them 5890 // even if the InCallScreen hasn't come to the foreground yet. 5891 // Look for the DOWN event here, to agree with the "fallback" 5892 // behavior in the InCallScreen. 5893 Log.i(TAG, "interceptKeyBeforeQueueing:" 5894 + " VOLUME key-down while ringing: Silence ringer!"); 5895 5896 // Silence the ringer. (It's safe to call this 5897 // even if the ringer has already been silenced.) 5898 telecomManager.silenceRinger(); 5899 5900 // And *don't* pass this key thru to the current activity 5901 // (which is probably the InCallScreen.) 5902 result &= ~ACTION_PASS_TO_USER; 5903 break; 5904 } 5905 if (telecomManager.isInCall() 5906 && (result & ACTION_PASS_TO_USER) == 0) { 5907 // If we are in call but we decided not to pass the key to 5908 // the application, just pass it to the session service. 5909 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 5910 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false); 5911 break; 5912 } 5913 } 5914 } 5915 if (mUseTvRouting) { 5916 // On TVs, defer special key handlings to 5917 // {@link interceptKeyBeforeDispatching()}. 5918 result |= ACTION_PASS_TO_USER; 5919 } else if ((result & ACTION_PASS_TO_USER) == 0) { 5920 // If we aren't passing to the user and no one else 5921 // handled it send it to the session manager to 5922 // figure out. 5923 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 5924 event, AudioManager.USE_DEFAULT_STREAM_TYPE, true); 5925 } 5926 break; 5927 } 5928 5929 case KeyEvent.KEYCODE_ENDCALL: { 5930 result &= ~ACTION_PASS_TO_USER; 5931 if (down) { 5932 TelecomManager telecomManager = getTelecommService(); 5933 boolean hungUp = false; 5934 if (telecomManager != null) { 5935 hungUp = telecomManager.endCall(); 5936 } 5937 if (interactive && !hungUp) { 5938 mEndCallKeyHandled = false; 5939 mHandler.postDelayed(mEndCallLongPress, 5940 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 5941 } else { 5942 mEndCallKeyHandled = true; 5943 } 5944 } else { 5945 if (!mEndCallKeyHandled) { 5946 mHandler.removeCallbacks(mEndCallLongPress); 5947 if (!canceled) { 5948 if ((mEndcallBehavior 5949 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) { 5950 if (goHome()) { 5951 break; 5952 } 5953 } 5954 if ((mEndcallBehavior 5955 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { 5956 mPowerManager.goToSleep(event.getEventTime(), 5957 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); 5958 isWakeKey = false; 5959 } 5960 } 5961 } 5962 } 5963 break; 5964 } 5965 5966 case KeyEvent.KEYCODE_POWER: { 5967 // Any activity on the power button stops the accessibility shortcut 5968 cancelPendingAccessibilityShortcutAction(); 5969 result &= ~ACTION_PASS_TO_USER; 5970 isWakeKey = false; // wake-up will be handled separately 5971 if (down) { 5972 interceptPowerKeyDown(event, interactive); 5973 } else { 5974 interceptPowerKeyUp(event, interactive, canceled); 5975 } 5976 break; 5977 } 5978 5979 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN: 5980 // fall through 5981 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP: 5982 // fall through 5983 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT: 5984 // fall through 5985 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: { 5986 result &= ~ACTION_PASS_TO_USER; 5987 interceptSystemNavigationKey(event); 5988 break; 5989 } 5990 5991 case KeyEvent.KEYCODE_SLEEP: { 5992 result &= ~ACTION_PASS_TO_USER; 5993 isWakeKey = false; 5994 if (!mPowerManager.isInteractive()) { 5995 useHapticFeedback = false; // suppress feedback if already non-interactive 5996 } 5997 if (down) { 5998 sleepPress(event.getEventTime()); 5999 } else { 6000 sleepRelease(event.getEventTime()); 6001 } 6002 break; 6003 } 6004 6005 case KeyEvent.KEYCODE_SOFT_SLEEP: { 6006 result &= ~ACTION_PASS_TO_USER; 6007 isWakeKey = false; 6008 if (!down) { 6009 mPowerManagerInternal.setUserInactiveOverrideFromWindowManager(); 6010 } 6011 break; 6012 } 6013 6014 case KeyEvent.KEYCODE_WAKEUP: { 6015 result &= ~ACTION_PASS_TO_USER; 6016 isWakeKey = true; 6017 break; 6018 } 6019 6020 case KeyEvent.KEYCODE_MEDIA_PLAY: 6021 case KeyEvent.KEYCODE_MEDIA_PAUSE: 6022 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 6023 case KeyEvent.KEYCODE_HEADSETHOOK: 6024 case KeyEvent.KEYCODE_MUTE: 6025 case KeyEvent.KEYCODE_MEDIA_STOP: 6026 case KeyEvent.KEYCODE_MEDIA_NEXT: 6027 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 6028 case KeyEvent.KEYCODE_MEDIA_REWIND: 6029 case KeyEvent.KEYCODE_MEDIA_RECORD: 6030 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 6031 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { 6032 if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) { 6033 // If the global session is active pass all media keys to it 6034 // instead of the active window. 6035 result &= ~ACTION_PASS_TO_USER; 6036 } 6037 if ((result & ACTION_PASS_TO_USER) == 0) { 6038 // Only do this if we would otherwise not pass it to the user. In that 6039 // case, the PhoneWindow class will do the same thing, except it will 6040 // only do it if the showing app doesn't process the key on its own. 6041 // Note that we need to make a copy of the key event here because the 6042 // original key event will be recycled when we return. 6043 mBroadcastWakeLock.acquire(); 6044 Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK, 6045 new KeyEvent(event)); 6046 msg.setAsynchronous(true); 6047 msg.sendToTarget(); 6048 } 6049 break; 6050 } 6051 6052 case KeyEvent.KEYCODE_CALL: { 6053 if (down) { 6054 TelecomManager telecomManager = getTelecommService(); 6055 if (telecomManager != null) { 6056 if (telecomManager.isRinging()) { 6057 Log.i(TAG, "interceptKeyBeforeQueueing:" 6058 + " CALL key-down while ringing: Answer the call!"); 6059 telecomManager.acceptRingingCall(); 6060 6061 // And *don't* pass this key thru to the current activity 6062 // (which is presumably the InCallScreen.) 6063 result &= ~ACTION_PASS_TO_USER; 6064 } 6065 } 6066 } 6067 break; 6068 } 6069 case KeyEvent.KEYCODE_VOICE_ASSIST: { 6070 // Only do this if we would otherwise not pass it to the user. In that case, 6071 // interceptKeyBeforeDispatching would apply a similar but different policy in 6072 // order to invoke voice assist actions. Note that we need to make a copy of the 6073 // key event here because the original key event will be recycled when we return. 6074 if ((result & ACTION_PASS_TO_USER) == 0 && !down) { 6075 mBroadcastWakeLock.acquire(); 6076 Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK, 6077 keyguardActive ? 1 : 0, 0); 6078 msg.setAsynchronous(true); 6079 msg.sendToTarget(); 6080 } 6081 break; 6082 } 6083 case KeyEvent.KEYCODE_WINDOW: { 6084 if (mShortPressWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) { 6085 if (mPictureInPictureVisible) { 6086 // Consumes the key only if picture-in-picture is visible to show 6087 // picture-in-picture control menu. This gives a chance to the foreground 6088 // activity to customize PIP key behavior. 6089 if (!down) { 6090 showPictureInPictureMenu(event); 6091 } 6092 result &= ~ACTION_PASS_TO_USER; 6093 } 6094 } 6095 break; 6096 } 6097 } 6098 6099 if (useHapticFeedback) { 6100 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); 6101 } 6102 6103 if (isWakeKey) { 6104 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 6105 } 6106 6107 return result; 6108 } 6109 6110 /** 6111 * Handle statusbar expansion events. 6112 * @param event 6113 */ 6114 private void interceptSystemNavigationKey(KeyEvent event) { 6115 if (event.getAction() == KeyEvent.ACTION_UP) { 6116 if (!mAccessibilityManager.isEnabled() 6117 || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) { 6118 if (areSystemNavigationKeysEnabled()) { 6119 IStatusBarService sbar = getStatusBarService(); 6120 if (sbar != null) { 6121 try { 6122 sbar.handleSystemNavigationKey(event.getKeyCode()); 6123 } catch (RemoteException e1) { 6124 // oops, no statusbar. Ignore event. 6125 } 6126 } 6127 } 6128 } 6129 } 6130 } 6131 6132 /** 6133 * Returns true if the key can have global actions attached to it. 6134 * We reserve all power management keys for the system since they require 6135 * very careful handling. 6136 */ 6137 private static boolean isValidGlobalKey(int keyCode) { 6138 switch (keyCode) { 6139 case KeyEvent.KEYCODE_POWER: 6140 case KeyEvent.KEYCODE_WAKEUP: 6141 case KeyEvent.KEYCODE_SLEEP: 6142 return false; 6143 default: 6144 return true; 6145 } 6146 } 6147 6148 /** 6149 * When the screen is off we ignore some keys that might otherwise typically 6150 * be considered wake keys. We filter them out here. 6151 * 6152 * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it 6153 * is always considered a wake key. 6154 */ 6155 private boolean isWakeKeyWhenScreenOff(int keyCode) { 6156 switch (keyCode) { 6157 // ignore volume keys unless docked 6158 case KeyEvent.KEYCODE_VOLUME_UP: 6159 case KeyEvent.KEYCODE_VOLUME_DOWN: 6160 case KeyEvent.KEYCODE_VOLUME_MUTE: 6161 return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED; 6162 6163 // ignore media and camera keys 6164 case KeyEvent.KEYCODE_MUTE: 6165 case KeyEvent.KEYCODE_HEADSETHOOK: 6166 case KeyEvent.KEYCODE_MEDIA_PLAY: 6167 case KeyEvent.KEYCODE_MEDIA_PAUSE: 6168 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 6169 case KeyEvent.KEYCODE_MEDIA_STOP: 6170 case KeyEvent.KEYCODE_MEDIA_NEXT: 6171 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 6172 case KeyEvent.KEYCODE_MEDIA_REWIND: 6173 case KeyEvent.KEYCODE_MEDIA_RECORD: 6174 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 6175 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: 6176 case KeyEvent.KEYCODE_CAMERA: 6177 return false; 6178 } 6179 return true; 6180 } 6181 6182 6183 /** {@inheritDoc} */ 6184 @Override 6185 public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) { 6186 if ((policyFlags & FLAG_WAKE) != 0) { 6187 if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion, 6188 "android.policy:MOTION")) { 6189 return 0; 6190 } 6191 } 6192 6193 if (shouldDispatchInputWhenNonInteractive(null)) { 6194 return ACTION_PASS_TO_USER; 6195 } 6196 6197 // If we have not passed the action up and we are in theater mode without dreaming, 6198 // there will be no dream to intercept the touch and wake into ambient. The device should 6199 // wake up in this case. 6200 if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) { 6201 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming, 6202 "android.policy:MOTION"); 6203 } 6204 6205 return 0; 6206 } 6207 6208 private boolean shouldDispatchInputWhenNonInteractive(KeyEvent event) { 6209 final boolean displayOff = (mDisplay == null || mDisplay.getState() == Display.STATE_OFF); 6210 6211 if (displayOff && !mHasFeatureWatch) { 6212 return false; 6213 } 6214 6215 // Send events to keyguard while the screen is on and it's showing. 6216 if (isKeyguardShowingAndNotOccluded() && !displayOff) { 6217 return true; 6218 } 6219 6220 // Watches handle BACK specially 6221 if (mHasFeatureWatch 6222 && event != null 6223 && (event.getKeyCode() == KeyEvent.KEYCODE_BACK 6224 || event.getKeyCode() == KeyEvent.KEYCODE_STEM_PRIMARY)) { 6225 return false; 6226 } 6227 6228 // Send events to a dozing dream even if the screen is off since the dream 6229 // is in control of the state of the screen. 6230 IDreamManager dreamManager = getDreamManager(); 6231 6232 try { 6233 if (dreamManager != null && dreamManager.isDreaming()) { 6234 return true; 6235 } 6236 } catch (RemoteException e) { 6237 Slog.e(TAG, "RemoteException when checking if dreaming", e); 6238 } 6239 6240 // Otherwise, consume events since the user can't see what is being 6241 // interacted with. 6242 return false; 6243 } 6244 6245 private void dispatchDirectAudioEvent(KeyEvent event) { 6246 if (event.getAction() != KeyEvent.ACTION_DOWN) { 6247 return; 6248 } 6249 int keyCode = event.getKeyCode(); 6250 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 6251 | AudioManager.FLAG_FROM_KEY; 6252 String pkgName = mContext.getOpPackageName(); 6253 switch (keyCode) { 6254 case KeyEvent.KEYCODE_VOLUME_UP: 6255 try { 6256 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 6257 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6258 } catch (RemoteException e) { 6259 Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e); 6260 } 6261 break; 6262 case KeyEvent.KEYCODE_VOLUME_DOWN: 6263 try { 6264 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 6265 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6266 } catch (RemoteException e) { 6267 Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e); 6268 } 6269 break; 6270 case KeyEvent.KEYCODE_VOLUME_MUTE: 6271 try { 6272 if (event.getRepeatCount() == 0) { 6273 getAudioService().adjustSuggestedStreamVolume( 6274 AudioManager.ADJUST_TOGGLE_MUTE, 6275 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6276 } 6277 } catch (RemoteException e) { 6278 Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e); 6279 } 6280 break; 6281 } 6282 } 6283 6284 void dispatchMediaKeyWithWakeLock(KeyEvent event) { 6285 if (DEBUG_INPUT) { 6286 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event); 6287 } 6288 6289 if (mHavePendingMediaKeyRepeatWithWakeLock) { 6290 if (DEBUG_INPUT) { 6291 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat"); 6292 } 6293 6294 mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK); 6295 mHavePendingMediaKeyRepeatWithWakeLock = false; 6296 mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock 6297 } 6298 6299 dispatchMediaKeyWithWakeLockToAudioService(event); 6300 6301 if (event.getAction() == KeyEvent.ACTION_DOWN 6302 && event.getRepeatCount() == 0) { 6303 mHavePendingMediaKeyRepeatWithWakeLock = true; 6304 6305 Message msg = mHandler.obtainMessage( 6306 MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event); 6307 msg.setAsynchronous(true); 6308 mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout()); 6309 } else { 6310 mBroadcastWakeLock.release(); 6311 } 6312 } 6313 6314 void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) { 6315 mHavePendingMediaKeyRepeatWithWakeLock = false; 6316 6317 KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event, 6318 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS); 6319 if (DEBUG_INPUT) { 6320 Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent); 6321 } 6322 6323 dispatchMediaKeyWithWakeLockToAudioService(repeatEvent); 6324 mBroadcastWakeLock.release(); 6325 } 6326 6327 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) { 6328 if (mActivityManagerInternal.isSystemReady()) { 6329 MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true); 6330 } 6331 } 6332 6333 void launchVoiceAssistWithWakeLock(boolean keyguardActive) { 6334 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface( 6335 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 6336 if (dic != null) { 6337 try { 6338 dic.exitIdle("voice-search"); 6339 } catch (RemoteException e) { 6340 } 6341 } 6342 Intent voiceIntent = 6343 new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 6344 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive); 6345 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 6346 mBroadcastWakeLock.release(); 6347 } 6348 6349 BroadcastReceiver mDockReceiver = new BroadcastReceiver() { 6350 @Override 6351 public void onReceive(Context context, Intent intent) { 6352 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 6353 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 6354 Intent.EXTRA_DOCK_STATE_UNDOCKED); 6355 } else { 6356 try { 6357 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface( 6358 ServiceManager.getService(Context.UI_MODE_SERVICE)); 6359 mUiMode = uiModeService.getCurrentModeType(); 6360 } catch (RemoteException e) { 6361 } 6362 } 6363 updateRotation(true); 6364 synchronized (mLock) { 6365 updateOrientationListenerLp(); 6366 } 6367 } 6368 }; 6369 6370 BroadcastReceiver mDreamReceiver = new BroadcastReceiver() { 6371 @Override 6372 public void onReceive(Context context, Intent intent) { 6373 if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) { 6374 if (mKeyguardDelegate != null) { 6375 mKeyguardDelegate.onDreamingStarted(); 6376 } 6377 } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) { 6378 if (mKeyguardDelegate != null) { 6379 mKeyguardDelegate.onDreamingStopped(); 6380 } 6381 } 6382 } 6383 }; 6384 6385 BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() { 6386 @Override 6387 public void onReceive(Context context, Intent intent) { 6388 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 6389 // tickle the settings observer: this first ensures that we're 6390 // observing the relevant settings for the newly-active user, 6391 // and then updates our own bookkeeping based on the now- 6392 // current user. 6393 mSettingsObserver.onChange(false); 6394 6395 // force a re-application of focused window sysui visibility. 6396 // the window may never have been shown for this user 6397 // e.g. the keyguard when going through the new-user setup flow 6398 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6399 mLastSystemUiFlags = 0; 6400 updateSystemUiVisibilityLw(); 6401 } 6402 } 6403 } 6404 }; 6405 6406 private final Runnable mHiddenNavPanic = new Runnable() { 6407 @Override 6408 public void run() { 6409 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6410 if (!isUserSetupComplete()) { 6411 // Swipe-up for navigation bar is disabled during setup 6412 return; 6413 } 6414 mPendingPanicGestureUptime = SystemClock.uptimeMillis(); 6415 if (!isNavBarEmpty(mLastSystemUiFlags)) { 6416 mNavigationBarController.showTransient(); 6417 } 6418 } 6419 } 6420 }; 6421 6422 private void requestTransientBars(WindowState swipeTarget) { 6423 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6424 if (!isUserSetupComplete()) { 6425 // Swipe-up for navigation bar is disabled during setup 6426 return; 6427 } 6428 boolean sb = mStatusBarController.checkShowTransientBarLw(); 6429 boolean nb = mNavigationBarController.checkShowTransientBarLw() 6430 && !isNavBarEmpty(mLastSystemUiFlags); 6431 if (sb || nb) { 6432 // Don't show status bar when swiping on already visible navigation bar 6433 if (!nb && swipeTarget == mNavigationBar) { 6434 if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target"); 6435 return; 6436 } 6437 if (sb) mStatusBarController.showTransient(); 6438 if (nb) mNavigationBarController.showTransient(); 6439 mImmersiveModeConfirmation.confirmCurrentPrompt(); 6440 updateSystemUiVisibilityLw(); 6441 } 6442 } 6443 } 6444 6445 // Called on the PowerManager's Notifier thread. 6446 @Override 6447 public void startedGoingToSleep(int why) { 6448 if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")"); 6449 mCameraGestureTriggeredDuringGoingToSleep = false; 6450 mGoingToSleep = true; 6451 if (mKeyguardDelegate != null) { 6452 mKeyguardDelegate.onStartedGoingToSleep(why); 6453 } 6454 } 6455 6456 // Called on the PowerManager's Notifier thread. 6457 @Override 6458 public void finishedGoingToSleep(int why) { 6459 EventLog.writeEvent(70000, 0); 6460 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")"); 6461 MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000); 6462 6463 mGoingToSleep = false; 6464 6465 // We must get this work done here because the power manager will drop 6466 // the wake lock and let the system suspend once this function returns. 6467 synchronized (mLock) { 6468 mAwake = false; 6469 updateWakeGestureListenerLp(); 6470 updateOrientationListenerLp(); 6471 updateLockScreenTimeout(); 6472 } 6473 if (mKeyguardDelegate != null) { 6474 mKeyguardDelegate.onFinishedGoingToSleep(why, 6475 mCameraGestureTriggeredDuringGoingToSleep); 6476 } 6477 mCameraGestureTriggeredDuringGoingToSleep = false; 6478 } 6479 6480 // Called on the PowerManager's Notifier thread. 6481 @Override 6482 public void startedWakingUp() { 6483 EventLog.writeEvent(70000, 1); 6484 if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up..."); 6485 6486 // Since goToSleep performs these functions synchronously, we must 6487 // do the same here. We cannot post this work to a handler because 6488 // that might cause it to become reordered with respect to what 6489 // may happen in a future call to goToSleep. 6490 synchronized (mLock) { 6491 mAwake = true; 6492 6493 updateWakeGestureListenerLp(); 6494 updateOrientationListenerLp(); 6495 updateLockScreenTimeout(); 6496 } 6497 6498 if (mKeyguardDelegate != null) { 6499 mKeyguardDelegate.onStartedWakingUp(); 6500 } 6501 } 6502 6503 // Called on the PowerManager's Notifier thread. 6504 @Override 6505 public void finishedWakingUp() { 6506 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up..."); 6507 } 6508 6509 private void wakeUpFromPowerKey(long eventTime) { 6510 wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER"); 6511 } 6512 6513 private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) { 6514 final boolean theaterModeEnabled = isTheaterModeEnabled(); 6515 if (!wakeInTheaterMode && theaterModeEnabled) { 6516 return false; 6517 } 6518 6519 if (theaterModeEnabled) { 6520 Settings.Global.putInt(mContext.getContentResolver(), 6521 Settings.Global.THEATER_MODE_ON, 0); 6522 } 6523 6524 mPowerManager.wakeUp(wakeTime, reason); 6525 return true; 6526 } 6527 6528 private void finishKeyguardDrawn() { 6529 synchronized (mLock) { 6530 if (!mScreenOnEarly || mKeyguardDrawComplete) { 6531 return; // We are not awake yet or we have already informed of this event. 6532 } 6533 6534 mKeyguardDrawComplete = true; 6535 if (mKeyguardDelegate != null) { 6536 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6537 } 6538 mWindowManagerDrawComplete = false; 6539 } 6540 6541 // ... eventually calls finishWindowsDrawn which will finalize our screen turn on 6542 // as well as enabling the orientation change logic/sensor. 6543 mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, 6544 WAITING_FOR_DRAWN_TIMEOUT); 6545 } 6546 6547 // Called on the DisplayManager's DisplayPowerController thread. 6548 @Override 6549 public void screenTurnedOff() { 6550 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off..."); 6551 6552 updateScreenOffSleepToken(true); 6553 synchronized (mLock) { 6554 mScreenOnEarly = false; 6555 mScreenOnFully = false; 6556 mKeyguardDrawComplete = false; 6557 mWindowManagerDrawComplete = false; 6558 mScreenOnListener = null; 6559 updateOrientationListenerLp(); 6560 6561 if (mKeyguardDelegate != null) { 6562 mKeyguardDelegate.onScreenTurnedOff(); 6563 } 6564 } 6565 reportScreenStateToVrManager(false); 6566 } 6567 6568 // Called on the DisplayManager's DisplayPowerController thread. 6569 @Override 6570 public void screenTurningOn(final ScreenOnListener screenOnListener) { 6571 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on..."); 6572 6573 updateScreenOffSleepToken(false); 6574 synchronized (mLock) { 6575 mScreenOnEarly = true; 6576 mScreenOnFully = false; 6577 mKeyguardDrawComplete = false; 6578 mWindowManagerDrawComplete = false; 6579 mScreenOnListener = screenOnListener; 6580 6581 if (mKeyguardDelegate != null) { 6582 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6583 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000); 6584 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); 6585 } else { 6586 if (DEBUG_WAKEUP) Slog.d(TAG, 6587 "null mKeyguardDelegate: setting mKeyguardDrawComplete."); 6588 finishKeyguardDrawn(); 6589 } 6590 } 6591 } 6592 6593 // Called on the DisplayManager's DisplayPowerController thread. 6594 @Override 6595 public void screenTurnedOn() { 6596 synchronized (mLock) { 6597 if (mKeyguardDelegate != null) { 6598 mKeyguardDelegate.onScreenTurnedOn(); 6599 } 6600 } 6601 reportScreenStateToVrManager(true); 6602 } 6603 6604 private void reportScreenStateToVrManager(boolean isScreenOn) { 6605 if (mVrManagerInternal == null) { 6606 return; 6607 } 6608 mVrManagerInternal.onScreenStateChanged(isScreenOn); 6609 } 6610 6611 private void finishWindowsDrawn() { 6612 synchronized (mLock) { 6613 if (!mScreenOnEarly || mWindowManagerDrawComplete) { 6614 return; // Screen is not turned on or we did already handle this case earlier. 6615 } 6616 6617 mWindowManagerDrawComplete = true; 6618 } 6619 6620 finishScreenTurningOn(); 6621 } 6622 6623 private void finishScreenTurningOn() { 6624 synchronized (mLock) { 6625 // We have just finished drawing screen content. Since the orientation listener 6626 // gets only installed when all windows are drawn, we try to install it again. 6627 updateOrientationListenerLp(); 6628 } 6629 final ScreenOnListener listener; 6630 final boolean enableScreen; 6631 synchronized (mLock) { 6632 if (DEBUG_WAKEUP) Slog.d(TAG, 6633 "finishScreenTurningOn: mAwake=" + mAwake 6634 + ", mScreenOnEarly=" + mScreenOnEarly 6635 + ", mScreenOnFully=" + mScreenOnFully 6636 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete 6637 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); 6638 6639 if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete 6640 || (mAwake && !mKeyguardDrawComplete)) { 6641 return; // spurious or not ready yet 6642 } 6643 6644 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on..."); 6645 listener = mScreenOnListener; 6646 mScreenOnListener = null; 6647 mScreenOnFully = true; 6648 6649 // Remember the first time we draw the keyguard so we know when we're done with 6650 // the main part of booting and can enable the screen and hide boot messages. 6651 if (!mKeyguardDrawnOnce && mAwake) { 6652 mKeyguardDrawnOnce = true; 6653 enableScreen = true; 6654 if (mBootMessageNeedsHiding) { 6655 mBootMessageNeedsHiding = false; 6656 hideBootMessages(); 6657 } 6658 } else { 6659 enableScreen = false; 6660 } 6661 } 6662 6663 if (listener != null) { 6664 listener.onScreenOn(); 6665 } 6666 6667 if (enableScreen) { 6668 try { 6669 mWindowManager.enableScreenIfNeeded(); 6670 } catch (RemoteException unhandled) { 6671 } 6672 } 6673 } 6674 6675 private void handleHideBootMessage() { 6676 synchronized (mLock) { 6677 if (!mKeyguardDrawnOnce) { 6678 mBootMessageNeedsHiding = true; 6679 return; // keyguard hasn't drawn the first time yet, not done booting 6680 } 6681 } 6682 6683 if (mBootMsgDialog != null) { 6684 if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing"); 6685 mBootMsgDialog.dismiss(); 6686 mBootMsgDialog = null; 6687 } 6688 } 6689 6690 @Override 6691 public boolean isScreenOn() { 6692 return mScreenOnFully; 6693 } 6694 6695 /** {@inheritDoc} */ 6696 @Override 6697 public void enableKeyguard(boolean enabled) { 6698 if (mKeyguardDelegate != null) { 6699 mKeyguardDelegate.setKeyguardEnabled(enabled); 6700 } 6701 } 6702 6703 /** {@inheritDoc} */ 6704 @Override 6705 public void exitKeyguardSecurely(OnKeyguardExitResult callback) { 6706 if (mKeyguardDelegate != null) { 6707 mKeyguardDelegate.verifyUnlock(callback); 6708 } 6709 } 6710 6711 @Override 6712 public boolean isKeyguardShowingAndNotOccluded() { 6713 if (mKeyguardDelegate == null) return false; 6714 return mKeyguardDelegate.isShowing() && !mKeyguardOccluded; 6715 } 6716 6717 @Override 6718 public boolean isKeyguardTrustedLw() { 6719 if (mKeyguardDelegate == null) return false; 6720 return mKeyguardDelegate.isTrusted(); 6721 } 6722 6723 /** {@inheritDoc} */ 6724 @Override 6725 public boolean isKeyguardLocked() { 6726 return keyguardOn(); 6727 } 6728 6729 /** {@inheritDoc} */ 6730 @Override 6731 public boolean isKeyguardSecure(int userId) { 6732 if (mKeyguardDelegate == null) return false; 6733 return mKeyguardDelegate.isSecure(userId); 6734 } 6735 6736 /** {@inheritDoc} */ 6737 @Override 6738 public boolean isKeyguardOccluded() { 6739 if (mKeyguardDelegate == null) return false; 6740 return mKeyguardOccluded; 6741 } 6742 6743 /** {@inheritDoc} */ 6744 @Override 6745 public boolean inKeyguardRestrictedKeyInputMode() { 6746 if (mKeyguardDelegate == null) return false; 6747 return mKeyguardDelegate.isInputRestricted(); 6748 } 6749 6750 @Override 6751 public void dismissKeyguardLw(IKeyguardDismissCallback callback) { 6752 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 6753 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw"); 6754 6755 // ask the keyguard to prompt the user to authenticate if necessary 6756 mKeyguardDelegate.dismiss(callback); 6757 } else if (callback != null) { 6758 try { 6759 callback.onDismissError(); 6760 } catch (RemoteException e) { 6761 Slog.w(TAG, "Failed to call callback", e); 6762 } 6763 } 6764 } 6765 6766 @Override 6767 public boolean isKeyguardDrawnLw() { 6768 synchronized (mLock) { 6769 return mKeyguardDrawnOnce; 6770 } 6771 } 6772 6773 @Override 6774 public boolean isShowingDreamLw() { 6775 return mShowingDream; 6776 } 6777 6778 @Override 6779 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 6780 if (mKeyguardDelegate != null) { 6781 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation"); 6782 mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration); 6783 } 6784 } 6785 6786 @Override 6787 public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6788 Rect outInsets) { 6789 outInsets.setEmpty(); 6790 6791 // Navigation bar and status bar. 6792 getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, outInsets); 6793 outInsets.top = mStatusBarHeight; 6794 } 6795 6796 @Override 6797 public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6798 Rect outInsets) { 6799 outInsets.setEmpty(); 6800 6801 // Only navigation bar 6802 if (mHasNavigationBar) { 6803 int position = navigationBarPosition(displayWidth, displayHeight, displayRotation); 6804 if (position == NAV_BAR_BOTTOM) { 6805 outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode); 6806 } else if (position == NAV_BAR_RIGHT) { 6807 outInsets.right = getNavigationBarWidth(displayRotation, mUiMode); 6808 } else if (position == NAV_BAR_LEFT) { 6809 outInsets.left = getNavigationBarWidth(displayRotation, mUiMode); 6810 } 6811 } 6812 } 6813 6814 @Override 6815 public boolean isNavBarForcedShownLw(WindowState windowState) { 6816 return mForceShowSystemBars; 6817 } 6818 6819 @Override 6820 public boolean isDockSideAllowed(int dockSide) { 6821 6822 // We do not allow all dock sides at which the navigation bar touches the docked stack. 6823 if (!mNavigationBarCanMove) { 6824 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT; 6825 } else { 6826 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT; 6827 } 6828 } 6829 6830 void sendCloseSystemWindows() { 6831 PhoneWindow.sendCloseSystemWindows(mContext, null); 6832 } 6833 6834 void sendCloseSystemWindows(String reason) { 6835 PhoneWindow.sendCloseSystemWindows(mContext, reason); 6836 } 6837 6838 @Override 6839 public int rotationForOrientationLw(int orientation, int lastRotation) { 6840 if (false) { 6841 Slog.v(TAG, "rotationForOrientationLw(orient=" 6842 + orientation + ", last=" + lastRotation 6843 + "); user=" + mUserRotation + " " 6844 + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) 6845 ? "USER_ROTATION_LOCKED" : "") 6846 ); 6847 } 6848 6849 if (mForceDefaultOrientation) { 6850 return Surface.ROTATION_0; 6851 } 6852 6853 synchronized (mLock) { 6854 int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1 6855 if (sensorRotation < 0) { 6856 sensorRotation = lastRotation; 6857 } 6858 6859 final int preferredRotation; 6860 if (mLidState == LID_OPEN && mLidOpenRotation >= 0) { 6861 // Ignore sensor when lid switch is open and rotation is forced. 6862 preferredRotation = mLidOpenRotation; 6863 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR 6864 && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) { 6865 // Ignore sensor when in car dock unless explicitly enabled. 6866 // This case can override the behavior of NOSENSOR, and can also 6867 // enable 180 degree rotation while docked. 6868 preferredRotation = mCarDockEnablesAccelerometer 6869 ? sensorRotation : mCarDockRotation; 6870 } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK 6871 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK 6872 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK) 6873 && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) { 6874 // Ignore sensor when in desk dock unless explicitly enabled. 6875 // This case can override the behavior of NOSENSOR, and can also 6876 // enable 180 degree rotation while docked. 6877 preferredRotation = mDeskDockEnablesAccelerometer 6878 ? sensorRotation : mDeskDockRotation; 6879 } else if (mHdmiPlugged && mDemoHdmiRotationLock) { 6880 // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled. 6881 // Note that the dock orientation overrides the HDMI orientation. 6882 preferredRotation = mDemoHdmiRotation; 6883 } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED 6884 && mUndockedHdmiRotation >= 0) { 6885 // Ignore sensor when plugged into HDMI and an undocked orientation has 6886 // been specified in the configuration (only for legacy devices without 6887 // full multi-display support). 6888 // Note that the dock orientation overrides the HDMI orientation. 6889 preferredRotation = mUndockedHdmiRotation; 6890 } else if (mDemoRotationLock) { 6891 // Ignore sensor when demo rotation lock is enabled. 6892 // Note that the dock orientation and HDMI rotation lock override this. 6893 preferredRotation = mDemoRotation; 6894 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { 6895 // Application just wants to remain locked in the last rotation. 6896 preferredRotation = lastRotation; 6897 } else if (!mSupportAutoRotation) { 6898 // If we don't support auto-rotation then bail out here and ignore 6899 // the sensor and any rotation lock settings. 6900 preferredRotation = -1; 6901 } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE 6902 && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER 6903 || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 6904 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE 6905 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT 6906 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER)) 6907 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR 6908 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 6909 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE 6910 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { 6911 // Otherwise, use sensor only if requested by the application or enabled 6912 // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR. 6913 if (mAllowAllRotations < 0) { 6914 // Can't read this during init() because the context doesn't 6915 // have display metrics at that time so we cannot determine 6916 // tablet vs. phone then. 6917 mAllowAllRotations = mContext.getResources().getBoolean( 6918 com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0; 6919 } 6920 if (sensorRotation != Surface.ROTATION_180 6921 || mAllowAllRotations == 1 6922 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 6923 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) { 6924 // In VrMode, we report the sensor as always being in default orientation so: 6925 // 1) The orientation doesn't change as the user moves their head. 6926 // 2) 2D apps within VR show in the device's default orientation. 6927 // This only overwrites the sensor-provided orientation and does not affect any 6928 // explicit orientation preferences specified by any activities. 6929 preferredRotation = 6930 mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation; 6931 } else { 6932 preferredRotation = lastRotation; 6933 } 6934 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED 6935 && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { 6936 // Apply rotation lock. Does not apply to NOSENSOR. 6937 // The idea is that the user rotation expresses a weak preference for the direction 6938 // of gravity and as NOSENSOR is never affected by gravity, then neither should 6939 // NOSENSOR be affected by rotation lock (although it will be affected by docks). 6940 preferredRotation = mUserRotation; 6941 } else { 6942 // No overriding preference. 6943 // We will do exactly what the application asked us to do. 6944 preferredRotation = -1; 6945 } 6946 6947 switch (orientation) { 6948 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 6949 // Return portrait unless overridden. 6950 if (isAnyPortrait(preferredRotation)) { 6951 return preferredRotation; 6952 } 6953 return mPortraitRotation; 6954 6955 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 6956 // Return landscape unless overridden. 6957 if (isLandscapeOrSeascape(preferredRotation)) { 6958 return preferredRotation; 6959 } 6960 return mLandscapeRotation; 6961 6962 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 6963 // Return reverse portrait unless overridden. 6964 if (isAnyPortrait(preferredRotation)) { 6965 return preferredRotation; 6966 } 6967 return mUpsideDownRotation; 6968 6969 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 6970 // Return seascape unless overridden. 6971 if (isLandscapeOrSeascape(preferredRotation)) { 6972 return preferredRotation; 6973 } 6974 return mSeascapeRotation; 6975 6976 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 6977 case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE: 6978 // Return either landscape rotation. 6979 if (isLandscapeOrSeascape(preferredRotation)) { 6980 return preferredRotation; 6981 } 6982 if (isLandscapeOrSeascape(lastRotation)) { 6983 return lastRotation; 6984 } 6985 return mLandscapeRotation; 6986 6987 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 6988 case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT: 6989 // Return either portrait rotation. 6990 if (isAnyPortrait(preferredRotation)) { 6991 return preferredRotation; 6992 } 6993 if (isAnyPortrait(lastRotation)) { 6994 return lastRotation; 6995 } 6996 return mPortraitRotation; 6997 6998 default: 6999 // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR, 7000 // just return the preferred orientation we already calculated. 7001 if (preferredRotation >= 0) { 7002 return preferredRotation; 7003 } 7004 return Surface.ROTATION_0; 7005 } 7006 } 7007 } 7008 7009 @Override 7010 public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) { 7011 switch (orientation) { 7012 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 7013 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 7014 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 7015 return isAnyPortrait(rotation); 7016 7017 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 7018 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 7019 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 7020 return isLandscapeOrSeascape(rotation); 7021 7022 default: 7023 return true; 7024 } 7025 } 7026 7027 @Override 7028 public void setRotationLw(int rotation) { 7029 mOrientationListener.setCurrentRotation(rotation); 7030 } 7031 7032 private boolean isLandscapeOrSeascape(int rotation) { 7033 return rotation == mLandscapeRotation || rotation == mSeascapeRotation; 7034 } 7035 7036 private boolean isAnyPortrait(int rotation) { 7037 return rotation == mPortraitRotation || rotation == mUpsideDownRotation; 7038 } 7039 7040 @Override 7041 public int getUserRotationMode() { 7042 return Settings.System.getIntForUser(mContext.getContentResolver(), 7043 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ? 7044 WindowManagerPolicy.USER_ROTATION_FREE : 7045 WindowManagerPolicy.USER_ROTATION_LOCKED; 7046 } 7047 7048 // User rotation: to be used when all else fails in assigning an orientation to the device 7049 @Override 7050 public void setUserRotationMode(int mode, int rot) { 7051 ContentResolver res = mContext.getContentResolver(); 7052 7053 // mUserRotationMode and mUserRotation will be assigned by the content observer 7054 if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) { 7055 Settings.System.putIntForUser(res, 7056 Settings.System.USER_ROTATION, 7057 rot, 7058 UserHandle.USER_CURRENT); 7059 Settings.System.putIntForUser(res, 7060 Settings.System.ACCELEROMETER_ROTATION, 7061 0, 7062 UserHandle.USER_CURRENT); 7063 } else { 7064 Settings.System.putIntForUser(res, 7065 Settings.System.ACCELEROMETER_ROTATION, 7066 1, 7067 UserHandle.USER_CURRENT); 7068 } 7069 } 7070 7071 @Override 7072 public void setSafeMode(boolean safeMode) { 7073 mSafeMode = safeMode; 7074 performHapticFeedbackLw(null, safeMode 7075 ? HapticFeedbackConstants.SAFE_MODE_ENABLED 7076 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true); 7077 } 7078 7079 static long[] getLongIntArray(Resources r, int resid) { 7080 int[] ar = r.getIntArray(resid); 7081 if (ar == null) { 7082 return null; 7083 } 7084 long[] out = new long[ar.length]; 7085 for (int i=0; i<ar.length; i++) { 7086 out[i] = ar[i]; 7087 } 7088 return out; 7089 } 7090 7091 /** {@inheritDoc} */ 7092 @Override 7093 public void systemReady() { 7094 mKeyguardDelegate = new KeyguardServiceDelegate(mContext, 7095 new StateCallback() { 7096 @Override 7097 public void onTrustedChanged() { 7098 mWindowManagerFuncs.notifyKeyguardTrustedChanged(); 7099 } 7100 }); 7101 mKeyguardDelegate.onSystemReady(); 7102 7103 mVrManagerInternal = LocalServices.getService(VrManagerInternal.class); 7104 if (mVrManagerInternal != null) { 7105 mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); 7106 } 7107 7108 readCameraLensCoverState(); 7109 updateUiMode(); 7110 boolean bindKeyguardNow; 7111 synchronized (mLock) { 7112 updateOrientationListenerLp(); 7113 mSystemReady = true; 7114 mHandler.post(new Runnable() { 7115 @Override 7116 public void run() { 7117 updateSettings(); 7118 } 7119 }); 7120 7121 bindKeyguardNow = mDeferBindKeyguard; 7122 if (bindKeyguardNow) { 7123 // systemBooted ran but wasn't able to bind to the Keyguard, we'll do it now. 7124 mDeferBindKeyguard = false; 7125 } 7126 } 7127 7128 if (bindKeyguardNow) { 7129 mKeyguardDelegate.bindService(mContext); 7130 mKeyguardDelegate.onBootCompleted(); 7131 } 7132 mSystemGestures.systemReady(); 7133 mImmersiveModeConfirmation.systemReady(); 7134 } 7135 7136 /** {@inheritDoc} */ 7137 @Override 7138 public void systemBooted() { 7139 boolean bindKeyguardNow = false; 7140 synchronized (mLock) { 7141 // Time to bind Keyguard; take care to only bind it once, either here if ready or 7142 // in systemReady if not. 7143 if (mKeyguardDelegate != null) { 7144 bindKeyguardNow = true; 7145 } else { 7146 // Because mKeyguardDelegate is null, we know that the synchronized block in 7147 // systemReady didn't run yet and setting this will actually have an effect. 7148 mDeferBindKeyguard = true; 7149 } 7150 } 7151 if (bindKeyguardNow) { 7152 mKeyguardDelegate.bindService(mContext); 7153 mKeyguardDelegate.onBootCompleted(); 7154 } 7155 synchronized (mLock) { 7156 mSystemBooted = true; 7157 } 7158 startedWakingUp(); 7159 screenTurningOn(null); 7160 screenTurnedOn(); 7161 } 7162 7163 ProgressDialog mBootMsgDialog = null; 7164 7165 /** {@inheritDoc} */ 7166 @Override 7167 public void showBootMessage(final CharSequence msg, final boolean always) { 7168 mHandler.post(new Runnable() { 7169 @Override public void run() { 7170 if (mBootMsgDialog == null) { 7171 int theme; 7172 if (mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK)) { 7173 theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert; 7174 } else { 7175 theme = 0; 7176 } 7177 7178 mBootMsgDialog = new ProgressDialog(mContext, theme) { 7179 // This dialog will consume all events coming in to 7180 // it, to avoid it trying to do things too early in boot. 7181 @Override public boolean dispatchKeyEvent(KeyEvent event) { 7182 return true; 7183 } 7184 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { 7185 return true; 7186 } 7187 @Override public boolean dispatchTouchEvent(MotionEvent ev) { 7188 return true; 7189 } 7190 @Override public boolean dispatchTrackballEvent(MotionEvent ev) { 7191 return true; 7192 } 7193 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) { 7194 return true; 7195 } 7196 @Override public boolean dispatchPopulateAccessibilityEvent( 7197 AccessibilityEvent event) { 7198 return true; 7199 } 7200 }; 7201 if (mContext.getPackageManager().isUpgrade()) { 7202 mBootMsgDialog.setTitle(R.string.android_upgrading_title); 7203 } else { 7204 mBootMsgDialog.setTitle(R.string.android_start_title); 7205 } 7206 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 7207 mBootMsgDialog.setIndeterminate(true); 7208 mBootMsgDialog.getWindow().setType( 7209 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS); 7210 mBootMsgDialog.getWindow().addFlags( 7211 WindowManager.LayoutParams.FLAG_DIM_BEHIND 7212 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 7213 mBootMsgDialog.getWindow().setDimAmount(1); 7214 WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes(); 7215 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 7216 mBootMsgDialog.getWindow().setAttributes(lp); 7217 mBootMsgDialog.setCancelable(false); 7218 mBootMsgDialog.show(); 7219 } 7220 mBootMsgDialog.setMessage(msg); 7221 } 7222 }); 7223 } 7224 7225 /** {@inheritDoc} */ 7226 @Override 7227 public void hideBootMessages() { 7228 mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE); 7229 } 7230 7231 /** {@inheritDoc} */ 7232 @Override 7233 public void userActivity() { 7234 // *************************************** 7235 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE 7236 // *************************************** 7237 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER 7238 // WITH ITS LOCKS HELD. 7239 // 7240 // This code must be VERY careful about the locks 7241 // it acquires. 7242 // In fact, the current code acquires way too many, 7243 // and probably has lurking deadlocks. 7244 7245 synchronized (mScreenLockTimeout) { 7246 if (mLockScreenTimerActive) { 7247 // reset the timer 7248 mHandler.removeCallbacks(mScreenLockTimeout); 7249 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 7250 } 7251 } 7252 } 7253 7254 class ScreenLockTimeout implements Runnable { 7255 Bundle options; 7256 7257 @Override 7258 public void run() { 7259 synchronized (this) { 7260 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard"); 7261 if (mKeyguardDelegate != null) { 7262 mKeyguardDelegate.doKeyguardTimeout(options); 7263 } 7264 mLockScreenTimerActive = false; 7265 options = null; 7266 } 7267 } 7268 7269 public void setLockOptions(Bundle options) { 7270 this.options = options; 7271 } 7272 } 7273 7274 ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout(); 7275 7276 @Override 7277 public void lockNow(Bundle options) { 7278 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 7279 mHandler.removeCallbacks(mScreenLockTimeout); 7280 if (options != null) { 7281 // In case multiple calls are made to lockNow, we don't wipe out the options 7282 // until the runnable actually executes. 7283 mScreenLockTimeout.setLockOptions(options); 7284 } 7285 mHandler.post(mScreenLockTimeout); 7286 } 7287 7288 private void updateLockScreenTimeout() { 7289 synchronized (mScreenLockTimeout) { 7290 boolean enable = (mAllowLockscreenWhenOn && mAwake && 7291 mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId)); 7292 if (mLockScreenTimerActive != enable) { 7293 if (enable) { 7294 if (localLOGV) Log.v(TAG, "setting lockscreen timer"); 7295 mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests 7296 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 7297 } else { 7298 if (localLOGV) Log.v(TAG, "clearing lockscreen timer"); 7299 mHandler.removeCallbacks(mScreenLockTimeout); 7300 } 7301 mLockScreenTimerActive = enable; 7302 } 7303 } 7304 } 7305 7306 private void updateDreamingSleepToken(boolean acquire) { 7307 if (acquire) { 7308 if (mDreamingSleepToken == null) { 7309 mDreamingSleepToken = mActivityManagerInternal.acquireSleepToken("Dream"); 7310 } 7311 } else { 7312 if (mDreamingSleepToken != null) { 7313 mDreamingSleepToken.release(); 7314 mDreamingSleepToken = null; 7315 } 7316 } 7317 } 7318 7319 private void updateScreenOffSleepToken(boolean acquire) { 7320 if (acquire) { 7321 if (mScreenOffSleepToken == null) { 7322 mScreenOffSleepToken = mActivityManagerInternal.acquireSleepToken("ScreenOff"); 7323 } 7324 } else { 7325 if (mScreenOffSleepToken != null) { 7326 mScreenOffSleepToken.release(); 7327 mScreenOffSleepToken = null; 7328 } 7329 } 7330 } 7331 7332 /** {@inheritDoc} */ 7333 @Override 7334 public void enableScreenAfterBoot() { 7335 readLidState(); 7336 applyLidSwitchState(); 7337 updateRotation(true); 7338 } 7339 7340 private void applyLidSwitchState() { 7341 if (mLidState == LID_CLOSED && mLidControlsSleep) { 7342 mPowerManager.goToSleep(SystemClock.uptimeMillis(), 7343 PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH, 7344 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 7345 } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) { 7346 mWindowManagerFuncs.lockDeviceNow(); 7347 } 7348 7349 synchronized (mLock) { 7350 updateWakeGestureListenerLp(); 7351 } 7352 } 7353 7354 void updateUiMode() { 7355 if (mUiModeManager == null) { 7356 mUiModeManager = IUiModeManager.Stub.asInterface( 7357 ServiceManager.getService(Context.UI_MODE_SERVICE)); 7358 } 7359 try { 7360 mUiMode = mUiModeManager.getCurrentModeType(); 7361 } catch (RemoteException e) { 7362 } 7363 } 7364 7365 void updateRotation(boolean alwaysSendConfiguration) { 7366 try { 7367 //set orientation on WindowManager 7368 mWindowManager.updateRotation(alwaysSendConfiguration, false); 7369 } catch (RemoteException e) { 7370 // Ignore 7371 } 7372 } 7373 7374 void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { 7375 try { 7376 //set orientation on WindowManager 7377 mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout); 7378 } catch (RemoteException e) { 7379 // Ignore 7380 } 7381 } 7382 7383 /** 7384 * Return an Intent to launch the currently active dock app as home. Returns 7385 * null if the standard home should be launched, which is the case if any of the following is 7386 * true: 7387 * <ul> 7388 * <li>The device is not in either car mode or desk mode 7389 * <li>The device is in car mode but mEnableCarDockHomeCapture is false 7390 * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false 7391 * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME 7392 * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME 7393 * </ul> 7394 * @return A dock intent. 7395 */ 7396 Intent createHomeDockIntent() { 7397 Intent intent = null; 7398 7399 // What home does is based on the mode, not the dock state. That 7400 // is, when in car mode you should be taken to car home regardless 7401 // of whether we are actually in a car dock. 7402 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) { 7403 if (mEnableCarDockHomeCapture) { 7404 intent = mCarDockIntent; 7405 } 7406 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) { 7407 if (ENABLE_DESK_DOCK_HOME_CAPTURE) { 7408 intent = mDeskDockIntent; 7409 } 7410 } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH 7411 && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK 7412 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK 7413 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) { 7414 // Always launch dock home from home when watch is docked, if it exists. 7415 intent = mDeskDockIntent; 7416 } else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) { 7417 if (ENABLE_VR_HEADSET_HOME_CAPTURE) { 7418 intent = mVrHeadsetHomeIntent; 7419 } 7420 } 7421 7422 if (intent == null) { 7423 return null; 7424 } 7425 7426 ActivityInfo ai = null; 7427 ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser( 7428 intent, 7429 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, 7430 mCurrentUserId); 7431 if (info != null) { 7432 ai = info.activityInfo; 7433 } 7434 if (ai != null 7435 && ai.metaData != null 7436 && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) { 7437 intent = new Intent(intent); 7438 intent.setClassName(ai.packageName, ai.name); 7439 return intent; 7440 } 7441 7442 return null; 7443 } 7444 7445 void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) { 7446 if (awakenFromDreams) { 7447 awakenDreams(); 7448 } 7449 7450 Intent dock = createHomeDockIntent(); 7451 if (dock != null) { 7452 try { 7453 if (fromHomeKey) { 7454 dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7455 } 7456 startActivityAsUser(dock, UserHandle.CURRENT); 7457 return; 7458 } catch (ActivityNotFoundException e) { 7459 } 7460 } 7461 7462 Intent intent; 7463 7464 if (fromHomeKey) { 7465 intent = new Intent(mHomeIntent); 7466 intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7467 } else { 7468 intent = mHomeIntent; 7469 } 7470 7471 startActivityAsUser(intent, UserHandle.CURRENT); 7472 } 7473 7474 /** 7475 * goes to the home screen 7476 * @return whether it did anything 7477 */ 7478 boolean goHome() { 7479 if (!isUserSetupComplete()) { 7480 Slog.i(TAG, "Not going home because user setup is in progress."); 7481 return false; 7482 } 7483 if (false) { 7484 // This code always brings home to the front. 7485 try { 7486 ActivityManager.getService().stopAppSwitches(); 7487 } catch (RemoteException e) { 7488 } 7489 sendCloseSystemWindows(); 7490 startDockOrHome(false /*fromHomeKey*/, true /* awakenFromDreams */); 7491 } else { 7492 // This code brings home to the front or, if it is already 7493 // at the front, puts the device to sleep. 7494 try { 7495 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) { 7496 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry. 7497 Log.d(TAG, "UTS-TEST-MODE"); 7498 } else { 7499 ActivityManager.getService().stopAppSwitches(); 7500 sendCloseSystemWindows(); 7501 Intent dock = createHomeDockIntent(); 7502 if (dock != null) { 7503 int result = ActivityManager.getService() 7504 .startActivityAsUser(null, null, dock, 7505 dock.resolveTypeIfNeeded(mContext.getContentResolver()), 7506 null, null, 0, 7507 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7508 null, null, UserHandle.USER_CURRENT); 7509 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7510 return false; 7511 } 7512 } 7513 } 7514 int result = ActivityManager.getService() 7515 .startActivityAsUser(null, null, mHomeIntent, 7516 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()), 7517 null, null, 0, 7518 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7519 null, null, UserHandle.USER_CURRENT); 7520 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7521 return false; 7522 } 7523 } catch (RemoteException ex) { 7524 // bummer, the activity manager, which is in this process, is dead 7525 } 7526 } 7527 return true; 7528 } 7529 7530 @Override 7531 public void setCurrentOrientationLw(int newOrientation) { 7532 synchronized (mLock) { 7533 if (newOrientation != mCurrentAppOrientation) { 7534 mCurrentAppOrientation = newOrientation; 7535 updateOrientationListenerLp(); 7536 } 7537 } 7538 } 7539 7540 private boolean isTheaterModeEnabled() { 7541 return Settings.Global.getInt(mContext.getContentResolver(), 7542 Settings.Global.THEATER_MODE_ON, 0) == 1; 7543 } 7544 7545 private boolean areSystemNavigationKeysEnabled() { 7546 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 7547 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, 0, UserHandle.USER_CURRENT) == 1; 7548 } 7549 7550 @Override 7551 public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) { 7552 if (!mVibrator.hasVibrator()) { 7553 return false; 7554 } 7555 final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(), 7556 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0; 7557 if (hapticsDisabled && !always) { 7558 return false; 7559 } 7560 7561 VibrationEffect effect = getVibrationEffect(effectId); 7562 if (effect == null) { 7563 return false; 7564 } 7565 7566 int owningUid; 7567 String owningPackage; 7568 if (win != null) { 7569 owningUid = win.getOwningUid(); 7570 owningPackage = win.getOwningPackage(); 7571 } else { 7572 owningUid = android.os.Process.myUid(); 7573 owningPackage = mContext.getOpPackageName(); 7574 } 7575 mVibrator.vibrate(owningUid, owningPackage, effect, VIBRATION_ATTRIBUTES); 7576 return true; 7577 } 7578 7579 private VibrationEffect getVibrationEffect(int effectId) { 7580 long[] pattern; 7581 switch (effectId) { 7582 case HapticFeedbackConstants.VIRTUAL_KEY: 7583 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); 7584 case HapticFeedbackConstants.LONG_PRESS: 7585 pattern = mLongPressVibePattern; 7586 break; 7587 case HapticFeedbackConstants.KEYBOARD_TAP: 7588 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); 7589 case HapticFeedbackConstants.CLOCK_TICK: 7590 pattern = mClockTickVibePattern; 7591 break; 7592 case HapticFeedbackConstants.CALENDAR_DATE: 7593 pattern = mCalendarDateVibePattern; 7594 break; 7595 case HapticFeedbackConstants.SAFE_MODE_DISABLED: 7596 pattern = mSafeModeDisabledVibePattern; 7597 break; 7598 case HapticFeedbackConstants.SAFE_MODE_ENABLED: 7599 pattern = mSafeModeEnabledVibePattern; 7600 break; 7601 case HapticFeedbackConstants.CONTEXT_CLICK: 7602 pattern = mContextClickVibePattern; 7603 break; 7604 default: 7605 return null; 7606 } 7607 if (pattern.length == 1) { 7608 // One-shot vibration 7609 return VibrationEffect.createOneShot(pattern[0], VibrationEffect.DEFAULT_AMPLITUDE); 7610 } else { 7611 // Pattern vibration 7612 return VibrationEffect.createWaveform(pattern, -1); 7613 } 7614 } 7615 7616 @Override 7617 public void keepScreenOnStartedLw() { 7618 } 7619 7620 @Override 7621 public void keepScreenOnStoppedLw() { 7622 if (isKeyguardShowingAndNotOccluded()) { 7623 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 7624 } 7625 } 7626 7627 private int updateSystemUiVisibilityLw() { 7628 // If there is no window focused, there will be nobody to handle the events 7629 // anyway, so just hang on in whatever state we're in until things settle down. 7630 WindowState winCandidate = mFocusedWindow != null ? mFocusedWindow 7631 : mTopFullscreenOpaqueWindowState; 7632 if (winCandidate == null) { 7633 return 0; 7634 } 7635 if (winCandidate.getAttrs().token == mImmersiveModeConfirmation.getWindowToken()) { 7636 // The immersive mode confirmation should never affect the system bar visibility, 7637 // otherwise it will unhide the navigation bar and hide itself. 7638 winCandidate = isStatusBarKeyguard() ? mStatusBar : mTopFullscreenOpaqueWindowState; 7639 if (winCandidate == null) { 7640 return 0; 7641 } 7642 } 7643 final WindowState win = winCandidate; 7644 if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mKeyguardOccluded) { 7645 // We are updating at a point where the keyguard has gotten 7646 // focus, but we were last in a state where the top window is 7647 // hiding it. This is probably because the keyguard as been 7648 // shown while the top window was displayed, so we want to ignore 7649 // it here because this is just a very transient change and it 7650 // will quickly lose focus once it correctly gets hidden. 7651 return 0; 7652 } 7653 7654 int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null) 7655 & ~mResettingSystemUiFlags 7656 & ~mForceClearedSystemUiFlags; 7657 if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) { 7658 tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS); 7659 } 7660 7661 final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */, 7662 mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState); 7663 final int dockedVisibility = updateLightStatusBarLw(0 /* vis */, 7664 mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState); 7665 mWindowManagerFuncs.getStackBounds(HOME_STACK_ID, mNonDockedStackBounds); 7666 mWindowManagerFuncs.getStackBounds(DOCKED_STACK_ID, mDockedStackBounds); 7667 final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility); 7668 final int diff = visibility ^ mLastSystemUiFlags; 7669 final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags; 7670 final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags; 7671 final boolean needsMenu = win.getNeedsMenuLw(mTopFullscreenOpaqueWindowState); 7672 if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0 && mLastFocusNeedsMenu == needsMenu 7673 && mFocusedApp == win.getAppToken() 7674 && mLastNonDockedStackBounds.equals(mNonDockedStackBounds) 7675 && mLastDockedStackBounds.equals(mDockedStackBounds)) { 7676 return 0; 7677 } 7678 mLastSystemUiFlags = visibility; 7679 mLastFullscreenStackSysUiFlags = fullscreenVisibility; 7680 mLastDockedStackSysUiFlags = dockedVisibility; 7681 mLastFocusNeedsMenu = needsMenu; 7682 mFocusedApp = win.getAppToken(); 7683 final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds); 7684 final Rect dockedStackBounds = new Rect(mDockedStackBounds); 7685 mHandler.post(new Runnable() { 7686 @Override 7687 public void run() { 7688 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 7689 if (statusbar != null) { 7690 statusbar.setSystemUiVisibility(visibility, fullscreenVisibility, 7691 dockedVisibility, 0xffffffff, fullscreenStackBounds, 7692 dockedStackBounds, win.toString()); 7693 statusbar.topAppWindowChanged(needsMenu); 7694 } 7695 } 7696 }); 7697 return diff; 7698 } 7699 7700 private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) { 7701 WindowState statusColorWin = isStatusBarKeyguard() && !mKeyguardOccluded 7702 ? mStatusBar 7703 : opaqueOrDimming; 7704 7705 if (statusColorWin != null) { 7706 if (statusColorWin == opaque) { 7707 // If the top fullscreen-or-dimming window is also the top fullscreen, respect 7708 // its light flag. 7709 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7710 vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null) 7711 & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7712 } else if (statusColorWin != null && statusColorWin.isDimming()) { 7713 // Otherwise if it's dimming, clear the light flag. 7714 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7715 } 7716 } 7717 return vis; 7718 } 7719 7720 private int updateLightNavigationBarLw(int vis, WindowState opaque, 7721 WindowState opaqueOrDimming) { 7722 final WindowState imeWin = mWindowManagerFuncs.getInputMethodWindowLw(); 7723 7724 final WindowState navColorWin; 7725 if (imeWin != null && imeWin.isVisibleLw()) { 7726 navColorWin = imeWin; 7727 } else { 7728 navColorWin = opaqueOrDimming; 7729 } 7730 7731 if (navColorWin != null) { 7732 if (navColorWin == opaque) { 7733 // If the top fullscreen-or-dimming window is also the top fullscreen, respect 7734 // its light flag. 7735 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7736 vis |= PolicyControl.getSystemUiVisibility(navColorWin, null) 7737 & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7738 } else if (navColorWin.isDimming() || navColorWin == imeWin) { 7739 // Otherwise if it's dimming or it's the IME window, clear the light flag. 7740 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7741 } 7742 } 7743 return vis; 7744 } 7745 7746 private boolean drawsSystemBarBackground(WindowState win) { 7747 return win == null || (win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; 7748 } 7749 7750 private boolean forcesDrawStatusBarBackground(WindowState win) { 7751 return win == null || (win.getAttrs().privateFlags 7752 & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0; 7753 } 7754 7755 private int updateSystemBarsLw(WindowState win, int oldVis, int vis) { 7756 final boolean dockedStackVisible = mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID); 7757 final boolean freeformStackVisible = 7758 mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID); 7759 final boolean resizing = mWindowManagerInternal.isDockedDividerResizing(); 7760 7761 // We need to force system bars when the docked stack is visible, when the freeform stack 7762 // is visible but also when we are resizing for the transitions when docked stack 7763 // visibility changes. 7764 mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; 7765 final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard; 7766 7767 // apply translucent bar vis flags 7768 WindowState fullscreenTransWin = isStatusBarKeyguard() && !mKeyguardOccluded 7769 ? mStatusBar 7770 : mTopFullscreenOpaqueWindowState; 7771 vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7772 vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7773 final int dockedVis = mStatusBarController.applyTranslucentFlagLw( 7774 mTopDockedOpaqueWindowState, 0, 0); 7775 7776 final boolean fullscreenDrawsStatusBarBackground = 7777 (drawsSystemBarBackground(mTopFullscreenOpaqueWindowState) 7778 && (vis & View.STATUS_BAR_TRANSLUCENT) == 0) 7779 || forcesDrawStatusBarBackground(mTopFullscreenOpaqueWindowState); 7780 final boolean dockedDrawsStatusBarBackground = 7781 (drawsSystemBarBackground(mTopDockedOpaqueWindowState) 7782 && (dockedVis & View.STATUS_BAR_TRANSLUCENT) == 0) 7783 || forcesDrawStatusBarBackground(mTopDockedOpaqueWindowState); 7784 7785 // prevent status bar interaction from clearing certain flags 7786 int type = win.getAttrs().type; 7787 boolean statusBarHasFocus = type == TYPE_STATUS_BAR; 7788 if (statusBarHasFocus && !isStatusBarKeyguard()) { 7789 int flags = View.SYSTEM_UI_FLAG_FULLSCREEN 7790 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 7791 | View.SYSTEM_UI_FLAG_IMMERSIVE 7792 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 7793 | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7794 if (mKeyguardOccluded) { 7795 flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT; 7796 } 7797 vis = (vis & ~flags) | (oldVis & flags); 7798 } 7799 7800 if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) { 7801 vis |= View.STATUS_BAR_TRANSPARENT; 7802 vis &= ~View.STATUS_BAR_TRANSLUCENT; 7803 } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar) 7804 || forceOpaqueStatusBar) { 7805 vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT); 7806 } 7807 7808 vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing); 7809 7810 // update status bar 7811 boolean immersiveSticky = 7812 (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7813 final boolean hideStatusBarWM = 7814 mTopFullscreenOpaqueWindowState != null 7815 && (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null) 7816 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; 7817 final boolean hideStatusBarSysui = 7818 (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 7819 final boolean hideNavBarSysui = 7820 (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; 7821 7822 final boolean transientStatusBarAllowed = mStatusBar != null 7823 && (statusBarHasFocus || (!mForceShowSystemBars 7824 && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky)))); 7825 7826 final boolean transientNavBarAllowed = mNavigationBar != null 7827 && !mForceShowSystemBars && hideNavBarSysui && immersiveSticky; 7828 7829 final long now = SystemClock.uptimeMillis(); 7830 final boolean pendingPanic = mPendingPanicGestureUptime != 0 7831 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION; 7832 if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) { 7833 // The user performed the panic gesture recently, we're about to hide the bars, 7834 // we're no longer on the Keyguard and the screen is ready. We can now request the bars. 7835 mPendingPanicGestureUptime = 0; 7836 mStatusBarController.showTransient(); 7837 if (!isNavBarEmpty(vis)) { 7838 mNavigationBarController.showTransient(); 7839 } 7840 } 7841 7842 final boolean denyTransientStatus = mStatusBarController.isTransientShowRequested() 7843 && !transientStatusBarAllowed && hideStatusBarSysui; 7844 final boolean denyTransientNav = mNavigationBarController.isTransientShowRequested() 7845 && !transientNavBarAllowed; 7846 if (denyTransientStatus || denyTransientNav || mForceShowSystemBars) { 7847 // clear the clearable flags instead 7848 clearClearableFlagsLw(); 7849 vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS; 7850 } 7851 7852 final boolean immersive = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; 7853 immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7854 final boolean navAllowedHidden = immersive || immersiveSticky; 7855 7856 if (hideNavBarSysui && !navAllowedHidden 7857 && getWindowLayerLw(win) > getWindowLayerFromTypeLw(TYPE_INPUT_CONSUMER)) { 7858 // We can't hide the navbar from this window otherwise the input consumer would not get 7859 // the input events. 7860 vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 7861 } 7862 7863 vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis); 7864 7865 // update navigation bar 7866 boolean oldImmersiveMode = isImmersiveMode(oldVis); 7867 boolean newImmersiveMode = isImmersiveMode(vis); 7868 if (win != null && oldImmersiveMode != newImmersiveMode) { 7869 final String pkg = win.getOwningPackage(); 7870 mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode, 7871 isUserSetupComplete(), isNavBarEmpty(win.getSystemUiVisibility())); 7872 } 7873 7874 vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis); 7875 7876 vis = updateLightNavigationBarLw(vis, mTopFullscreenOpaqueWindowState, 7877 mTopFullscreenOpaqueOrDimmingWindowState); 7878 7879 return vis; 7880 } 7881 7882 /** 7883 * @return the current visibility flags with the nav-bar opacity related flags toggled based 7884 * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}. 7885 */ 7886 private int configureNavBarOpacity(int visibility, boolean dockedStackVisible, 7887 boolean freeformStackVisible, boolean isDockedDividerResizing) { 7888 if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { 7889 if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { 7890 visibility = setNavBarOpaqueFlag(visibility); 7891 } 7892 } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { 7893 if (isDockedDividerResizing) { 7894 visibility = setNavBarOpaqueFlag(visibility); 7895 } else if (freeformStackVisible) { 7896 visibility = setNavBarTranslucentFlag(visibility); 7897 } else { 7898 visibility = setNavBarOpaqueFlag(visibility); 7899 } 7900 } 7901 7902 if (!areTranslucentBarsAllowed()) { 7903 visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT; 7904 } 7905 return visibility; 7906 } 7907 7908 private int setNavBarOpaqueFlag(int visibility) { 7909 return visibility &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT); 7910 } 7911 7912 private int setNavBarTranslucentFlag(int visibility) { 7913 visibility &= ~View.NAVIGATION_BAR_TRANSPARENT; 7914 return visibility |= View.NAVIGATION_BAR_TRANSLUCENT; 7915 } 7916 7917 private void clearClearableFlagsLw() { 7918 int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS; 7919 if (newVal != mResettingSystemUiFlags) { 7920 mResettingSystemUiFlags = newVal; 7921 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 7922 } 7923 } 7924 7925 private boolean isImmersiveMode(int vis) { 7926 final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 7927 return mNavigationBar != null 7928 && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 7929 && (vis & flags) != 0 7930 && canHideNavigationBar(); 7931 } 7932 7933 private static boolean isNavBarEmpty(int systemUiFlags) { 7934 final int disableNavigationBar = (View.STATUS_BAR_DISABLE_HOME 7935 | View.STATUS_BAR_DISABLE_BACK 7936 | View.STATUS_BAR_DISABLE_RECENT); 7937 7938 return (systemUiFlags & disableNavigationBar) == disableNavigationBar; 7939 } 7940 7941 /** 7942 * @return whether the navigation or status bar can be made translucent 7943 * 7944 * This should return true unless touch exploration is not enabled or 7945 * R.boolean.config_enableTranslucentDecor is false. 7946 */ 7947 private boolean areTranslucentBarsAllowed() { 7948 return mTranslucentDecorEnabled; 7949 } 7950 7951 // Use this instead of checking config_showNavigationBar so that it can be consistently 7952 // overridden by qemu.hw.mainkeys in the emulator. 7953 @Override 7954 public boolean hasNavigationBar() { 7955 return mHasNavigationBar; 7956 } 7957 7958 @Override 7959 public void setLastInputMethodWindowLw(WindowState ime, WindowState target) { 7960 mLastInputMethodWindow = ime; 7961 mLastInputMethodTargetWindow = target; 7962 } 7963 7964 @Override 7965 public void setDismissImeOnBackKeyPressed(boolean newValue) { 7966 mDismissImeOnBackKeyPressed = newValue; 7967 } 7968 7969 @Override 7970 public int getInputMethodWindowVisibleHeightLw() { 7971 return mDockBottom - mCurBottom; 7972 } 7973 7974 @Override 7975 public void setCurrentUserLw(int newUserId) { 7976 mCurrentUserId = newUserId; 7977 if (mKeyguardDelegate != null) { 7978 mKeyguardDelegate.setCurrentUser(newUserId); 7979 } 7980 if (mAccessibilityShortcutController != null) { 7981 mAccessibilityShortcutController.setCurrentUser(newUserId); 7982 } 7983 StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); 7984 if (statusBar != null) { 7985 statusBar.setCurrentUser(newUserId); 7986 } 7987 setLastInputMethodWindowLw(null, null); 7988 } 7989 7990 @Override 7991 public void setSwitchingUser(boolean switching) { 7992 mKeyguardDelegate.setSwitchingUser(switching); 7993 } 7994 7995 @Override 7996 public boolean canMagnifyWindow(int windowType) { 7997 switch (windowType) { 7998 case WindowManager.LayoutParams.TYPE_INPUT_METHOD: 7999 case WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG: 8000 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR: 8001 case WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY: { 8002 return false; 8003 } 8004 } 8005 return true; 8006 } 8007 8008 @Override 8009 public boolean isTopLevelWindow(int windowType) { 8010 if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW 8011 && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 8012 return (windowType == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG); 8013 } 8014 return true; 8015 } 8016 8017 @Override 8018 public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) { 8019 // For the upside down rotation we don't rotate seamlessly as the navigation 8020 // bar moves position. 8021 // Note most apps (using orientation:sensor or user as opposed to fullSensor) 8022 // will not enter the reverse portrait orientation, so actually the 8023 // orientation won't change at all. 8024 if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) { 8025 return false; 8026 } 8027 // If the navigation bar can't change sides, then it will 8028 // jump when we change orientations and we don't rotate 8029 // seamlessly. 8030 if (!mNavigationBarCanMove) { 8031 return false; 8032 } 8033 int delta = newRotation - oldRotation; 8034 if (delta < 0) delta += 4; 8035 // Likewise we don't rotate seamlessly for 180 degree rotations 8036 // in this case the surfaces never resize, and our logic to 8037 // revert the transformations on size change will fail. We could 8038 // fix this in the future with the "tagged" frames idea. 8039 if (delta == Surface.ROTATION_180) { 8040 return false; 8041 } 8042 8043 final WindowState w = mTopFullscreenOpaqueWindowState; 8044 if (w != mFocusedWindow) { 8045 return false; 8046 } 8047 8048 // We only enable seamless rotation if the top window has requested 8049 // it and is in the fullscreen opaque state. Seamless rotation 8050 // requires freezing various Surface states and won't work well 8051 // with animations, so we disable it in the animation case for now. 8052 if (w != null && !w.isAnimatingLw() && 8053 ((w.getAttrs().rotationAnimation == ROTATION_ANIMATION_JUMPCUT) || 8054 (w.getAttrs().rotationAnimation == ROTATION_ANIMATION_SEAMLESS))) { 8055 return true; 8056 } 8057 return false; 8058 } 8059 8060 @Override 8061 public void dump(String prefix, PrintWriter pw, String[] args) { 8062 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode); 8063 pw.print(" mSystemReady="); pw.print(mSystemReady); 8064 pw.print(" mSystemBooted="); pw.println(mSystemBooted); 8065 pw.print(prefix); pw.print("mLidState="); pw.print(mLidState); 8066 pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation); 8067 pw.print(" mCameraLensCoverState="); pw.print(mCameraLensCoverState); 8068 pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged); 8069 if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0 8070 || mForceClearedSystemUiFlags != 0) { 8071 pw.print(prefix); pw.print("mLastSystemUiFlags=0x"); 8072 pw.print(Integer.toHexString(mLastSystemUiFlags)); 8073 pw.print(" mResettingSystemUiFlags=0x"); 8074 pw.print(Integer.toHexString(mResettingSystemUiFlags)); 8075 pw.print(" mForceClearedSystemUiFlags=0x"); 8076 pw.println(Integer.toHexString(mForceClearedSystemUiFlags)); 8077 } 8078 if (mLastFocusNeedsMenu) { 8079 pw.print(prefix); pw.print("mLastFocusNeedsMenu="); 8080 pw.println(mLastFocusNeedsMenu); 8081 } 8082 pw.print(prefix); pw.print("mWakeGestureEnabledSetting="); 8083 pw.println(mWakeGestureEnabledSetting); 8084 8085 pw.print(prefix); pw.print("mSupportAutoRotation="); pw.println(mSupportAutoRotation); 8086 pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode); 8087 pw.print(" mDockMode="); pw.print(mDockMode); 8088 pw.print(" mEnableCarDockHomeCapture="); pw.print(mEnableCarDockHomeCapture); 8089 pw.print(" mCarDockRotation="); pw.print(mCarDockRotation); 8090 pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation); 8091 pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode); 8092 pw.print(" mUserRotation="); pw.print(mUserRotation); 8093 pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations); 8094 pw.print(prefix); pw.print("mCurrentAppOrientation="); pw.println(mCurrentAppOrientation); 8095 pw.print(prefix); pw.print("mCarDockEnablesAccelerometer="); 8096 pw.print(mCarDockEnablesAccelerometer); 8097 pw.print(" mDeskDockEnablesAccelerometer="); 8098 pw.println(mDeskDockEnablesAccelerometer); 8099 pw.print(prefix); pw.print("mLidKeyboardAccessibility="); 8100 pw.print(mLidKeyboardAccessibility); 8101 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility); 8102 pw.print(" mLidControlsScreenLock="); pw.println(mLidControlsScreenLock); 8103 pw.print(" mLidControlsSleep="); pw.println(mLidControlsSleep); 8104 pw.print(prefix); 8105 pw.print(" mLongPressOnBackBehavior="); pw.println(mLongPressOnBackBehavior); 8106 pw.print(prefix); 8107 pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior); 8108 pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior); 8109 pw.print(prefix); 8110 pw.print("mDoublePressOnPowerBehavior="); pw.print(mDoublePressOnPowerBehavior); 8111 pw.print(" mTriplePressOnPowerBehavior="); pw.println(mTriplePressOnPowerBehavior); 8112 pw.print(prefix); pw.print("mHasSoftInput="); pw.println(mHasSoftInput); 8113 pw.print(prefix); pw.print("mAwake="); pw.println(mAwake); 8114 pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly); 8115 pw.print(" mScreenOnFully="); pw.println(mScreenOnFully); 8116 pw.print(prefix); pw.print("mKeyguardDrawComplete="); pw.print(mKeyguardDrawComplete); 8117 pw.print(" mWindowManagerDrawComplete="); pw.println(mWindowManagerDrawComplete); 8118 pw.print(prefix); pw.print("mOrientationSensorEnabled="); 8119 pw.println(mOrientationSensorEnabled); 8120 pw.print(prefix); pw.print("mOverscanScreen=("); pw.print(mOverscanScreenLeft); 8121 pw.print(","); pw.print(mOverscanScreenTop); 8122 pw.print(") "); pw.print(mOverscanScreenWidth); 8123 pw.print("x"); pw.println(mOverscanScreenHeight); 8124 if (mOverscanLeft != 0 || mOverscanTop != 0 8125 || mOverscanRight != 0 || mOverscanBottom != 0) { 8126 pw.print(prefix); pw.print("mOverscan left="); pw.print(mOverscanLeft); 8127 pw.print(" top="); pw.print(mOverscanTop); 8128 pw.print(" right="); pw.print(mOverscanRight); 8129 pw.print(" bottom="); pw.println(mOverscanBottom); 8130 } 8131 pw.print(prefix); pw.print("mRestrictedOverscanScreen=("); 8132 pw.print(mRestrictedOverscanScreenLeft); 8133 pw.print(","); pw.print(mRestrictedOverscanScreenTop); 8134 pw.print(") "); pw.print(mRestrictedOverscanScreenWidth); 8135 pw.print("x"); pw.println(mRestrictedOverscanScreenHeight); 8136 pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft); 8137 pw.print(","); pw.print(mUnrestrictedScreenTop); 8138 pw.print(") "); pw.print(mUnrestrictedScreenWidth); 8139 pw.print("x"); pw.println(mUnrestrictedScreenHeight); 8140 pw.print(prefix); pw.print("mRestrictedScreen=("); pw.print(mRestrictedScreenLeft); 8141 pw.print(","); pw.print(mRestrictedScreenTop); 8142 pw.print(") "); pw.print(mRestrictedScreenWidth); 8143 pw.print("x"); pw.println(mRestrictedScreenHeight); 8144 pw.print(prefix); pw.print("mStableFullscreen=("); pw.print(mStableFullscreenLeft); 8145 pw.print(","); pw.print(mStableFullscreenTop); 8146 pw.print(")-("); pw.print(mStableFullscreenRight); 8147 pw.print(","); pw.print(mStableFullscreenBottom); pw.println(")"); 8148 pw.print(prefix); pw.print("mStable=("); pw.print(mStableLeft); 8149 pw.print(","); pw.print(mStableTop); 8150 pw.print(")-("); pw.print(mStableRight); 8151 pw.print(","); pw.print(mStableBottom); pw.println(")"); 8152 pw.print(prefix); pw.print("mSystem=("); pw.print(mSystemLeft); 8153 pw.print(","); pw.print(mSystemTop); 8154 pw.print(")-("); pw.print(mSystemRight); 8155 pw.print(","); pw.print(mSystemBottom); pw.println(")"); 8156 pw.print(prefix); pw.print("mCur=("); pw.print(mCurLeft); 8157 pw.print(","); pw.print(mCurTop); 8158 pw.print(")-("); pw.print(mCurRight); 8159 pw.print(","); pw.print(mCurBottom); pw.println(")"); 8160 pw.print(prefix); pw.print("mContent=("); pw.print(mContentLeft); 8161 pw.print(","); pw.print(mContentTop); 8162 pw.print(")-("); pw.print(mContentRight); 8163 pw.print(","); pw.print(mContentBottom); pw.println(")"); 8164 pw.print(prefix); pw.print("mVoiceContent=("); pw.print(mVoiceContentLeft); 8165 pw.print(","); pw.print(mVoiceContentTop); 8166 pw.print(")-("); pw.print(mVoiceContentRight); 8167 pw.print(","); pw.print(mVoiceContentBottom); pw.println(")"); 8168 pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft); 8169 pw.print(","); pw.print(mDockTop); 8170 pw.print(")-("); pw.print(mDockRight); 8171 pw.print(","); pw.print(mDockBottom); pw.println(")"); 8172 pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer); 8173 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer); 8174 pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream); 8175 pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen); 8176 pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken); 8177 if (mLastInputMethodWindow != null) { 8178 pw.print(prefix); pw.print("mLastInputMethodWindow="); 8179 pw.println(mLastInputMethodWindow); 8180 } 8181 if (mLastInputMethodTargetWindow != null) { 8182 pw.print(prefix); pw.print("mLastInputMethodTargetWindow="); 8183 pw.println(mLastInputMethodTargetWindow); 8184 } 8185 pw.print(prefix); pw.print("mDismissImeOnBackKeyPressed="); 8186 pw.println(mDismissImeOnBackKeyPressed); 8187 if (mStatusBar != null) { 8188 pw.print(prefix); pw.print("mStatusBar="); 8189 pw.print(mStatusBar); pw.print(" isStatusBarKeyguard="); 8190 pw.println(isStatusBarKeyguard()); 8191 } 8192 if (mNavigationBar != null) { 8193 pw.print(prefix); pw.print("mNavigationBar="); 8194 pw.println(mNavigationBar); 8195 } 8196 if (mFocusedWindow != null) { 8197 pw.print(prefix); pw.print("mFocusedWindow="); 8198 pw.println(mFocusedWindow); 8199 } 8200 if (mFocusedApp != null) { 8201 pw.print(prefix); pw.print("mFocusedApp="); 8202 pw.println(mFocusedApp); 8203 } 8204 if (mTopFullscreenOpaqueWindowState != null) { 8205 pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState="); 8206 pw.println(mTopFullscreenOpaqueWindowState); 8207 } 8208 if (mTopFullscreenOpaqueOrDimmingWindowState != null) { 8209 pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState="); 8210 pw.println(mTopFullscreenOpaqueOrDimmingWindowState); 8211 } 8212 if (mForcingShowNavBar) { 8213 pw.print(prefix); pw.print("mForcingShowNavBar="); 8214 pw.println(mForcingShowNavBar); pw.print( "mForcingShowNavBarLayer="); 8215 pw.println(mForcingShowNavBarLayer); 8216 } 8217 pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen); 8218 pw.print(" mKeyguardOccluded="); pw.println(mKeyguardOccluded); 8219 pw.print(" mKeyguardOccludedChanged="); pw.println(mKeyguardOccludedChanged); 8220 pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded); 8221 pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); 8222 pw.print(" mForceStatusBarFromKeyguard="); 8223 pw.println(mForceStatusBarFromKeyguard); 8224 pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed); 8225 pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn); 8226 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout); 8227 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive); 8228 pw.print(prefix); pw.print("mEndcallBehavior="); pw.print(mEndcallBehavior); 8229 pw.print(" mIncallPowerBehavior="); pw.print(mIncallPowerBehavior); 8230 pw.print(" mIncallBackBehavior="); pw.print(mIncallBackBehavior); 8231 pw.print(" mLongPressOnHomeBehavior="); pw.println(mLongPressOnHomeBehavior); 8232 pw.print(prefix); pw.print("mLandscapeRotation="); pw.print(mLandscapeRotation); 8233 pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation); 8234 pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation); 8235 pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation); 8236 pw.print(prefix); pw.print("mDemoHdmiRotation="); pw.print(mDemoHdmiRotation); 8237 pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock); 8238 pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation); 8239 8240 mGlobalKeyManager.dump(prefix, pw); 8241 mStatusBarController.dump(pw, prefix); 8242 mNavigationBarController.dump(pw, prefix); 8243 PolicyControl.dump(prefix, pw); 8244 8245 if (mWakeGestureListener != null) { 8246 mWakeGestureListener.dump(pw, prefix); 8247 } 8248 if (mOrientationListener != null) { 8249 mOrientationListener.dump(pw, prefix); 8250 } 8251 if (mBurnInProtectionHelper != null) { 8252 mBurnInProtectionHelper.dump(prefix, pw); 8253 } 8254 if (mKeyguardDelegate != null) { 8255 mKeyguardDelegate.dump(prefix, pw); 8256 } 8257 } 8258} 8259