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