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