PhoneWindowManager.java revision e4e953ae4c42c10efe0c578a8dcfa5726bf8c6f7
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 && mStatusBarController.isTransientShowing()) { 5431 mStatusBarController.updateVisibilityLw(false /*transientAllowed*/, 5432 mLastSystemUiFlags, mLastSystemUiFlags); 5433 } 5434 if (statusBarExpanded && mNavigationBar != null) { 5435 if (mNavigationBarController.setBarShowingLw(true)) { 5436 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5437 } 5438 } 5439 } else if (mTopFullscreenOpaqueWindowState != null) { 5440 final int fl = PolicyControl.getWindowFlags(null, lp); 5441 if (localLOGV) { 5442 Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() 5443 + " shown position: " 5444 + mTopFullscreenOpaqueWindowState.getShownPositionLw()); 5445 Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs() 5446 + " lp.flags=0x" + Integer.toHexString(fl)); 5447 } 5448 topIsFullscreen = (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0 5449 || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 5450 // The subtle difference between the window for mTopFullscreenOpaqueWindowState 5451 // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window 5452 // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the 5453 // case though. 5454 if (mStatusBarController.isTransientShowing()) { 5455 if (mStatusBarController.setBarShowingLw(true)) { 5456 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5457 } 5458 } else if (topIsFullscreen 5459 && !mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID) 5460 && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID)) { 5461 if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar"); 5462 if (mStatusBarController.setBarShowingLw(false)) { 5463 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5464 } else { 5465 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding"); 5466 } 5467 } else { 5468 if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen"); 5469 if (mStatusBarController.setBarShowingLw(true)) { 5470 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5471 } 5472 } 5473 } 5474 } 5475 5476 if (mTopIsFullscreen != topIsFullscreen) { 5477 if (!topIsFullscreen) { 5478 // Force another layout when status bar becomes fully shown. 5479 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5480 } 5481 mTopIsFullscreen = topIsFullscreen; 5482 } 5483 5484 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5485 // If the navigation bar has been hidden or shown, we need to do another 5486 // layout pass to update that window. 5487 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5488 } 5489 5490 if (mShowingDream != mLastShowingDream) { 5491 mLastShowingDream = mShowingDream; 5492 mWindowManagerFuncs.notifyShowingDreamChanged(); 5493 } 5494 5495 // update since mAllowLockscreenWhenOn might have changed 5496 updateLockScreenTimeout(); 5497 return changes; 5498 } 5499 5500 /** 5501 * Updates the occluded state of the Keyguard. 5502 * 5503 * @return Whether the flags have changed and we have to redo the layout. 5504 */ 5505 private boolean setKeyguardOccludedLw(boolean isOccluded, boolean force) { 5506 if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded); 5507 final boolean wasOccluded = mKeyguardOccluded; 5508 final boolean showing = mKeyguardDelegate.isShowing(); 5509 final boolean changed = wasOccluded != isOccluded || force; 5510 if (!isOccluded && changed && showing) { 5511 mKeyguardOccluded = false; 5512 mKeyguardDelegate.setOccluded(false, true /* animate */); 5513 if (mStatusBar != null) { 5514 mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD; 5515 if (!mKeyguardDelegate.hasLockscreenWallpaper()) { 5516 mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER; 5517 } 5518 } 5519 return true; 5520 } else if (isOccluded && changed && showing) { 5521 mKeyguardOccluded = true; 5522 mKeyguardDelegate.setOccluded(true, false /* animate */); 5523 if (mStatusBar != null) { 5524 mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD; 5525 mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER; 5526 } 5527 return true; 5528 } else if (changed) { 5529 mKeyguardOccluded = isOccluded; 5530 mKeyguardDelegate.setOccluded(isOccluded, false /* animate */); 5531 return false; 5532 } else { 5533 return false; 5534 } 5535 } 5536 5537 private boolean isStatusBarKeyguard() { 5538 return mStatusBar != null 5539 && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; 5540 } 5541 5542 @Override 5543 public boolean allowAppAnimationsLw() { 5544 if (mShowingDream) { 5545 // If keyguard or dreams is currently visible, no reason to animate behind it. 5546 return false; 5547 } 5548 return true; 5549 } 5550 5551 @Override 5552 public int focusChangedLw(WindowState lastFocus, WindowState newFocus) { 5553 mFocusedWindow = newFocus; 5554 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5555 // If the navigation bar has been hidden or shown, we need to do another 5556 // layout pass to update that window. 5557 return FINISH_LAYOUT_REDO_LAYOUT; 5558 } 5559 return 0; 5560 } 5561 5562 /** {@inheritDoc} */ 5563 @Override 5564 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { 5565 // lid changed state 5566 final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED; 5567 if (newLidState == mLidState) { 5568 return; 5569 } 5570 5571 mLidState = newLidState; 5572 applyLidSwitchState(); 5573 updateRotation(true); 5574 5575 if (lidOpen) { 5576 wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch, 5577 "android.policy:LID"); 5578 } else if (!mLidControlsSleep) { 5579 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 5580 } 5581 } 5582 5583 @Override 5584 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) { 5585 int lensCoverState = lensCovered ? CAMERA_LENS_COVERED : CAMERA_LENS_UNCOVERED; 5586 if (mCameraLensCoverState == lensCoverState) { 5587 return; 5588 } 5589 if (mCameraLensCoverState == CAMERA_LENS_COVERED && 5590 lensCoverState == CAMERA_LENS_UNCOVERED) { 5591 Intent intent; 5592 final boolean keyguardActive = mKeyguardDelegate == null ? false : 5593 mKeyguardDelegate.isShowing(); 5594 if (keyguardActive) { 5595 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); 5596 } else { 5597 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); 5598 } 5599 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens, 5600 "android.policy:CAMERA_COVER"); 5601 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 5602 } 5603 mCameraLensCoverState = lensCoverState; 5604 } 5605 5606 void setHdmiPlugged(boolean plugged) { 5607 if (mHdmiPlugged != plugged) { 5608 mHdmiPlugged = plugged; 5609 updateRotation(true, true); 5610 Intent intent = new Intent(ACTION_HDMI_PLUGGED); 5611 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 5612 intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged); 5613 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 5614 } 5615 } 5616 5617 void initializeHdmiState() { 5618 boolean plugged = false; 5619 // watch for HDMI plug messages if the hdmi switch exists 5620 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) { 5621 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi"); 5622 5623 final String filename = "/sys/class/switch/hdmi/state"; 5624 FileReader reader = null; 5625 try { 5626 reader = new FileReader(filename); 5627 char[] buf = new char[15]; 5628 int n = reader.read(buf); 5629 if (n > 1) { 5630 plugged = 0 != Integer.parseInt(new String(buf, 0, n-1)); 5631 } 5632 } catch (IOException ex) { 5633 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5634 } catch (NumberFormatException ex) { 5635 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5636 } finally { 5637 if (reader != null) { 5638 try { 5639 reader.close(); 5640 } catch (IOException ex) { 5641 } 5642 } 5643 } 5644 } 5645 // This dance forces the code in setHdmiPlugged to run. 5646 // Always do this so the sticky intent is stuck (to false) if there is no hdmi. 5647 mHdmiPlugged = !plugged; 5648 setHdmiPlugged(!mHdmiPlugged); 5649 } 5650 5651 final Object mScreenshotLock = new Object(); 5652 ServiceConnection mScreenshotConnection = null; 5653 5654 final Runnable mScreenshotTimeout = new Runnable() { 5655 @Override public void run() { 5656 synchronized (mScreenshotLock) { 5657 if (mScreenshotConnection != null) { 5658 mContext.unbindService(mScreenshotConnection); 5659 mScreenshotConnection = null; 5660 notifyScreenshotError(); 5661 } 5662 } 5663 } 5664 }; 5665 5666 // Assume this is called from the Handler thread. 5667 private void takeScreenshot(final int screenshotType) { 5668 synchronized (mScreenshotLock) { 5669 if (mScreenshotConnection != null) { 5670 return; 5671 } 5672 final ComponentName serviceComponent = new ComponentName(SYSUI_PACKAGE, 5673 SYSUI_SCREENSHOT_SERVICE); 5674 final Intent serviceIntent = new Intent(); 5675 serviceIntent.setComponent(serviceComponent); 5676 ServiceConnection conn = new ServiceConnection() { 5677 @Override 5678 public void onServiceConnected(ComponentName name, IBinder service) { 5679 synchronized (mScreenshotLock) { 5680 if (mScreenshotConnection != this) { 5681 return; 5682 } 5683 Messenger messenger = new Messenger(service); 5684 Message msg = Message.obtain(null, screenshotType); 5685 final ServiceConnection myConn = this; 5686 Handler h = new Handler(mHandler.getLooper()) { 5687 @Override 5688 public void handleMessage(Message msg) { 5689 synchronized (mScreenshotLock) { 5690 if (mScreenshotConnection == myConn) { 5691 mContext.unbindService(mScreenshotConnection); 5692 mScreenshotConnection = null; 5693 mHandler.removeCallbacks(mScreenshotTimeout); 5694 } 5695 } 5696 } 5697 }; 5698 msg.replyTo = new Messenger(h); 5699 msg.arg1 = msg.arg2 = 0; 5700 if (mStatusBar != null && mStatusBar.isVisibleLw()) 5701 msg.arg1 = 1; 5702 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) 5703 msg.arg2 = 1; 5704 try { 5705 messenger.send(msg); 5706 } catch (RemoteException e) { 5707 } 5708 } 5709 } 5710 5711 @Override 5712 public void onServiceDisconnected(ComponentName name) { 5713 synchronized (mScreenshotLock) { 5714 if (mScreenshotConnection != null) { 5715 mContext.unbindService(mScreenshotConnection); 5716 mScreenshotConnection = null; 5717 mHandler.removeCallbacks(mScreenshotTimeout); 5718 notifyScreenshotError(); 5719 } 5720 } 5721 } 5722 }; 5723 if (mContext.bindServiceAsUser(serviceIntent, conn, 5724 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, 5725 UserHandle.CURRENT)) { 5726 mScreenshotConnection = conn; 5727 mHandler.postDelayed(mScreenshotTimeout, 10000); 5728 } 5729 } 5730 } 5731 5732 /** 5733 * Notifies the screenshot service to show an error. 5734 */ 5735 private void notifyScreenshotError() { 5736 // If the service process is killed, then ask it to clean up after itself 5737 final ComponentName errorComponent = new ComponentName(SYSUI_PACKAGE, 5738 SYSUI_SCREENSHOT_ERROR_RECEIVER); 5739 Intent errorIntent = new Intent(Intent.ACTION_USER_PRESENT); 5740 errorIntent.setComponent(errorComponent); 5741 errorIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | 5742 Intent.FLAG_RECEIVER_FOREGROUND); 5743 mContext.sendBroadcastAsUser(errorIntent, UserHandle.CURRENT); 5744 } 5745 5746 /** {@inheritDoc} */ 5747 @Override 5748 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { 5749 if (!mSystemBooted) { 5750 // If we have not yet booted, don't let key events do anything. 5751 return 0; 5752 } 5753 5754 final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; 5755 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 5756 final boolean canceled = event.isCanceled(); 5757 final int keyCode = event.getKeyCode(); 5758 5759 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0; 5760 5761 // If screen is off then we treat the case where the keyguard is open but hidden 5762 // the same as if it were open and in front. 5763 // This will prevent any keys other than the power button from waking the screen 5764 // when the keyguard is hidden by another activity. 5765 final boolean keyguardActive = (mKeyguardDelegate == null ? false : 5766 (interactive ? 5767 isKeyguardShowingAndNotOccluded() : 5768 mKeyguardDelegate.isShowing())); 5769 5770 if (DEBUG_INPUT) { 5771 Log.d(TAG, "interceptKeyTq keycode=" + keyCode 5772 + " interactive=" + interactive + " keyguardActive=" + keyguardActive 5773 + " policyFlags=" + Integer.toHexString(policyFlags)); 5774 } 5775 5776 // Basic policy based on interactive state. 5777 int result; 5778 boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 5779 || event.isWakeKey(); 5780 if (interactive || (isInjected && !isWakeKey)) { 5781 // When the device is interactive or the key is injected pass the 5782 // key to the application. 5783 result = ACTION_PASS_TO_USER; 5784 isWakeKey = false; 5785 5786 if (interactive) { 5787 // If the screen is awake, but the button pressed was the one that woke the device 5788 // then don't pass it to the application 5789 if (keyCode == mPendingWakeKey && !down) { 5790 result = 0; 5791 } 5792 // Reset the pending key 5793 mPendingWakeKey = PENDING_KEY_NULL; 5794 } 5795 } else if (!interactive && shouldDispatchInputWhenNonInteractive(event)) { 5796 // If we're currently dozing with the screen on and the keyguard showing, pass the key 5797 // to the application but preserve its wake key status to make sure we still move 5798 // from dozing to fully interactive if we would normally go from off to fully 5799 // interactive. 5800 result = ACTION_PASS_TO_USER; 5801 // Since we're dispatching the input, reset the pending key 5802 mPendingWakeKey = PENDING_KEY_NULL; 5803 } else { 5804 // When the screen is off and the key is not injected, determine whether 5805 // to wake the device but don't pass the key to the application. 5806 result = 0; 5807 if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) { 5808 isWakeKey = false; 5809 } 5810 // Cache the wake key on down event so we can also avoid sending the up event to the app 5811 if (isWakeKey && down) { 5812 mPendingWakeKey = keyCode; 5813 } 5814 } 5815 5816 // If the key would be handled globally, just return the result, don't worry about special 5817 // key processing. 5818 if (isValidGlobalKey(keyCode) 5819 && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) { 5820 if (isWakeKey) { 5821 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 5822 } 5823 return result; 5824 } 5825 5826 boolean useHapticFeedback = down 5827 && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0 5828 && event.getRepeatCount() == 0; 5829 5830 // Handle special keys. 5831 switch (keyCode) { 5832 case KeyEvent.KEYCODE_BACK: { 5833 if (down) { 5834 interceptBackKeyDown(); 5835 } else { 5836 boolean handled = interceptBackKeyUp(event); 5837 5838 // Don't pass back press to app if we've already handled it via long press 5839 if (handled) { 5840 result &= ~ACTION_PASS_TO_USER; 5841 } 5842 } 5843 break; 5844 } 5845 5846 case KeyEvent.KEYCODE_VOLUME_DOWN: 5847 case KeyEvent.KEYCODE_VOLUME_UP: 5848 case KeyEvent.KEYCODE_VOLUME_MUTE: { 5849 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 5850 if (down) { 5851 if (interactive && !mScreenshotChordVolumeDownKeyTriggered 5852 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5853 mScreenshotChordVolumeDownKeyTriggered = true; 5854 mScreenshotChordVolumeDownKeyTime = event.getDownTime(); 5855 mScreenshotChordVolumeDownKeyConsumed = false; 5856 cancelPendingPowerKeyAction(); 5857 interceptScreenshotChord(); 5858 interceptAccessibilityShortcutChord(); 5859 } 5860 } else { 5861 mScreenshotChordVolumeDownKeyTriggered = false; 5862 cancelPendingScreenshotChordAction(); 5863 cancelPendingAccessibilityShortcutAction(); 5864 } 5865 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 5866 if (down) { 5867 if (interactive && !mA11yShortcutChordVolumeUpKeyTriggered 5868 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5869 mA11yShortcutChordVolumeUpKeyTriggered = true; 5870 mA11yShortcutChordVolumeUpKeyTime = event.getDownTime(); 5871 mA11yShortcutChordVolumeUpKeyConsumed = false; 5872 cancelPendingPowerKeyAction(); 5873 cancelPendingScreenshotChordAction(); 5874 interceptAccessibilityShortcutChord(); 5875 } 5876 } else { 5877 mA11yShortcutChordVolumeUpKeyTriggered = false; 5878 cancelPendingScreenshotChordAction(); 5879 cancelPendingAccessibilityShortcutAction(); 5880 } 5881 } 5882 if (down) { 5883 TelecomManager telecomManager = getTelecommService(); 5884 if (telecomManager != null) { 5885 if (telecomManager.isRinging()) { 5886 // If an incoming call is ringing, either VOLUME key means 5887 // "silence ringer". We handle these keys here, rather than 5888 // in the InCallScreen, to make sure we'll respond to them 5889 // even if the InCallScreen hasn't come to the foreground yet. 5890 // Look for the DOWN event here, to agree with the "fallback" 5891 // behavior in the InCallScreen. 5892 Log.i(TAG, "interceptKeyBeforeQueueing:" 5893 + " VOLUME key-down while ringing: Silence ringer!"); 5894 5895 // Silence the ringer. (It's safe to call this 5896 // even if the ringer has already been silenced.) 5897 telecomManager.silenceRinger(); 5898 5899 // And *don't* pass this key thru to the current activity 5900 // (which is probably the InCallScreen.) 5901 result &= ~ACTION_PASS_TO_USER; 5902 break; 5903 } 5904 if (telecomManager.isInCall() 5905 && (result & ACTION_PASS_TO_USER) == 0) { 5906 // If we are in call but we decided not to pass the key to 5907 // the application, just pass it to the session service. 5908 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 5909 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false); 5910 break; 5911 } 5912 } 5913 } 5914 if (mUseTvRouting) { 5915 // On TVs, defer special key handlings to 5916 // {@link interceptKeyBeforeDispatching()}. 5917 result |= ACTION_PASS_TO_USER; 5918 } else if ((result & ACTION_PASS_TO_USER) == 0) { 5919 // If we aren't passing to the user and no one else 5920 // handled it send it to the session manager to 5921 // figure out. 5922 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 5923 event, AudioManager.USE_DEFAULT_STREAM_TYPE, true); 5924 } 5925 break; 5926 } 5927 5928 case KeyEvent.KEYCODE_ENDCALL: { 5929 result &= ~ACTION_PASS_TO_USER; 5930 if (down) { 5931 TelecomManager telecomManager = getTelecommService(); 5932 boolean hungUp = false; 5933 if (telecomManager != null) { 5934 hungUp = telecomManager.endCall(); 5935 } 5936 if (interactive && !hungUp) { 5937 mEndCallKeyHandled = false; 5938 mHandler.postDelayed(mEndCallLongPress, 5939 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 5940 } else { 5941 mEndCallKeyHandled = true; 5942 } 5943 } else { 5944 if (!mEndCallKeyHandled) { 5945 mHandler.removeCallbacks(mEndCallLongPress); 5946 if (!canceled) { 5947 if ((mEndcallBehavior 5948 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) { 5949 if (goHome()) { 5950 break; 5951 } 5952 } 5953 if ((mEndcallBehavior 5954 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { 5955 mPowerManager.goToSleep(event.getEventTime(), 5956 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); 5957 isWakeKey = false; 5958 } 5959 } 5960 } 5961 } 5962 break; 5963 } 5964 5965 case KeyEvent.KEYCODE_POWER: { 5966 // Any activity on the power button stops the accessibility shortcut 5967 cancelPendingAccessibilityShortcutAction(); 5968 result &= ~ACTION_PASS_TO_USER; 5969 isWakeKey = false; // wake-up will be handled separately 5970 if (down) { 5971 interceptPowerKeyDown(event, interactive); 5972 } else { 5973 interceptPowerKeyUp(event, interactive, canceled); 5974 } 5975 break; 5976 } 5977 5978 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN: 5979 // fall through 5980 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP: 5981 // fall through 5982 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT: 5983 // fall through 5984 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: { 5985 result &= ~ACTION_PASS_TO_USER; 5986 interceptSystemNavigationKey(event); 5987 break; 5988 } 5989 5990 case KeyEvent.KEYCODE_SLEEP: { 5991 result &= ~ACTION_PASS_TO_USER; 5992 isWakeKey = false; 5993 if (!mPowerManager.isInteractive()) { 5994 useHapticFeedback = false; // suppress feedback if already non-interactive 5995 } 5996 if (down) { 5997 sleepPress(event.getEventTime()); 5998 } else { 5999 sleepRelease(event.getEventTime()); 6000 } 6001 break; 6002 } 6003 6004 case KeyEvent.KEYCODE_SOFT_SLEEP: { 6005 result &= ~ACTION_PASS_TO_USER; 6006 isWakeKey = false; 6007 if (!down) { 6008 mPowerManagerInternal.setUserInactiveOverrideFromWindowManager(); 6009 } 6010 break; 6011 } 6012 6013 case KeyEvent.KEYCODE_WAKEUP: { 6014 result &= ~ACTION_PASS_TO_USER; 6015 isWakeKey = true; 6016 break; 6017 } 6018 6019 case KeyEvent.KEYCODE_MEDIA_PLAY: 6020 case KeyEvent.KEYCODE_MEDIA_PAUSE: 6021 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 6022 case KeyEvent.KEYCODE_HEADSETHOOK: 6023 case KeyEvent.KEYCODE_MUTE: 6024 case KeyEvent.KEYCODE_MEDIA_STOP: 6025 case KeyEvent.KEYCODE_MEDIA_NEXT: 6026 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 6027 case KeyEvent.KEYCODE_MEDIA_REWIND: 6028 case KeyEvent.KEYCODE_MEDIA_RECORD: 6029 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 6030 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { 6031 if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) { 6032 // If the global session is active pass all media keys to it 6033 // instead of the active window. 6034 result &= ~ACTION_PASS_TO_USER; 6035 } 6036 if ((result & ACTION_PASS_TO_USER) == 0) { 6037 // Only do this if we would otherwise not pass it to the user. In that 6038 // case, the PhoneWindow class will do the same thing, except it will 6039 // only do it if the showing app doesn't process the key on its own. 6040 // Note that we need to make a copy of the key event here because the 6041 // original key event will be recycled when we return. 6042 mBroadcastWakeLock.acquire(); 6043 Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK, 6044 new KeyEvent(event)); 6045 msg.setAsynchronous(true); 6046 msg.sendToTarget(); 6047 } 6048 break; 6049 } 6050 6051 case KeyEvent.KEYCODE_CALL: { 6052 if (down) { 6053 TelecomManager telecomManager = getTelecommService(); 6054 if (telecomManager != null) { 6055 if (telecomManager.isRinging()) { 6056 Log.i(TAG, "interceptKeyBeforeQueueing:" 6057 + " CALL key-down while ringing: Answer the call!"); 6058 telecomManager.acceptRingingCall(); 6059 6060 // And *don't* pass this key thru to the current activity 6061 // (which is presumably the InCallScreen.) 6062 result &= ~ACTION_PASS_TO_USER; 6063 } 6064 } 6065 } 6066 break; 6067 } 6068 case KeyEvent.KEYCODE_VOICE_ASSIST: { 6069 // Only do this if we would otherwise not pass it to the user. In that case, 6070 // interceptKeyBeforeDispatching would apply a similar but different policy in 6071 // order to invoke voice assist actions. Note that we need to make a copy of the 6072 // key event here because the original key event will be recycled when we return. 6073 if ((result & ACTION_PASS_TO_USER) == 0 && !down) { 6074 mBroadcastWakeLock.acquire(); 6075 Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK, 6076 keyguardActive ? 1 : 0, 0); 6077 msg.setAsynchronous(true); 6078 msg.sendToTarget(); 6079 } 6080 break; 6081 } 6082 case KeyEvent.KEYCODE_WINDOW: { 6083 if (mShortPressWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) { 6084 if (mPictureInPictureVisible) { 6085 // Consumes the key only if picture-in-picture is visible to show 6086 // picture-in-picture control menu. This gives a chance to the foreground 6087 // activity to customize PIP key behavior. 6088 if (!down) { 6089 showPictureInPictureMenu(event); 6090 } 6091 result &= ~ACTION_PASS_TO_USER; 6092 } 6093 } 6094 break; 6095 } 6096 } 6097 6098 if (useHapticFeedback) { 6099 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); 6100 } 6101 6102 if (isWakeKey) { 6103 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 6104 } 6105 6106 return result; 6107 } 6108 6109 /** 6110 * Handle statusbar expansion events. 6111 * @param event 6112 */ 6113 private void interceptSystemNavigationKey(KeyEvent event) { 6114 if (event.getAction() == KeyEvent.ACTION_UP) { 6115 if (!mAccessibilityManager.isEnabled() 6116 || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) { 6117 if (areSystemNavigationKeysEnabled()) { 6118 IStatusBarService sbar = getStatusBarService(); 6119 if (sbar != null) { 6120 try { 6121 sbar.handleSystemNavigationKey(event.getKeyCode()); 6122 } catch (RemoteException e1) { 6123 // oops, no statusbar. Ignore event. 6124 } 6125 } 6126 } 6127 } 6128 } 6129 } 6130 6131 /** 6132 * Returns true if the key can have global actions attached to it. 6133 * We reserve all power management keys for the system since they require 6134 * very careful handling. 6135 */ 6136 private static boolean isValidGlobalKey(int keyCode) { 6137 switch (keyCode) { 6138 case KeyEvent.KEYCODE_POWER: 6139 case KeyEvent.KEYCODE_WAKEUP: 6140 case KeyEvent.KEYCODE_SLEEP: 6141 return false; 6142 default: 6143 return true; 6144 } 6145 } 6146 6147 /** 6148 * When the screen is off we ignore some keys that might otherwise typically 6149 * be considered wake keys. We filter them out here. 6150 * 6151 * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it 6152 * is always considered a wake key. 6153 */ 6154 private boolean isWakeKeyWhenScreenOff(int keyCode) { 6155 switch (keyCode) { 6156 // ignore volume keys unless docked 6157 case KeyEvent.KEYCODE_VOLUME_UP: 6158 case KeyEvent.KEYCODE_VOLUME_DOWN: 6159 case KeyEvent.KEYCODE_VOLUME_MUTE: 6160 return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED; 6161 6162 // ignore media and camera keys 6163 case KeyEvent.KEYCODE_MUTE: 6164 case KeyEvent.KEYCODE_HEADSETHOOK: 6165 case KeyEvent.KEYCODE_MEDIA_PLAY: 6166 case KeyEvent.KEYCODE_MEDIA_PAUSE: 6167 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 6168 case KeyEvent.KEYCODE_MEDIA_STOP: 6169 case KeyEvent.KEYCODE_MEDIA_NEXT: 6170 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 6171 case KeyEvent.KEYCODE_MEDIA_REWIND: 6172 case KeyEvent.KEYCODE_MEDIA_RECORD: 6173 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 6174 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: 6175 case KeyEvent.KEYCODE_CAMERA: 6176 return false; 6177 } 6178 return true; 6179 } 6180 6181 6182 /** {@inheritDoc} */ 6183 @Override 6184 public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) { 6185 if ((policyFlags & FLAG_WAKE) != 0) { 6186 if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion, 6187 "android.policy:MOTION")) { 6188 return 0; 6189 } 6190 } 6191 6192 if (shouldDispatchInputWhenNonInteractive(null)) { 6193 return ACTION_PASS_TO_USER; 6194 } 6195 6196 // If we have not passed the action up and we are in theater mode without dreaming, 6197 // there will be no dream to intercept the touch and wake into ambient. The device should 6198 // wake up in this case. 6199 if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) { 6200 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming, 6201 "android.policy:MOTION"); 6202 } 6203 6204 return 0; 6205 } 6206 6207 private boolean shouldDispatchInputWhenNonInteractive(KeyEvent event) { 6208 final boolean displayOff = (mDisplay == null || mDisplay.getState() == Display.STATE_OFF); 6209 6210 if (displayOff && !mHasFeatureWatch) { 6211 return false; 6212 } 6213 6214 // Send events to keyguard while the screen is on and it's showing. 6215 if (isKeyguardShowingAndNotOccluded() && !displayOff) { 6216 return true; 6217 } 6218 6219 // Watches handle BACK specially 6220 if (mHasFeatureWatch 6221 && event != null 6222 && (event.getKeyCode() == KeyEvent.KEYCODE_BACK 6223 || event.getKeyCode() == KeyEvent.KEYCODE_STEM_PRIMARY)) { 6224 return false; 6225 } 6226 6227 // Send events to a dozing dream even if the screen is off since the dream 6228 // is in control of the state of the screen. 6229 IDreamManager dreamManager = getDreamManager(); 6230 6231 try { 6232 if (dreamManager != null && dreamManager.isDreaming()) { 6233 return true; 6234 } 6235 } catch (RemoteException e) { 6236 Slog.e(TAG, "RemoteException when checking if dreaming", e); 6237 } 6238 6239 // Otherwise, consume events since the user can't see what is being 6240 // interacted with. 6241 return false; 6242 } 6243 6244 private void dispatchDirectAudioEvent(KeyEvent event) { 6245 if (event.getAction() != KeyEvent.ACTION_DOWN) { 6246 return; 6247 } 6248 int keyCode = event.getKeyCode(); 6249 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 6250 | AudioManager.FLAG_FROM_KEY; 6251 String pkgName = mContext.getOpPackageName(); 6252 switch (keyCode) { 6253 case KeyEvent.KEYCODE_VOLUME_UP: 6254 try { 6255 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 6256 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6257 } catch (RemoteException e) { 6258 Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e); 6259 } 6260 break; 6261 case KeyEvent.KEYCODE_VOLUME_DOWN: 6262 try { 6263 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 6264 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6265 } catch (RemoteException e) { 6266 Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e); 6267 } 6268 break; 6269 case KeyEvent.KEYCODE_VOLUME_MUTE: 6270 try { 6271 if (event.getRepeatCount() == 0) { 6272 getAudioService().adjustSuggestedStreamVolume( 6273 AudioManager.ADJUST_TOGGLE_MUTE, 6274 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6275 } 6276 } catch (RemoteException e) { 6277 Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e); 6278 } 6279 break; 6280 } 6281 } 6282 6283 void dispatchMediaKeyWithWakeLock(KeyEvent event) { 6284 if (DEBUG_INPUT) { 6285 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event); 6286 } 6287 6288 if (mHavePendingMediaKeyRepeatWithWakeLock) { 6289 if (DEBUG_INPUT) { 6290 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat"); 6291 } 6292 6293 mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK); 6294 mHavePendingMediaKeyRepeatWithWakeLock = false; 6295 mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock 6296 } 6297 6298 dispatchMediaKeyWithWakeLockToAudioService(event); 6299 6300 if (event.getAction() == KeyEvent.ACTION_DOWN 6301 && event.getRepeatCount() == 0) { 6302 mHavePendingMediaKeyRepeatWithWakeLock = true; 6303 6304 Message msg = mHandler.obtainMessage( 6305 MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event); 6306 msg.setAsynchronous(true); 6307 mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout()); 6308 } else { 6309 mBroadcastWakeLock.release(); 6310 } 6311 } 6312 6313 void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) { 6314 mHavePendingMediaKeyRepeatWithWakeLock = false; 6315 6316 KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event, 6317 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS); 6318 if (DEBUG_INPUT) { 6319 Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent); 6320 } 6321 6322 dispatchMediaKeyWithWakeLockToAudioService(repeatEvent); 6323 mBroadcastWakeLock.release(); 6324 } 6325 6326 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) { 6327 if (mActivityManagerInternal.isSystemReady()) { 6328 MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true); 6329 } 6330 } 6331 6332 void launchVoiceAssistWithWakeLock(boolean keyguardActive) { 6333 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface( 6334 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 6335 if (dic != null) { 6336 try { 6337 dic.exitIdle("voice-search"); 6338 } catch (RemoteException e) { 6339 } 6340 } 6341 Intent voiceIntent = 6342 new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 6343 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive); 6344 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 6345 mBroadcastWakeLock.release(); 6346 } 6347 6348 BroadcastReceiver mDockReceiver = new BroadcastReceiver() { 6349 @Override 6350 public void onReceive(Context context, Intent intent) { 6351 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 6352 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 6353 Intent.EXTRA_DOCK_STATE_UNDOCKED); 6354 } else { 6355 try { 6356 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface( 6357 ServiceManager.getService(Context.UI_MODE_SERVICE)); 6358 mUiMode = uiModeService.getCurrentModeType(); 6359 } catch (RemoteException e) { 6360 } 6361 } 6362 updateRotation(true); 6363 synchronized (mLock) { 6364 updateOrientationListenerLp(); 6365 } 6366 } 6367 }; 6368 6369 BroadcastReceiver mDreamReceiver = new BroadcastReceiver() { 6370 @Override 6371 public void onReceive(Context context, Intent intent) { 6372 if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) { 6373 if (mKeyguardDelegate != null) { 6374 mKeyguardDelegate.onDreamingStarted(); 6375 } 6376 } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) { 6377 if (mKeyguardDelegate != null) { 6378 mKeyguardDelegate.onDreamingStopped(); 6379 } 6380 } 6381 } 6382 }; 6383 6384 BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() { 6385 @Override 6386 public void onReceive(Context context, Intent intent) { 6387 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 6388 // tickle the settings observer: this first ensures that we're 6389 // observing the relevant settings for the newly-active user, 6390 // and then updates our own bookkeeping based on the now- 6391 // current user. 6392 mSettingsObserver.onChange(false); 6393 6394 // force a re-application of focused window sysui visibility. 6395 // the window may never have been shown for this user 6396 // e.g. the keyguard when going through the new-user setup flow 6397 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6398 mLastSystemUiFlags = 0; 6399 updateSystemUiVisibilityLw(); 6400 } 6401 } 6402 } 6403 }; 6404 6405 private final Runnable mHiddenNavPanic = new Runnable() { 6406 @Override 6407 public void run() { 6408 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6409 if (!isUserSetupComplete()) { 6410 // Swipe-up for navigation bar is disabled during setup 6411 return; 6412 } 6413 mPendingPanicGestureUptime = SystemClock.uptimeMillis(); 6414 if (!isNavBarEmpty(mLastSystemUiFlags)) { 6415 mNavigationBarController.showTransient(); 6416 } 6417 } 6418 } 6419 }; 6420 6421 private void requestTransientBars(WindowState swipeTarget) { 6422 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6423 if (!isUserSetupComplete()) { 6424 // Swipe-up for navigation bar is disabled during setup 6425 return; 6426 } 6427 boolean sb = mStatusBarController.checkShowTransientBarLw(); 6428 boolean nb = mNavigationBarController.checkShowTransientBarLw() 6429 && !isNavBarEmpty(mLastSystemUiFlags); 6430 if (sb || nb) { 6431 // Don't show status bar when swiping on already visible navigation bar 6432 if (!nb && swipeTarget == mNavigationBar) { 6433 if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target"); 6434 return; 6435 } 6436 if (sb) mStatusBarController.showTransient(); 6437 if (nb) mNavigationBarController.showTransient(); 6438 mImmersiveModeConfirmation.confirmCurrentPrompt(); 6439 updateSystemUiVisibilityLw(); 6440 } 6441 } 6442 } 6443 6444 // Called on the PowerManager's Notifier thread. 6445 @Override 6446 public void startedGoingToSleep(int why) { 6447 if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")"); 6448 mCameraGestureTriggeredDuringGoingToSleep = false; 6449 mGoingToSleep = true; 6450 if (mKeyguardDelegate != null) { 6451 mKeyguardDelegate.onStartedGoingToSleep(why); 6452 } 6453 } 6454 6455 // Called on the PowerManager's Notifier thread. 6456 @Override 6457 public void finishedGoingToSleep(int why) { 6458 EventLog.writeEvent(70000, 0); 6459 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")"); 6460 MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000); 6461 6462 mGoingToSleep = false; 6463 6464 // We must get this work done here because the power manager will drop 6465 // the wake lock and let the system suspend once this function returns. 6466 synchronized (mLock) { 6467 mAwake = false; 6468 updateWakeGestureListenerLp(); 6469 updateOrientationListenerLp(); 6470 updateLockScreenTimeout(); 6471 } 6472 if (mKeyguardDelegate != null) { 6473 mKeyguardDelegate.onFinishedGoingToSleep(why, 6474 mCameraGestureTriggeredDuringGoingToSleep); 6475 } 6476 mCameraGestureTriggeredDuringGoingToSleep = false; 6477 } 6478 6479 // Called on the PowerManager's Notifier thread. 6480 @Override 6481 public void startedWakingUp() { 6482 EventLog.writeEvent(70000, 1); 6483 if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up..."); 6484 6485 // Since goToSleep performs these functions synchronously, we must 6486 // do the same here. We cannot post this work to a handler because 6487 // that might cause it to become reordered with respect to what 6488 // may happen in a future call to goToSleep. 6489 synchronized (mLock) { 6490 mAwake = true; 6491 6492 updateWakeGestureListenerLp(); 6493 updateOrientationListenerLp(); 6494 updateLockScreenTimeout(); 6495 } 6496 6497 if (mKeyguardDelegate != null) { 6498 mKeyguardDelegate.onStartedWakingUp(); 6499 } 6500 } 6501 6502 // Called on the PowerManager's Notifier thread. 6503 @Override 6504 public void finishedWakingUp() { 6505 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up..."); 6506 } 6507 6508 private void wakeUpFromPowerKey(long eventTime) { 6509 wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER"); 6510 } 6511 6512 private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) { 6513 final boolean theaterModeEnabled = isTheaterModeEnabled(); 6514 if (!wakeInTheaterMode && theaterModeEnabled) { 6515 return false; 6516 } 6517 6518 if (theaterModeEnabled) { 6519 Settings.Global.putInt(mContext.getContentResolver(), 6520 Settings.Global.THEATER_MODE_ON, 0); 6521 } 6522 6523 mPowerManager.wakeUp(wakeTime, reason); 6524 return true; 6525 } 6526 6527 private void finishKeyguardDrawn() { 6528 synchronized (mLock) { 6529 if (!mScreenOnEarly || mKeyguardDrawComplete) { 6530 return; // We are not awake yet or we have already informed of this event. 6531 } 6532 6533 mKeyguardDrawComplete = true; 6534 if (mKeyguardDelegate != null) { 6535 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6536 } 6537 mWindowManagerDrawComplete = false; 6538 } 6539 6540 // ... eventually calls finishWindowsDrawn which will finalize our screen turn on 6541 // as well as enabling the orientation change logic/sensor. 6542 mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, 6543 WAITING_FOR_DRAWN_TIMEOUT); 6544 } 6545 6546 // Called on the DisplayManager's DisplayPowerController thread. 6547 @Override 6548 public void screenTurnedOff() { 6549 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off..."); 6550 6551 updateScreenOffSleepToken(true); 6552 synchronized (mLock) { 6553 mScreenOnEarly = false; 6554 mScreenOnFully = false; 6555 mKeyguardDrawComplete = false; 6556 mWindowManagerDrawComplete = false; 6557 mScreenOnListener = null; 6558 updateOrientationListenerLp(); 6559 6560 if (mKeyguardDelegate != null) { 6561 mKeyguardDelegate.onScreenTurnedOff(); 6562 } 6563 } 6564 reportScreenStateToVrManager(false); 6565 } 6566 6567 // Called on the DisplayManager's DisplayPowerController thread. 6568 @Override 6569 public void screenTurningOn(final ScreenOnListener screenOnListener) { 6570 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on..."); 6571 6572 updateScreenOffSleepToken(false); 6573 synchronized (mLock) { 6574 mScreenOnEarly = true; 6575 mScreenOnFully = false; 6576 mKeyguardDrawComplete = false; 6577 mWindowManagerDrawComplete = false; 6578 mScreenOnListener = screenOnListener; 6579 6580 if (mKeyguardDelegate != null) { 6581 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6582 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000); 6583 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); 6584 } else { 6585 if (DEBUG_WAKEUP) Slog.d(TAG, 6586 "null mKeyguardDelegate: setting mKeyguardDrawComplete."); 6587 finishKeyguardDrawn(); 6588 } 6589 } 6590 } 6591 6592 // Called on the DisplayManager's DisplayPowerController thread. 6593 @Override 6594 public void screenTurnedOn() { 6595 synchronized (mLock) { 6596 if (mKeyguardDelegate != null) { 6597 mKeyguardDelegate.onScreenTurnedOn(); 6598 } 6599 } 6600 reportScreenStateToVrManager(true); 6601 } 6602 6603 private void reportScreenStateToVrManager(boolean isScreenOn) { 6604 if (mVrManagerInternal == null) { 6605 return; 6606 } 6607 mVrManagerInternal.onScreenStateChanged(isScreenOn); 6608 } 6609 6610 private void finishWindowsDrawn() { 6611 synchronized (mLock) { 6612 if (!mScreenOnEarly || mWindowManagerDrawComplete) { 6613 return; // Screen is not turned on or we did already handle this case earlier. 6614 } 6615 6616 mWindowManagerDrawComplete = true; 6617 } 6618 6619 finishScreenTurningOn(); 6620 } 6621 6622 private void finishScreenTurningOn() { 6623 synchronized (mLock) { 6624 // We have just finished drawing screen content. Since the orientation listener 6625 // gets only installed when all windows are drawn, we try to install it again. 6626 updateOrientationListenerLp(); 6627 } 6628 final ScreenOnListener listener; 6629 final boolean enableScreen; 6630 synchronized (mLock) { 6631 if (DEBUG_WAKEUP) Slog.d(TAG, 6632 "finishScreenTurningOn: mAwake=" + mAwake 6633 + ", mScreenOnEarly=" + mScreenOnEarly 6634 + ", mScreenOnFully=" + mScreenOnFully 6635 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete 6636 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); 6637 6638 if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete 6639 || (mAwake && !mKeyguardDrawComplete)) { 6640 return; // spurious or not ready yet 6641 } 6642 6643 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on..."); 6644 listener = mScreenOnListener; 6645 mScreenOnListener = null; 6646 mScreenOnFully = true; 6647 6648 // Remember the first time we draw the keyguard so we know when we're done with 6649 // the main part of booting and can enable the screen and hide boot messages. 6650 if (!mKeyguardDrawnOnce && mAwake) { 6651 mKeyguardDrawnOnce = true; 6652 enableScreen = true; 6653 if (mBootMessageNeedsHiding) { 6654 mBootMessageNeedsHiding = false; 6655 hideBootMessages(); 6656 } 6657 } else { 6658 enableScreen = false; 6659 } 6660 } 6661 6662 if (listener != null) { 6663 listener.onScreenOn(); 6664 } 6665 6666 if (enableScreen) { 6667 try { 6668 mWindowManager.enableScreenIfNeeded(); 6669 } catch (RemoteException unhandled) { 6670 } 6671 } 6672 } 6673 6674 private void handleHideBootMessage() { 6675 synchronized (mLock) { 6676 if (!mKeyguardDrawnOnce) { 6677 mBootMessageNeedsHiding = true; 6678 return; // keyguard hasn't drawn the first time yet, not done booting 6679 } 6680 } 6681 6682 if (mBootMsgDialog != null) { 6683 if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing"); 6684 mBootMsgDialog.dismiss(); 6685 mBootMsgDialog = null; 6686 } 6687 } 6688 6689 @Override 6690 public boolean isScreenOn() { 6691 return mScreenOnFully; 6692 } 6693 6694 /** {@inheritDoc} */ 6695 @Override 6696 public void enableKeyguard(boolean enabled) { 6697 if (mKeyguardDelegate != null) { 6698 mKeyguardDelegate.setKeyguardEnabled(enabled); 6699 } 6700 } 6701 6702 /** {@inheritDoc} */ 6703 @Override 6704 public void exitKeyguardSecurely(OnKeyguardExitResult callback) { 6705 if (mKeyguardDelegate != null) { 6706 mKeyguardDelegate.verifyUnlock(callback); 6707 } 6708 } 6709 6710 @Override 6711 public boolean isKeyguardShowingAndNotOccluded() { 6712 if (mKeyguardDelegate == null) return false; 6713 return mKeyguardDelegate.isShowing() && !mKeyguardOccluded; 6714 } 6715 6716 @Override 6717 public boolean isKeyguardTrustedLw() { 6718 if (mKeyguardDelegate == null) return false; 6719 return mKeyguardDelegate.isTrusted(); 6720 } 6721 6722 /** {@inheritDoc} */ 6723 @Override 6724 public boolean isKeyguardLocked() { 6725 return keyguardOn(); 6726 } 6727 6728 /** {@inheritDoc} */ 6729 @Override 6730 public boolean isKeyguardSecure(int userId) { 6731 if (mKeyguardDelegate == null) return false; 6732 return mKeyguardDelegate.isSecure(userId); 6733 } 6734 6735 /** {@inheritDoc} */ 6736 @Override 6737 public boolean isKeyguardOccluded() { 6738 if (mKeyguardDelegate == null) return false; 6739 return mKeyguardOccluded; 6740 } 6741 6742 /** {@inheritDoc} */ 6743 @Override 6744 public boolean inKeyguardRestrictedKeyInputMode() { 6745 if (mKeyguardDelegate == null) return false; 6746 return mKeyguardDelegate.isInputRestricted(); 6747 } 6748 6749 @Override 6750 public void dismissKeyguardLw(IKeyguardDismissCallback callback) { 6751 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 6752 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw"); 6753 6754 // ask the keyguard to prompt the user to authenticate if necessary 6755 mKeyguardDelegate.dismiss(callback); 6756 } else if (callback != null) { 6757 try { 6758 callback.onDismissError(); 6759 } catch (RemoteException e) { 6760 Slog.w(TAG, "Failed to call callback", e); 6761 } 6762 } 6763 } 6764 6765 @Override 6766 public boolean isKeyguardDrawnLw() { 6767 synchronized (mLock) { 6768 return mKeyguardDrawnOnce; 6769 } 6770 } 6771 6772 @Override 6773 public boolean isShowingDreamLw() { 6774 return mShowingDream; 6775 } 6776 6777 @Override 6778 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 6779 if (mKeyguardDelegate != null) { 6780 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation"); 6781 mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration); 6782 } 6783 } 6784 6785 @Override 6786 public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6787 Rect outInsets) { 6788 outInsets.setEmpty(); 6789 6790 // Navigation bar and status bar. 6791 getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, outInsets); 6792 outInsets.top = mStatusBarHeight; 6793 } 6794 6795 @Override 6796 public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6797 Rect outInsets) { 6798 outInsets.setEmpty(); 6799 6800 // Only navigation bar 6801 if (mHasNavigationBar) { 6802 int position = navigationBarPosition(displayWidth, displayHeight, displayRotation); 6803 if (position == NAV_BAR_BOTTOM) { 6804 outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode); 6805 } else if (position == NAV_BAR_RIGHT) { 6806 outInsets.right = getNavigationBarWidth(displayRotation, mUiMode); 6807 } else if (position == NAV_BAR_LEFT) { 6808 outInsets.left = getNavigationBarWidth(displayRotation, mUiMode); 6809 } 6810 } 6811 } 6812 6813 @Override 6814 public boolean isNavBarForcedShownLw(WindowState windowState) { 6815 return mForceShowSystemBars; 6816 } 6817 6818 @Override 6819 public boolean isDockSideAllowed(int dockSide) { 6820 6821 // We do not allow all dock sides at which the navigation bar touches the docked stack. 6822 if (!mNavigationBarCanMove) { 6823 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT; 6824 } else { 6825 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT; 6826 } 6827 } 6828 6829 void sendCloseSystemWindows() { 6830 PhoneWindow.sendCloseSystemWindows(mContext, null); 6831 } 6832 6833 void sendCloseSystemWindows(String reason) { 6834 PhoneWindow.sendCloseSystemWindows(mContext, reason); 6835 } 6836 6837 @Override 6838 public int rotationForOrientationLw(int orientation, int lastRotation) { 6839 if (false) { 6840 Slog.v(TAG, "rotationForOrientationLw(orient=" 6841 + orientation + ", last=" + lastRotation 6842 + "); user=" + mUserRotation + " " 6843 + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) 6844 ? "USER_ROTATION_LOCKED" : "") 6845 ); 6846 } 6847 6848 if (mForceDefaultOrientation) { 6849 return Surface.ROTATION_0; 6850 } 6851 6852 synchronized (mLock) { 6853 int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1 6854 if (sensorRotation < 0) { 6855 sensorRotation = lastRotation; 6856 } 6857 6858 final int preferredRotation; 6859 if (mLidState == LID_OPEN && mLidOpenRotation >= 0) { 6860 // Ignore sensor when lid switch is open and rotation is forced. 6861 preferredRotation = mLidOpenRotation; 6862 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR 6863 && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) { 6864 // Ignore sensor when in car dock unless explicitly enabled. 6865 // This case can override the behavior of NOSENSOR, and can also 6866 // enable 180 degree rotation while docked. 6867 preferredRotation = mCarDockEnablesAccelerometer 6868 ? sensorRotation : mCarDockRotation; 6869 } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK 6870 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK 6871 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK) 6872 && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) { 6873 // Ignore sensor when in desk dock unless explicitly enabled. 6874 // This case can override the behavior of NOSENSOR, and can also 6875 // enable 180 degree rotation while docked. 6876 preferredRotation = mDeskDockEnablesAccelerometer 6877 ? sensorRotation : mDeskDockRotation; 6878 } else if (mHdmiPlugged && mDemoHdmiRotationLock) { 6879 // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled. 6880 // Note that the dock orientation overrides the HDMI orientation. 6881 preferredRotation = mDemoHdmiRotation; 6882 } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED 6883 && mUndockedHdmiRotation >= 0) { 6884 // Ignore sensor when plugged into HDMI and an undocked orientation has 6885 // been specified in the configuration (only for legacy devices without 6886 // full multi-display support). 6887 // Note that the dock orientation overrides the HDMI orientation. 6888 preferredRotation = mUndockedHdmiRotation; 6889 } else if (mDemoRotationLock) { 6890 // Ignore sensor when demo rotation lock is enabled. 6891 // Note that the dock orientation and HDMI rotation lock override this. 6892 preferredRotation = mDemoRotation; 6893 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { 6894 // Application just wants to remain locked in the last rotation. 6895 preferredRotation = lastRotation; 6896 } else if (!mSupportAutoRotation) { 6897 // If we don't support auto-rotation then bail out here and ignore 6898 // the sensor and any rotation lock settings. 6899 preferredRotation = -1; 6900 } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE 6901 && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER 6902 || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 6903 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE 6904 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT 6905 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER)) 6906 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR 6907 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 6908 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE 6909 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { 6910 // Otherwise, use sensor only if requested by the application or enabled 6911 // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR. 6912 if (mAllowAllRotations < 0) { 6913 // Can't read this during init() because the context doesn't 6914 // have display metrics at that time so we cannot determine 6915 // tablet vs. phone then. 6916 mAllowAllRotations = mContext.getResources().getBoolean( 6917 com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0; 6918 } 6919 if (sensorRotation != Surface.ROTATION_180 6920 || mAllowAllRotations == 1 6921 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 6922 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) { 6923 // In VrMode, we report the sensor as always being in default orientation so: 6924 // 1) The orientation doesn't change as the user moves their head. 6925 // 2) 2D apps within VR show in the device's default orientation. 6926 // This only overwrites the sensor-provided orientation and does not affect any 6927 // explicit orientation preferences specified by any activities. 6928 preferredRotation = 6929 mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation; 6930 } else { 6931 preferredRotation = lastRotation; 6932 } 6933 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED 6934 && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { 6935 // Apply rotation lock. Does not apply to NOSENSOR. 6936 // The idea is that the user rotation expresses a weak preference for the direction 6937 // of gravity and as NOSENSOR is never affected by gravity, then neither should 6938 // NOSENSOR be affected by rotation lock (although it will be affected by docks). 6939 preferredRotation = mUserRotation; 6940 } else { 6941 // No overriding preference. 6942 // We will do exactly what the application asked us to do. 6943 preferredRotation = -1; 6944 } 6945 6946 switch (orientation) { 6947 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 6948 // Return portrait unless overridden. 6949 if (isAnyPortrait(preferredRotation)) { 6950 return preferredRotation; 6951 } 6952 return mPortraitRotation; 6953 6954 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 6955 // Return landscape unless overridden. 6956 if (isLandscapeOrSeascape(preferredRotation)) { 6957 return preferredRotation; 6958 } 6959 return mLandscapeRotation; 6960 6961 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 6962 // Return reverse portrait unless overridden. 6963 if (isAnyPortrait(preferredRotation)) { 6964 return preferredRotation; 6965 } 6966 return mUpsideDownRotation; 6967 6968 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 6969 // Return seascape unless overridden. 6970 if (isLandscapeOrSeascape(preferredRotation)) { 6971 return preferredRotation; 6972 } 6973 return mSeascapeRotation; 6974 6975 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 6976 case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE: 6977 // Return either landscape rotation. 6978 if (isLandscapeOrSeascape(preferredRotation)) { 6979 return preferredRotation; 6980 } 6981 if (isLandscapeOrSeascape(lastRotation)) { 6982 return lastRotation; 6983 } 6984 return mLandscapeRotation; 6985 6986 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 6987 case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT: 6988 // Return either portrait rotation. 6989 if (isAnyPortrait(preferredRotation)) { 6990 return preferredRotation; 6991 } 6992 if (isAnyPortrait(lastRotation)) { 6993 return lastRotation; 6994 } 6995 return mPortraitRotation; 6996 6997 default: 6998 // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR, 6999 // just return the preferred orientation we already calculated. 7000 if (preferredRotation >= 0) { 7001 return preferredRotation; 7002 } 7003 return Surface.ROTATION_0; 7004 } 7005 } 7006 } 7007 7008 @Override 7009 public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) { 7010 switch (orientation) { 7011 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 7012 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 7013 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 7014 return isAnyPortrait(rotation); 7015 7016 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 7017 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 7018 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 7019 return isLandscapeOrSeascape(rotation); 7020 7021 default: 7022 return true; 7023 } 7024 } 7025 7026 @Override 7027 public void setRotationLw(int rotation) { 7028 mOrientationListener.setCurrentRotation(rotation); 7029 } 7030 7031 private boolean isLandscapeOrSeascape(int rotation) { 7032 return rotation == mLandscapeRotation || rotation == mSeascapeRotation; 7033 } 7034 7035 private boolean isAnyPortrait(int rotation) { 7036 return rotation == mPortraitRotation || rotation == mUpsideDownRotation; 7037 } 7038 7039 @Override 7040 public int getUserRotationMode() { 7041 return Settings.System.getIntForUser(mContext.getContentResolver(), 7042 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ? 7043 WindowManagerPolicy.USER_ROTATION_FREE : 7044 WindowManagerPolicy.USER_ROTATION_LOCKED; 7045 } 7046 7047 // User rotation: to be used when all else fails in assigning an orientation to the device 7048 @Override 7049 public void setUserRotationMode(int mode, int rot) { 7050 ContentResolver res = mContext.getContentResolver(); 7051 7052 // mUserRotationMode and mUserRotation will be assigned by the content observer 7053 if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) { 7054 Settings.System.putIntForUser(res, 7055 Settings.System.USER_ROTATION, 7056 rot, 7057 UserHandle.USER_CURRENT); 7058 Settings.System.putIntForUser(res, 7059 Settings.System.ACCELEROMETER_ROTATION, 7060 0, 7061 UserHandle.USER_CURRENT); 7062 } else { 7063 Settings.System.putIntForUser(res, 7064 Settings.System.ACCELEROMETER_ROTATION, 7065 1, 7066 UserHandle.USER_CURRENT); 7067 } 7068 } 7069 7070 @Override 7071 public void setSafeMode(boolean safeMode) { 7072 mSafeMode = safeMode; 7073 performHapticFeedbackLw(null, safeMode 7074 ? HapticFeedbackConstants.SAFE_MODE_ENABLED 7075 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true); 7076 } 7077 7078 static long[] getLongIntArray(Resources r, int resid) { 7079 int[] ar = r.getIntArray(resid); 7080 if (ar == null) { 7081 return null; 7082 } 7083 long[] out = new long[ar.length]; 7084 for (int i=0; i<ar.length; i++) { 7085 out[i] = ar[i]; 7086 } 7087 return out; 7088 } 7089 7090 /** {@inheritDoc} */ 7091 @Override 7092 public void systemReady() { 7093 mKeyguardDelegate = new KeyguardServiceDelegate(mContext, 7094 new StateCallback() { 7095 @Override 7096 public void onTrustedChanged() { 7097 mWindowManagerFuncs.notifyKeyguardTrustedChanged(); 7098 } 7099 }); 7100 mKeyguardDelegate.onSystemReady(); 7101 7102 mVrManagerInternal = LocalServices.getService(VrManagerInternal.class); 7103 if (mVrManagerInternal != null) { 7104 mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); 7105 } 7106 7107 readCameraLensCoverState(); 7108 updateUiMode(); 7109 boolean bindKeyguardNow; 7110 synchronized (mLock) { 7111 updateOrientationListenerLp(); 7112 mSystemReady = true; 7113 mHandler.post(new Runnable() { 7114 @Override 7115 public void run() { 7116 updateSettings(); 7117 } 7118 }); 7119 7120 bindKeyguardNow = mDeferBindKeyguard; 7121 if (bindKeyguardNow) { 7122 // systemBooted ran but wasn't able to bind to the Keyguard, we'll do it now. 7123 mDeferBindKeyguard = false; 7124 } 7125 } 7126 7127 if (bindKeyguardNow) { 7128 mKeyguardDelegate.bindService(mContext); 7129 mKeyguardDelegate.onBootCompleted(); 7130 } 7131 mSystemGestures.systemReady(); 7132 mImmersiveModeConfirmation.systemReady(); 7133 } 7134 7135 /** {@inheritDoc} */ 7136 @Override 7137 public void systemBooted() { 7138 boolean bindKeyguardNow = false; 7139 synchronized (mLock) { 7140 // Time to bind Keyguard; take care to only bind it once, either here if ready or 7141 // in systemReady if not. 7142 if (mKeyguardDelegate != null) { 7143 bindKeyguardNow = true; 7144 } else { 7145 // Because mKeyguardDelegate is null, we know that the synchronized block in 7146 // systemReady didn't run yet and setting this will actually have an effect. 7147 mDeferBindKeyguard = true; 7148 } 7149 } 7150 if (bindKeyguardNow) { 7151 mKeyguardDelegate.bindService(mContext); 7152 mKeyguardDelegate.onBootCompleted(); 7153 } 7154 synchronized (mLock) { 7155 mSystemBooted = true; 7156 } 7157 startedWakingUp(); 7158 screenTurningOn(null); 7159 screenTurnedOn(); 7160 } 7161 7162 ProgressDialog mBootMsgDialog = null; 7163 7164 /** {@inheritDoc} */ 7165 @Override 7166 public void showBootMessage(final CharSequence msg, final boolean always) { 7167 mHandler.post(new Runnable() { 7168 @Override public void run() { 7169 if (mBootMsgDialog == null) { 7170 int theme; 7171 if (mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK)) { 7172 theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert; 7173 } else { 7174 theme = 0; 7175 } 7176 7177 mBootMsgDialog = new ProgressDialog(mContext, theme) { 7178 // This dialog will consume all events coming in to 7179 // it, to avoid it trying to do things too early in boot. 7180 @Override public boolean dispatchKeyEvent(KeyEvent event) { 7181 return true; 7182 } 7183 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { 7184 return true; 7185 } 7186 @Override public boolean dispatchTouchEvent(MotionEvent ev) { 7187 return true; 7188 } 7189 @Override public boolean dispatchTrackballEvent(MotionEvent ev) { 7190 return true; 7191 } 7192 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) { 7193 return true; 7194 } 7195 @Override public boolean dispatchPopulateAccessibilityEvent( 7196 AccessibilityEvent event) { 7197 return true; 7198 } 7199 }; 7200 if (mContext.getPackageManager().isUpgrade()) { 7201 mBootMsgDialog.setTitle(R.string.android_upgrading_title); 7202 } else { 7203 mBootMsgDialog.setTitle(R.string.android_start_title); 7204 } 7205 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 7206 mBootMsgDialog.setIndeterminate(true); 7207 mBootMsgDialog.getWindow().setType( 7208 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS); 7209 mBootMsgDialog.getWindow().addFlags( 7210 WindowManager.LayoutParams.FLAG_DIM_BEHIND 7211 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 7212 mBootMsgDialog.getWindow().setDimAmount(1); 7213 WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes(); 7214 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 7215 mBootMsgDialog.getWindow().setAttributes(lp); 7216 mBootMsgDialog.setCancelable(false); 7217 mBootMsgDialog.show(); 7218 } 7219 mBootMsgDialog.setMessage(msg); 7220 } 7221 }); 7222 } 7223 7224 /** {@inheritDoc} */ 7225 @Override 7226 public void hideBootMessages() { 7227 mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE); 7228 } 7229 7230 /** {@inheritDoc} */ 7231 @Override 7232 public void userActivity() { 7233 // *************************************** 7234 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE 7235 // *************************************** 7236 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER 7237 // WITH ITS LOCKS HELD. 7238 // 7239 // This code must be VERY careful about the locks 7240 // it acquires. 7241 // In fact, the current code acquires way too many, 7242 // and probably has lurking deadlocks. 7243 7244 synchronized (mScreenLockTimeout) { 7245 if (mLockScreenTimerActive) { 7246 // reset the timer 7247 mHandler.removeCallbacks(mScreenLockTimeout); 7248 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 7249 } 7250 } 7251 } 7252 7253 class ScreenLockTimeout implements Runnable { 7254 Bundle options; 7255 7256 @Override 7257 public void run() { 7258 synchronized (this) { 7259 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard"); 7260 if (mKeyguardDelegate != null) { 7261 mKeyguardDelegate.doKeyguardTimeout(options); 7262 } 7263 mLockScreenTimerActive = false; 7264 options = null; 7265 } 7266 } 7267 7268 public void setLockOptions(Bundle options) { 7269 this.options = options; 7270 } 7271 } 7272 7273 ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout(); 7274 7275 @Override 7276 public void lockNow(Bundle options) { 7277 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 7278 mHandler.removeCallbacks(mScreenLockTimeout); 7279 if (options != null) { 7280 // In case multiple calls are made to lockNow, we don't wipe out the options 7281 // until the runnable actually executes. 7282 mScreenLockTimeout.setLockOptions(options); 7283 } 7284 mHandler.post(mScreenLockTimeout); 7285 } 7286 7287 private void updateLockScreenTimeout() { 7288 synchronized (mScreenLockTimeout) { 7289 boolean enable = (mAllowLockscreenWhenOn && mAwake && 7290 mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId)); 7291 if (mLockScreenTimerActive != enable) { 7292 if (enable) { 7293 if (localLOGV) Log.v(TAG, "setting lockscreen timer"); 7294 mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests 7295 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 7296 } else { 7297 if (localLOGV) Log.v(TAG, "clearing lockscreen timer"); 7298 mHandler.removeCallbacks(mScreenLockTimeout); 7299 } 7300 mLockScreenTimerActive = enable; 7301 } 7302 } 7303 } 7304 7305 private void updateDreamingSleepToken(boolean acquire) { 7306 if (acquire) { 7307 if (mDreamingSleepToken == null) { 7308 mDreamingSleepToken = mActivityManagerInternal.acquireSleepToken("Dream"); 7309 } 7310 } else { 7311 if (mDreamingSleepToken != null) { 7312 mDreamingSleepToken.release(); 7313 mDreamingSleepToken = null; 7314 } 7315 } 7316 } 7317 7318 private void updateScreenOffSleepToken(boolean acquire) { 7319 if (acquire) { 7320 if (mScreenOffSleepToken == null) { 7321 mScreenOffSleepToken = mActivityManagerInternal.acquireSleepToken("ScreenOff"); 7322 } 7323 } else { 7324 if (mScreenOffSleepToken != null) { 7325 mScreenOffSleepToken.release(); 7326 mScreenOffSleepToken = null; 7327 } 7328 } 7329 } 7330 7331 /** {@inheritDoc} */ 7332 @Override 7333 public void enableScreenAfterBoot() { 7334 readLidState(); 7335 applyLidSwitchState(); 7336 updateRotation(true); 7337 } 7338 7339 private void applyLidSwitchState() { 7340 if (mLidState == LID_CLOSED && mLidControlsSleep) { 7341 mPowerManager.goToSleep(SystemClock.uptimeMillis(), 7342 PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH, 7343 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 7344 } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) { 7345 mWindowManagerFuncs.lockDeviceNow(); 7346 } 7347 7348 synchronized (mLock) { 7349 updateWakeGestureListenerLp(); 7350 } 7351 } 7352 7353 void updateUiMode() { 7354 if (mUiModeManager == null) { 7355 mUiModeManager = IUiModeManager.Stub.asInterface( 7356 ServiceManager.getService(Context.UI_MODE_SERVICE)); 7357 } 7358 try { 7359 mUiMode = mUiModeManager.getCurrentModeType(); 7360 } catch (RemoteException e) { 7361 } 7362 } 7363 7364 void updateRotation(boolean alwaysSendConfiguration) { 7365 try { 7366 //set orientation on WindowManager 7367 mWindowManager.updateRotation(alwaysSendConfiguration, false); 7368 } catch (RemoteException e) { 7369 // Ignore 7370 } 7371 } 7372 7373 void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { 7374 try { 7375 //set orientation on WindowManager 7376 mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout); 7377 } catch (RemoteException e) { 7378 // Ignore 7379 } 7380 } 7381 7382 /** 7383 * Return an Intent to launch the currently active dock app as home. Returns 7384 * null if the standard home should be launched, which is the case if any of the following is 7385 * true: 7386 * <ul> 7387 * <li>The device is not in either car mode or desk mode 7388 * <li>The device is in car mode but mEnableCarDockHomeCapture is false 7389 * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false 7390 * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME 7391 * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME 7392 * </ul> 7393 * @return A dock intent. 7394 */ 7395 Intent createHomeDockIntent() { 7396 Intent intent = null; 7397 7398 // What home does is based on the mode, not the dock state. That 7399 // is, when in car mode you should be taken to car home regardless 7400 // of whether we are actually in a car dock. 7401 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) { 7402 if (mEnableCarDockHomeCapture) { 7403 intent = mCarDockIntent; 7404 } 7405 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) { 7406 if (ENABLE_DESK_DOCK_HOME_CAPTURE) { 7407 intent = mDeskDockIntent; 7408 } 7409 } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH 7410 && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK 7411 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK 7412 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) { 7413 // Always launch dock home from home when watch is docked, if it exists. 7414 intent = mDeskDockIntent; 7415 } else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) { 7416 if (ENABLE_VR_HEADSET_HOME_CAPTURE) { 7417 intent = mVrHeadsetHomeIntent; 7418 } 7419 } 7420 7421 if (intent == null) { 7422 return null; 7423 } 7424 7425 ActivityInfo ai = null; 7426 ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser( 7427 intent, 7428 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, 7429 mCurrentUserId); 7430 if (info != null) { 7431 ai = info.activityInfo; 7432 } 7433 if (ai != null 7434 && ai.metaData != null 7435 && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) { 7436 intent = new Intent(intent); 7437 intent.setClassName(ai.packageName, ai.name); 7438 return intent; 7439 } 7440 7441 return null; 7442 } 7443 7444 void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) { 7445 if (awakenFromDreams) { 7446 awakenDreams(); 7447 } 7448 7449 Intent dock = createHomeDockIntent(); 7450 if (dock != null) { 7451 try { 7452 if (fromHomeKey) { 7453 dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7454 } 7455 startActivityAsUser(dock, UserHandle.CURRENT); 7456 return; 7457 } catch (ActivityNotFoundException e) { 7458 } 7459 } 7460 7461 Intent intent; 7462 7463 if (fromHomeKey) { 7464 intent = new Intent(mHomeIntent); 7465 intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7466 } else { 7467 intent = mHomeIntent; 7468 } 7469 7470 startActivityAsUser(intent, UserHandle.CURRENT); 7471 } 7472 7473 /** 7474 * goes to the home screen 7475 * @return whether it did anything 7476 */ 7477 boolean goHome() { 7478 if (!isUserSetupComplete()) { 7479 Slog.i(TAG, "Not going home because user setup is in progress."); 7480 return false; 7481 } 7482 if (false) { 7483 // This code always brings home to the front. 7484 try { 7485 ActivityManager.getService().stopAppSwitches(); 7486 } catch (RemoteException e) { 7487 } 7488 sendCloseSystemWindows(); 7489 startDockOrHome(false /*fromHomeKey*/, true /* awakenFromDreams */); 7490 } else { 7491 // This code brings home to the front or, if it is already 7492 // at the front, puts the device to sleep. 7493 try { 7494 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) { 7495 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry. 7496 Log.d(TAG, "UTS-TEST-MODE"); 7497 } else { 7498 ActivityManager.getService().stopAppSwitches(); 7499 sendCloseSystemWindows(); 7500 Intent dock = createHomeDockIntent(); 7501 if (dock != null) { 7502 int result = ActivityManager.getService() 7503 .startActivityAsUser(null, null, dock, 7504 dock.resolveTypeIfNeeded(mContext.getContentResolver()), 7505 null, null, 0, 7506 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7507 null, null, UserHandle.USER_CURRENT); 7508 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7509 return false; 7510 } 7511 } 7512 } 7513 int result = ActivityManager.getService() 7514 .startActivityAsUser(null, null, mHomeIntent, 7515 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()), 7516 null, null, 0, 7517 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7518 null, null, UserHandle.USER_CURRENT); 7519 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7520 return false; 7521 } 7522 } catch (RemoteException ex) { 7523 // bummer, the activity manager, which is in this process, is dead 7524 } 7525 } 7526 return true; 7527 } 7528 7529 @Override 7530 public void setCurrentOrientationLw(int newOrientation) { 7531 synchronized (mLock) { 7532 if (newOrientation != mCurrentAppOrientation) { 7533 mCurrentAppOrientation = newOrientation; 7534 updateOrientationListenerLp(); 7535 } 7536 } 7537 } 7538 7539 private boolean isTheaterModeEnabled() { 7540 return Settings.Global.getInt(mContext.getContentResolver(), 7541 Settings.Global.THEATER_MODE_ON, 0) == 1; 7542 } 7543 7544 private boolean areSystemNavigationKeysEnabled() { 7545 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 7546 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, 0, UserHandle.USER_CURRENT) == 1; 7547 } 7548 7549 @Override 7550 public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) { 7551 if (!mVibrator.hasVibrator()) { 7552 return false; 7553 } 7554 final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(), 7555 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0; 7556 if (hapticsDisabled && !always) { 7557 return false; 7558 } 7559 7560 VibrationEffect effect = getVibrationEffect(effectId); 7561 if (effect == null) { 7562 return false; 7563 } 7564 7565 int owningUid; 7566 String owningPackage; 7567 if (win != null) { 7568 owningUid = win.getOwningUid(); 7569 owningPackage = win.getOwningPackage(); 7570 } else { 7571 owningUid = android.os.Process.myUid(); 7572 owningPackage = mContext.getOpPackageName(); 7573 } 7574 mVibrator.vibrate(owningUid, owningPackage, effect, VIBRATION_ATTRIBUTES); 7575 return true; 7576 } 7577 7578 private VibrationEffect getVibrationEffect(int effectId) { 7579 long[] pattern; 7580 switch (effectId) { 7581 case HapticFeedbackConstants.VIRTUAL_KEY: 7582 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); 7583 case HapticFeedbackConstants.LONG_PRESS: 7584 pattern = mLongPressVibePattern; 7585 break; 7586 case HapticFeedbackConstants.KEYBOARD_TAP: 7587 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); 7588 case HapticFeedbackConstants.CLOCK_TICK: 7589 pattern = mClockTickVibePattern; 7590 break; 7591 case HapticFeedbackConstants.CALENDAR_DATE: 7592 pattern = mCalendarDateVibePattern; 7593 break; 7594 case HapticFeedbackConstants.SAFE_MODE_DISABLED: 7595 pattern = mSafeModeDisabledVibePattern; 7596 break; 7597 case HapticFeedbackConstants.SAFE_MODE_ENABLED: 7598 pattern = mSafeModeEnabledVibePattern; 7599 break; 7600 case HapticFeedbackConstants.CONTEXT_CLICK: 7601 pattern = mContextClickVibePattern; 7602 break; 7603 default: 7604 return null; 7605 } 7606 if (pattern.length == 1) { 7607 // One-shot vibration 7608 return VibrationEffect.createOneShot(pattern[0], VibrationEffect.DEFAULT_AMPLITUDE); 7609 } else { 7610 // Pattern vibration 7611 return VibrationEffect.createWaveform(pattern, -1); 7612 } 7613 } 7614 7615 @Override 7616 public void keepScreenOnStartedLw() { 7617 } 7618 7619 @Override 7620 public void keepScreenOnStoppedLw() { 7621 if (isKeyguardShowingAndNotOccluded()) { 7622 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 7623 } 7624 } 7625 7626 private int updateSystemUiVisibilityLw() { 7627 // If there is no window focused, there will be nobody to handle the events 7628 // anyway, so just hang on in whatever state we're in until things settle down. 7629 WindowState winCandidate = mFocusedWindow != null ? mFocusedWindow 7630 : mTopFullscreenOpaqueWindowState; 7631 if (winCandidate == null) { 7632 return 0; 7633 } 7634 if (winCandidate.getAttrs().token == mImmersiveModeConfirmation.getWindowToken()) { 7635 // The immersive mode confirmation should never affect the system bar visibility, 7636 // otherwise it will unhide the navigation bar and hide itself. 7637 winCandidate = isStatusBarKeyguard() ? mStatusBar : mTopFullscreenOpaqueWindowState; 7638 if (winCandidate == null) { 7639 return 0; 7640 } 7641 } 7642 final WindowState win = winCandidate; 7643 if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mKeyguardOccluded) { 7644 // We are updating at a point where the keyguard has gotten 7645 // focus, but we were last in a state where the top window is 7646 // hiding it. This is probably because the keyguard as been 7647 // shown while the top window was displayed, so we want to ignore 7648 // it here because this is just a very transient change and it 7649 // will quickly lose focus once it correctly gets hidden. 7650 return 0; 7651 } 7652 7653 int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null) 7654 & ~mResettingSystemUiFlags 7655 & ~mForceClearedSystemUiFlags; 7656 if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) { 7657 tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS); 7658 } 7659 7660 final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */, 7661 mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState); 7662 final int dockedVisibility = updateLightStatusBarLw(0 /* vis */, 7663 mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState); 7664 mWindowManagerFuncs.getStackBounds(HOME_STACK_ID, mNonDockedStackBounds); 7665 mWindowManagerFuncs.getStackBounds(DOCKED_STACK_ID, mDockedStackBounds); 7666 final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility); 7667 final int diff = visibility ^ mLastSystemUiFlags; 7668 final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags; 7669 final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags; 7670 final boolean needsMenu = win.getNeedsMenuLw(mTopFullscreenOpaqueWindowState); 7671 if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0 && mLastFocusNeedsMenu == needsMenu 7672 && mFocusedApp == win.getAppToken() 7673 && mLastNonDockedStackBounds.equals(mNonDockedStackBounds) 7674 && mLastDockedStackBounds.equals(mDockedStackBounds)) { 7675 return 0; 7676 } 7677 mLastSystemUiFlags = visibility; 7678 mLastFullscreenStackSysUiFlags = fullscreenVisibility; 7679 mLastDockedStackSysUiFlags = dockedVisibility; 7680 mLastFocusNeedsMenu = needsMenu; 7681 mFocusedApp = win.getAppToken(); 7682 final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds); 7683 final Rect dockedStackBounds = new Rect(mDockedStackBounds); 7684 mHandler.post(new Runnable() { 7685 @Override 7686 public void run() { 7687 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 7688 if (statusbar != null) { 7689 statusbar.setSystemUiVisibility(visibility, fullscreenVisibility, 7690 dockedVisibility, 0xffffffff, fullscreenStackBounds, 7691 dockedStackBounds, win.toString()); 7692 statusbar.topAppWindowChanged(needsMenu); 7693 } 7694 } 7695 }); 7696 return diff; 7697 } 7698 7699 private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) { 7700 WindowState statusColorWin = isStatusBarKeyguard() && !mKeyguardOccluded 7701 ? mStatusBar 7702 : opaqueOrDimming; 7703 7704 if (statusColorWin != null) { 7705 if (statusColorWin == opaque) { 7706 // If the top fullscreen-or-dimming window is also the top fullscreen, respect 7707 // its light flag. 7708 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7709 vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null) 7710 & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7711 } else if (statusColorWin != null && statusColorWin.isDimming()) { 7712 // Otherwise if it's dimming, clear the light flag. 7713 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7714 } 7715 } 7716 return vis; 7717 } 7718 7719 private int updateLightNavigationBarLw(int vis, WindowState opaque, 7720 WindowState opaqueOrDimming) { 7721 final WindowState imeWin = mWindowManagerFuncs.getInputMethodWindowLw(); 7722 7723 final WindowState navColorWin; 7724 if (imeWin != null && imeWin.isVisibleLw()) { 7725 navColorWin = imeWin; 7726 } else { 7727 navColorWin = opaqueOrDimming; 7728 } 7729 7730 if (navColorWin != null) { 7731 if (navColorWin == opaque) { 7732 // If the top fullscreen-or-dimming window is also the top fullscreen, respect 7733 // its light flag. 7734 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7735 vis |= PolicyControl.getSystemUiVisibility(navColorWin, null) 7736 & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7737 } else if (navColorWin.isDimming() || navColorWin == imeWin) { 7738 // Otherwise if it's dimming or it's the IME window, clear the light flag. 7739 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7740 } 7741 } 7742 return vis; 7743 } 7744 7745 private boolean drawsSystemBarBackground(WindowState win) { 7746 return win == null || (win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; 7747 } 7748 7749 private boolean forcesDrawStatusBarBackground(WindowState win) { 7750 return win == null || (win.getAttrs().privateFlags 7751 & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0; 7752 } 7753 7754 private int updateSystemBarsLw(WindowState win, int oldVis, int vis) { 7755 final boolean dockedStackVisible = mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID); 7756 final boolean freeformStackVisible = 7757 mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID); 7758 final boolean resizing = mWindowManagerInternal.isDockedDividerResizing(); 7759 7760 // We need to force system bars when the docked stack is visible, when the freeform stack 7761 // is visible but also when we are resizing for the transitions when docked stack 7762 // visibility changes. 7763 mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; 7764 final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard; 7765 7766 // apply translucent bar vis flags 7767 WindowState fullscreenTransWin = isStatusBarKeyguard() && !mKeyguardOccluded 7768 ? mStatusBar 7769 : mTopFullscreenOpaqueWindowState; 7770 vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7771 vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7772 final int dockedVis = mStatusBarController.applyTranslucentFlagLw( 7773 mTopDockedOpaqueWindowState, 0, 0); 7774 7775 final boolean fullscreenDrawsStatusBarBackground = 7776 (drawsSystemBarBackground(mTopFullscreenOpaqueWindowState) 7777 && (vis & View.STATUS_BAR_TRANSLUCENT) == 0) 7778 || forcesDrawStatusBarBackground(mTopFullscreenOpaqueWindowState); 7779 final boolean dockedDrawsStatusBarBackground = 7780 (drawsSystemBarBackground(mTopDockedOpaqueWindowState) 7781 && (dockedVis & View.STATUS_BAR_TRANSLUCENT) == 0) 7782 || forcesDrawStatusBarBackground(mTopDockedOpaqueWindowState); 7783 7784 // prevent status bar interaction from clearing certain flags 7785 int type = win.getAttrs().type; 7786 boolean statusBarHasFocus = type == TYPE_STATUS_BAR; 7787 if (statusBarHasFocus && !isStatusBarKeyguard()) { 7788 int flags = View.SYSTEM_UI_FLAG_FULLSCREEN 7789 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 7790 | View.SYSTEM_UI_FLAG_IMMERSIVE 7791 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 7792 | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7793 if (mKeyguardOccluded) { 7794 flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT; 7795 } 7796 vis = (vis & ~flags) | (oldVis & flags); 7797 } 7798 7799 if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) { 7800 vis |= View.STATUS_BAR_TRANSPARENT; 7801 vis &= ~View.STATUS_BAR_TRANSLUCENT; 7802 } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar) 7803 || forceOpaqueStatusBar) { 7804 vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT); 7805 } 7806 7807 vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing); 7808 7809 // update status bar 7810 boolean immersiveSticky = 7811 (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7812 final boolean hideStatusBarWM = 7813 mTopFullscreenOpaqueWindowState != null 7814 && (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null) 7815 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; 7816 final boolean hideStatusBarSysui = 7817 (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 7818 final boolean hideNavBarSysui = 7819 (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; 7820 7821 final boolean transientStatusBarAllowed = mStatusBar != null 7822 && (statusBarHasFocus || (!mForceShowSystemBars 7823 && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky)))); 7824 7825 final boolean transientNavBarAllowed = mNavigationBar != null 7826 && !mForceShowSystemBars && hideNavBarSysui && immersiveSticky; 7827 7828 final long now = SystemClock.uptimeMillis(); 7829 final boolean pendingPanic = mPendingPanicGestureUptime != 0 7830 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION; 7831 if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) { 7832 // The user performed the panic gesture recently, we're about to hide the bars, 7833 // we're no longer on the Keyguard and the screen is ready. We can now request the bars. 7834 mPendingPanicGestureUptime = 0; 7835 mStatusBarController.showTransient(); 7836 if (!isNavBarEmpty(vis)) { 7837 mNavigationBarController.showTransient(); 7838 } 7839 } 7840 7841 final boolean denyTransientStatus = mStatusBarController.isTransientShowRequested() 7842 && !transientStatusBarAllowed && hideStatusBarSysui; 7843 final boolean denyTransientNav = mNavigationBarController.isTransientShowRequested() 7844 && !transientNavBarAllowed; 7845 if (denyTransientStatus || denyTransientNav || mForceShowSystemBars) { 7846 // clear the clearable flags instead 7847 clearClearableFlagsLw(); 7848 vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS; 7849 } 7850 7851 final boolean immersive = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; 7852 immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7853 final boolean navAllowedHidden = immersive || immersiveSticky; 7854 7855 if (hideNavBarSysui && !navAllowedHidden 7856 && getWindowLayerLw(win) > getWindowLayerFromTypeLw(TYPE_INPUT_CONSUMER)) { 7857 // We can't hide the navbar from this window otherwise the input consumer would not get 7858 // the input events. 7859 vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 7860 } 7861 7862 vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis); 7863 7864 // update navigation bar 7865 boolean oldImmersiveMode = isImmersiveMode(oldVis); 7866 boolean newImmersiveMode = isImmersiveMode(vis); 7867 if (win != null && oldImmersiveMode != newImmersiveMode) { 7868 final String pkg = win.getOwningPackage(); 7869 mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode, 7870 isUserSetupComplete(), isNavBarEmpty(win.getSystemUiVisibility())); 7871 } 7872 7873 vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis); 7874 7875 vis = updateLightNavigationBarLw(vis, mTopFullscreenOpaqueWindowState, 7876 mTopFullscreenOpaqueOrDimmingWindowState); 7877 7878 return vis; 7879 } 7880 7881 /** 7882 * @return the current visibility flags with the nav-bar opacity related flags toggled based 7883 * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}. 7884 */ 7885 private int configureNavBarOpacity(int visibility, boolean dockedStackVisible, 7886 boolean freeformStackVisible, boolean isDockedDividerResizing) { 7887 if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { 7888 if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { 7889 visibility = setNavBarOpaqueFlag(visibility); 7890 } 7891 } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { 7892 if (isDockedDividerResizing) { 7893 visibility = setNavBarOpaqueFlag(visibility); 7894 } else if (freeformStackVisible) { 7895 visibility = setNavBarTranslucentFlag(visibility); 7896 } else { 7897 visibility = setNavBarOpaqueFlag(visibility); 7898 } 7899 } 7900 7901 if (!areTranslucentBarsAllowed()) { 7902 visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT; 7903 } 7904 return visibility; 7905 } 7906 7907 private int setNavBarOpaqueFlag(int visibility) { 7908 return visibility &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT); 7909 } 7910 7911 private int setNavBarTranslucentFlag(int visibility) { 7912 visibility &= ~View.NAVIGATION_BAR_TRANSPARENT; 7913 return visibility |= View.NAVIGATION_BAR_TRANSLUCENT; 7914 } 7915 7916 private void clearClearableFlagsLw() { 7917 int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS; 7918 if (newVal != mResettingSystemUiFlags) { 7919 mResettingSystemUiFlags = newVal; 7920 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 7921 } 7922 } 7923 7924 private boolean isImmersiveMode(int vis) { 7925 final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 7926 return mNavigationBar != null 7927 && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 7928 && (vis & flags) != 0 7929 && canHideNavigationBar(); 7930 } 7931 7932 private static boolean isNavBarEmpty(int systemUiFlags) { 7933 final int disableNavigationBar = (View.STATUS_BAR_DISABLE_HOME 7934 | View.STATUS_BAR_DISABLE_BACK 7935 | View.STATUS_BAR_DISABLE_RECENT); 7936 7937 return (systemUiFlags & disableNavigationBar) == disableNavigationBar; 7938 } 7939 7940 /** 7941 * @return whether the navigation or status bar can be made translucent 7942 * 7943 * This should return true unless touch exploration is not enabled or 7944 * R.boolean.config_enableTranslucentDecor is false. 7945 */ 7946 private boolean areTranslucentBarsAllowed() { 7947 return mTranslucentDecorEnabled; 7948 } 7949 7950 // Use this instead of checking config_showNavigationBar so that it can be consistently 7951 // overridden by qemu.hw.mainkeys in the emulator. 7952 @Override 7953 public boolean hasNavigationBar() { 7954 return mHasNavigationBar; 7955 } 7956 7957 @Override 7958 public void setLastInputMethodWindowLw(WindowState ime, WindowState target) { 7959 mLastInputMethodWindow = ime; 7960 mLastInputMethodTargetWindow = target; 7961 } 7962 7963 @Override 7964 public void setDismissImeOnBackKeyPressed(boolean newValue) { 7965 mDismissImeOnBackKeyPressed = newValue; 7966 } 7967 7968 @Override 7969 public int getInputMethodWindowVisibleHeightLw() { 7970 return mDockBottom - mCurBottom; 7971 } 7972 7973 @Override 7974 public void setCurrentUserLw(int newUserId) { 7975 mCurrentUserId = newUserId; 7976 if (mKeyguardDelegate != null) { 7977 mKeyguardDelegate.setCurrentUser(newUserId); 7978 } 7979 if (mAccessibilityShortcutController != null) { 7980 mAccessibilityShortcutController.setCurrentUser(newUserId); 7981 } 7982 StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); 7983 if (statusBar != null) { 7984 statusBar.setCurrentUser(newUserId); 7985 } 7986 setLastInputMethodWindowLw(null, null); 7987 } 7988 7989 @Override 7990 public void setSwitchingUser(boolean switching) { 7991 mKeyguardDelegate.setSwitchingUser(switching); 7992 } 7993 7994 @Override 7995 public boolean canMagnifyWindow(int windowType) { 7996 switch (windowType) { 7997 case WindowManager.LayoutParams.TYPE_INPUT_METHOD: 7998 case WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG: 7999 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR: 8000 case WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY: { 8001 return false; 8002 } 8003 } 8004 return true; 8005 } 8006 8007 @Override 8008 public boolean isTopLevelWindow(int windowType) { 8009 if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW 8010 && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 8011 return (windowType == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG); 8012 } 8013 return true; 8014 } 8015 8016 @Override 8017 public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) { 8018 // For the upside down rotation we don't rotate seamlessly as the navigation 8019 // bar moves position. 8020 // Note most apps (using orientation:sensor or user as opposed to fullSensor) 8021 // will not enter the reverse portrait orientation, so actually the 8022 // orientation won't change at all. 8023 if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) { 8024 return false; 8025 } 8026 // If the navigation bar can't change sides, then it will 8027 // jump when we change orientations and we don't rotate 8028 // seamlessly. 8029 if (!mNavigationBarCanMove) { 8030 return false; 8031 } 8032 int delta = newRotation - oldRotation; 8033 if (delta < 0) delta += 4; 8034 // Likewise we don't rotate seamlessly for 180 degree rotations 8035 // in this case the surfaces never resize, and our logic to 8036 // revert the transformations on size change will fail. We could 8037 // fix this in the future with the "tagged" frames idea. 8038 if (delta == Surface.ROTATION_180) { 8039 return false; 8040 } 8041 8042 final WindowState w = mTopFullscreenOpaqueWindowState; 8043 if (w != mFocusedWindow) { 8044 return false; 8045 } 8046 8047 // We only enable seamless rotation if the top window has requested 8048 // it and is in the fullscreen opaque state. Seamless rotation 8049 // requires freezing various Surface states and won't work well 8050 // with animations, so we disable it in the animation case for now. 8051 if (w != null && !w.isAnimatingLw() && 8052 ((w.getAttrs().rotationAnimation == ROTATION_ANIMATION_JUMPCUT) || 8053 (w.getAttrs().rotationAnimation == ROTATION_ANIMATION_SEAMLESS))) { 8054 return true; 8055 } 8056 return false; 8057 } 8058 8059 @Override 8060 public void dump(String prefix, PrintWriter pw, String[] args) { 8061 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode); 8062 pw.print(" mSystemReady="); pw.print(mSystemReady); 8063 pw.print(" mSystemBooted="); pw.println(mSystemBooted); 8064 pw.print(prefix); pw.print("mLidState="); pw.print(mLidState); 8065 pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation); 8066 pw.print(" mCameraLensCoverState="); pw.print(mCameraLensCoverState); 8067 pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged); 8068 if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0 8069 || mForceClearedSystemUiFlags != 0) { 8070 pw.print(prefix); pw.print("mLastSystemUiFlags=0x"); 8071 pw.print(Integer.toHexString(mLastSystemUiFlags)); 8072 pw.print(" mResettingSystemUiFlags=0x"); 8073 pw.print(Integer.toHexString(mResettingSystemUiFlags)); 8074 pw.print(" mForceClearedSystemUiFlags=0x"); 8075 pw.println(Integer.toHexString(mForceClearedSystemUiFlags)); 8076 } 8077 if (mLastFocusNeedsMenu) { 8078 pw.print(prefix); pw.print("mLastFocusNeedsMenu="); 8079 pw.println(mLastFocusNeedsMenu); 8080 } 8081 pw.print(prefix); pw.print("mWakeGestureEnabledSetting="); 8082 pw.println(mWakeGestureEnabledSetting); 8083 8084 pw.print(prefix); pw.print("mSupportAutoRotation="); pw.println(mSupportAutoRotation); 8085 pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode); 8086 pw.print(" mDockMode="); pw.print(mDockMode); 8087 pw.print(" mEnableCarDockHomeCapture="); pw.print(mEnableCarDockHomeCapture); 8088 pw.print(" mCarDockRotation="); pw.print(mCarDockRotation); 8089 pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation); 8090 pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode); 8091 pw.print(" mUserRotation="); pw.print(mUserRotation); 8092 pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations); 8093 pw.print(prefix); pw.print("mCurrentAppOrientation="); pw.println(mCurrentAppOrientation); 8094 pw.print(prefix); pw.print("mCarDockEnablesAccelerometer="); 8095 pw.print(mCarDockEnablesAccelerometer); 8096 pw.print(" mDeskDockEnablesAccelerometer="); 8097 pw.println(mDeskDockEnablesAccelerometer); 8098 pw.print(prefix); pw.print("mLidKeyboardAccessibility="); 8099 pw.print(mLidKeyboardAccessibility); 8100 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility); 8101 pw.print(" mLidControlsScreenLock="); pw.println(mLidControlsScreenLock); 8102 pw.print(" mLidControlsSleep="); pw.println(mLidControlsSleep); 8103 pw.print(prefix); 8104 pw.print(" mLongPressOnBackBehavior="); pw.println(mLongPressOnBackBehavior); 8105 pw.print(prefix); 8106 pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior); 8107 pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior); 8108 pw.print(prefix); 8109 pw.print("mDoublePressOnPowerBehavior="); pw.print(mDoublePressOnPowerBehavior); 8110 pw.print(" mTriplePressOnPowerBehavior="); pw.println(mTriplePressOnPowerBehavior); 8111 pw.print(prefix); pw.print("mHasSoftInput="); pw.println(mHasSoftInput); 8112 pw.print(prefix); pw.print("mAwake="); pw.println(mAwake); 8113 pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly); 8114 pw.print(" mScreenOnFully="); pw.println(mScreenOnFully); 8115 pw.print(prefix); pw.print("mKeyguardDrawComplete="); pw.print(mKeyguardDrawComplete); 8116 pw.print(" mWindowManagerDrawComplete="); pw.println(mWindowManagerDrawComplete); 8117 pw.print(prefix); pw.print("mOrientationSensorEnabled="); 8118 pw.println(mOrientationSensorEnabled); 8119 pw.print(prefix); pw.print("mOverscanScreen=("); pw.print(mOverscanScreenLeft); 8120 pw.print(","); pw.print(mOverscanScreenTop); 8121 pw.print(") "); pw.print(mOverscanScreenWidth); 8122 pw.print("x"); pw.println(mOverscanScreenHeight); 8123 if (mOverscanLeft != 0 || mOverscanTop != 0 8124 || mOverscanRight != 0 || mOverscanBottom != 0) { 8125 pw.print(prefix); pw.print("mOverscan left="); pw.print(mOverscanLeft); 8126 pw.print(" top="); pw.print(mOverscanTop); 8127 pw.print(" right="); pw.print(mOverscanRight); 8128 pw.print(" bottom="); pw.println(mOverscanBottom); 8129 } 8130 pw.print(prefix); pw.print("mRestrictedOverscanScreen=("); 8131 pw.print(mRestrictedOverscanScreenLeft); 8132 pw.print(","); pw.print(mRestrictedOverscanScreenTop); 8133 pw.print(") "); pw.print(mRestrictedOverscanScreenWidth); 8134 pw.print("x"); pw.println(mRestrictedOverscanScreenHeight); 8135 pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft); 8136 pw.print(","); pw.print(mUnrestrictedScreenTop); 8137 pw.print(") "); pw.print(mUnrestrictedScreenWidth); 8138 pw.print("x"); pw.println(mUnrestrictedScreenHeight); 8139 pw.print(prefix); pw.print("mRestrictedScreen=("); pw.print(mRestrictedScreenLeft); 8140 pw.print(","); pw.print(mRestrictedScreenTop); 8141 pw.print(") "); pw.print(mRestrictedScreenWidth); 8142 pw.print("x"); pw.println(mRestrictedScreenHeight); 8143 pw.print(prefix); pw.print("mStableFullscreen=("); pw.print(mStableFullscreenLeft); 8144 pw.print(","); pw.print(mStableFullscreenTop); 8145 pw.print(")-("); pw.print(mStableFullscreenRight); 8146 pw.print(","); pw.print(mStableFullscreenBottom); pw.println(")"); 8147 pw.print(prefix); pw.print("mStable=("); pw.print(mStableLeft); 8148 pw.print(","); pw.print(mStableTop); 8149 pw.print(")-("); pw.print(mStableRight); 8150 pw.print(","); pw.print(mStableBottom); pw.println(")"); 8151 pw.print(prefix); pw.print("mSystem=("); pw.print(mSystemLeft); 8152 pw.print(","); pw.print(mSystemTop); 8153 pw.print(")-("); pw.print(mSystemRight); 8154 pw.print(","); pw.print(mSystemBottom); pw.println(")"); 8155 pw.print(prefix); pw.print("mCur=("); pw.print(mCurLeft); 8156 pw.print(","); pw.print(mCurTop); 8157 pw.print(")-("); pw.print(mCurRight); 8158 pw.print(","); pw.print(mCurBottom); pw.println(")"); 8159 pw.print(prefix); pw.print("mContent=("); pw.print(mContentLeft); 8160 pw.print(","); pw.print(mContentTop); 8161 pw.print(")-("); pw.print(mContentRight); 8162 pw.print(","); pw.print(mContentBottom); pw.println(")"); 8163 pw.print(prefix); pw.print("mVoiceContent=("); pw.print(mVoiceContentLeft); 8164 pw.print(","); pw.print(mVoiceContentTop); 8165 pw.print(")-("); pw.print(mVoiceContentRight); 8166 pw.print(","); pw.print(mVoiceContentBottom); pw.println(")"); 8167 pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft); 8168 pw.print(","); pw.print(mDockTop); 8169 pw.print(")-("); pw.print(mDockRight); 8170 pw.print(","); pw.print(mDockBottom); pw.println(")"); 8171 pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer); 8172 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer); 8173 pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream); 8174 pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen); 8175 pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken); 8176 if (mLastInputMethodWindow != null) { 8177 pw.print(prefix); pw.print("mLastInputMethodWindow="); 8178 pw.println(mLastInputMethodWindow); 8179 } 8180 if (mLastInputMethodTargetWindow != null) { 8181 pw.print(prefix); pw.print("mLastInputMethodTargetWindow="); 8182 pw.println(mLastInputMethodTargetWindow); 8183 } 8184 pw.print(prefix); pw.print("mDismissImeOnBackKeyPressed="); 8185 pw.println(mDismissImeOnBackKeyPressed); 8186 if (mStatusBar != null) { 8187 pw.print(prefix); pw.print("mStatusBar="); 8188 pw.print(mStatusBar); pw.print(" isStatusBarKeyguard="); 8189 pw.println(isStatusBarKeyguard()); 8190 } 8191 if (mNavigationBar != null) { 8192 pw.print(prefix); pw.print("mNavigationBar="); 8193 pw.println(mNavigationBar); 8194 } 8195 if (mFocusedWindow != null) { 8196 pw.print(prefix); pw.print("mFocusedWindow="); 8197 pw.println(mFocusedWindow); 8198 } 8199 if (mFocusedApp != null) { 8200 pw.print(prefix); pw.print("mFocusedApp="); 8201 pw.println(mFocusedApp); 8202 } 8203 if (mTopFullscreenOpaqueWindowState != null) { 8204 pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState="); 8205 pw.println(mTopFullscreenOpaqueWindowState); 8206 } 8207 if (mTopFullscreenOpaqueOrDimmingWindowState != null) { 8208 pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState="); 8209 pw.println(mTopFullscreenOpaqueOrDimmingWindowState); 8210 } 8211 if (mForcingShowNavBar) { 8212 pw.print(prefix); pw.print("mForcingShowNavBar="); 8213 pw.println(mForcingShowNavBar); pw.print( "mForcingShowNavBarLayer="); 8214 pw.println(mForcingShowNavBarLayer); 8215 } 8216 pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen); 8217 pw.print(" mKeyguardOccluded="); pw.println(mKeyguardOccluded); 8218 pw.print(" mKeyguardOccludedChanged="); pw.println(mKeyguardOccludedChanged); 8219 pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded); 8220 pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); 8221 pw.print(" mForceStatusBarFromKeyguard="); 8222 pw.println(mForceStatusBarFromKeyguard); 8223 pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed); 8224 pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn); 8225 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout); 8226 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive); 8227 pw.print(prefix); pw.print("mEndcallBehavior="); pw.print(mEndcallBehavior); 8228 pw.print(" mIncallPowerBehavior="); pw.print(mIncallPowerBehavior); 8229 pw.print(" mIncallBackBehavior="); pw.print(mIncallBackBehavior); 8230 pw.print(" mLongPressOnHomeBehavior="); pw.println(mLongPressOnHomeBehavior); 8231 pw.print(prefix); pw.print("mLandscapeRotation="); pw.print(mLandscapeRotation); 8232 pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation); 8233 pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation); 8234 pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation); 8235 pw.print(prefix); pw.print("mDemoHdmiRotation="); pw.print(mDemoHdmiRotation); 8236 pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock); 8237 pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation); 8238 8239 mGlobalKeyManager.dump(prefix, pw); 8240 mStatusBarController.dump(pw, prefix); 8241 mNavigationBarController.dump(pw, prefix); 8242 PolicyControl.dump(prefix, pw); 8243 8244 if (mWakeGestureListener != null) { 8245 mWakeGestureListener.dump(pw, prefix); 8246 } 8247 if (mOrientationListener != null) { 8248 mOrientationListener.dump(pw, prefix); 8249 } 8250 if (mBurnInProtectionHelper != null) { 8251 mBurnInProtectionHelper.dump(prefix, pw); 8252 } 8253 if (mKeyguardDelegate != null) { 8254 mKeyguardDelegate.dump(prefix, pw); 8255 } 8256 } 8257} 8258