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