PhoneWindowManager.java revision 5f97880714e0ee2c503bca0d7681e896c53386b0
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.notifyAccessibilityButtonAvailabilityChanged(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); 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 boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; 3076 if (transit == TRANSIT_EXIT 3077 || transit == TRANSIT_HIDE) { 3078 return isKeyguard ? -1 : R.anim.dock_top_exit; 3079 } else if (transit == TRANSIT_ENTER 3080 || transit == TRANSIT_SHOW) { 3081 return isKeyguard ? -1 : R.anim.dock_top_enter; 3082 } 3083 } else if (win == mNavigationBar) { 3084 if (win.getAttrs().windowAnimations != 0) { 3085 return 0; 3086 } 3087 // This can be on either the bottom or the right or the left. 3088 if (mNavigationBarPosition == NAV_BAR_BOTTOM) { 3089 if (transit == TRANSIT_EXIT 3090 || transit == TRANSIT_HIDE) { 3091 if (isKeyguardShowingAndNotOccluded()) { 3092 return R.anim.dock_bottom_exit_keyguard; 3093 } else { 3094 return R.anim.dock_bottom_exit; 3095 } 3096 } else if (transit == TRANSIT_ENTER 3097 || transit == TRANSIT_SHOW) { 3098 return R.anim.dock_bottom_enter; 3099 } 3100 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) { 3101 if (transit == TRANSIT_EXIT 3102 || transit == TRANSIT_HIDE) { 3103 return R.anim.dock_right_exit; 3104 } else if (transit == TRANSIT_ENTER 3105 || transit == TRANSIT_SHOW) { 3106 return R.anim.dock_right_enter; 3107 } 3108 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 3109 if (transit == TRANSIT_EXIT 3110 || transit == TRANSIT_HIDE) { 3111 return R.anim.dock_left_exit; 3112 } else if (transit == TRANSIT_ENTER 3113 || transit == TRANSIT_SHOW) { 3114 return R.anim.dock_left_enter; 3115 } 3116 } 3117 } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) { 3118 return selectDockedDividerAnimationLw(win, transit); 3119 } 3120 3121 if (transit == TRANSIT_PREVIEW_DONE) { 3122 if (win.hasAppShownWindows()) { 3123 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT"); 3124 return com.android.internal.R.anim.app_starting_exit; 3125 } 3126 } else if (win.getAttrs().type == TYPE_DREAM && mDreamingLockscreen 3127 && transit == TRANSIT_ENTER) { 3128 // Special case: we are animating in a dream, while the keyguard 3129 // is shown. We don't want an animation on the dream, because 3130 // we need it shown immediately with the keyguard animating away 3131 // to reveal it. 3132 return -1; 3133 } 3134 3135 return 0; 3136 } 3137 3138 private int selectDockedDividerAnimationLw(WindowState win, int transit) { 3139 int insets = mWindowManagerFuncs.getDockedDividerInsetsLw(); 3140 3141 // If the divider is behind the navigation bar, don't animate. 3142 final Rect frame = win.getFrameLw(); 3143 final boolean behindNavBar = mNavigationBar != null 3144 && ((mNavigationBarPosition == NAV_BAR_BOTTOM 3145 && frame.top + insets >= mNavigationBar.getFrameLw().top) 3146 || (mNavigationBarPosition == NAV_BAR_RIGHT 3147 && frame.left + insets >= mNavigationBar.getFrameLw().left) 3148 || (mNavigationBarPosition == NAV_BAR_LEFT 3149 && frame.right - insets <= mNavigationBar.getFrameLw().right)); 3150 final boolean landscape = frame.height() > frame.width(); 3151 final boolean offscreenLandscape = landscape && (frame.right - insets <= 0 3152 || frame.left + insets >= win.getDisplayFrameLw().right); 3153 final boolean offscreenPortrait = !landscape && (frame.top - insets <= 0 3154 || frame.bottom + insets >= win.getDisplayFrameLw().bottom); 3155 final boolean offscreen = offscreenLandscape || offscreenPortrait; 3156 if (behindNavBar || offscreen) { 3157 return 0; 3158 } 3159 if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) { 3160 return R.anim.fade_in; 3161 } else if (transit == TRANSIT_EXIT) { 3162 return R.anim.fade_out; 3163 } else { 3164 return 0; 3165 } 3166 } 3167 3168 @Override 3169 public void selectRotationAnimationLw(int anim[]) { 3170 if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen=" 3171 + mTopFullscreenOpaqueWindowState + " rotationAnimation=" 3172 + (mTopFullscreenOpaqueWindowState == null ? 3173 "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation)); 3174 if (mTopFullscreenOpaqueWindowState != null) { 3175 int animationHint = mTopFullscreenOpaqueWindowState.getRotationAnimationHint(); 3176 if (animationHint < 0 && mTopIsFullscreen) { 3177 animationHint = mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation; 3178 } 3179 switch (animationHint) { 3180 case ROTATION_ANIMATION_CROSSFADE: 3181 case ROTATION_ANIMATION_SEAMLESS: // Crossfade is fallback for seamless. 3182 anim[0] = R.anim.rotation_animation_xfade_exit; 3183 anim[1] = R.anim.rotation_animation_enter; 3184 break; 3185 case ROTATION_ANIMATION_JUMPCUT: 3186 anim[0] = R.anim.rotation_animation_jump_exit; 3187 anim[1] = R.anim.rotation_animation_enter; 3188 break; 3189 case ROTATION_ANIMATION_ROTATE: 3190 default: 3191 anim[0] = anim[1] = 0; 3192 break; 3193 } 3194 } else { 3195 anim[0] = anim[1] = 0; 3196 } 3197 } 3198 3199 @Override 3200 public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId, 3201 boolean forceDefault) { 3202 switch (exitAnimId) { 3203 case R.anim.rotation_animation_xfade_exit: 3204 case R.anim.rotation_animation_jump_exit: 3205 // These are the only cases that matter. 3206 if (forceDefault) { 3207 return false; 3208 } 3209 int anim[] = new int[2]; 3210 selectRotationAnimationLw(anim); 3211 return (exitAnimId == anim[0] && enterAnimId == anim[1]); 3212 default: 3213 return true; 3214 } 3215 } 3216 3217 @Override 3218 public Animation createHiddenByKeyguardExit(boolean onWallpaper, 3219 boolean goingToNotificationShade) { 3220 if (goingToNotificationShade) { 3221 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in); 3222 } 3223 3224 AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ? 3225 R.anim.lock_screen_behind_enter_wallpaper : 3226 R.anim.lock_screen_behind_enter); 3227 3228 // TODO: Use XML interpolators when we have log interpolators available in XML. 3229 final List<Animation> animations = set.getAnimations(); 3230 for (int i = animations.size() - 1; i >= 0; --i) { 3231 animations.get(i).setInterpolator(mLogDecelerateInterpolator); 3232 } 3233 3234 return set; 3235 } 3236 3237 3238 @Override 3239 public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) { 3240 if (goingToNotificationShade) { 3241 return null; 3242 } else { 3243 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit); 3244 } 3245 } 3246 3247 private static void awakenDreams() { 3248 IDreamManager dreamManager = getDreamManager(); 3249 if (dreamManager != null) { 3250 try { 3251 dreamManager.awaken(); 3252 } catch (RemoteException e) { 3253 // fine, stay asleep then 3254 } 3255 } 3256 } 3257 3258 static IDreamManager getDreamManager() { 3259 return IDreamManager.Stub.asInterface( 3260 ServiceManager.checkService(DreamService.DREAM_SERVICE)); 3261 } 3262 3263 TelecomManager getTelecommService() { 3264 return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 3265 } 3266 3267 static IAudioService getAudioService() { 3268 IAudioService audioService = IAudioService.Stub.asInterface( 3269 ServiceManager.checkService(Context.AUDIO_SERVICE)); 3270 if (audioService == null) { 3271 Log.w(TAG, "Unable to find IAudioService interface."); 3272 } 3273 return audioService; 3274 } 3275 3276 boolean keyguardOn() { 3277 return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode(); 3278 } 3279 3280 private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = { 3281 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 3282 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, 3283 }; 3284 3285 /** {@inheritDoc} */ 3286 @Override 3287 public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) { 3288 final boolean keyguardOn = keyguardOn(); 3289 final int keyCode = event.getKeyCode(); 3290 final int repeatCount = event.getRepeatCount(); 3291 final int metaState = event.getMetaState(); 3292 final int flags = event.getFlags(); 3293 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 3294 final boolean canceled = event.isCanceled(); 3295 3296 if (DEBUG_INPUT) { 3297 Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount=" 3298 + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed 3299 + " canceled=" + canceled); 3300 } 3301 3302 // If we think we might have a volume down & power key chord on the way 3303 // but we're not sure, then tell the dispatcher to wait a little while and 3304 // try again later before dispatching. 3305 if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) { 3306 if (mScreenshotChordVolumeDownKeyTriggered && !mScreenshotChordPowerKeyTriggered) { 3307 final long now = SystemClock.uptimeMillis(); 3308 final long timeoutTime = mScreenshotChordVolumeDownKeyTime 3309 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS; 3310 if (now < timeoutTime) { 3311 return timeoutTime - now; 3312 } 3313 } 3314 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 3315 && mScreenshotChordVolumeDownKeyConsumed) { 3316 if (!down) { 3317 mScreenshotChordVolumeDownKeyConsumed = false; 3318 } 3319 return -1; 3320 } 3321 } 3322 3323 // If an accessibility shortcut might be partially complete, hold off dispatching until we 3324 // know if it is complete or not 3325 if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false) 3326 && (flags & KeyEvent.FLAG_FALLBACK) == 0) { 3327 if (mScreenshotChordVolumeDownKeyTriggered ^ mA11yShortcutChordVolumeUpKeyTriggered) { 3328 final long now = SystemClock.uptimeMillis(); 3329 final long timeoutTime = (mScreenshotChordVolumeDownKeyTriggered 3330 ? mScreenshotChordVolumeDownKeyTime : mA11yShortcutChordVolumeUpKeyTime) 3331 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS; 3332 if (now < timeoutTime) { 3333 return timeoutTime - now; 3334 } 3335 } 3336 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mScreenshotChordVolumeDownKeyConsumed) { 3337 if (!down) { 3338 mScreenshotChordVolumeDownKeyConsumed = false; 3339 } 3340 return -1; 3341 } 3342 if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mA11yShortcutChordVolumeUpKeyConsumed) { 3343 if (!down) { 3344 mA11yShortcutChordVolumeUpKeyConsumed = false; 3345 } 3346 return -1; 3347 } 3348 } 3349 3350 // Cancel any pending meta actions if we see any other keys being pressed between the down 3351 // of the meta key and its corresponding up. 3352 if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) { 3353 mPendingMetaAction = false; 3354 } 3355 // Any key that is not Alt or Meta cancels Caps Lock combo tracking. 3356 if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) { 3357 mPendingCapsLockToggle = false; 3358 } 3359 3360 // First we always handle the home key here, so applications 3361 // can never break it, although if keyguard is on, we do let 3362 // it handle it, because that gives us the correct 5 second 3363 // timeout. 3364 if (keyCode == KeyEvent.KEYCODE_HOME) { 3365 3366 // If we have released the home key, and didn't do anything else 3367 // while it was pressed, then it is time to go home! 3368 if (!down) { 3369 cancelPreloadRecentApps(); 3370 3371 if (mHasFeatureLeanback) { 3372 // Clear flags 3373 mAccessibilityTvKey2Pressed = down; 3374 } 3375 3376 mHomePressed = false; 3377 if (mHomeConsumed) { 3378 mHomeConsumed = false; 3379 return -1; 3380 } 3381 3382 if (canceled) { 3383 Log.i(TAG, "Ignoring HOME; event canceled."); 3384 return -1; 3385 } 3386 3387 // Delay handling home if a double-tap is possible. 3388 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) { 3389 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case 3390 mHomeDoubleTapPending = true; 3391 mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable, 3392 ViewConfiguration.getDoubleTapTimeout()); 3393 return -1; 3394 } 3395 3396 handleShortPressOnHome(); 3397 return -1; 3398 } 3399 3400 // If a system window has focus, then it doesn't make sense 3401 // right now to interact with applications. 3402 WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null; 3403 if (attrs != null) { 3404 final int type = attrs.type; 3405 if (type == TYPE_KEYGUARD_DIALOG 3406 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 3407 // the "app" is keyguard, so give it the key 3408 return 0; 3409 } 3410 final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length; 3411 for (int i=0; i<typeCount; i++) { 3412 if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) { 3413 // don't do anything, but also don't pass it to the app 3414 return -1; 3415 } 3416 } 3417 } 3418 3419 // Remember that home is pressed and handle special actions. 3420 if (repeatCount == 0) { 3421 mHomePressed = true; 3422 if (mHomeDoubleTapPending) { 3423 mHomeDoubleTapPending = false; 3424 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); 3425 handleDoubleTapOnHome(); 3426 } else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) { 3427 preloadRecentApps(); 3428 } 3429 } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) { 3430 if (mHasFeatureLeanback) { 3431 mAccessibilityTvKey2Pressed = down; 3432 if (interceptAccessibilityGestureTv()) { 3433 return -1; 3434 } 3435 } 3436 3437 if (!keyguardOn) { 3438 handleLongPressOnHome(event.getDeviceId()); 3439 } 3440 } 3441 return -1; 3442 } else if (keyCode == KeyEvent.KEYCODE_MENU) { 3443 // Hijack modified menu keys for debugging features 3444 final int chordBug = KeyEvent.META_SHIFT_ON; 3445 3446 if (down && repeatCount == 0) { 3447 if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) { 3448 Intent intent = new Intent(Intent.ACTION_BUG_REPORT); 3449 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, 3450 null, null, null, 0, null, null); 3451 return -1; 3452 } 3453 } 3454 } else if (keyCode == KeyEvent.KEYCODE_SEARCH) { 3455 if (down) { 3456 if (repeatCount == 0) { 3457 mSearchKeyShortcutPending = true; 3458 mConsumeSearchKeyUp = false; 3459 } 3460 } else { 3461 mSearchKeyShortcutPending = false; 3462 if (mConsumeSearchKeyUp) { 3463 mConsumeSearchKeyUp = false; 3464 return -1; 3465 } 3466 } 3467 return 0; 3468 } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) { 3469 if (!keyguardOn) { 3470 if (down && repeatCount == 0) { 3471 preloadRecentApps(); 3472 } else if (!down) { 3473 toggleRecentApps(); 3474 } 3475 } 3476 return -1; 3477 } else if (keyCode == KeyEvent.KEYCODE_N && event.isMetaPressed()) { 3478 if (down) { 3479 IStatusBarService service = getStatusBarService(); 3480 if (service != null) { 3481 try { 3482 service.expandNotificationsPanel(); 3483 } catch (RemoteException e) { 3484 // do nothing. 3485 } 3486 } 3487 } 3488 } else if (keyCode == KeyEvent.KEYCODE_S && event.isMetaPressed() 3489 && event.isCtrlPressed()) { 3490 if (down && repeatCount == 0) { 3491 int type = event.isShiftPressed() ? TAKE_SCREENSHOT_SELECTED_REGION 3492 : TAKE_SCREENSHOT_FULLSCREEN; 3493 mScreenshotRunnable.setScreenshotType(type); 3494 mHandler.post(mScreenshotRunnable); 3495 return -1; 3496 } 3497 } else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) { 3498 if (down && repeatCount == 0 && !isKeyguardLocked()) { 3499 toggleKeyboardShortcutsMenu(event.getDeviceId()); 3500 } 3501 } else if (keyCode == KeyEvent.KEYCODE_ASSIST) { 3502 if (down) { 3503 if (repeatCount == 0) { 3504 mAssistKeyLongPressed = false; 3505 } else if (repeatCount == 1) { 3506 mAssistKeyLongPressed = true; 3507 if (!keyguardOn) { 3508 launchAssistLongPressAction(); 3509 } 3510 } 3511 } else { 3512 if (mAssistKeyLongPressed) { 3513 mAssistKeyLongPressed = false; 3514 } else { 3515 if (!keyguardOn) { 3516 launchAssistAction(null, event.getDeviceId()); 3517 } 3518 } 3519 } 3520 return -1; 3521 } else if (keyCode == KeyEvent.KEYCODE_VOICE_ASSIST) { 3522 if (!down) { 3523 Intent voiceIntent; 3524 if (!keyguardOn) { 3525 voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH); 3526 } else { 3527 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface( 3528 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 3529 if (dic != null) { 3530 try { 3531 dic.exitIdle("voice-search"); 3532 } catch (RemoteException e) { 3533 } 3534 } 3535 voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 3536 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true); 3537 } 3538 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 3539 } 3540 } else if (keyCode == KeyEvent.KEYCODE_SYSRQ) { 3541 if (down && repeatCount == 0) { 3542 mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN); 3543 mHandler.post(mScreenshotRunnable); 3544 } 3545 return -1; 3546 } else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP 3547 || keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) { 3548 if (down) { 3549 int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1; 3550 3551 // Disable autobrightness if it's on 3552 int auto = Settings.System.getIntForUser( 3553 mContext.getContentResolver(), 3554 Settings.System.SCREEN_BRIGHTNESS_MODE, 3555 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, 3556 UserHandle.USER_CURRENT_OR_SELF); 3557 if (auto != 0) { 3558 Settings.System.putIntForUser(mContext.getContentResolver(), 3559 Settings.System.SCREEN_BRIGHTNESS_MODE, 3560 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, 3561 UserHandle.USER_CURRENT_OR_SELF); 3562 } 3563 3564 int min = mPowerManager.getMinimumScreenBrightnessSetting(); 3565 int max = mPowerManager.getMaximumScreenBrightnessSetting(); 3566 int step = (max - min + BRIGHTNESS_STEPS - 1) / BRIGHTNESS_STEPS * direction; 3567 int brightness = Settings.System.getIntForUser(mContext.getContentResolver(), 3568 Settings.System.SCREEN_BRIGHTNESS, 3569 mPowerManager.getDefaultScreenBrightnessSetting(), 3570 UserHandle.USER_CURRENT_OR_SELF); 3571 brightness += step; 3572 // Make sure we don't go beyond the limits. 3573 brightness = Math.min(max, brightness); 3574 brightness = Math.max(min, brightness); 3575 3576 Settings.System.putIntForUser(mContext.getContentResolver(), 3577 Settings.System.SCREEN_BRIGHTNESS, brightness, 3578 UserHandle.USER_CURRENT_OR_SELF); 3579 startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG), 3580 UserHandle.CURRENT_OR_SELF); 3581 } 3582 return -1; 3583 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP 3584 || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 3585 || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) { 3586 if (mUseTvRouting || mHandleVolumeKeysInWM) { 3587 // On TVs or when the configuration is enabled, volume keys never 3588 // go to the foreground app. 3589 dispatchDirectAudioEvent(event); 3590 return -1; 3591 } 3592 3593 // If the device is in Vr mode, drop the volume keys and don't 3594 // forward it to the application/dispatch the audio event. 3595 if (mPersistentVrModeEnabled) { 3596 return -1; 3597 } 3598 } else if (keyCode == KeyEvent.KEYCODE_TAB && event.isMetaPressed()) { 3599 // Pass through keyboard navigation keys. 3600 return 0; 3601 } else if (mHasFeatureLeanback && interceptBugreportGestureTv(keyCode, down)) { 3602 return -1; 3603 } else if (mHasFeatureLeanback && keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 3604 mAccessibilityTvKey1Pressed = down; 3605 if (interceptAccessibilityGestureTv()) { 3606 return -1; 3607 } 3608 } 3609 3610 // Toggle Caps Lock on META-ALT. 3611 boolean actionTriggered = false; 3612 if (KeyEvent.isModifierKey(keyCode)) { 3613 if (!mPendingCapsLockToggle) { 3614 // Start tracking meta state for combo. 3615 mInitialMetaState = mMetaState; 3616 mPendingCapsLockToggle = true; 3617 } else if (event.getAction() == KeyEvent.ACTION_UP) { 3618 int altOnMask = mMetaState & KeyEvent.META_ALT_MASK; 3619 int metaOnMask = mMetaState & KeyEvent.META_META_MASK; 3620 3621 // Check for Caps Lock toggle 3622 if ((metaOnMask != 0) && (altOnMask != 0)) { 3623 // Check if nothing else is pressed 3624 if (mInitialMetaState == (mMetaState ^ (altOnMask | metaOnMask))) { 3625 // Handle Caps Lock Toggle 3626 mInputManagerInternal.toggleCapsLock(event.getDeviceId()); 3627 actionTriggered = true; 3628 } 3629 } 3630 3631 // Always stop tracking when key goes up. 3632 mPendingCapsLockToggle = false; 3633 } 3634 } 3635 // Store current meta state to be able to evaluate it later. 3636 mMetaState = metaState; 3637 3638 if (actionTriggered) { 3639 return -1; 3640 } 3641 3642 if (KeyEvent.isMetaKey(keyCode)) { 3643 if (down) { 3644 mPendingMetaAction = true; 3645 } else if (mPendingMetaAction) { 3646 launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, event.getDeviceId()); 3647 } 3648 return -1; 3649 } 3650 3651 // Shortcuts are invoked through Search+key, so intercept those here 3652 // Any printing key that is chorded with Search should be consumed 3653 // even if no shortcut was invoked. This prevents text from being 3654 // inadvertently inserted when using a keyboard that has built-in macro 3655 // shortcut keys (that emit Search+x) and some of them are not registered. 3656 if (mSearchKeyShortcutPending) { 3657 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3658 if (kcm.isPrintingKey(keyCode)) { 3659 mConsumeSearchKeyUp = true; 3660 mSearchKeyShortcutPending = false; 3661 if (down && repeatCount == 0 && !keyguardOn) { 3662 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState); 3663 if (shortcutIntent != null) { 3664 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3665 try { 3666 startActivityAsUser(shortcutIntent, UserHandle.CURRENT); 3667 dismissKeyboardShortcutsMenu(); 3668 } catch (ActivityNotFoundException ex) { 3669 Slog.w(TAG, "Dropping shortcut key combination because " 3670 + "the activity to which it is registered was not found: " 3671 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex); 3672 } 3673 } else { 3674 Slog.i(TAG, "Dropping unregistered shortcut key combination: " 3675 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode)); 3676 } 3677 } 3678 return -1; 3679 } 3680 } 3681 3682 // Invoke shortcuts using Meta. 3683 if (down && repeatCount == 0 && !keyguardOn 3684 && (metaState & KeyEvent.META_META_ON) != 0) { 3685 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3686 if (kcm.isPrintingKey(keyCode)) { 3687 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, 3688 metaState & ~(KeyEvent.META_META_ON 3689 | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON)); 3690 if (shortcutIntent != null) { 3691 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3692 try { 3693 startActivityAsUser(shortcutIntent, UserHandle.CURRENT); 3694 dismissKeyboardShortcutsMenu(); 3695 } catch (ActivityNotFoundException ex) { 3696 Slog.w(TAG, "Dropping shortcut key combination because " 3697 + "the activity to which it is registered was not found: " 3698 + "META+" + KeyEvent.keyCodeToString(keyCode), ex); 3699 } 3700 return -1; 3701 } 3702 } 3703 } 3704 3705 // Handle application launch keys. 3706 if (down && repeatCount == 0 && !keyguardOn) { 3707 String category = sApplicationLaunchKeyCategories.get(keyCode); 3708 if (category != null) { 3709 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category); 3710 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3711 try { 3712 startActivityAsUser(intent, UserHandle.CURRENT); 3713 dismissKeyboardShortcutsMenu(); 3714 } catch (ActivityNotFoundException ex) { 3715 Slog.w(TAG, "Dropping application launch key because " 3716 + "the activity to which it is registered was not found: " 3717 + "keyCode=" + keyCode + ", category=" + category, ex); 3718 } 3719 return -1; 3720 } 3721 } 3722 3723 // Display task switcher for ALT-TAB. 3724 if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) { 3725 if (mRecentAppsHeldModifiers == 0 && !keyguardOn && isUserSetupComplete()) { 3726 final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK; 3727 if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)) { 3728 mRecentAppsHeldModifiers = shiftlessModifiers; 3729 showRecentApps(true, false); 3730 return -1; 3731 } 3732 } 3733 } else if (!down && mRecentAppsHeldModifiers != 0 3734 && (metaState & mRecentAppsHeldModifiers) == 0) { 3735 mRecentAppsHeldModifiers = 0; 3736 hideRecentApps(true, false); 3737 } 3738 3739 // Handle input method switching. 3740 if (down && repeatCount == 0 3741 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH 3742 || (keyCode == KeyEvent.KEYCODE_SPACE 3743 && (metaState & KeyEvent.META_META_MASK) != 0))) { 3744 final boolean forwardDirection = (metaState & KeyEvent.META_SHIFT_MASK) == 0; 3745 mWindowManagerFuncs.switchInputMethod(forwardDirection); 3746 return -1; 3747 } 3748 if (mLanguageSwitchKeyPressed && !down 3749 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH 3750 || keyCode == KeyEvent.KEYCODE_SPACE)) { 3751 mLanguageSwitchKeyPressed = false; 3752 return -1; 3753 } 3754 3755 if (isValidGlobalKey(keyCode) 3756 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) { 3757 return -1; 3758 } 3759 3760 if (down) { 3761 long shortcutCode = keyCode; 3762 if (event.isCtrlPressed()) { 3763 shortcutCode |= ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE; 3764 } 3765 3766 if (event.isAltPressed()) { 3767 shortcutCode |= ((long) KeyEvent.META_ALT_ON) << Integer.SIZE; 3768 } 3769 3770 if (event.isShiftPressed()) { 3771 shortcutCode |= ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE; 3772 } 3773 3774 if (event.isMetaPressed()) { 3775 shortcutCode |= ((long) KeyEvent.META_META_ON) << Integer.SIZE; 3776 } 3777 3778 IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode); 3779 if (shortcutService != null) { 3780 try { 3781 if (isUserSetupComplete()) { 3782 shortcutService.notifyShortcutKeyPressed(shortcutCode); 3783 } 3784 } catch (RemoteException e) { 3785 mShortcutKeyServices.delete(shortcutCode); 3786 } 3787 return -1; 3788 } 3789 } 3790 3791 // Reserve all the META modifier combos for system behavior 3792 if ((metaState & KeyEvent.META_META_ON) != 0) { 3793 return -1; 3794 } 3795 3796 // Let the application handle the key. 3797 return 0; 3798 } 3799 3800 /** 3801 * TV only: recognizes a remote control gesture for capturing a bug report. 3802 */ 3803 private boolean interceptBugreportGestureTv(int keyCode, boolean down) { 3804 // The bugreport capture chord is a long press on DPAD CENTER and BACK simultaneously. 3805 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 3806 mBugreportTvKey1Pressed = down; 3807 } else if (keyCode == KeyEvent.KEYCODE_BACK) { 3808 mBugreportTvKey2Pressed = down; 3809 } 3810 3811 if (mBugreportTvKey1Pressed && mBugreportTvKey2Pressed) { 3812 if (!mBugreportTvScheduled) { 3813 mBugreportTvScheduled = true; 3814 Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV); 3815 msg.setAsynchronous(true); 3816 mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS); 3817 } 3818 } else if (mBugreportTvScheduled) { 3819 mHandler.removeMessages(MSG_BUGREPORT_TV); 3820 mBugreportTvScheduled = false; 3821 } 3822 3823 return mBugreportTvScheduled; 3824 } 3825 3826 /** 3827 * TV only: recognizes a remote control gesture as Accessibility shortcut. 3828 * Shortcut: Long press (HOME + DPAD_CENTER) 3829 */ 3830 private boolean interceptAccessibilityGestureTv() { 3831 if (mAccessibilityTvKey1Pressed && mAccessibilityTvKey2Pressed) { 3832 if (!mAccessibilityTvScheduled) { 3833 mAccessibilityTvScheduled = true; 3834 Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV); 3835 msg.setAsynchronous(true); 3836 mHandler.sendMessage(msg); 3837 } 3838 } else if (mAccessibilityTvScheduled) { 3839 mHandler.removeMessages(MSG_ACCESSIBILITY_TV); 3840 mAccessibilityTvScheduled = false; 3841 } 3842 return mAccessibilityTvScheduled; 3843 } 3844 3845 private void takeBugreport() { 3846 if ("1".equals(SystemProperties.get("ro.debuggable")) 3847 || Settings.Global.getInt(mContext.getContentResolver(), 3848 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) { 3849 try { 3850 ActivityManager.getService() 3851 .requestBugReport(ActivityManager.BUGREPORT_OPTION_INTERACTIVE); 3852 } catch (RemoteException e) { 3853 Slog.e(TAG, "Error taking bugreport", e); 3854 } 3855 } 3856 } 3857 3858 /** {@inheritDoc} */ 3859 @Override 3860 public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) { 3861 // Note: This method is only called if the initial down was unhandled. 3862 if (DEBUG_INPUT) { 3863 Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction() 3864 + ", flags=" + event.getFlags() 3865 + ", keyCode=" + event.getKeyCode() 3866 + ", scanCode=" + event.getScanCode() 3867 + ", metaState=" + event.getMetaState() 3868 + ", repeatCount=" + event.getRepeatCount() 3869 + ", policyFlags=" + policyFlags); 3870 } 3871 3872 KeyEvent fallbackEvent = null; 3873 if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 3874 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3875 final int keyCode = event.getKeyCode(); 3876 final int metaState = event.getMetaState(); 3877 final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN 3878 && event.getRepeatCount() == 0; 3879 3880 // Check for fallback actions specified by the key character map. 3881 final FallbackAction fallbackAction; 3882 if (initialDown) { 3883 fallbackAction = kcm.getFallbackAction(keyCode, metaState); 3884 } else { 3885 fallbackAction = mFallbackActions.get(keyCode); 3886 } 3887 3888 if (fallbackAction != null) { 3889 if (DEBUG_INPUT) { 3890 Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode 3891 + " metaState=" + Integer.toHexString(fallbackAction.metaState)); 3892 } 3893 3894 final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK; 3895 fallbackEvent = KeyEvent.obtain( 3896 event.getDownTime(), event.getEventTime(), 3897 event.getAction(), fallbackAction.keyCode, 3898 event.getRepeatCount(), fallbackAction.metaState, 3899 event.getDeviceId(), event.getScanCode(), 3900 flags, event.getSource(), null); 3901 3902 if (!interceptFallback(win, fallbackEvent, policyFlags)) { 3903 fallbackEvent.recycle(); 3904 fallbackEvent = null; 3905 } 3906 3907 if (initialDown) { 3908 mFallbackActions.put(keyCode, fallbackAction); 3909 } else if (event.getAction() == KeyEvent.ACTION_UP) { 3910 mFallbackActions.remove(keyCode); 3911 fallbackAction.recycle(); 3912 } 3913 } 3914 } 3915 3916 if (DEBUG_INPUT) { 3917 if (fallbackEvent == null) { 3918 Slog.d(TAG, "No fallback."); 3919 } else { 3920 Slog.d(TAG, "Performing fallback: " + fallbackEvent); 3921 } 3922 } 3923 return fallbackEvent; 3924 } 3925 3926 private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) { 3927 int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags); 3928 if ((actions & ACTION_PASS_TO_USER) != 0) { 3929 long delayMillis = interceptKeyBeforeDispatching( 3930 win, fallbackEvent, policyFlags); 3931 if (delayMillis == 0) { 3932 return true; 3933 } 3934 } 3935 return false; 3936 } 3937 3938 @Override 3939 public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService) 3940 throws RemoteException { 3941 synchronized (mLock) { 3942 IShortcutService service = mShortcutKeyServices.get(shortcutCode); 3943 if (service != null && service.asBinder().pingBinder()) { 3944 throw new RemoteException("Key already exists."); 3945 } 3946 3947 mShortcutKeyServices.put(shortcutCode, shortcutService); 3948 } 3949 } 3950 3951 @Override 3952 public void onKeyguardOccludedChangedLw(boolean occluded) { 3953 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 3954 mPendingKeyguardOccluded = occluded; 3955 mKeyguardOccludedChanged = true; 3956 } else { 3957 setKeyguardOccludedLw(occluded, false /* force */); 3958 } 3959 } 3960 3961 private int handleStartTransitionForKeyguardLw(int transit, @Nullable Animation anim) { 3962 if (mKeyguardOccludedChanged) { 3963 if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded=" 3964 + mPendingKeyguardOccluded); 3965 mKeyguardOccludedChanged = false; 3966 if (setKeyguardOccludedLw(mPendingKeyguardOccluded, false /* force */)) { 3967 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER; 3968 } 3969 } 3970 if (AppTransition.isKeyguardGoingAwayTransit(transit)) { 3971 if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation"); 3972 final long startTime = anim != null 3973 ? SystemClock.uptimeMillis() + anim.getStartOffset() 3974 : SystemClock.uptimeMillis(); 3975 final long duration = anim != null 3976 ? anim.getDuration() 3977 : 0; 3978 startKeyguardExitAnimation(startTime, duration); 3979 } 3980 return 0; 3981 } 3982 3983 private void launchAssistLongPressAction() { 3984 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); 3985 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 3986 3987 // launch the search activity 3988 Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); 3989 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3990 try { 3991 // TODO: This only stops the factory-installed search manager. 3992 // Need to formalize an API to handle others 3993 SearchManager searchManager = getSearchManager(); 3994 if (searchManager != null) { 3995 searchManager.stopSearch(); 3996 } 3997 startActivityAsUser(intent, UserHandle.CURRENT); 3998 } catch (ActivityNotFoundException e) { 3999 Slog.w(TAG, "No activity to handle assist long press action.", e); 4000 } 4001 } 4002 4003 private void launchAssistAction(String hint, int deviceId) { 4004 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 4005 if (!isUserSetupComplete()) { 4006 // Disable opening assist window during setup 4007 return; 4008 } 4009 Bundle args = null; 4010 if (deviceId > Integer.MIN_VALUE) { 4011 args = new Bundle(); 4012 args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, deviceId); 4013 } 4014 if ((mContext.getResources().getConfiguration().uiMode 4015 & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) { 4016 // On TV, use legacy handling until assistants are implemented in the proper way. 4017 ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 4018 .launchLegacyAssist(hint, UserHandle.myUserId(), args); 4019 } else { 4020 if (hint != null) { 4021 if (args == null) { 4022 args = new Bundle(); 4023 } 4024 args.putBoolean(hint, true); 4025 } 4026 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4027 if (statusbar != null) { 4028 statusbar.startAssist(args); 4029 } 4030 } 4031 } 4032 4033 private void startActivityAsUser(Intent intent, UserHandle handle) { 4034 if (isUserSetupComplete()) { 4035 mContext.startActivityAsUser(intent, handle); 4036 } else { 4037 Slog.i(TAG, "Not starting activity because user setup is in progress: " + intent); 4038 } 4039 } 4040 4041 private SearchManager getSearchManager() { 4042 if (mSearchManager == null) { 4043 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 4044 } 4045 return mSearchManager; 4046 } 4047 4048 private void preloadRecentApps() { 4049 mPreloadedRecentApps = true; 4050 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4051 if (statusbar != null) { 4052 statusbar.preloadRecentApps(); 4053 } 4054 } 4055 4056 private void cancelPreloadRecentApps() { 4057 if (mPreloadedRecentApps) { 4058 mPreloadedRecentApps = false; 4059 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4060 if (statusbar != null) { 4061 statusbar.cancelPreloadRecentApps(); 4062 } 4063 } 4064 } 4065 4066 private void toggleRecentApps() { 4067 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 4068 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4069 if (statusbar != null) { 4070 statusbar.toggleRecentApps(); 4071 } 4072 } 4073 4074 @Override 4075 public void showRecentApps(boolean fromHome) { 4076 mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS); 4077 mHandler.obtainMessage(MSG_DISPATCH_SHOW_RECENTS, fromHome ? 1 : 0, 0).sendToTarget(); 4078 } 4079 4080 private void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) { 4081 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 4082 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4083 if (statusbar != null) { 4084 statusbar.showRecentApps(triggeredFromAltTab, fromHome); 4085 } 4086 } 4087 4088 private void toggleKeyboardShortcutsMenu(int deviceId) { 4089 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4090 if (statusbar != null) { 4091 statusbar.toggleKeyboardShortcutsMenu(deviceId); 4092 } 4093 } 4094 4095 private void dismissKeyboardShortcutsMenu() { 4096 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4097 if (statusbar != null) { 4098 statusbar.dismissKeyboardShortcutsMenu(); 4099 } 4100 } 4101 4102 private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) { 4103 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 4104 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 4105 if (statusbar != null) { 4106 statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome); 4107 } 4108 } 4109 4110 void launchHomeFromHotKey() { 4111 launchHomeFromHotKey(true /* awakenFromDreams */, true /*respectKeyguard*/); 4112 } 4113 4114 /** 4115 * A home key -> launch home action was detected. Take the appropriate action 4116 * given the situation with the keyguard. 4117 */ 4118 void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) { 4119 if (respectKeyguard) { 4120 if (isKeyguardShowingAndNotOccluded()) { 4121 // don't launch home if keyguard showing 4122 return; 4123 } 4124 4125 if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) { 4126 // when in keyguard restricted mode, must first verify unlock 4127 // before launching home 4128 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() { 4129 @Override 4130 public void onKeyguardExitResult(boolean success) { 4131 if (success) { 4132 try { 4133 ActivityManager.getService().stopAppSwitches(); 4134 } catch (RemoteException e) { 4135 } 4136 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 4137 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); 4138 } 4139 } 4140 }); 4141 return; 4142 } 4143 } 4144 4145 // no keyguard stuff to worry about, just launch home! 4146 try { 4147 ActivityManager.getService().stopAppSwitches(); 4148 } catch (RemoteException e) { 4149 } 4150 if (mRecentsVisible) { 4151 // Hide Recents and notify it to launch Home 4152 if (awakenFromDreams) { 4153 awakenDreams(); 4154 } 4155 hideRecentApps(false, true); 4156 } else { 4157 // Otherwise, just launch Home 4158 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 4159 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); 4160 } 4161 } 4162 4163 private final Runnable mClearHideNavigationFlag = new Runnable() { 4164 @Override 4165 public void run() { 4166 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 4167 // Clear flags. 4168 mForceClearedSystemUiFlags &= 4169 ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 4170 } 4171 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 4172 } 4173 }; 4174 4175 /** 4176 * Input handler used while nav bar is hidden. Captures any touch on the screen, 4177 * to determine when the nav bar should be shown and prevent applications from 4178 * receiving those touches. 4179 */ 4180 final class HideNavInputEventReceiver extends InputEventReceiver { 4181 public HideNavInputEventReceiver(InputChannel inputChannel, Looper looper) { 4182 super(inputChannel, looper); 4183 } 4184 4185 @Override 4186 public void onInputEvent(InputEvent event) { 4187 boolean handled = false; 4188 try { 4189 if (event instanceof MotionEvent 4190 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { 4191 final MotionEvent motionEvent = (MotionEvent)event; 4192 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 4193 // When the user taps down, we re-show the nav bar. 4194 boolean changed = false; 4195 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 4196 if (mInputConsumer == null) { 4197 return; 4198 } 4199 // Any user activity always causes us to show the 4200 // navigation controls, if they had been hidden. 4201 // We also clear the low profile and only content 4202 // flags so that tapping on the screen will atomically 4203 // restore all currently hidden screen decorations. 4204 int newVal = mResettingSystemUiFlags | 4205 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 4206 View.SYSTEM_UI_FLAG_LOW_PROFILE | 4207 View.SYSTEM_UI_FLAG_FULLSCREEN; 4208 if (mResettingSystemUiFlags != newVal) { 4209 mResettingSystemUiFlags = newVal; 4210 changed = true; 4211 } 4212 // We don't allow the system's nav bar to be hidden 4213 // again for 1 second, to prevent applications from 4214 // spamming us and keeping it from being shown. 4215 newVal = mForceClearedSystemUiFlags | 4216 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 4217 if (mForceClearedSystemUiFlags != newVal) { 4218 mForceClearedSystemUiFlags = newVal; 4219 changed = true; 4220 mHandler.postDelayed(mClearHideNavigationFlag, 1000); 4221 } 4222 } 4223 if (changed) { 4224 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 4225 } 4226 } 4227 } 4228 } finally { 4229 finishInputEvent(event, handled); 4230 } 4231 } 4232 } 4233 4234 @Override 4235 public void setRecentsVisibilityLw(boolean visible) { 4236 mRecentsVisible = visible; 4237 } 4238 4239 @Override 4240 public void setPipVisibilityLw(boolean visible) { 4241 mPictureInPictureVisible = visible; 4242 } 4243 4244 @Override 4245 public int adjustSystemUiVisibilityLw(int visibility) { 4246 mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); 4247 mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); 4248 4249 // Reset any bits in mForceClearingStatusBarVisibility that 4250 // are now clear. 4251 mResettingSystemUiFlags &= visibility; 4252 // Clear any bits in the new visibility that are currently being 4253 // force cleared, before reporting it. 4254 return visibility & ~mResettingSystemUiFlags 4255 & ~mForceClearedSystemUiFlags; 4256 } 4257 4258 @Override 4259 public boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds, 4260 int displayRotation, int displayWidth, int displayHeight, Rect outContentInsets, 4261 Rect outStableInsets, Rect outOutsets) { 4262 final int fl = PolicyControl.getWindowFlags(null, attrs); 4263 final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs); 4264 final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility); 4265 4266 final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl); 4267 if (useOutsets) { 4268 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); 4269 if (outset > 0) { 4270 if (displayRotation == Surface.ROTATION_0) { 4271 outOutsets.bottom += outset; 4272 } else if (displayRotation == Surface.ROTATION_90) { 4273 outOutsets.right += outset; 4274 } else if (displayRotation == Surface.ROTATION_180) { 4275 outOutsets.top += outset; 4276 } else if (displayRotation == Surface.ROTATION_270) { 4277 outOutsets.left += outset; 4278 } 4279 } 4280 } 4281 4282 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) 4283 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { 4284 int availRight, availBottom; 4285 if (canHideNavigationBar() && 4286 (systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { 4287 availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4288 availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4289 } else { 4290 availRight = mRestrictedScreenLeft + mRestrictedScreenWidth; 4291 availBottom = mRestrictedScreenTop + mRestrictedScreenHeight; 4292 } 4293 if ((systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 4294 if ((fl & FLAG_FULLSCREEN) != 0) { 4295 outContentInsets.set(mStableFullscreenLeft, mStableFullscreenTop, 4296 availRight - mStableFullscreenRight, 4297 availBottom - mStableFullscreenBottom); 4298 } else { 4299 outContentInsets.set(mStableLeft, mStableTop, 4300 availRight - mStableRight, availBottom - mStableBottom); 4301 } 4302 } else if ((fl & FLAG_FULLSCREEN) != 0 || (fl & FLAG_LAYOUT_IN_OVERSCAN) != 0) { 4303 outContentInsets.setEmpty(); 4304 } else if ((systemUiVisibility & (View.SYSTEM_UI_FLAG_FULLSCREEN 4305 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)) == 0) { 4306 outContentInsets.set(mCurLeft, mCurTop, 4307 availRight - mCurRight, availBottom - mCurBottom); 4308 } else { 4309 outContentInsets.set(mCurLeft, mCurTop, 4310 availRight - mCurRight, availBottom - mCurBottom); 4311 } 4312 4313 outStableInsets.set(mStableLeft, mStableTop, 4314 availRight - mStableRight, availBottom - mStableBottom); 4315 if (taskBounds != null) { 4316 calculateRelevantTaskInsets(taskBounds, outContentInsets, 4317 displayWidth, displayHeight); 4318 calculateRelevantTaskInsets(taskBounds, outStableInsets, 4319 displayWidth, displayHeight); 4320 } 4321 return mForceShowSystemBars; 4322 } 4323 outContentInsets.setEmpty(); 4324 outStableInsets.setEmpty(); 4325 return mForceShowSystemBars; 4326 } 4327 4328 /** 4329 * For any given task bounds, the insets relevant for these bounds given the insets relevant 4330 * for the entire display. 4331 */ 4332 private void calculateRelevantTaskInsets(Rect taskBounds, Rect inOutInsets, int displayWidth, 4333 int displayHeight) { 4334 mTmpRect.set(0, 0, displayWidth, displayHeight); 4335 mTmpRect.inset(inOutInsets); 4336 mTmpRect.intersect(taskBounds); 4337 int leftInset = mTmpRect.left - taskBounds.left; 4338 int topInset = mTmpRect.top - taskBounds.top; 4339 int rightInset = taskBounds.right - mTmpRect.right; 4340 int bottomInset = taskBounds.bottom - mTmpRect.bottom; 4341 inOutInsets.set(leftInset, topInset, rightInset, bottomInset); 4342 } 4343 4344 private boolean shouldUseOutsets(WindowManager.LayoutParams attrs, int fl) { 4345 return attrs.type == TYPE_WALLPAPER || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN 4346 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0; 4347 } 4348 4349 /** {@inheritDoc} */ 4350 @Override 4351 public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight, 4352 int displayRotation, int uiMode) { 4353 mDisplayRotation = displayRotation; 4354 final int overscanLeft, overscanTop, overscanRight, overscanBottom; 4355 if (isDefaultDisplay) { 4356 switch (displayRotation) { 4357 case Surface.ROTATION_90: 4358 overscanLeft = mOverscanTop; 4359 overscanTop = mOverscanRight; 4360 overscanRight = mOverscanBottom; 4361 overscanBottom = mOverscanLeft; 4362 break; 4363 case Surface.ROTATION_180: 4364 overscanLeft = mOverscanRight; 4365 overscanTop = mOverscanBottom; 4366 overscanRight = mOverscanLeft; 4367 overscanBottom = mOverscanTop; 4368 break; 4369 case Surface.ROTATION_270: 4370 overscanLeft = mOverscanBottom; 4371 overscanTop = mOverscanLeft; 4372 overscanRight = mOverscanTop; 4373 overscanBottom = mOverscanRight; 4374 break; 4375 default: 4376 overscanLeft = mOverscanLeft; 4377 overscanTop = mOverscanTop; 4378 overscanRight = mOverscanRight; 4379 overscanBottom = mOverscanBottom; 4380 break; 4381 } 4382 } else { 4383 overscanLeft = 0; 4384 overscanTop = 0; 4385 overscanRight = 0; 4386 overscanBottom = 0; 4387 } 4388 mOverscanScreenLeft = mRestrictedOverscanScreenLeft = 0; 4389 mOverscanScreenTop = mRestrictedOverscanScreenTop = 0; 4390 mOverscanScreenWidth = mRestrictedOverscanScreenWidth = displayWidth; 4391 mOverscanScreenHeight = mRestrictedOverscanScreenHeight = displayHeight; 4392 mSystemLeft = 0; 4393 mSystemTop = 0; 4394 mSystemRight = displayWidth; 4395 mSystemBottom = displayHeight; 4396 mUnrestrictedScreenLeft = overscanLeft; 4397 mUnrestrictedScreenTop = overscanTop; 4398 mUnrestrictedScreenWidth = displayWidth - overscanLeft - overscanRight; 4399 mUnrestrictedScreenHeight = displayHeight - overscanTop - overscanBottom; 4400 mRestrictedScreenLeft = mUnrestrictedScreenLeft; 4401 mRestrictedScreenTop = mUnrestrictedScreenTop; 4402 mRestrictedScreenWidth = mSystemGestures.screenWidth = mUnrestrictedScreenWidth; 4403 mRestrictedScreenHeight = mSystemGestures.screenHeight = mUnrestrictedScreenHeight; 4404 mDockLeft = mContentLeft = mVoiceContentLeft = mStableLeft = mStableFullscreenLeft 4405 = mCurLeft = mUnrestrictedScreenLeft; 4406 mDockTop = mContentTop = mVoiceContentTop = mStableTop = mStableFullscreenTop 4407 = mCurTop = mUnrestrictedScreenTop; 4408 mDockRight = mContentRight = mVoiceContentRight = mStableRight = mStableFullscreenRight 4409 = mCurRight = displayWidth - overscanRight; 4410 mDockBottom = mContentBottom = mVoiceContentBottom = mStableBottom = mStableFullscreenBottom 4411 = mCurBottom = displayHeight - overscanBottom; 4412 mDockLayer = 0x10000000; 4413 mStatusBarLayer = -1; 4414 4415 // start with the current dock rect, which will be (0,0,displayWidth,displayHeight) 4416 final Rect pf = mTmpParentFrame; 4417 final Rect df = mTmpDisplayFrame; 4418 final Rect of = mTmpOverscanFrame; 4419 final Rect vf = mTmpVisibleFrame; 4420 final Rect dcf = mTmpDecorFrame; 4421 pf.left = df.left = of.left = vf.left = mDockLeft; 4422 pf.top = df.top = of.top = vf.top = mDockTop; 4423 pf.right = df.right = of.right = vf.right = mDockRight; 4424 pf.bottom = df.bottom = of.bottom = vf.bottom = mDockBottom; 4425 dcf.setEmpty(); // Decor frame N/A for system bars. 4426 4427 if (isDefaultDisplay) { 4428 // For purposes of putting out fake window up to steal focus, we will 4429 // drive nav being hidden only by whether it is requested. 4430 final int sysui = mLastSystemUiFlags; 4431 boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; 4432 boolean navTranslucent = (sysui 4433 & (View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT)) != 0; 4434 boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; 4435 boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 4436 boolean navAllowedHidden = immersive || immersiveSticky; 4437 navTranslucent &= !immersiveSticky; // transient trumps translucent 4438 boolean isKeyguardShowing = isStatusBarKeyguard() && !mKeyguardOccluded; 4439 if (!isKeyguardShowing) { 4440 navTranslucent &= areTranslucentBarsAllowed(); 4441 } 4442 boolean statusBarExpandedNotKeyguard = !isKeyguardShowing && mStatusBar != null 4443 && mStatusBar.getAttrs().height == MATCH_PARENT 4444 && mStatusBar.getAttrs().width == MATCH_PARENT; 4445 4446 // When the navigation bar isn't visible, we put up a fake 4447 // input window to catch all touch events. This way we can 4448 // detect when the user presses anywhere to bring back the nav 4449 // bar and ensure the application doesn't see the event. 4450 if (navVisible || navAllowedHidden) { 4451 if (mInputConsumer != null) { 4452 mHandler.sendMessage( 4453 mHandler.obtainMessage(MSG_DISPOSE_INPUT_CONSUMER, mInputConsumer)); 4454 mInputConsumer = null; 4455 } 4456 } else if (mInputConsumer == null) { 4457 mInputConsumer = mWindowManagerFuncs.createInputConsumer(mHandler.getLooper(), 4458 INPUT_CONSUMER_NAVIGATION, 4459 (channel, looper) -> new HideNavInputEventReceiver(channel, looper)); 4460 // As long as mInputConsumer is active, hover events are not dispatched to the app 4461 // and the pointer icon is likely to become stale. Hide it to avoid confusion. 4462 InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_NULL); 4463 } 4464 4465 // For purposes of positioning and showing the nav bar, if we have 4466 // decided that it can't be hidden (because of the screen aspect ratio), 4467 // then take that into account. 4468 navVisible |= !canHideNavigationBar(); 4469 4470 boolean updateSysUiVisibility = layoutNavigationBar(displayWidth, displayHeight, 4471 displayRotation, uiMode, overscanLeft, overscanRight, overscanBottom, dcf, navVisible, navTranslucent, 4472 navAllowedHidden, statusBarExpandedNotKeyguard); 4473 if (DEBUG_LAYOUT) Slog.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)", 4474 mDockLeft, mDockTop, mDockRight, mDockBottom)); 4475 updateSysUiVisibility |= layoutStatusBar(pf, df, of, vf, dcf, sysui, isKeyguardShowing); 4476 if (updateSysUiVisibility) { 4477 updateSystemUiVisibilityLw(); 4478 } 4479 } 4480 } 4481 4482 private boolean layoutStatusBar(Rect pf, Rect df, Rect of, Rect vf, Rect dcf, int sysui, 4483 boolean isKeyguardShowing) { 4484 // decide where the status bar goes ahead of time 4485 if (mStatusBar != null) { 4486 // apply any navigation bar insets 4487 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4488 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4489 pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft; 4490 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight 4491 + mUnrestrictedScreenTop; 4492 vf.left = mStableLeft; 4493 vf.top = mStableTop; 4494 vf.right = mStableRight; 4495 vf.bottom = mStableBottom; 4496 4497 mStatusBarLayer = mStatusBar.getSurfaceLayer(); 4498 4499 // Let the status bar determine its size. 4500 mStatusBar.computeFrameLw(pf /* parentFrame */, df /* displayFrame */, 4501 vf /* overlayFrame */, vf /* contentFrame */, vf /* visibleFrame */, 4502 dcf /* decorFrame */, vf /* stableFrame */, vf /* outsetFrame */); 4503 4504 // For layout, the status bar is always at the top with our fixed height. 4505 mStableTop = mUnrestrictedScreenTop + mStatusBarHeight; 4506 4507 boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0; 4508 boolean statusBarTranslucent = (sysui 4509 & (View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT)) != 0; 4510 if (!isKeyguardShowing) { 4511 statusBarTranslucent &= areTranslucentBarsAllowed(); 4512 } 4513 4514 // If the status bar is hidden, we don't want to cause 4515 // windows behind it to scroll. 4516 if (mStatusBar.isVisibleLw() && !statusBarTransient) { 4517 // Status bar may go away, so the screen area it occupies 4518 // is available to apps but just covering them when the 4519 // status bar is visible. 4520 mDockTop = mUnrestrictedScreenTop + mStatusBarHeight; 4521 4522 mContentTop = mVoiceContentTop = mCurTop = mDockTop; 4523 mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; 4524 mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; 4525 mContentRight = mVoiceContentRight = mCurRight = mDockRight; 4526 4527 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " + 4528 String.format( 4529 "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]", 4530 mDockLeft, mDockTop, mDockRight, mDockBottom, 4531 mContentLeft, mContentTop, mContentRight, mContentBottom, 4532 mCurLeft, mCurTop, mCurRight, mCurBottom)); 4533 } 4534 if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw() 4535 && !statusBarTransient && !statusBarTranslucent 4536 && !mStatusBarController.wasRecentlyTranslucent()) { 4537 // If the opaque status bar is currently requested to be visible, 4538 // and not in the process of animating on or off, then 4539 // we can tell the app that it is covered by it. 4540 mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight; 4541 } 4542 if (mStatusBarController.checkHiddenLw()) { 4543 return true; 4544 } 4545 } 4546 return false; 4547 } 4548 4549 private boolean layoutNavigationBar(int displayWidth, int displayHeight, int displayRotation, 4550 int uiMode, int overscanLeft, int overscanRight, int overscanBottom, Rect dcf, 4551 boolean navVisible, boolean navTranslucent, boolean navAllowedHidden, 4552 boolean statusBarExpandedNotKeyguard) { 4553 if (mNavigationBar != null) { 4554 boolean transientNavBarShowing = mNavigationBarController.isTransientShowing(); 4555 // Force the navigation bar to its appropriate place and 4556 // size. We need to do this directly, instead of relying on 4557 // it to bubble up from the nav bar, because this needs to 4558 // change atomically with screen rotations. 4559 mNavigationBarPosition = navigationBarPosition(displayWidth, displayHeight, 4560 displayRotation); 4561 if (mNavigationBarPosition == NAV_BAR_BOTTOM) { 4562 // It's a system nav bar or a portrait screen; nav bar goes on bottom. 4563 int top = displayHeight - overscanBottom 4564 - getNavigationBarHeight(displayRotation, uiMode); 4565 mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom); 4566 mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top; 4567 if (transientNavBarShowing) { 4568 mNavigationBarController.setBarShowingLw(true); 4569 } else if (navVisible) { 4570 mNavigationBarController.setBarShowingLw(true); 4571 mDockBottom = mTmpNavigationFrame.top; 4572 mRestrictedScreenHeight = mDockBottom - mRestrictedScreenTop; 4573 mRestrictedOverscanScreenHeight = mDockBottom - mRestrictedOverscanScreenTop; 4574 } else { 4575 // We currently want to hide the navigation UI - unless we expanded the status 4576 // bar. 4577 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4578 } 4579 if (navVisible && !navTranslucent && !navAllowedHidden 4580 && !mNavigationBar.isAnimatingLw() 4581 && !mNavigationBarController.wasRecentlyTranslucent()) { 4582 // If the opaque nav bar is currently requested to be visible, 4583 // and not in the process of animating on or off, then 4584 // we can tell the app that it is covered by it. 4585 mSystemBottom = mTmpNavigationFrame.top; 4586 } 4587 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) { 4588 // Landscape screen; nav bar goes to the right. 4589 int left = displayWidth - overscanRight 4590 - getNavigationBarWidth(displayRotation, uiMode); 4591 mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight); 4592 mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left; 4593 if (transientNavBarShowing) { 4594 mNavigationBarController.setBarShowingLw(true); 4595 } else if (navVisible) { 4596 mNavigationBarController.setBarShowingLw(true); 4597 mDockRight = mTmpNavigationFrame.left; 4598 mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft; 4599 mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft; 4600 } else { 4601 // We currently want to hide the navigation UI - unless we expanded the status 4602 // bar. 4603 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4604 } 4605 if (navVisible && !navTranslucent && !navAllowedHidden 4606 && !mNavigationBar.isAnimatingLw() 4607 && !mNavigationBarController.wasRecentlyTranslucent()) { 4608 // If the nav bar is currently requested to be visible, 4609 // and not in the process of animating on or off, then 4610 // we can tell the app that it is covered by it. 4611 mSystemRight = mTmpNavigationFrame.left; 4612 } 4613 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 4614 // Seascape screen; nav bar goes to the left. 4615 int right = overscanLeft + getNavigationBarWidth(displayRotation, uiMode); 4616 mTmpNavigationFrame.set(overscanLeft, 0, right, displayHeight); 4617 mStableLeft = mStableFullscreenLeft = mTmpNavigationFrame.right; 4618 if (transientNavBarShowing) { 4619 mNavigationBarController.setBarShowingLw(true); 4620 } else if (navVisible) { 4621 mNavigationBarController.setBarShowingLw(true); 4622 mDockLeft = mTmpNavigationFrame.right; 4623 // TODO: not so sure about those: 4624 mRestrictedScreenLeft = mRestrictedOverscanScreenLeft = mDockLeft; 4625 mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft; 4626 mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft; 4627 } else { 4628 // We currently want to hide the navigation UI - unless we expanded the status 4629 // bar. 4630 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4631 } 4632 if (navVisible && !navTranslucent && !navAllowedHidden 4633 && !mNavigationBar.isAnimatingLw() 4634 && !mNavigationBarController.wasRecentlyTranslucent()) { 4635 // If the nav bar is currently requested to be visible, 4636 // and not in the process of animating on or off, then 4637 // we can tell the app that it is covered by it. 4638 mSystemLeft = mTmpNavigationFrame.right; 4639 } 4640 } 4641 // Make sure the content and current rectangles are updated to 4642 // account for the restrictions from the navigation bar. 4643 mContentTop = mVoiceContentTop = mCurTop = mDockTop; 4644 mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; 4645 mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; 4646 mContentRight = mVoiceContentRight = mCurRight = mDockRight; 4647 mStatusBarLayer = mNavigationBar.getSurfaceLayer(); 4648 // And compute the final frame. 4649 mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, 4650 mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf, 4651 mTmpNavigationFrame, mTmpNavigationFrame); 4652 if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame); 4653 if (mNavigationBarController.checkHiddenLw()) { 4654 return true; 4655 } 4656 } 4657 return false; 4658 } 4659 4660 private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) { 4661 if (mNavigationBarCanMove && displayWidth > displayHeight) { 4662 if (displayRotation == Surface.ROTATION_270) { 4663 return NAV_BAR_LEFT; 4664 } else { 4665 return NAV_BAR_RIGHT; 4666 } 4667 } 4668 return NAV_BAR_BOTTOM; 4669 } 4670 4671 /** {@inheritDoc} */ 4672 @Override 4673 public int getSystemDecorLayerLw() { 4674 if (mStatusBar != null && mStatusBar.isVisibleLw()) { 4675 return mStatusBar.getSurfaceLayer(); 4676 } 4677 4678 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) { 4679 return mNavigationBar.getSurfaceLayer(); 4680 } 4681 4682 return 0; 4683 } 4684 4685 @Override 4686 public void getContentRectLw(Rect r) { 4687 r.set(mContentLeft, mContentTop, mContentRight, mContentBottom); 4688 } 4689 4690 void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached, 4691 boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf) { 4692 if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { 4693 // Here's a special case: if this attached window is a panel that is 4694 // above the dock window, and the window it is attached to is below 4695 // the dock window, then the frames we computed for the window it is 4696 // attached to can not be used because the dock is effectively part 4697 // of the underlying window and the attached window is floating on top 4698 // of the whole thing. So, we ignore the attached window and explicitly 4699 // compute the frames that would be appropriate without the dock. 4700 df.left = of.left = cf.left = vf.left = mDockLeft; 4701 df.top = of.top = cf.top = vf.top = mDockTop; 4702 df.right = of.right = cf.right = vf.right = mDockRight; 4703 df.bottom = of.bottom = cf.bottom = vf.bottom = mDockBottom; 4704 } else { 4705 // The effective display frame of the attached window depends on 4706 // whether it is taking care of insetting its content. If not, 4707 // we need to use the parent's content frame so that the entire 4708 // window is positioned within that content. Otherwise we can use 4709 // the overscan frame and let the attached window take care of 4710 // positioning its content appropriately. 4711 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4712 // Set the content frame of the attached window to the parent's decor frame 4713 // (same as content frame when IME isn't present) if specifically requested by 4714 // setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag. 4715 // Otherwise, use the overscan frame. 4716 cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0 4717 ? attached.getContentFrameLw() : attached.getOverscanFrameLw()); 4718 } else { 4719 // If the window is resizing, then we want to base the content 4720 // frame on our attached content frame to resize... however, 4721 // things can be tricky if the attached window is NOT in resize 4722 // mode, in which case its content frame will be larger. 4723 // Ungh. So to deal with that, make sure the content frame 4724 // we end up using is not covering the IM dock. 4725 cf.set(attached.getContentFrameLw()); 4726 if (attached.isVoiceInteraction()) { 4727 if (cf.left < mVoiceContentLeft) cf.left = mVoiceContentLeft; 4728 if (cf.top < mVoiceContentTop) cf.top = mVoiceContentTop; 4729 if (cf.right > mVoiceContentRight) cf.right = mVoiceContentRight; 4730 if (cf.bottom > mVoiceContentBottom) cf.bottom = mVoiceContentBottom; 4731 } else if (attached.getSurfaceLayer() < mDockLayer) { 4732 if (cf.left < mContentLeft) cf.left = mContentLeft; 4733 if (cf.top < mContentTop) cf.top = mContentTop; 4734 if (cf.right > mContentRight) cf.right = mContentRight; 4735 if (cf.bottom > mContentBottom) cf.bottom = mContentBottom; 4736 } 4737 } 4738 df.set(insetDecors ? attached.getDisplayFrameLw() : cf); 4739 of.set(insetDecors ? attached.getOverscanFrameLw() : cf); 4740 vf.set(attached.getVisibleFrameLw()); 4741 } 4742 // The LAYOUT_IN_SCREEN flag is used to determine whether the attached 4743 // window should be positioned relative to its parent or the entire 4744 // screen. 4745 pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 4746 ? attached.getFrameLw() : df); 4747 } 4748 4749 private void applyStableConstraints(int sysui, int fl, Rect r) { 4750 if ((sysui & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 4751 // If app is requesting a stable layout, don't let the 4752 // content insets go below the stable values. 4753 if ((fl & FLAG_FULLSCREEN) != 0) { 4754 if (r.left < mStableFullscreenLeft) r.left = mStableFullscreenLeft; 4755 if (r.top < mStableFullscreenTop) r.top = mStableFullscreenTop; 4756 if (r.right > mStableFullscreenRight) r.right = mStableFullscreenRight; 4757 if (r.bottom > mStableFullscreenBottom) r.bottom = mStableFullscreenBottom; 4758 } else { 4759 if (r.left < mStableLeft) r.left = mStableLeft; 4760 if (r.top < mStableTop) r.top = mStableTop; 4761 if (r.right > mStableRight) r.right = mStableRight; 4762 if (r.bottom > mStableBottom) r.bottom = mStableBottom; 4763 } 4764 } 4765 } 4766 4767 private boolean canReceiveInput(WindowState win) { 4768 boolean notFocusable = 4769 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0; 4770 boolean altFocusableIm = 4771 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0; 4772 boolean notFocusableForIm = notFocusable ^ altFocusableIm; 4773 return !notFocusableForIm; 4774 } 4775 4776 /** {@inheritDoc} */ 4777 @Override 4778 public void layoutWindowLw(WindowState win, WindowState attached) { 4779 // We've already done the navigation bar and status bar. If the status bar can receive 4780 // input, we need to layout it again to accomodate for the IME window. 4781 if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar) { 4782 return; 4783 } 4784 final WindowManager.LayoutParams attrs = win.getAttrs(); 4785 final boolean isDefaultDisplay = win.isDefaultDisplay(); 4786 final boolean needsToOffsetInputMethodTarget = isDefaultDisplay && 4787 (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null); 4788 if (needsToOffsetInputMethodTarget) { 4789 if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state"); 4790 offsetInputMethodWindowLw(mLastInputMethodWindow); 4791 } 4792 4793 final int fl = PolicyControl.getWindowFlags(win, attrs); 4794 final int pfl = attrs.privateFlags; 4795 final int sim = attrs.softInputMode; 4796 final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null); 4797 4798 final Rect pf = mTmpParentFrame; 4799 final Rect df = mTmpDisplayFrame; 4800 final Rect of = mTmpOverscanFrame; 4801 final Rect cf = mTmpContentFrame; 4802 final Rect vf = mTmpVisibleFrame; 4803 final Rect dcf = mTmpDecorFrame; 4804 final Rect sf = mTmpStableFrame; 4805 Rect osf = null; 4806 dcf.setEmpty(); 4807 4808 final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar 4809 && mNavigationBar != null && mNavigationBar.isVisibleLw()); 4810 4811 final int adjust = sim & SOFT_INPUT_MASK_ADJUST; 4812 4813 if (isDefaultDisplay) { 4814 sf.set(mStableLeft, mStableTop, mStableRight, mStableBottom); 4815 } else { 4816 sf.set(mOverscanLeft, mOverscanTop, mOverscanRight, mOverscanBottom); 4817 } 4818 4819 if (!isDefaultDisplay) { 4820 if (attached != null) { 4821 // If this window is attached to another, our display 4822 // frame is the same as the one we are attached to. 4823 setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf); 4824 } else { 4825 // Give the window full screen. 4826 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 4827 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 4828 pf.right = df.right = of.right = cf.right 4829 = mOverscanScreenLeft + mOverscanScreenWidth; 4830 pf.bottom = df.bottom = of.bottom = cf.bottom 4831 = mOverscanScreenTop + mOverscanScreenHeight; 4832 } 4833 } else if (attrs.type == TYPE_INPUT_METHOD) { 4834 pf.left = df.left = of.left = cf.left = vf.left = mDockLeft; 4835 pf.top = df.top = of.top = cf.top = vf.top = mDockTop; 4836 pf.right = df.right = of.right = cf.right = vf.right = mDockRight; 4837 // IM dock windows layout below the nav bar... 4838 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4839 // ...with content insets above the nav bar 4840 cf.bottom = vf.bottom = mStableBottom; 4841 if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) { 4842 // The status bar forces the navigation bar while it's visible. Make sure the IME 4843 // avoids the navigation bar in that case. 4844 if (mNavigationBarPosition == NAV_BAR_RIGHT) { 4845 pf.right = df.right = of.right = cf.right = vf.right = mStableRight; 4846 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 4847 pf.left = df.left = of.left = cf.left = vf.left = mStableLeft; 4848 } 4849 } 4850 // IM dock windows always go to the bottom of the screen. 4851 attrs.gravity = Gravity.BOTTOM; 4852 mDockLayer = win.getSurfaceLayer(); 4853 } else if (attrs.type == TYPE_VOICE_INTERACTION) { 4854 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4855 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4856 pf.right = df.right = of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4857 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4858 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4859 cf.left = mDockLeft; 4860 cf.top = mDockTop; 4861 cf.right = mDockRight; 4862 cf.bottom = mDockBottom; 4863 } else { 4864 cf.left = mContentLeft; 4865 cf.top = mContentTop; 4866 cf.right = mContentRight; 4867 cf.bottom = mContentBottom; 4868 } 4869 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 4870 vf.left = mCurLeft; 4871 vf.top = mCurTop; 4872 vf.right = mCurRight; 4873 vf.bottom = mCurBottom; 4874 } else { 4875 vf.set(cf); 4876 } 4877 } else if (attrs.type == TYPE_WALLPAPER) { 4878 layoutWallpaper(win, pf, df, of, cf); 4879 } else if (win == mStatusBar) { 4880 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4881 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4882 pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft; 4883 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight + mUnrestrictedScreenTop; 4884 cf.left = vf.left = mStableLeft; 4885 cf.top = vf.top = mStableTop; 4886 cf.right = vf.right = mStableRight; 4887 vf.bottom = mStableBottom; 4888 4889 if (adjust == SOFT_INPUT_ADJUST_RESIZE) { 4890 cf.bottom = mContentBottom; 4891 } else { 4892 cf.bottom = mDockBottom; 4893 vf.bottom = mContentBottom; 4894 } 4895 } else { 4896 4897 // Default policy decor for the default display 4898 dcf.left = mSystemLeft; 4899 dcf.top = mSystemTop; 4900 dcf.right = mSystemRight; 4901 dcf.bottom = mSystemBottom; 4902 final boolean inheritTranslucentDecor = (attrs.privateFlags 4903 & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) != 0; 4904 final boolean isAppWindow = 4905 attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && 4906 attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 4907 final boolean topAtRest = 4908 win == mTopFullscreenOpaqueWindowState && !win.isAnimatingLw(); 4909 if (isAppWindow && !inheritTranslucentDecor && !topAtRest) { 4910 if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 4911 && (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0 4912 && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0 4913 && (fl & WindowManager.LayoutParams. 4914 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0 4915 && (pfl & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) == 0) { 4916 // Ensure policy decor includes status bar 4917 dcf.top = mStableTop; 4918 } 4919 if ((fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == 0 4920 && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0 4921 && (fl & WindowManager.LayoutParams. 4922 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) { 4923 // Ensure policy decor includes navigation bar 4924 dcf.bottom = mStableBottom; 4925 dcf.right = mStableRight; 4926 } 4927 } 4928 4929 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) 4930 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { 4931 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() 4932 + "): IN_SCREEN, INSET_DECOR"); 4933 // This is the case for a normal activity window: we want it 4934 // to cover all of the screen space, and it can take care of 4935 // moving its contents to account for screen decorations that 4936 // intrude into that space. 4937 if (attached != null) { 4938 // If this window is attached to another, our display 4939 // frame is the same as the one we are attached to. 4940 setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf); 4941 } else { 4942 if (attrs.type == TYPE_STATUS_BAR_PANEL 4943 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) { 4944 // Status bar panels are the only windows who can go on top of 4945 // the status bar. They are protected by the STATUS_BAR_SERVICE 4946 // permission, so they have the same privileges as the status 4947 // bar itself. 4948 // 4949 // However, they should still dodge the navigation bar if it exists. 4950 4951 pf.left = df.left = of.left = hasNavBar 4952 ? mDockLeft : mUnrestrictedScreenLeft; 4953 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4954 pf.right = df.right = of.right = hasNavBar 4955 ? mRestrictedScreenLeft+mRestrictedScreenWidth 4956 : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4957 pf.bottom = df.bottom = of.bottom = hasNavBar 4958 ? mRestrictedScreenTop+mRestrictedScreenHeight 4959 : mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4960 4961 if (DEBUG_LAYOUT) Slog.v(TAG, String.format( 4962 "Laying out status bar window: (%d,%d - %d,%d)", 4963 pf.left, pf.top, pf.right, pf.bottom)); 4964 } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0 4965 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 4966 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 4967 // Asking to layout into the overscan region, so give it that pure 4968 // unrestricted area. 4969 pf.left = df.left = of.left = mOverscanScreenLeft; 4970 pf.top = df.top = of.top = mOverscanScreenTop; 4971 pf.right = df.right = of.right = mOverscanScreenLeft + mOverscanScreenWidth; 4972 pf.bottom = df.bottom = of.bottom = mOverscanScreenTop 4973 + mOverscanScreenHeight; 4974 } else if (canHideNavigationBar() 4975 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 4976 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 4977 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 4978 // Asking for layout as if the nav bar is hidden, lets the 4979 // application extend into the unrestricted overscan screen area. We 4980 // only do this for application windows to ensure no window that 4981 // can be above the nav bar can do this. 4982 pf.left = df.left = mOverscanScreenLeft; 4983 pf.top = df.top = mOverscanScreenTop; 4984 pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; 4985 pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; 4986 // We need to tell the app about where the frame inside the overscan 4987 // is, so it can inset its content by that amount -- it didn't ask 4988 // to actually extend itself into the overscan region. 4989 of.left = mUnrestrictedScreenLeft; 4990 of.top = mUnrestrictedScreenTop; 4991 of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4992 of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4993 } else { 4994 pf.left = df.left = mRestrictedOverscanScreenLeft; 4995 pf.top = df.top = mRestrictedOverscanScreenTop; 4996 pf.right = df.right = mRestrictedOverscanScreenLeft 4997 + mRestrictedOverscanScreenWidth; 4998 pf.bottom = df.bottom = mRestrictedOverscanScreenTop 4999 + mRestrictedOverscanScreenHeight; 5000 // We need to tell the app about where the frame inside the overscan 5001 // is, so it can inset its content by that amount -- it didn't ask 5002 // to actually extend itself into the overscan region. 5003 of.left = mUnrestrictedScreenLeft; 5004 of.top = mUnrestrictedScreenTop; 5005 of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 5006 of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 5007 } 5008 5009 if ((fl & FLAG_FULLSCREEN) == 0) { 5010 if (win.isVoiceInteraction()) { 5011 cf.left = mVoiceContentLeft; 5012 cf.top = mVoiceContentTop; 5013 cf.right = mVoiceContentRight; 5014 cf.bottom = mVoiceContentBottom; 5015 } else { 5016 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 5017 cf.left = mDockLeft; 5018 cf.top = mDockTop; 5019 cf.right = mDockRight; 5020 cf.bottom = mDockBottom; 5021 } else { 5022 cf.left = mContentLeft; 5023 cf.top = mContentTop; 5024 cf.right = mContentRight; 5025 cf.bottom = mContentBottom; 5026 } 5027 } 5028 } else { 5029 // Full screen windows are always given a layout that is as if the 5030 // status bar and other transient decors are gone. This is to avoid 5031 // bad states when moving from a window that is not hding the 5032 // status bar to one that is. 5033 cf.left = mRestrictedScreenLeft; 5034 cf.top = mRestrictedScreenTop; 5035 cf.right = mRestrictedScreenLeft + mRestrictedScreenWidth; 5036 cf.bottom = mRestrictedScreenTop + mRestrictedScreenHeight; 5037 } 5038 applyStableConstraints(sysUiFl, fl, cf); 5039 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 5040 vf.left = mCurLeft; 5041 vf.top = mCurTop; 5042 vf.right = mCurRight; 5043 vf.bottom = mCurBottom; 5044 } else { 5045 vf.set(cf); 5046 } 5047 } 5048 } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0 || (sysUiFl 5049 & (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 5050 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) { 5051 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 5052 "): IN_SCREEN"); 5053 // A window that has requested to fill the entire screen just 5054 // gets everything, period. 5055 if (attrs.type == TYPE_STATUS_BAR_PANEL 5056 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL 5057 || attrs.type == TYPE_VOLUME_OVERLAY) { 5058 pf.left = df.left = of.left = cf.left = hasNavBar 5059 ? mDockLeft : mUnrestrictedScreenLeft; 5060 pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; 5061 pf.right = df.right = of.right = cf.right = hasNavBar 5062 ? mRestrictedScreenLeft+mRestrictedScreenWidth 5063 : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 5064 pf.bottom = df.bottom = of.bottom = cf.bottom = hasNavBar 5065 ? mRestrictedScreenTop+mRestrictedScreenHeight 5066 : mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 5067 if (DEBUG_LAYOUT) Slog.v(TAG, String.format( 5068 "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)", 5069 pf.left, pf.top, pf.right, pf.bottom)); 5070 } else if (attrs.type == TYPE_NAVIGATION_BAR 5071 || attrs.type == TYPE_NAVIGATION_BAR_PANEL) { 5072 // The navigation bar has Real Ultimate Power. 5073 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 5074 pf.top = df.top = of.top = mUnrestrictedScreenTop; 5075 pf.right = df.right = of.right = mUnrestrictedScreenLeft 5076 + mUnrestrictedScreenWidth; 5077 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop 5078 + mUnrestrictedScreenHeight; 5079 if (DEBUG_LAYOUT) Slog.v(TAG, String.format( 5080 "Laying out navigation bar window: (%d,%d - %d,%d)", 5081 pf.left, pf.top, pf.right, pf.bottom)); 5082 } else if ((attrs.type == TYPE_SECURE_SYSTEM_OVERLAY 5083 || attrs.type == TYPE_BOOT_PROGRESS 5084 || attrs.type == TYPE_SCREENSHOT) 5085 && ((fl & FLAG_FULLSCREEN) != 0)) { 5086 // Fullscreen secure system overlays get what they ask for. Screenshot region 5087 // selection overlay should also expand to full screen. 5088 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 5089 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 5090 pf.right = df.right = of.right = cf.right = mOverscanScreenLeft 5091 + mOverscanScreenWidth; 5092 pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop 5093 + mOverscanScreenHeight; 5094 } else if (attrs.type == TYPE_BOOT_PROGRESS) { 5095 // Boot progress screen always covers entire display. 5096 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 5097 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 5098 pf.right = df.right = of.right = cf.right = mOverscanScreenLeft 5099 + mOverscanScreenWidth; 5100 pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop 5101 + mOverscanScreenHeight; 5102 } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0 5103 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 5104 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 5105 // Asking to layout into the overscan region, so give it that pure 5106 // unrestricted area. 5107 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 5108 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 5109 pf.right = df.right = of.right = cf.right 5110 = mOverscanScreenLeft + mOverscanScreenWidth; 5111 pf.bottom = df.bottom = of.bottom = cf.bottom 5112 = mOverscanScreenTop + mOverscanScreenHeight; 5113 } else if (canHideNavigationBar() 5114 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 5115 && (attrs.type == TYPE_STATUS_BAR 5116 || attrs.type == TYPE_TOAST 5117 || attrs.type == TYPE_DOCK_DIVIDER 5118 || attrs.type == TYPE_VOICE_INTERACTION_STARTING 5119 || (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 5120 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) { 5121 // Asking for layout as if the nav bar is hidden, lets the 5122 // application extend into the unrestricted screen area. We 5123 // only do this for application windows (or toasts) to ensure no window that 5124 // can be above the nav bar can do this. 5125 // XXX This assumes that an app asking for this will also 5126 // ask for layout in only content. We can't currently figure out 5127 // what the screen would be if only laying out to hide the nav bar. 5128 pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft; 5129 pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; 5130 pf.right = df.right = of.right = cf.right = mUnrestrictedScreenLeft 5131 + mUnrestrictedScreenWidth; 5132 pf.bottom = df.bottom = of.bottom = cf.bottom = mUnrestrictedScreenTop 5133 + mUnrestrictedScreenHeight; 5134 } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) { 5135 pf.left = df.left = of.left = mRestrictedScreenLeft; 5136 pf.top = df.top = of.top = mRestrictedScreenTop; 5137 pf.right = df.right = of.right = mRestrictedScreenLeft + mRestrictedScreenWidth; 5138 pf.bottom = df.bottom = of.bottom = mRestrictedScreenTop 5139 + mRestrictedScreenHeight; 5140 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 5141 cf.left = mDockLeft; 5142 cf.top = mDockTop; 5143 cf.right = mDockRight; 5144 cf.bottom = mDockBottom; 5145 } else { 5146 cf.left = mContentLeft; 5147 cf.top = mContentTop; 5148 cf.right = mContentRight; 5149 cf.bottom = mContentBottom; 5150 } 5151 } else { 5152 pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; 5153 pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; 5154 pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft 5155 + mRestrictedScreenWidth; 5156 pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop 5157 + mRestrictedScreenHeight; 5158 } 5159 5160 applyStableConstraints(sysUiFl, fl, cf); 5161 5162 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 5163 vf.left = mCurLeft; 5164 vf.top = mCurTop; 5165 vf.right = mCurRight; 5166 vf.bottom = mCurBottom; 5167 } else { 5168 vf.set(cf); 5169 } 5170 } else if (attached != null) { 5171 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 5172 "): attached to " + attached); 5173 // A child window should be placed inside of the same visible 5174 // frame that its parent had. 5175 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, of, cf, vf); 5176 } else { 5177 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 5178 "): normal window"); 5179 // Otherwise, a normal window must be placed inside the content 5180 // of all screen decorations. 5181 if (attrs.type == TYPE_STATUS_BAR_PANEL || attrs.type == TYPE_VOLUME_OVERLAY) { 5182 // Status bar panels and the volume dialog are the only windows who can go on 5183 // top of the status bar. They are protected by the STATUS_BAR_SERVICE 5184 // permission, so they have the same privileges as the status 5185 // bar itself. 5186 pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; 5187 pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; 5188 pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft 5189 + mRestrictedScreenWidth; 5190 pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop 5191 + mRestrictedScreenHeight; 5192 } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT) { 5193 // These dialogs are stable to interim decor changes. 5194 pf.left = df.left = of.left = cf.left = mStableLeft; 5195 pf.top = df.top = of.top = cf.top = mStableTop; 5196 pf.right = df.right = of.right = cf.right = mStableRight; 5197 pf.bottom = df.bottom = of.bottom = cf.bottom = mStableBottom; 5198 } else { 5199 pf.left = mContentLeft; 5200 pf.top = mContentTop; 5201 pf.right = mContentRight; 5202 pf.bottom = mContentBottom; 5203 if (win.isVoiceInteraction()) { 5204 df.left = of.left = cf.left = mVoiceContentLeft; 5205 df.top = of.top = cf.top = mVoiceContentTop; 5206 df.right = of.right = cf.right = mVoiceContentRight; 5207 df.bottom = of.bottom = cf.bottom = mVoiceContentBottom; 5208 } else if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 5209 df.left = of.left = cf.left = mDockLeft; 5210 df.top = of.top = cf.top = mDockTop; 5211 df.right = of.right = cf.right = mDockRight; 5212 df.bottom = of.bottom = cf.bottom = mDockBottom; 5213 } else { 5214 df.left = of.left = cf.left = mContentLeft; 5215 df.top = of.top = cf.top = mContentTop; 5216 df.right = of.right = cf.right = mContentRight; 5217 df.bottom = of.bottom = cf.bottom = mContentBottom; 5218 } 5219 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 5220 vf.left = mCurLeft; 5221 vf.top = mCurTop; 5222 vf.right = mCurRight; 5223 vf.bottom = mCurBottom; 5224 } else { 5225 vf.set(cf); 5226 } 5227 } 5228 } 5229 } 5230 5231 // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it. 5232 // Also, we don't allow windows in multi-window mode to extend out of the screen. 5233 if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR 5234 && !win.isInMultiWindowMode()) { 5235 df.left = df.top = -10000; 5236 df.right = df.bottom = 10000; 5237 if (attrs.type != TYPE_WALLPAPER) { 5238 of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000; 5239 of.right = of.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000; 5240 } 5241 } 5242 5243 // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we 5244 // need to provide information to the clients that want to pretend that you can draw there. 5245 // We only want to apply outsets to certain types of windows. For example, we never want to 5246 // apply the outsets to floating dialogs, because they wouldn't make sense there. 5247 final boolean useOutsets = shouldUseOutsets(attrs, fl); 5248 if (isDefaultDisplay && useOutsets) { 5249 osf = mTmpOutsetFrame; 5250 osf.set(cf.left, cf.top, cf.right, cf.bottom); 5251 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); 5252 if (outset > 0) { 5253 int rotation = mDisplayRotation; 5254 if (rotation == Surface.ROTATION_0) { 5255 osf.bottom += outset; 5256 } else if (rotation == Surface.ROTATION_90) { 5257 osf.right += outset; 5258 } else if (rotation == Surface.ROTATION_180) { 5259 osf.top -= outset; 5260 } else if (rotation == Surface.ROTATION_270) { 5261 osf.left -= outset; 5262 } 5263 if (DEBUG_LAYOUT) Slog.v(TAG, "applying bottom outset of " + outset 5264 + " with rotation " + rotation + ", result: " + osf); 5265 } 5266 } 5267 5268 if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle() 5269 + ": sim=#" + Integer.toHexString(sim) 5270 + " attach=" + attached + " type=" + attrs.type 5271 + String.format(" flags=0x%08x", fl) 5272 + " pf=" + pf.toShortString() + " df=" + df.toShortString() 5273 + " of=" + of.toShortString() 5274 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString() 5275 + " dcf=" + dcf.toShortString() 5276 + " sf=" + sf.toShortString() 5277 + " osf=" + (osf == null ? "null" : osf.toShortString())); 5278 5279 win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf); 5280 5281 // Dock windows carve out the bottom of the screen, so normal windows 5282 // can't appear underneath them. 5283 if (attrs.type == TYPE_INPUT_METHOD && win.isVisibleLw() 5284 && !win.getGivenInsetsPendingLw()) { 5285 setLastInputMethodWindowLw(null, null); 5286 offsetInputMethodWindowLw(win); 5287 } 5288 if (attrs.type == TYPE_VOICE_INTERACTION && win.isVisibleLw() 5289 && !win.getGivenInsetsPendingLw()) { 5290 offsetVoiceInputWindowLw(win); 5291 } 5292 } 5293 5294 private void layoutWallpaper(WindowState win, Rect pf, Rect df, Rect of, Rect cf) { 5295 5296 // The wallpaper also has Real Ultimate Power, but we want to tell 5297 // it about the overscan area. 5298 pf.left = df.left = mOverscanScreenLeft; 5299 pf.top = df.top = mOverscanScreenTop; 5300 pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; 5301 pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; 5302 of.left = cf.left = mUnrestrictedScreenLeft; 5303 of.top = cf.top = mUnrestrictedScreenTop; 5304 of.right = cf.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 5305 of.bottom = cf.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 5306 } 5307 5308 private void offsetInputMethodWindowLw(WindowState win) { 5309 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top); 5310 top += win.getGivenContentInsetsLw().top; 5311 if (mContentBottom > top) { 5312 mContentBottom = top; 5313 } 5314 if (mVoiceContentBottom > top) { 5315 mVoiceContentBottom = top; 5316 } 5317 top = win.getVisibleFrameLw().top; 5318 top += win.getGivenVisibleInsetsLw().top; 5319 if (mCurBottom > top) { 5320 mCurBottom = top; 5321 } 5322 if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom=" 5323 + mDockBottom + " mContentBottom=" 5324 + mContentBottom + " mCurBottom=" + mCurBottom); 5325 } 5326 5327 private void offsetVoiceInputWindowLw(WindowState win) { 5328 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top); 5329 top += win.getGivenContentInsetsLw().top; 5330 if (mVoiceContentBottom > top) { 5331 mVoiceContentBottom = top; 5332 } 5333 } 5334 5335 /** {@inheritDoc} */ 5336 @Override 5337 public void finishLayoutLw() { 5338 return; 5339 } 5340 5341 /** {@inheritDoc} */ 5342 @Override 5343 public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { 5344 mTopFullscreenOpaqueWindowState = null; 5345 mTopFullscreenOpaqueOrDimmingWindowState = null; 5346 mTopDockedOpaqueWindowState = null; 5347 mTopDockedOpaqueOrDimmingWindowState = null; 5348 mForceStatusBar = false; 5349 mForceStatusBarFromKeyguard = false; 5350 mForceStatusBarTransparent = false; 5351 mForcingShowNavBar = false; 5352 mForcingShowNavBarLayer = -1; 5353 5354 mAllowLockscreenWhenOn = false; 5355 mShowingDream = false; 5356 } 5357 5358 /** {@inheritDoc} */ 5359 @Override 5360 public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs, 5361 WindowState attached, WindowState imeTarget) { 5362 final boolean affectsSystemUi = win.canAffectSystemUiFlags(); 5363 if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi); 5364 applyKeyguardPolicyLw(win, imeTarget); 5365 final int fl = PolicyControl.getWindowFlags(win, attrs); 5366 if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi 5367 && attrs.type == TYPE_INPUT_METHOD) { 5368 mForcingShowNavBar = true; 5369 mForcingShowNavBarLayer = win.getSurfaceLayer(); 5370 } 5371 if (attrs.type == TYPE_STATUS_BAR) { 5372 if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 5373 mForceStatusBarFromKeyguard = true; 5374 } 5375 if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) { 5376 mForceStatusBarTransparent = true; 5377 } 5378 } 5379 5380 boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW 5381 && attrs.type < FIRST_SYSTEM_WINDOW; 5382 final int stackId = win.getStackId(); 5383 if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi) { 5384 if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) { 5385 mForceStatusBar = true; 5386 } 5387 if (attrs.type == TYPE_DREAM) { 5388 // If the lockscreen was showing when the dream started then wait 5389 // for the dream to draw before hiding the lockscreen. 5390 if (!mDreamingLockscreen 5391 || (win.isVisibleLw() && win.hasDrawnLw())) { 5392 mShowingDream = true; 5393 appWindow = true; 5394 } 5395 } 5396 5397 // For app windows that are not attached, we decide if all windows in the app they 5398 // represent should be hidden or if we should hide the lockscreen. For attached app 5399 // windows we defer the decision to the window it is attached to. 5400 if (appWindow && attached == null) { 5401 if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) { 5402 if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win); 5403 mTopFullscreenOpaqueWindowState = win; 5404 if (mTopFullscreenOpaqueOrDimmingWindowState == null) { 5405 mTopFullscreenOpaqueOrDimmingWindowState = win; 5406 } 5407 if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { 5408 mAllowLockscreenWhenOn = true; 5409 } 5410 } 5411 } 5412 } 5413 5414 // Voice interaction overrides both top fullscreen and top docked. 5415 if (affectsSystemUi && win.getAttrs().type == TYPE_VOICE_INTERACTION) { 5416 if (mTopFullscreenOpaqueWindowState == null) { 5417 mTopFullscreenOpaqueWindowState = win; 5418 if (mTopFullscreenOpaqueOrDimmingWindowState == null) { 5419 mTopFullscreenOpaqueOrDimmingWindowState = win; 5420 } 5421 } 5422 if (mTopDockedOpaqueWindowState == null) { 5423 mTopDockedOpaqueWindowState = win; 5424 if (mTopDockedOpaqueOrDimmingWindowState == null) { 5425 mTopDockedOpaqueOrDimmingWindowState = win; 5426 } 5427 } 5428 } 5429 5430 // Keep track of the window if it's dimming but not necessarily fullscreen. 5431 if (mTopFullscreenOpaqueOrDimmingWindowState == null && affectsSystemUi 5432 && win.isDimming() && StackId.normallyFullscreenWindows(stackId)) { 5433 mTopFullscreenOpaqueOrDimmingWindowState = win; 5434 } 5435 5436 // We need to keep track of the top "fullscreen" opaque window for the docked stack 5437 // separately, because both the "real fullscreen" opaque window and the one for the docked 5438 // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR. 5439 if (mTopDockedOpaqueWindowState == null && affectsSystemUi && appWindow && attached == null 5440 && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) { 5441 mTopDockedOpaqueWindowState = win; 5442 if (mTopDockedOpaqueOrDimmingWindowState == null) { 5443 mTopDockedOpaqueOrDimmingWindowState = win; 5444 } 5445 } 5446 5447 // Also keep track of any windows that are dimming but not necessarily fullscreen in the 5448 // docked stack. 5449 if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming() 5450 && stackId == DOCKED_STACK_ID) { 5451 mTopDockedOpaqueOrDimmingWindowState = win; 5452 } 5453 } 5454 5455 private void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget) { 5456 if (canBeHiddenByKeyguardLw(win)) { 5457 if (shouldBeHiddenByKeyguard(win, imeTarget)) { 5458 win.hideLw(false /* doAnimation */); 5459 } else { 5460 win.showLw(false /* doAnimation */); 5461 } 5462 } 5463 } 5464 5465 private boolean isFullscreen(WindowManager.LayoutParams attrs) { 5466 return attrs.x == 0 && attrs.y == 0 5467 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT 5468 && attrs.height == WindowManager.LayoutParams.MATCH_PARENT; 5469 } 5470 5471 /** {@inheritDoc} */ 5472 @Override 5473 public int finishPostLayoutPolicyLw() { 5474 int changes = 0; 5475 boolean topIsFullscreen = false; 5476 5477 final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null) 5478 ? mTopFullscreenOpaqueWindowState.getAttrs() 5479 : null; 5480 5481 // If we are not currently showing a dream then remember the current 5482 // lockscreen state. We will use this to determine whether the dream 5483 // started while the lockscreen was showing and remember this state 5484 // while the dream is showing. 5485 if (!mShowingDream) { 5486 mDreamingLockscreen = isKeyguardShowingAndNotOccluded(); 5487 if (mDreamingSleepTokenNeeded) { 5488 mDreamingSleepTokenNeeded = false; 5489 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget(); 5490 } 5491 } else { 5492 if (!mDreamingSleepTokenNeeded) { 5493 mDreamingSleepTokenNeeded = true; 5494 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 1, 1).sendToTarget(); 5495 } 5496 } 5497 5498 if (mStatusBar != null) { 5499 if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar 5500 + " forcefkg=" + mForceStatusBarFromKeyguard 5501 + " top=" + mTopFullscreenOpaqueWindowState); 5502 boolean shouldBeTransparent = mForceStatusBarTransparent 5503 && !mForceStatusBar 5504 && !mForceStatusBarFromKeyguard; 5505 if (!shouldBeTransparent) { 5506 mStatusBarController.setShowTransparent(false /* transparent */); 5507 } else if (!mStatusBar.isVisibleLw()) { 5508 mStatusBarController.setShowTransparent(true /* transparent */); 5509 } 5510 5511 WindowManager.LayoutParams statusBarAttrs = mStatusBar.getAttrs(); 5512 boolean statusBarExpanded = statusBarAttrs.height == MATCH_PARENT 5513 && statusBarAttrs.width == MATCH_PARENT; 5514 if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent 5515 || statusBarExpanded) { 5516 if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced"); 5517 if (mStatusBarController.setBarShowingLw(true)) { 5518 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5519 } 5520 // Maintain fullscreen layout until incoming animation is complete. 5521 topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw(); 5522 // Transient status bar on the lockscreen is not allowed 5523 if ((mForceStatusBarFromKeyguard || statusBarExpanded) 5524 && mStatusBarController.isTransientShowing()) { 5525 mStatusBarController.updateVisibilityLw(false /*transientAllowed*/, 5526 mLastSystemUiFlags, mLastSystemUiFlags); 5527 } 5528 if (statusBarExpanded && mNavigationBar != null) { 5529 if (mNavigationBarController.setBarShowingLw(true)) { 5530 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5531 } 5532 } 5533 } else if (mTopFullscreenOpaqueWindowState != null) { 5534 final int fl = PolicyControl.getWindowFlags(null, lp); 5535 if (localLOGV) { 5536 Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() 5537 + " shown position: " 5538 + mTopFullscreenOpaqueWindowState.getShownPositionLw()); 5539 Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs() 5540 + " lp.flags=0x" + Integer.toHexString(fl)); 5541 } 5542 topIsFullscreen = (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0 5543 || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 5544 // The subtle difference between the window for mTopFullscreenOpaqueWindowState 5545 // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window 5546 // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the 5547 // case though. 5548 if (mStatusBarController.isTransientShowing()) { 5549 if (mStatusBarController.setBarShowingLw(true)) { 5550 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5551 } 5552 } else if (topIsFullscreen 5553 && !mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID) 5554 && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID)) { 5555 if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar"); 5556 if (mStatusBarController.setBarShowingLw(false)) { 5557 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5558 } else { 5559 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding"); 5560 } 5561 } else { 5562 if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen"); 5563 if (mStatusBarController.setBarShowingLw(true)) { 5564 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5565 } 5566 } 5567 } 5568 } 5569 5570 if (mTopIsFullscreen != topIsFullscreen) { 5571 if (!topIsFullscreen) { 5572 // Force another layout when status bar becomes fully shown. 5573 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5574 } 5575 mTopIsFullscreen = topIsFullscreen; 5576 } 5577 5578 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5579 // If the navigation bar has been hidden or shown, we need to do another 5580 // layout pass to update that window. 5581 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5582 } 5583 5584 if (mShowingDream != mLastShowingDream) { 5585 mLastShowingDream = mShowingDream; 5586 mWindowManagerFuncs.notifyShowingDreamChanged(); 5587 } 5588 5589 // update since mAllowLockscreenWhenOn might have changed 5590 updateLockScreenTimeout(); 5591 return changes; 5592 } 5593 5594 /** 5595 * Updates the occluded state of the Keyguard. 5596 * 5597 * @return Whether the flags have changed and we have to redo the layout. 5598 */ 5599 private boolean setKeyguardOccludedLw(boolean isOccluded, boolean force) { 5600 if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded); 5601 final boolean wasOccluded = mKeyguardOccluded; 5602 final boolean showing = mKeyguardDelegate.isShowing(); 5603 final boolean changed = wasOccluded != isOccluded || force; 5604 if (!isOccluded && changed && showing) { 5605 mKeyguardOccluded = false; 5606 mKeyguardDelegate.setOccluded(false, true /* animate */); 5607 if (mStatusBar != null) { 5608 mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD; 5609 if (!mKeyguardDelegate.hasLockscreenWallpaper()) { 5610 mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER; 5611 } 5612 } 5613 return true; 5614 } else if (isOccluded && changed && showing) { 5615 mKeyguardOccluded = true; 5616 mKeyguardDelegate.setOccluded(true, false /* animate */); 5617 if (mStatusBar != null) { 5618 mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD; 5619 mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER; 5620 } 5621 return true; 5622 } else if (changed) { 5623 mKeyguardOccluded = isOccluded; 5624 mKeyguardDelegate.setOccluded(isOccluded, false /* animate */); 5625 return false; 5626 } else { 5627 return false; 5628 } 5629 } 5630 5631 private boolean isStatusBarKeyguard() { 5632 return mStatusBar != null 5633 && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; 5634 } 5635 5636 @Override 5637 public boolean allowAppAnimationsLw() { 5638 if (mShowingDream) { 5639 // If keyguard or dreams is currently visible, no reason to animate behind it. 5640 return false; 5641 } 5642 return true; 5643 } 5644 5645 @Override 5646 public int focusChangedLw(WindowState lastFocus, WindowState newFocus) { 5647 mFocusedWindow = newFocus; 5648 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5649 // If the navigation bar has been hidden or shown, we need to do another 5650 // layout pass to update that window. 5651 return FINISH_LAYOUT_REDO_LAYOUT; 5652 } 5653 return 0; 5654 } 5655 5656 /** {@inheritDoc} */ 5657 @Override 5658 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { 5659 // lid changed state 5660 final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED; 5661 if (newLidState == mLidState) { 5662 return; 5663 } 5664 5665 mLidState = newLidState; 5666 applyLidSwitchState(); 5667 updateRotation(true); 5668 5669 if (lidOpen) { 5670 wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch, 5671 "android.policy:LID"); 5672 } else if (!mLidControlsSleep) { 5673 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 5674 } 5675 } 5676 5677 @Override 5678 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) { 5679 int lensCoverState = lensCovered ? CAMERA_LENS_COVERED : CAMERA_LENS_UNCOVERED; 5680 if (mCameraLensCoverState == lensCoverState) { 5681 return; 5682 } 5683 if (mCameraLensCoverState == CAMERA_LENS_COVERED && 5684 lensCoverState == CAMERA_LENS_UNCOVERED) { 5685 Intent intent; 5686 final boolean keyguardActive = mKeyguardDelegate == null ? false : 5687 mKeyguardDelegate.isShowing(); 5688 if (keyguardActive) { 5689 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); 5690 } else { 5691 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); 5692 } 5693 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens, 5694 "android.policy:CAMERA_COVER"); 5695 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 5696 } 5697 mCameraLensCoverState = lensCoverState; 5698 } 5699 5700 void setHdmiPlugged(boolean plugged) { 5701 if (mHdmiPlugged != plugged) { 5702 mHdmiPlugged = plugged; 5703 updateRotation(true, true); 5704 Intent intent = new Intent(ACTION_HDMI_PLUGGED); 5705 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 5706 intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged); 5707 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 5708 } 5709 } 5710 5711 void initializeHdmiState() { 5712 boolean plugged = false; 5713 // watch for HDMI plug messages if the hdmi switch exists 5714 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) { 5715 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi"); 5716 5717 final String filename = "/sys/class/switch/hdmi/state"; 5718 FileReader reader = null; 5719 try { 5720 reader = new FileReader(filename); 5721 char[] buf = new char[15]; 5722 int n = reader.read(buf); 5723 if (n > 1) { 5724 plugged = 0 != Integer.parseInt(new String(buf, 0, n-1)); 5725 } 5726 } catch (IOException ex) { 5727 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5728 } catch (NumberFormatException ex) { 5729 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5730 } finally { 5731 if (reader != null) { 5732 try { 5733 reader.close(); 5734 } catch (IOException ex) { 5735 } 5736 } 5737 } 5738 } 5739 // This dance forces the code in setHdmiPlugged to run. 5740 // Always do this so the sticky intent is stuck (to false) if there is no hdmi. 5741 mHdmiPlugged = !plugged; 5742 setHdmiPlugged(!mHdmiPlugged); 5743 } 5744 5745 final Object mScreenshotLock = new Object(); 5746 ServiceConnection mScreenshotConnection = null; 5747 5748 final Runnable mScreenshotTimeout = new Runnable() { 5749 @Override public void run() { 5750 synchronized (mScreenshotLock) { 5751 if (mScreenshotConnection != null) { 5752 mContext.unbindService(mScreenshotConnection); 5753 mScreenshotConnection = null; 5754 notifyScreenshotError(); 5755 } 5756 } 5757 } 5758 }; 5759 5760 // Assume this is called from the Handler thread. 5761 private void takeScreenshot(final int screenshotType) { 5762 synchronized (mScreenshotLock) { 5763 if (mScreenshotConnection != null) { 5764 return; 5765 } 5766 final ComponentName serviceComponent = new ComponentName(SYSUI_PACKAGE, 5767 SYSUI_SCREENSHOT_SERVICE); 5768 final Intent serviceIntent = new Intent(); 5769 serviceIntent.setComponent(serviceComponent); 5770 ServiceConnection conn = new ServiceConnection() { 5771 @Override 5772 public void onServiceConnected(ComponentName name, IBinder service) { 5773 synchronized (mScreenshotLock) { 5774 if (mScreenshotConnection != this) { 5775 return; 5776 } 5777 Messenger messenger = new Messenger(service); 5778 Message msg = Message.obtain(null, screenshotType); 5779 final ServiceConnection myConn = this; 5780 Handler h = new Handler(mHandler.getLooper()) { 5781 @Override 5782 public void handleMessage(Message msg) { 5783 synchronized (mScreenshotLock) { 5784 if (mScreenshotConnection == myConn) { 5785 mContext.unbindService(mScreenshotConnection); 5786 mScreenshotConnection = null; 5787 mHandler.removeCallbacks(mScreenshotTimeout); 5788 } 5789 } 5790 } 5791 }; 5792 msg.replyTo = new Messenger(h); 5793 msg.arg1 = msg.arg2 = 0; 5794 if (mStatusBar != null && mStatusBar.isVisibleLw()) 5795 msg.arg1 = 1; 5796 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) 5797 msg.arg2 = 1; 5798 try { 5799 messenger.send(msg); 5800 } catch (RemoteException e) { 5801 } 5802 } 5803 } 5804 5805 @Override 5806 public void onServiceDisconnected(ComponentName name) { 5807 synchronized (mScreenshotLock) { 5808 if (mScreenshotConnection != null) { 5809 mContext.unbindService(mScreenshotConnection); 5810 mScreenshotConnection = null; 5811 mHandler.removeCallbacks(mScreenshotTimeout); 5812 notifyScreenshotError(); 5813 } 5814 } 5815 } 5816 }; 5817 if (mContext.bindServiceAsUser(serviceIntent, conn, 5818 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, 5819 UserHandle.CURRENT)) { 5820 mScreenshotConnection = conn; 5821 mHandler.postDelayed(mScreenshotTimeout, 10000); 5822 } 5823 } 5824 } 5825 5826 /** 5827 * Notifies the screenshot service to show an error. 5828 */ 5829 private void notifyScreenshotError() { 5830 // If the service process is killed, then ask it to clean up after itself 5831 final ComponentName errorComponent = new ComponentName(SYSUI_PACKAGE, 5832 SYSUI_SCREENSHOT_ERROR_RECEIVER); 5833 Intent errorIntent = new Intent(Intent.ACTION_USER_PRESENT); 5834 errorIntent.setComponent(errorComponent); 5835 errorIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | 5836 Intent.FLAG_RECEIVER_FOREGROUND); 5837 mContext.sendBroadcastAsUser(errorIntent, UserHandle.CURRENT); 5838 } 5839 5840 /** {@inheritDoc} */ 5841 @Override 5842 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { 5843 if (!mSystemBooted) { 5844 // If we have not yet booted, don't let key events do anything. 5845 return 0; 5846 } 5847 5848 final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; 5849 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 5850 final boolean canceled = event.isCanceled(); 5851 final int keyCode = event.getKeyCode(); 5852 5853 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0; 5854 5855 // If screen is off then we treat the case where the keyguard is open but hidden 5856 // the same as if it were open and in front. 5857 // This will prevent any keys other than the power button from waking the screen 5858 // when the keyguard is hidden by another activity. 5859 final boolean keyguardActive = (mKeyguardDelegate == null ? false : 5860 (interactive ? 5861 isKeyguardShowingAndNotOccluded() : 5862 mKeyguardDelegate.isShowing())); 5863 5864 if (DEBUG_INPUT) { 5865 Log.d(TAG, "interceptKeyTq keycode=" + keyCode 5866 + " interactive=" + interactive + " keyguardActive=" + keyguardActive 5867 + " policyFlags=" + Integer.toHexString(policyFlags)); 5868 } 5869 5870 // Basic policy based on interactive state. 5871 int result; 5872 boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 5873 || event.isWakeKey(); 5874 if (interactive || (isInjected && !isWakeKey)) { 5875 // When the device is interactive or the key is injected pass the 5876 // key to the application. 5877 result = ACTION_PASS_TO_USER; 5878 isWakeKey = false; 5879 5880 if (interactive) { 5881 // If the screen is awake, but the button pressed was the one that woke the device 5882 // then don't pass it to the application 5883 if (keyCode == mPendingWakeKey && !down) { 5884 result = 0; 5885 } 5886 // Reset the pending key 5887 mPendingWakeKey = PENDING_KEY_NULL; 5888 } 5889 } else if (!interactive && shouldDispatchInputWhenNonInteractive(event)) { 5890 // If we're currently dozing with the screen on and the keyguard showing, pass the key 5891 // to the application but preserve its wake key status to make sure we still move 5892 // from dozing to fully interactive if we would normally go from off to fully 5893 // interactive. 5894 result = ACTION_PASS_TO_USER; 5895 // Since we're dispatching the input, reset the pending key 5896 mPendingWakeKey = PENDING_KEY_NULL; 5897 } else { 5898 // When the screen is off and the key is not injected, determine whether 5899 // to wake the device but don't pass the key to the application. 5900 result = 0; 5901 if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) { 5902 isWakeKey = false; 5903 } 5904 // Cache the wake key on down event so we can also avoid sending the up event to the app 5905 if (isWakeKey && down) { 5906 mPendingWakeKey = keyCode; 5907 } 5908 } 5909 5910 // If the key would be handled globally, just return the result, don't worry about special 5911 // key processing. 5912 if (isValidGlobalKey(keyCode) 5913 && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) { 5914 if (isWakeKey) { 5915 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 5916 } 5917 return result; 5918 } 5919 5920 boolean useHapticFeedback = down 5921 && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0 5922 && event.getRepeatCount() == 0; 5923 5924 // Handle special keys. 5925 switch (keyCode) { 5926 case KeyEvent.KEYCODE_BACK: { 5927 if (down) { 5928 interceptBackKeyDown(); 5929 } else { 5930 boolean handled = interceptBackKeyUp(event); 5931 5932 // Don't pass back press to app if we've already handled it via long press 5933 if (handled) { 5934 result &= ~ACTION_PASS_TO_USER; 5935 } 5936 } 5937 break; 5938 } 5939 5940 case KeyEvent.KEYCODE_VOLUME_DOWN: 5941 case KeyEvent.KEYCODE_VOLUME_UP: 5942 case KeyEvent.KEYCODE_VOLUME_MUTE: { 5943 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 5944 if (down) { 5945 if (interactive && !mScreenshotChordVolumeDownKeyTriggered 5946 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5947 mScreenshotChordVolumeDownKeyTriggered = true; 5948 mScreenshotChordVolumeDownKeyTime = event.getDownTime(); 5949 mScreenshotChordVolumeDownKeyConsumed = false; 5950 cancelPendingPowerKeyAction(); 5951 interceptScreenshotChord(); 5952 interceptAccessibilityShortcutChord(); 5953 } 5954 } else { 5955 mScreenshotChordVolumeDownKeyTriggered = false; 5956 cancelPendingScreenshotChordAction(); 5957 cancelPendingAccessibilityShortcutAction(); 5958 } 5959 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 5960 if (down) { 5961 if (interactive && !mA11yShortcutChordVolumeUpKeyTriggered 5962 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5963 mA11yShortcutChordVolumeUpKeyTriggered = true; 5964 mA11yShortcutChordVolumeUpKeyTime = event.getDownTime(); 5965 mA11yShortcutChordVolumeUpKeyConsumed = false; 5966 cancelPendingPowerKeyAction(); 5967 cancelPendingScreenshotChordAction(); 5968 interceptAccessibilityShortcutChord(); 5969 } 5970 } else { 5971 mA11yShortcutChordVolumeUpKeyTriggered = false; 5972 cancelPendingScreenshotChordAction(); 5973 cancelPendingAccessibilityShortcutAction(); 5974 } 5975 } 5976 if (down) { 5977 TelecomManager telecomManager = getTelecommService(); 5978 if (telecomManager != null) { 5979 if (telecomManager.isRinging()) { 5980 // If an incoming call is ringing, either VOLUME key means 5981 // "silence ringer". We handle these keys here, rather than 5982 // in the InCallScreen, to make sure we'll respond to them 5983 // even if the InCallScreen hasn't come to the foreground yet. 5984 // Look for the DOWN event here, to agree with the "fallback" 5985 // behavior in the InCallScreen. 5986 Log.i(TAG, "interceptKeyBeforeQueueing:" 5987 + " VOLUME key-down while ringing: Silence ringer!"); 5988 5989 // Silence the ringer. (It's safe to call this 5990 // even if the ringer has already been silenced.) 5991 telecomManager.silenceRinger(); 5992 5993 // And *don't* pass this key thru to the current activity 5994 // (which is probably the InCallScreen.) 5995 result &= ~ACTION_PASS_TO_USER; 5996 break; 5997 } 5998 } 5999 int audioMode = AudioManager.MODE_NORMAL; 6000 try { 6001 audioMode = getAudioService().getMode(); 6002 } catch (Exception e) { 6003 Log.e(TAG, "Error getting AudioService in interceptKeyBeforeQueueing.", e); 6004 } 6005 boolean isInCall = (telecomManager != null && telecomManager.isInCall()) || 6006 audioMode == AudioManager.MODE_IN_COMMUNICATION; 6007 if (isInCall && (result & ACTION_PASS_TO_USER) == 0) { 6008 // If we are in call but we decided not to pass the key to 6009 // the application, just pass it to the session service. 6010 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 6011 event, AudioManager.USE_DEFAULT_STREAM_TYPE, false); 6012 break; 6013 } 6014 6015 } 6016 if (mUseTvRouting || mHandleVolumeKeysInWM) { 6017 // Defer special key handlings to 6018 // {@link interceptKeyBeforeDispatching()}. 6019 result |= ACTION_PASS_TO_USER; 6020 } else if ((result & ACTION_PASS_TO_USER) == 0) { 6021 // If we aren't passing to the user and no one else 6022 // handled it send it to the session manager to 6023 // figure out. 6024 MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent( 6025 event, AudioManager.USE_DEFAULT_STREAM_TYPE, true); 6026 } 6027 break; 6028 } 6029 6030 case KeyEvent.KEYCODE_ENDCALL: { 6031 result &= ~ACTION_PASS_TO_USER; 6032 if (down) { 6033 TelecomManager telecomManager = getTelecommService(); 6034 boolean hungUp = false; 6035 if (telecomManager != null) { 6036 hungUp = telecomManager.endCall(); 6037 } 6038 if (interactive && !hungUp) { 6039 mEndCallKeyHandled = false; 6040 mHandler.postDelayed(mEndCallLongPress, 6041 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 6042 } else { 6043 mEndCallKeyHandled = true; 6044 } 6045 } else { 6046 if (!mEndCallKeyHandled) { 6047 mHandler.removeCallbacks(mEndCallLongPress); 6048 if (!canceled) { 6049 if ((mEndcallBehavior 6050 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) { 6051 if (goHome()) { 6052 break; 6053 } 6054 } 6055 if ((mEndcallBehavior 6056 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { 6057 mPowerManager.goToSleep(event.getEventTime(), 6058 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); 6059 isWakeKey = false; 6060 } 6061 } 6062 } 6063 } 6064 break; 6065 } 6066 6067 case KeyEvent.KEYCODE_POWER: { 6068 // Any activity on the power button stops the accessibility shortcut 6069 cancelPendingAccessibilityShortcutAction(); 6070 result &= ~ACTION_PASS_TO_USER; 6071 isWakeKey = false; // wake-up will be handled separately 6072 if (down) { 6073 interceptPowerKeyDown(event, interactive); 6074 } else { 6075 interceptPowerKeyUp(event, interactive, canceled); 6076 } 6077 break; 6078 } 6079 6080 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN: 6081 // fall through 6082 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP: 6083 // fall through 6084 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT: 6085 // fall through 6086 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: { 6087 result &= ~ACTION_PASS_TO_USER; 6088 interceptSystemNavigationKey(event); 6089 break; 6090 } 6091 6092 case KeyEvent.KEYCODE_SLEEP: { 6093 result &= ~ACTION_PASS_TO_USER; 6094 isWakeKey = false; 6095 if (!mPowerManager.isInteractive()) { 6096 useHapticFeedback = false; // suppress feedback if already non-interactive 6097 } 6098 if (down) { 6099 sleepPress(event.getEventTime()); 6100 } else { 6101 sleepRelease(event.getEventTime()); 6102 } 6103 break; 6104 } 6105 6106 case KeyEvent.KEYCODE_SOFT_SLEEP: { 6107 result &= ~ACTION_PASS_TO_USER; 6108 isWakeKey = false; 6109 if (!down) { 6110 mPowerManagerInternal.setUserInactiveOverrideFromWindowManager(); 6111 } 6112 break; 6113 } 6114 6115 case KeyEvent.KEYCODE_WAKEUP: { 6116 result &= ~ACTION_PASS_TO_USER; 6117 isWakeKey = true; 6118 break; 6119 } 6120 6121 case KeyEvent.KEYCODE_MEDIA_PLAY: 6122 case KeyEvent.KEYCODE_MEDIA_PAUSE: 6123 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 6124 case KeyEvent.KEYCODE_HEADSETHOOK: 6125 case KeyEvent.KEYCODE_MUTE: 6126 case KeyEvent.KEYCODE_MEDIA_STOP: 6127 case KeyEvent.KEYCODE_MEDIA_NEXT: 6128 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 6129 case KeyEvent.KEYCODE_MEDIA_REWIND: 6130 case KeyEvent.KEYCODE_MEDIA_RECORD: 6131 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 6132 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { 6133 if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) { 6134 // If the global session is active pass all media keys to it 6135 // instead of the active window. 6136 result &= ~ACTION_PASS_TO_USER; 6137 } 6138 if ((result & ACTION_PASS_TO_USER) == 0) { 6139 // Only do this if we would otherwise not pass it to the user. In that 6140 // case, the PhoneWindow class will do the same thing, except it will 6141 // only do it if the showing app doesn't process the key on its own. 6142 // Note that we need to make a copy of the key event here because the 6143 // original key event will be recycled when we return. 6144 mBroadcastWakeLock.acquire(); 6145 Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK, 6146 new KeyEvent(event)); 6147 msg.setAsynchronous(true); 6148 msg.sendToTarget(); 6149 } 6150 break; 6151 } 6152 6153 case KeyEvent.KEYCODE_CALL: { 6154 if (down) { 6155 TelecomManager telecomManager = getTelecommService(); 6156 if (telecomManager != null) { 6157 if (telecomManager.isRinging()) { 6158 Log.i(TAG, "interceptKeyBeforeQueueing:" 6159 + " CALL key-down while ringing: Answer the call!"); 6160 telecomManager.acceptRingingCall(); 6161 6162 // And *don't* pass this key thru to the current activity 6163 // (which is presumably the InCallScreen.) 6164 result &= ~ACTION_PASS_TO_USER; 6165 } 6166 } 6167 } 6168 break; 6169 } 6170 case KeyEvent.KEYCODE_VOICE_ASSIST: { 6171 // Only do this if we would otherwise not pass it to the user. In that case, 6172 // interceptKeyBeforeDispatching would apply a similar but different policy in 6173 // order to invoke voice assist actions. Note that we need to make a copy of the 6174 // key event here because the original key event will be recycled when we return. 6175 if ((result & ACTION_PASS_TO_USER) == 0 && !down) { 6176 mBroadcastWakeLock.acquire(); 6177 Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK, 6178 keyguardActive ? 1 : 0, 0); 6179 msg.setAsynchronous(true); 6180 msg.sendToTarget(); 6181 } 6182 break; 6183 } 6184 case KeyEvent.KEYCODE_WINDOW: { 6185 if (mShortPressWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) { 6186 if (mPictureInPictureVisible) { 6187 // Consumes the key only if picture-in-picture is visible to show 6188 // picture-in-picture control menu. This gives a chance to the foreground 6189 // activity to customize PIP key behavior. 6190 if (!down) { 6191 showPictureInPictureMenu(event); 6192 } 6193 result &= ~ACTION_PASS_TO_USER; 6194 } 6195 } 6196 break; 6197 } 6198 } 6199 6200 if (useHapticFeedback) { 6201 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); 6202 } 6203 6204 if (isWakeKey) { 6205 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 6206 } 6207 6208 return result; 6209 } 6210 6211 /** 6212 * Handle statusbar expansion events. 6213 * @param event 6214 */ 6215 private void interceptSystemNavigationKey(KeyEvent event) { 6216 if (event.getAction() == KeyEvent.ACTION_UP) { 6217 if (!mAccessibilityManager.isEnabled() 6218 || !mAccessibilityManager.sendFingerprintGesture(event.getKeyCode())) { 6219 if (areSystemNavigationKeysEnabled()) { 6220 IStatusBarService sbar = getStatusBarService(); 6221 if (sbar != null) { 6222 try { 6223 sbar.handleSystemNavigationKey(event.getKeyCode()); 6224 } catch (RemoteException e1) { 6225 // oops, no statusbar. Ignore event. 6226 } 6227 } 6228 } 6229 } 6230 } 6231 } 6232 6233 /** 6234 * Returns true if the key can have global actions attached to it. 6235 * We reserve all power management keys for the system since they require 6236 * very careful handling. 6237 */ 6238 private static boolean isValidGlobalKey(int keyCode) { 6239 switch (keyCode) { 6240 case KeyEvent.KEYCODE_POWER: 6241 case KeyEvent.KEYCODE_WAKEUP: 6242 case KeyEvent.KEYCODE_SLEEP: 6243 return false; 6244 default: 6245 return true; 6246 } 6247 } 6248 6249 /** 6250 * When the screen is off we ignore some keys that might otherwise typically 6251 * be considered wake keys. We filter them out here. 6252 * 6253 * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it 6254 * is always considered a wake key. 6255 */ 6256 private boolean isWakeKeyWhenScreenOff(int keyCode) { 6257 switch (keyCode) { 6258 // ignore volume keys unless docked 6259 case KeyEvent.KEYCODE_VOLUME_UP: 6260 case KeyEvent.KEYCODE_VOLUME_DOWN: 6261 case KeyEvent.KEYCODE_VOLUME_MUTE: 6262 return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED; 6263 6264 // ignore media and camera keys 6265 case KeyEvent.KEYCODE_MUTE: 6266 case KeyEvent.KEYCODE_HEADSETHOOK: 6267 case KeyEvent.KEYCODE_MEDIA_PLAY: 6268 case KeyEvent.KEYCODE_MEDIA_PAUSE: 6269 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 6270 case KeyEvent.KEYCODE_MEDIA_STOP: 6271 case KeyEvent.KEYCODE_MEDIA_NEXT: 6272 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 6273 case KeyEvent.KEYCODE_MEDIA_REWIND: 6274 case KeyEvent.KEYCODE_MEDIA_RECORD: 6275 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 6276 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: 6277 case KeyEvent.KEYCODE_CAMERA: 6278 return false; 6279 } 6280 return true; 6281 } 6282 6283 6284 /** {@inheritDoc} */ 6285 @Override 6286 public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) { 6287 if ((policyFlags & FLAG_WAKE) != 0) { 6288 if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion, 6289 "android.policy:MOTION")) { 6290 return 0; 6291 } 6292 } 6293 6294 if (shouldDispatchInputWhenNonInteractive(null)) { 6295 return ACTION_PASS_TO_USER; 6296 } 6297 6298 // If we have not passed the action up and we are in theater mode without dreaming, 6299 // there will be no dream to intercept the touch and wake into ambient. The device should 6300 // wake up in this case. 6301 if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) { 6302 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming, 6303 "android.policy:MOTION"); 6304 } 6305 6306 return 0; 6307 } 6308 6309 private boolean shouldDispatchInputWhenNonInteractive(KeyEvent event) { 6310 final boolean displayOff = (mDisplay == null || mDisplay.getState() == Display.STATE_OFF); 6311 6312 if (displayOff && !mHasFeatureWatch) { 6313 return false; 6314 } 6315 6316 // Send events to keyguard while the screen is on and it's showing. 6317 if (isKeyguardShowingAndNotOccluded() && !displayOff) { 6318 return true; 6319 } 6320 6321 // Watches handle BACK specially 6322 if (mHasFeatureWatch 6323 && event != null 6324 && (event.getKeyCode() == KeyEvent.KEYCODE_BACK 6325 || event.getKeyCode() == KeyEvent.KEYCODE_STEM_PRIMARY)) { 6326 return false; 6327 } 6328 6329 // Send events to a dozing dream even if the screen is off since the dream 6330 // is in control of the state of the screen. 6331 IDreamManager dreamManager = getDreamManager(); 6332 6333 try { 6334 if (dreamManager != null && dreamManager.isDreaming()) { 6335 return true; 6336 } 6337 } catch (RemoteException e) { 6338 Slog.e(TAG, "RemoteException when checking if dreaming", e); 6339 } 6340 6341 // Otherwise, consume events since the user can't see what is being 6342 // interacted with. 6343 return false; 6344 } 6345 6346 private void dispatchDirectAudioEvent(KeyEvent event) { 6347 if (event.getAction() != KeyEvent.ACTION_DOWN) { 6348 return; 6349 } 6350 int keyCode = event.getKeyCode(); 6351 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 6352 | AudioManager.FLAG_FROM_KEY; 6353 String pkgName = mContext.getOpPackageName(); 6354 switch (keyCode) { 6355 case KeyEvent.KEYCODE_VOLUME_UP: 6356 try { 6357 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 6358 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6359 } catch (Exception e) { 6360 Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e); 6361 } 6362 break; 6363 case KeyEvent.KEYCODE_VOLUME_DOWN: 6364 try { 6365 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 6366 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6367 } catch (Exception e) { 6368 Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e); 6369 } 6370 break; 6371 case KeyEvent.KEYCODE_VOLUME_MUTE: 6372 try { 6373 if (event.getRepeatCount() == 0) { 6374 getAudioService().adjustSuggestedStreamVolume( 6375 AudioManager.ADJUST_TOGGLE_MUTE, 6376 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6377 } 6378 } catch (Exception e) { 6379 Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e); 6380 } 6381 break; 6382 } 6383 } 6384 6385 void dispatchMediaKeyWithWakeLock(KeyEvent event) { 6386 if (DEBUG_INPUT) { 6387 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event); 6388 } 6389 6390 if (mHavePendingMediaKeyRepeatWithWakeLock) { 6391 if (DEBUG_INPUT) { 6392 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat"); 6393 } 6394 6395 mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK); 6396 mHavePendingMediaKeyRepeatWithWakeLock = false; 6397 mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock 6398 } 6399 6400 dispatchMediaKeyWithWakeLockToAudioService(event); 6401 6402 if (event.getAction() == KeyEvent.ACTION_DOWN 6403 && event.getRepeatCount() == 0) { 6404 mHavePendingMediaKeyRepeatWithWakeLock = true; 6405 6406 Message msg = mHandler.obtainMessage( 6407 MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event); 6408 msg.setAsynchronous(true); 6409 mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout()); 6410 } else { 6411 mBroadcastWakeLock.release(); 6412 } 6413 } 6414 6415 void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) { 6416 mHavePendingMediaKeyRepeatWithWakeLock = false; 6417 6418 KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event, 6419 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS); 6420 if (DEBUG_INPUT) { 6421 Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent); 6422 } 6423 6424 dispatchMediaKeyWithWakeLockToAudioService(repeatEvent); 6425 mBroadcastWakeLock.release(); 6426 } 6427 6428 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) { 6429 if (mActivityManagerInternal.isSystemReady()) { 6430 MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true); 6431 } 6432 } 6433 6434 void launchVoiceAssistWithWakeLock(boolean keyguardActive) { 6435 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface( 6436 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 6437 if (dic != null) { 6438 try { 6439 dic.exitIdle("voice-search"); 6440 } catch (RemoteException e) { 6441 } 6442 } 6443 Intent voiceIntent = 6444 new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 6445 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive); 6446 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 6447 mBroadcastWakeLock.release(); 6448 } 6449 6450 BroadcastReceiver mDockReceiver = new BroadcastReceiver() { 6451 @Override 6452 public void onReceive(Context context, Intent intent) { 6453 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 6454 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 6455 Intent.EXTRA_DOCK_STATE_UNDOCKED); 6456 } else { 6457 try { 6458 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface( 6459 ServiceManager.getService(Context.UI_MODE_SERVICE)); 6460 mUiMode = uiModeService.getCurrentModeType(); 6461 } catch (RemoteException e) { 6462 } 6463 } 6464 updateRotation(true); 6465 synchronized (mLock) { 6466 updateOrientationListenerLp(); 6467 } 6468 } 6469 }; 6470 6471 BroadcastReceiver mDreamReceiver = new BroadcastReceiver() { 6472 @Override 6473 public void onReceive(Context context, Intent intent) { 6474 if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) { 6475 if (mKeyguardDelegate != null) { 6476 mKeyguardDelegate.onDreamingStarted(); 6477 } 6478 } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) { 6479 if (mKeyguardDelegate != null) { 6480 mKeyguardDelegate.onDreamingStopped(); 6481 } 6482 } 6483 } 6484 }; 6485 6486 BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() { 6487 @Override 6488 public void onReceive(Context context, Intent intent) { 6489 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 6490 // tickle the settings observer: this first ensures that we're 6491 // observing the relevant settings for the newly-active user, 6492 // and then updates our own bookkeeping based on the now- 6493 // current user. 6494 mSettingsObserver.onChange(false); 6495 6496 // force a re-application of focused window sysui visibility. 6497 // the window may never have been shown for this user 6498 // e.g. the keyguard when going through the new-user setup flow 6499 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6500 mLastSystemUiFlags = 0; 6501 updateSystemUiVisibilityLw(); 6502 } 6503 } 6504 } 6505 }; 6506 6507 private final Runnable mHiddenNavPanic = new Runnable() { 6508 @Override 6509 public void run() { 6510 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6511 if (!isUserSetupComplete()) { 6512 // Swipe-up for navigation bar is disabled during setup 6513 return; 6514 } 6515 mPendingPanicGestureUptime = SystemClock.uptimeMillis(); 6516 if (!isNavBarEmpty(mLastSystemUiFlags)) { 6517 mNavigationBarController.showTransient(); 6518 } 6519 } 6520 } 6521 }; 6522 6523 private void requestTransientBars(WindowState swipeTarget) { 6524 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6525 if (!isUserSetupComplete()) { 6526 // Swipe-up for navigation bar is disabled during setup 6527 return; 6528 } 6529 boolean sb = mStatusBarController.checkShowTransientBarLw(); 6530 boolean nb = mNavigationBarController.checkShowTransientBarLw() 6531 && !isNavBarEmpty(mLastSystemUiFlags); 6532 if (sb || nb) { 6533 // Don't show status bar when swiping on already visible navigation bar 6534 if (!nb && swipeTarget == mNavigationBar) { 6535 if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target"); 6536 return; 6537 } 6538 if (sb) mStatusBarController.showTransient(); 6539 if (nb) mNavigationBarController.showTransient(); 6540 mImmersiveModeConfirmation.confirmCurrentPrompt(); 6541 updateSystemUiVisibilityLw(); 6542 } 6543 } 6544 } 6545 6546 // Called on the PowerManager's Notifier thread. 6547 @Override 6548 public void startedGoingToSleep(int why) { 6549 if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")"); 6550 mCameraGestureTriggeredDuringGoingToSleep = false; 6551 mGoingToSleep = true; 6552 if (mKeyguardDelegate != null) { 6553 mKeyguardDelegate.onStartedGoingToSleep(why); 6554 } 6555 } 6556 6557 // Called on the PowerManager's Notifier thread. 6558 @Override 6559 public void finishedGoingToSleep(int why) { 6560 EventLog.writeEvent(70000, 0); 6561 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")"); 6562 MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000); 6563 6564 mGoingToSleep = false; 6565 6566 // We must get this work done here because the power manager will drop 6567 // the wake lock and let the system suspend once this function returns. 6568 synchronized (mLock) { 6569 mAwake = false; 6570 updateWakeGestureListenerLp(); 6571 updateOrientationListenerLp(); 6572 updateLockScreenTimeout(); 6573 } 6574 if (mKeyguardDelegate != null) { 6575 mKeyguardDelegate.onFinishedGoingToSleep(why, 6576 mCameraGestureTriggeredDuringGoingToSleep); 6577 } 6578 mCameraGestureTriggeredDuringGoingToSleep = false; 6579 } 6580 6581 // Called on the PowerManager's Notifier thread. 6582 @Override 6583 public void startedWakingUp() { 6584 EventLog.writeEvent(70000, 1); 6585 if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up..."); 6586 6587 // Since goToSleep performs these functions synchronously, we must 6588 // do the same here. We cannot post this work to a handler because 6589 // that might cause it to become reordered with respect to what 6590 // may happen in a future call to goToSleep. 6591 synchronized (mLock) { 6592 mAwake = true; 6593 6594 updateWakeGestureListenerLp(); 6595 updateOrientationListenerLp(); 6596 updateLockScreenTimeout(); 6597 } 6598 6599 if (mKeyguardDelegate != null) { 6600 mKeyguardDelegate.onStartedWakingUp(); 6601 } 6602 } 6603 6604 // Called on the PowerManager's Notifier thread. 6605 @Override 6606 public void finishedWakingUp() { 6607 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up..."); 6608 } 6609 6610 private void wakeUpFromPowerKey(long eventTime) { 6611 wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER"); 6612 } 6613 6614 private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) { 6615 final boolean theaterModeEnabled = isTheaterModeEnabled(); 6616 if (!wakeInTheaterMode && theaterModeEnabled) { 6617 return false; 6618 } 6619 6620 if (theaterModeEnabled) { 6621 Settings.Global.putInt(mContext.getContentResolver(), 6622 Settings.Global.THEATER_MODE_ON, 0); 6623 } 6624 6625 mPowerManager.wakeUp(wakeTime, reason); 6626 return true; 6627 } 6628 6629 private void finishKeyguardDrawn() { 6630 synchronized (mLock) { 6631 if (!mScreenOnEarly || mKeyguardDrawComplete) { 6632 return; // We are not awake yet or we have already informed of this event. 6633 } 6634 6635 mKeyguardDrawComplete = true; 6636 if (mKeyguardDelegate != null) { 6637 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6638 } 6639 mWindowManagerDrawComplete = false; 6640 } 6641 6642 // ... eventually calls finishWindowsDrawn which will finalize our screen turn on 6643 // as well as enabling the orientation change logic/sensor. 6644 mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, 6645 WAITING_FOR_DRAWN_TIMEOUT); 6646 } 6647 6648 // Called on the DisplayManager's DisplayPowerController thread. 6649 @Override 6650 public void screenTurnedOff() { 6651 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off..."); 6652 6653 updateScreenOffSleepToken(true); 6654 synchronized (mLock) { 6655 mScreenOnEarly = false; 6656 mScreenOnFully = false; 6657 mKeyguardDrawComplete = false; 6658 mWindowManagerDrawComplete = false; 6659 mScreenOnListener = null; 6660 updateOrientationListenerLp(); 6661 6662 if (mKeyguardDelegate != null) { 6663 mKeyguardDelegate.onScreenTurnedOff(); 6664 } 6665 } 6666 reportScreenStateToVrManager(false); 6667 } 6668 6669 private long getKeyguardDrawnTimeout() { 6670 final boolean bootCompleted = 6671 LocalServices.getService(SystemServiceManager.class).isBootCompleted(); 6672 // Set longer timeout if it has not booted yet to prevent showing empty window. 6673 return bootCompleted ? 1000 : 5000; 6674 } 6675 6676 // Called on the DisplayManager's DisplayPowerController thread. 6677 @Override 6678 public void screenTurningOn(final ScreenOnListener screenOnListener) { 6679 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on..."); 6680 6681 updateScreenOffSleepToken(false); 6682 synchronized (mLock) { 6683 mScreenOnEarly = true; 6684 mScreenOnFully = false; 6685 mKeyguardDrawComplete = false; 6686 mWindowManagerDrawComplete = false; 6687 mScreenOnListener = screenOnListener; 6688 6689 if (mKeyguardDelegate != null) { 6690 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6691 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 6692 getKeyguardDrawnTimeout()); 6693 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); 6694 } else { 6695 if (DEBUG_WAKEUP) Slog.d(TAG, 6696 "null mKeyguardDelegate: setting mKeyguardDrawComplete."); 6697 finishKeyguardDrawn(); 6698 } 6699 } 6700 } 6701 6702 // Called on the DisplayManager's DisplayPowerController thread. 6703 @Override 6704 public void screenTurnedOn() { 6705 synchronized (mLock) { 6706 if (mKeyguardDelegate != null) { 6707 mKeyguardDelegate.onScreenTurnedOn(); 6708 } 6709 } 6710 reportScreenStateToVrManager(true); 6711 } 6712 6713 @Override 6714 public void screenTurningOff(ScreenOffListener screenOffListener) { 6715 mWindowManagerFuncs.screenTurningOff(screenOffListener); 6716 } 6717 6718 private void reportScreenStateToVrManager(boolean isScreenOn) { 6719 if (mVrManagerInternal == null) { 6720 return; 6721 } 6722 mVrManagerInternal.onScreenStateChanged(isScreenOn); 6723 } 6724 6725 private void finishWindowsDrawn() { 6726 synchronized (mLock) { 6727 if (!mScreenOnEarly || mWindowManagerDrawComplete) { 6728 return; // Screen is not turned on or we did already handle this case earlier. 6729 } 6730 6731 mWindowManagerDrawComplete = true; 6732 } 6733 6734 finishScreenTurningOn(); 6735 } 6736 6737 private void finishScreenTurningOn() { 6738 synchronized (mLock) { 6739 // We have just finished drawing screen content. Since the orientation listener 6740 // gets only installed when all windows are drawn, we try to install it again. 6741 updateOrientationListenerLp(); 6742 } 6743 final ScreenOnListener listener; 6744 final boolean enableScreen; 6745 synchronized (mLock) { 6746 if (DEBUG_WAKEUP) Slog.d(TAG, 6747 "finishScreenTurningOn: mAwake=" + mAwake 6748 + ", mScreenOnEarly=" + mScreenOnEarly 6749 + ", mScreenOnFully=" + mScreenOnFully 6750 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete 6751 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); 6752 6753 if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete 6754 || (mAwake && !mKeyguardDrawComplete)) { 6755 return; // spurious or not ready yet 6756 } 6757 6758 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on..."); 6759 listener = mScreenOnListener; 6760 mScreenOnListener = null; 6761 mScreenOnFully = true; 6762 6763 // Remember the first time we draw the keyguard so we know when we're done with 6764 // the main part of booting and can enable the screen and hide boot messages. 6765 if (!mKeyguardDrawnOnce && mAwake) { 6766 mKeyguardDrawnOnce = true; 6767 enableScreen = true; 6768 if (mBootMessageNeedsHiding) { 6769 mBootMessageNeedsHiding = false; 6770 hideBootMessages(); 6771 } 6772 } else { 6773 enableScreen = false; 6774 } 6775 } 6776 6777 if (listener != null) { 6778 listener.onScreenOn(); 6779 } 6780 6781 if (enableScreen) { 6782 try { 6783 mWindowManager.enableScreenIfNeeded(); 6784 } catch (RemoteException unhandled) { 6785 } 6786 } 6787 } 6788 6789 private void handleHideBootMessage() { 6790 synchronized (mLock) { 6791 if (!mKeyguardDrawnOnce) { 6792 mBootMessageNeedsHiding = true; 6793 return; // keyguard hasn't drawn the first time yet, not done booting 6794 } 6795 } 6796 6797 if (mBootMsgDialog != null) { 6798 if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing"); 6799 mBootMsgDialog.dismiss(); 6800 mBootMsgDialog = null; 6801 } 6802 } 6803 6804 @Override 6805 public boolean isScreenOn() { 6806 return mScreenOnFully; 6807 } 6808 6809 /** {@inheritDoc} */ 6810 @Override 6811 public void enableKeyguard(boolean enabled) { 6812 if (mKeyguardDelegate != null) { 6813 mKeyguardDelegate.setKeyguardEnabled(enabled); 6814 } 6815 } 6816 6817 /** {@inheritDoc} */ 6818 @Override 6819 public void exitKeyguardSecurely(OnKeyguardExitResult callback) { 6820 if (mKeyguardDelegate != null) { 6821 mKeyguardDelegate.verifyUnlock(callback); 6822 } 6823 } 6824 6825 @Override 6826 public boolean isKeyguardShowingAndNotOccluded() { 6827 if (mKeyguardDelegate == null) return false; 6828 return mKeyguardDelegate.isShowing() && !mKeyguardOccluded; 6829 } 6830 6831 @Override 6832 public boolean isKeyguardTrustedLw() { 6833 if (mKeyguardDelegate == null) return false; 6834 return mKeyguardDelegate.isTrusted(); 6835 } 6836 6837 /** {@inheritDoc} */ 6838 @Override 6839 public boolean isKeyguardLocked() { 6840 return keyguardOn(); 6841 } 6842 6843 /** {@inheritDoc} */ 6844 @Override 6845 public boolean isKeyguardSecure(int userId) { 6846 if (mKeyguardDelegate == null) return false; 6847 return mKeyguardDelegate.isSecure(userId); 6848 } 6849 6850 /** {@inheritDoc} */ 6851 @Override 6852 public boolean isKeyguardOccluded() { 6853 if (mKeyguardDelegate == null) return false; 6854 return mKeyguardOccluded; 6855 } 6856 6857 /** {@inheritDoc} */ 6858 @Override 6859 public boolean inKeyguardRestrictedKeyInputMode() { 6860 if (mKeyguardDelegate == null) return false; 6861 return mKeyguardDelegate.isInputRestricted(); 6862 } 6863 6864 @Override 6865 public void dismissKeyguardLw(IKeyguardDismissCallback callback) { 6866 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 6867 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw"); 6868 6869 // ask the keyguard to prompt the user to authenticate if necessary 6870 mKeyguardDelegate.dismiss(callback); 6871 } else if (callback != null) { 6872 try { 6873 callback.onDismissError(); 6874 } catch (RemoteException e) { 6875 Slog.w(TAG, "Failed to call callback", e); 6876 } 6877 } 6878 } 6879 6880 @Override 6881 public boolean isKeyguardDrawnLw() { 6882 synchronized (mLock) { 6883 return mKeyguardDrawnOnce; 6884 } 6885 } 6886 6887 @Override 6888 public boolean isShowingDreamLw() { 6889 return mShowingDream; 6890 } 6891 6892 @Override 6893 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 6894 if (mKeyguardDelegate != null) { 6895 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation"); 6896 mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration); 6897 } 6898 } 6899 6900 @Override 6901 public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6902 Rect outInsets) { 6903 outInsets.setEmpty(); 6904 6905 // Navigation bar and status bar. 6906 getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, outInsets); 6907 outInsets.top = mStatusBarHeight; 6908 } 6909 6910 @Override 6911 public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6912 Rect outInsets) { 6913 outInsets.setEmpty(); 6914 6915 // Only navigation bar 6916 if (mHasNavigationBar) { 6917 int position = navigationBarPosition(displayWidth, displayHeight, displayRotation); 6918 if (position == NAV_BAR_BOTTOM) { 6919 outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode); 6920 } else if (position == NAV_BAR_RIGHT) { 6921 outInsets.right = getNavigationBarWidth(displayRotation, mUiMode); 6922 } else if (position == NAV_BAR_LEFT) { 6923 outInsets.left = getNavigationBarWidth(displayRotation, mUiMode); 6924 } 6925 } 6926 } 6927 6928 @Override 6929 public boolean isNavBarForcedShownLw(WindowState windowState) { 6930 return mForceShowSystemBars; 6931 } 6932 6933 @Override 6934 public boolean isDockSideAllowed(int dockSide) { 6935 6936 // We do not allow all dock sides at which the navigation bar touches the docked stack. 6937 if (!mNavigationBarCanMove) { 6938 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT; 6939 } else { 6940 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT; 6941 } 6942 } 6943 6944 void sendCloseSystemWindows() { 6945 PhoneWindow.sendCloseSystemWindows(mContext, null); 6946 } 6947 6948 void sendCloseSystemWindows(String reason) { 6949 PhoneWindow.sendCloseSystemWindows(mContext, reason); 6950 } 6951 6952 @Override 6953 public int rotationForOrientationLw(int orientation, int lastRotation) { 6954 if (false) { 6955 Slog.v(TAG, "rotationForOrientationLw(orient=" 6956 + orientation + ", last=" + lastRotation 6957 + "); user=" + mUserRotation + " " 6958 + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) 6959 ? "USER_ROTATION_LOCKED" : "") 6960 ); 6961 } 6962 6963 if (mForceDefaultOrientation) { 6964 return Surface.ROTATION_0; 6965 } 6966 6967 synchronized (mLock) { 6968 int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1 6969 if (sensorRotation < 0) { 6970 sensorRotation = lastRotation; 6971 } 6972 6973 final int preferredRotation; 6974 if (mLidState == LID_OPEN && mLidOpenRotation >= 0) { 6975 // Ignore sensor when lid switch is open and rotation is forced. 6976 preferredRotation = mLidOpenRotation; 6977 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR 6978 && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) { 6979 // Ignore sensor when in car dock unless explicitly enabled. 6980 // This case can override the behavior of NOSENSOR, and can also 6981 // enable 180 degree rotation while docked. 6982 preferredRotation = mCarDockEnablesAccelerometer 6983 ? sensorRotation : mCarDockRotation; 6984 } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK 6985 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK 6986 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK) 6987 && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) { 6988 // Ignore sensor when in desk dock unless explicitly enabled. 6989 // This case can override the behavior of NOSENSOR, and can also 6990 // enable 180 degree rotation while docked. 6991 preferredRotation = mDeskDockEnablesAccelerometer 6992 ? sensorRotation : mDeskDockRotation; 6993 } else if (mHdmiPlugged && mDemoHdmiRotationLock) { 6994 // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled. 6995 // Note that the dock orientation overrides the HDMI orientation. 6996 preferredRotation = mDemoHdmiRotation; 6997 } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED 6998 && mUndockedHdmiRotation >= 0) { 6999 // Ignore sensor when plugged into HDMI and an undocked orientation has 7000 // been specified in the configuration (only for legacy devices without 7001 // full multi-display support). 7002 // Note that the dock orientation overrides the HDMI orientation. 7003 preferredRotation = mUndockedHdmiRotation; 7004 } else if (mDemoRotationLock) { 7005 // Ignore sensor when demo rotation lock is enabled. 7006 // Note that the dock orientation and HDMI rotation lock override this. 7007 preferredRotation = mDemoRotation; 7008 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { 7009 // Application just wants to remain locked in the last rotation. 7010 preferredRotation = lastRotation; 7011 } else if (!mSupportAutoRotation) { 7012 // If we don't support auto-rotation then bail out here and ignore 7013 // the sensor and any rotation lock settings. 7014 preferredRotation = -1; 7015 } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE 7016 && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER 7017 || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 7018 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE 7019 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT 7020 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER)) 7021 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR 7022 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 7023 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE 7024 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { 7025 // Otherwise, use sensor only if requested by the application or enabled 7026 // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR. 7027 if (mAllowAllRotations < 0) { 7028 // Can't read this during init() because the context doesn't 7029 // have display metrics at that time so we cannot determine 7030 // tablet vs. phone then. 7031 mAllowAllRotations = mContext.getResources().getBoolean( 7032 com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0; 7033 } 7034 if (sensorRotation != Surface.ROTATION_180 7035 || mAllowAllRotations == 1 7036 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 7037 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) { 7038 // In VrMode, we report the sensor as always being in default orientation so: 7039 // 1) The orientation doesn't change as the user moves their head. 7040 // 2) 2D apps within VR show in the device's default orientation. 7041 // This only overwrites the sensor-provided orientation and does not affect any 7042 // explicit orientation preferences specified by any activities. 7043 preferredRotation = 7044 mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation; 7045 } else { 7046 preferredRotation = lastRotation; 7047 } 7048 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED 7049 && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { 7050 // Apply rotation lock. Does not apply to NOSENSOR. 7051 // The idea is that the user rotation expresses a weak preference for the direction 7052 // of gravity and as NOSENSOR is never affected by gravity, then neither should 7053 // NOSENSOR be affected by rotation lock (although it will be affected by docks). 7054 preferredRotation = mUserRotation; 7055 } else { 7056 // No overriding preference. 7057 // We will do exactly what the application asked us to do. 7058 preferredRotation = -1; 7059 } 7060 7061 switch (orientation) { 7062 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 7063 // Return portrait unless overridden. 7064 if (isAnyPortrait(preferredRotation)) { 7065 return preferredRotation; 7066 } 7067 return mPortraitRotation; 7068 7069 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 7070 // Return landscape unless overridden. 7071 if (isLandscapeOrSeascape(preferredRotation)) { 7072 return preferredRotation; 7073 } 7074 return mLandscapeRotation; 7075 7076 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 7077 // Return reverse portrait unless overridden. 7078 if (isAnyPortrait(preferredRotation)) { 7079 return preferredRotation; 7080 } 7081 return mUpsideDownRotation; 7082 7083 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 7084 // Return seascape unless overridden. 7085 if (isLandscapeOrSeascape(preferredRotation)) { 7086 return preferredRotation; 7087 } 7088 return mSeascapeRotation; 7089 7090 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 7091 case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE: 7092 // Return either landscape rotation. 7093 if (isLandscapeOrSeascape(preferredRotation)) { 7094 return preferredRotation; 7095 } 7096 if (isLandscapeOrSeascape(lastRotation)) { 7097 return lastRotation; 7098 } 7099 return mLandscapeRotation; 7100 7101 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 7102 case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT: 7103 // Return either portrait rotation. 7104 if (isAnyPortrait(preferredRotation)) { 7105 return preferredRotation; 7106 } 7107 if (isAnyPortrait(lastRotation)) { 7108 return lastRotation; 7109 } 7110 return mPortraitRotation; 7111 7112 default: 7113 // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR, 7114 // just return the preferred orientation we already calculated. 7115 if (preferredRotation >= 0) { 7116 return preferredRotation; 7117 } 7118 return Surface.ROTATION_0; 7119 } 7120 } 7121 } 7122 7123 @Override 7124 public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) { 7125 switch (orientation) { 7126 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 7127 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 7128 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 7129 return isAnyPortrait(rotation); 7130 7131 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 7132 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 7133 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 7134 return isLandscapeOrSeascape(rotation); 7135 7136 default: 7137 return true; 7138 } 7139 } 7140 7141 @Override 7142 public void setRotationLw(int rotation) { 7143 mOrientationListener.setCurrentRotation(rotation); 7144 } 7145 7146 private boolean isLandscapeOrSeascape(int rotation) { 7147 return rotation == mLandscapeRotation || rotation == mSeascapeRotation; 7148 } 7149 7150 private boolean isAnyPortrait(int rotation) { 7151 return rotation == mPortraitRotation || rotation == mUpsideDownRotation; 7152 } 7153 7154 @Override 7155 public int getUserRotationMode() { 7156 return Settings.System.getIntForUser(mContext.getContentResolver(), 7157 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ? 7158 WindowManagerPolicy.USER_ROTATION_FREE : 7159 WindowManagerPolicy.USER_ROTATION_LOCKED; 7160 } 7161 7162 // User rotation: to be used when all else fails in assigning an orientation to the device 7163 @Override 7164 public void setUserRotationMode(int mode, int rot) { 7165 ContentResolver res = mContext.getContentResolver(); 7166 7167 // mUserRotationMode and mUserRotation will be assigned by the content observer 7168 if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) { 7169 Settings.System.putIntForUser(res, 7170 Settings.System.USER_ROTATION, 7171 rot, 7172 UserHandle.USER_CURRENT); 7173 Settings.System.putIntForUser(res, 7174 Settings.System.ACCELEROMETER_ROTATION, 7175 0, 7176 UserHandle.USER_CURRENT); 7177 } else { 7178 Settings.System.putIntForUser(res, 7179 Settings.System.ACCELEROMETER_ROTATION, 7180 1, 7181 UserHandle.USER_CURRENT); 7182 } 7183 } 7184 7185 @Override 7186 public void setSafeMode(boolean safeMode) { 7187 mSafeMode = safeMode; 7188 performHapticFeedbackLw(null, safeMode 7189 ? HapticFeedbackConstants.SAFE_MODE_ENABLED 7190 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true); 7191 } 7192 7193 static long[] getLongIntArray(Resources r, int resid) { 7194 int[] ar = r.getIntArray(resid); 7195 if (ar == null) { 7196 return null; 7197 } 7198 long[] out = new long[ar.length]; 7199 for (int i=0; i<ar.length; i++) { 7200 out[i] = ar[i]; 7201 } 7202 return out; 7203 } 7204 7205 private void bindKeyguard() { 7206 synchronized (mLock) { 7207 if (mKeyguardBound) { 7208 return; 7209 } 7210 mKeyguardBound = true; 7211 } 7212 mKeyguardDelegate.bindService(mContext); 7213 } 7214 7215 @Override 7216 public void onSystemUiStarted() { 7217 bindKeyguard(); 7218 } 7219 7220 /** {@inheritDoc} */ 7221 @Override 7222 public void systemReady() { 7223 // In normal flow, systemReady is called before other system services are ready. 7224 // So it is better not to bind keyguard here. 7225 mKeyguardDelegate.onSystemReady(); 7226 7227 mVrManagerInternal = LocalServices.getService(VrManagerInternal.class); 7228 if (mVrManagerInternal != null) { 7229 mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); 7230 } 7231 7232 readCameraLensCoverState(); 7233 updateUiMode(); 7234 synchronized (mLock) { 7235 updateOrientationListenerLp(); 7236 mSystemReady = true; 7237 mHandler.post(new Runnable() { 7238 @Override 7239 public void run() { 7240 updateSettings(); 7241 } 7242 }); 7243 // If this happens, for whatever reason, systemReady came later than systemBooted. 7244 // And keyguard should be already bound from systemBooted 7245 if (mSystemBooted) { 7246 mKeyguardDelegate.onBootCompleted(); 7247 } 7248 } 7249 7250 mSystemGestures.systemReady(); 7251 mImmersiveModeConfirmation.systemReady(); 7252 7253 mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class); 7254 } 7255 7256 /** {@inheritDoc} */ 7257 @Override 7258 public void systemBooted() { 7259 bindKeyguard(); 7260 synchronized (mLock) { 7261 mSystemBooted = true; 7262 if (mSystemReady) { 7263 mKeyguardDelegate.onBootCompleted(); 7264 } 7265 } 7266 startedWakingUp(); 7267 screenTurningOn(null); 7268 screenTurnedOn(); 7269 } 7270 7271 @Override 7272 public boolean canDismissBootAnimation() { 7273 synchronized (mLock) { 7274 return mKeyguardDrawComplete; 7275 } 7276 } 7277 7278 ProgressDialog mBootMsgDialog = null; 7279 7280 /** {@inheritDoc} */ 7281 @Override 7282 public void showBootMessage(final CharSequence msg, final boolean always) { 7283 mHandler.post(new Runnable() { 7284 @Override public void run() { 7285 if (mBootMsgDialog == null) { 7286 int theme; 7287 if (mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK)) { 7288 theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert; 7289 } else { 7290 theme = 0; 7291 } 7292 7293 mBootMsgDialog = new ProgressDialog(mContext, theme) { 7294 // This dialog will consume all events coming in to 7295 // it, to avoid it trying to do things too early in boot. 7296 @Override public boolean dispatchKeyEvent(KeyEvent event) { 7297 return true; 7298 } 7299 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { 7300 return true; 7301 } 7302 @Override public boolean dispatchTouchEvent(MotionEvent ev) { 7303 return true; 7304 } 7305 @Override public boolean dispatchTrackballEvent(MotionEvent ev) { 7306 return true; 7307 } 7308 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) { 7309 return true; 7310 } 7311 @Override public boolean dispatchPopulateAccessibilityEvent( 7312 AccessibilityEvent event) { 7313 return true; 7314 } 7315 }; 7316 if (mContext.getPackageManager().isUpgrade()) { 7317 mBootMsgDialog.setTitle(R.string.android_upgrading_title); 7318 } else { 7319 mBootMsgDialog.setTitle(R.string.android_start_title); 7320 } 7321 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 7322 mBootMsgDialog.setIndeterminate(true); 7323 mBootMsgDialog.getWindow().setType( 7324 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS); 7325 mBootMsgDialog.getWindow().addFlags( 7326 WindowManager.LayoutParams.FLAG_DIM_BEHIND 7327 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 7328 mBootMsgDialog.getWindow().setDimAmount(1); 7329 WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes(); 7330 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 7331 mBootMsgDialog.getWindow().setAttributes(lp); 7332 mBootMsgDialog.setCancelable(false); 7333 mBootMsgDialog.show(); 7334 } 7335 mBootMsgDialog.setMessage(msg); 7336 } 7337 }); 7338 } 7339 7340 /** {@inheritDoc} */ 7341 @Override 7342 public void hideBootMessages() { 7343 mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE); 7344 } 7345 7346 /** {@inheritDoc} */ 7347 @Override 7348 public void userActivity() { 7349 // *************************************** 7350 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE 7351 // *************************************** 7352 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER 7353 // WITH ITS LOCKS HELD. 7354 // 7355 // This code must be VERY careful about the locks 7356 // it acquires. 7357 // In fact, the current code acquires way too many, 7358 // and probably has lurking deadlocks. 7359 7360 synchronized (mScreenLockTimeout) { 7361 if (mLockScreenTimerActive) { 7362 // reset the timer 7363 mHandler.removeCallbacks(mScreenLockTimeout); 7364 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 7365 } 7366 } 7367 } 7368 7369 class ScreenLockTimeout implements Runnable { 7370 Bundle options; 7371 7372 @Override 7373 public void run() { 7374 synchronized (this) { 7375 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard"); 7376 if (mKeyguardDelegate != null) { 7377 mKeyguardDelegate.doKeyguardTimeout(options); 7378 } 7379 mLockScreenTimerActive = false; 7380 options = null; 7381 } 7382 } 7383 7384 public void setLockOptions(Bundle options) { 7385 this.options = options; 7386 } 7387 } 7388 7389 ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout(); 7390 7391 @Override 7392 public void lockNow(Bundle options) { 7393 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 7394 mHandler.removeCallbacks(mScreenLockTimeout); 7395 if (options != null) { 7396 // In case multiple calls are made to lockNow, we don't wipe out the options 7397 // until the runnable actually executes. 7398 mScreenLockTimeout.setLockOptions(options); 7399 } 7400 mHandler.post(mScreenLockTimeout); 7401 } 7402 7403 private void updateLockScreenTimeout() { 7404 synchronized (mScreenLockTimeout) { 7405 boolean enable = (mAllowLockscreenWhenOn && mAwake && 7406 mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId)); 7407 if (mLockScreenTimerActive != enable) { 7408 if (enable) { 7409 if (localLOGV) Log.v(TAG, "setting lockscreen timer"); 7410 mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests 7411 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 7412 } else { 7413 if (localLOGV) Log.v(TAG, "clearing lockscreen timer"); 7414 mHandler.removeCallbacks(mScreenLockTimeout); 7415 } 7416 mLockScreenTimerActive = enable; 7417 } 7418 } 7419 } 7420 7421 private void updateDreamingSleepToken(boolean acquire) { 7422 if (acquire) { 7423 if (mDreamingSleepToken == null) { 7424 mDreamingSleepToken = mActivityManagerInternal.acquireSleepToken("Dream"); 7425 } 7426 } else { 7427 if (mDreamingSleepToken != null) { 7428 mDreamingSleepToken.release(); 7429 mDreamingSleepToken = null; 7430 } 7431 } 7432 } 7433 7434 private void updateScreenOffSleepToken(boolean acquire) { 7435 if (acquire) { 7436 if (mScreenOffSleepToken == null) { 7437 mScreenOffSleepToken = mActivityManagerInternal.acquireSleepToken("ScreenOff"); 7438 } 7439 } else { 7440 if (mScreenOffSleepToken != null) { 7441 mScreenOffSleepToken.release(); 7442 mScreenOffSleepToken = null; 7443 } 7444 } 7445 } 7446 7447 /** {@inheritDoc} */ 7448 @Override 7449 public void enableScreenAfterBoot() { 7450 readLidState(); 7451 applyLidSwitchState(); 7452 updateRotation(true); 7453 } 7454 7455 private void applyLidSwitchState() { 7456 if (mLidState == LID_CLOSED && mLidControlsSleep) { 7457 mPowerManager.goToSleep(SystemClock.uptimeMillis(), 7458 PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH, 7459 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 7460 } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) { 7461 mWindowManagerFuncs.lockDeviceNow(); 7462 } 7463 7464 synchronized (mLock) { 7465 updateWakeGestureListenerLp(); 7466 } 7467 } 7468 7469 void updateUiMode() { 7470 if (mUiModeManager == null) { 7471 mUiModeManager = IUiModeManager.Stub.asInterface( 7472 ServiceManager.getService(Context.UI_MODE_SERVICE)); 7473 } 7474 try { 7475 mUiMode = mUiModeManager.getCurrentModeType(); 7476 } catch (RemoteException e) { 7477 } 7478 } 7479 7480 void updateRotation(boolean alwaysSendConfiguration) { 7481 try { 7482 //set orientation on WindowManager 7483 mWindowManager.updateRotation(alwaysSendConfiguration, false); 7484 } catch (RemoteException e) { 7485 // Ignore 7486 } 7487 } 7488 7489 void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { 7490 try { 7491 //set orientation on WindowManager 7492 mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout); 7493 } catch (RemoteException e) { 7494 // Ignore 7495 } 7496 } 7497 7498 /** 7499 * Return an Intent to launch the currently active dock app as home. Returns 7500 * null if the standard home should be launched, which is the case if any of the following is 7501 * true: 7502 * <ul> 7503 * <li>The device is not in either car mode or desk mode 7504 * <li>The device is in car mode but mEnableCarDockHomeCapture is false 7505 * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false 7506 * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME 7507 * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME 7508 * </ul> 7509 * @return A dock intent. 7510 */ 7511 Intent createHomeDockIntent() { 7512 Intent intent = null; 7513 7514 // What home does is based on the mode, not the dock state. That 7515 // is, when in car mode you should be taken to car home regardless 7516 // of whether we are actually in a car dock. 7517 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) { 7518 if (mEnableCarDockHomeCapture) { 7519 intent = mCarDockIntent; 7520 } 7521 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) { 7522 if (ENABLE_DESK_DOCK_HOME_CAPTURE) { 7523 intent = mDeskDockIntent; 7524 } 7525 } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH 7526 && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK 7527 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK 7528 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) { 7529 // Always launch dock home from home when watch is docked, if it exists. 7530 intent = mDeskDockIntent; 7531 } else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) { 7532 if (ENABLE_VR_HEADSET_HOME_CAPTURE) { 7533 intent = mVrHeadsetHomeIntent; 7534 } 7535 } 7536 7537 if (intent == null) { 7538 return null; 7539 } 7540 7541 ActivityInfo ai = null; 7542 ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser( 7543 intent, 7544 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, 7545 mCurrentUserId); 7546 if (info != null) { 7547 ai = info.activityInfo; 7548 } 7549 if (ai != null 7550 && ai.metaData != null 7551 && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) { 7552 intent = new Intent(intent); 7553 intent.setClassName(ai.packageName, ai.name); 7554 return intent; 7555 } 7556 7557 return null; 7558 } 7559 7560 void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) { 7561 if (awakenFromDreams) { 7562 awakenDreams(); 7563 } 7564 7565 Intent dock = createHomeDockIntent(); 7566 if (dock != null) { 7567 try { 7568 if (fromHomeKey) { 7569 dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7570 } 7571 startActivityAsUser(dock, UserHandle.CURRENT); 7572 return; 7573 } catch (ActivityNotFoundException e) { 7574 } 7575 } 7576 7577 Intent intent; 7578 7579 if (fromHomeKey) { 7580 intent = new Intent(mHomeIntent); 7581 intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7582 } else { 7583 intent = mHomeIntent; 7584 } 7585 7586 startActivityAsUser(intent, UserHandle.CURRENT); 7587 } 7588 7589 /** 7590 * goes to the home screen 7591 * @return whether it did anything 7592 */ 7593 boolean goHome() { 7594 if (!isUserSetupComplete()) { 7595 Slog.i(TAG, "Not going home because user setup is in progress."); 7596 return false; 7597 } 7598 if (false) { 7599 // This code always brings home to the front. 7600 try { 7601 ActivityManager.getService().stopAppSwitches(); 7602 } catch (RemoteException e) { 7603 } 7604 sendCloseSystemWindows(); 7605 startDockOrHome(false /*fromHomeKey*/, true /* awakenFromDreams */); 7606 } else { 7607 // This code brings home to the front or, if it is already 7608 // at the front, puts the device to sleep. 7609 try { 7610 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) { 7611 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry. 7612 Log.d(TAG, "UTS-TEST-MODE"); 7613 } else { 7614 ActivityManager.getService().stopAppSwitches(); 7615 sendCloseSystemWindows(); 7616 Intent dock = createHomeDockIntent(); 7617 if (dock != null) { 7618 int result = ActivityManager.getService() 7619 .startActivityAsUser(null, null, dock, 7620 dock.resolveTypeIfNeeded(mContext.getContentResolver()), 7621 null, null, 0, 7622 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7623 null, null, UserHandle.USER_CURRENT); 7624 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7625 return false; 7626 } 7627 } 7628 } 7629 int result = ActivityManager.getService() 7630 .startActivityAsUser(null, null, mHomeIntent, 7631 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()), 7632 null, null, 0, 7633 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7634 null, null, UserHandle.USER_CURRENT); 7635 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7636 return false; 7637 } 7638 } catch (RemoteException ex) { 7639 // bummer, the activity manager, which is in this process, is dead 7640 } 7641 } 7642 return true; 7643 } 7644 7645 @Override 7646 public void setCurrentOrientationLw(int newOrientation) { 7647 synchronized (mLock) { 7648 if (newOrientation != mCurrentAppOrientation) { 7649 mCurrentAppOrientation = newOrientation; 7650 updateOrientationListenerLp(); 7651 } 7652 } 7653 } 7654 7655 private boolean isTheaterModeEnabled() { 7656 return Settings.Global.getInt(mContext.getContentResolver(), 7657 Settings.Global.THEATER_MODE_ON, 0) == 1; 7658 } 7659 7660 private boolean areSystemNavigationKeysEnabled() { 7661 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 7662 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, 0, UserHandle.USER_CURRENT) == 1; 7663 } 7664 7665 @Override 7666 public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) { 7667 if (!mVibrator.hasVibrator()) { 7668 return false; 7669 } 7670 final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(), 7671 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0; 7672 if (hapticsDisabled && !always) { 7673 return false; 7674 } 7675 7676 VibrationEffect effect = getVibrationEffect(effectId); 7677 if (effect == null) { 7678 return false; 7679 } 7680 7681 int owningUid; 7682 String owningPackage; 7683 if (win != null) { 7684 owningUid = win.getOwningUid(); 7685 owningPackage = win.getOwningPackage(); 7686 } else { 7687 owningUid = android.os.Process.myUid(); 7688 owningPackage = mContext.getOpPackageName(); 7689 } 7690 mVibrator.vibrate(owningUid, owningPackage, effect, VIBRATION_ATTRIBUTES); 7691 return true; 7692 } 7693 7694 private VibrationEffect getVibrationEffect(int effectId) { 7695 long[] pattern; 7696 switch (effectId) { 7697 case HapticFeedbackConstants.VIRTUAL_KEY: 7698 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); 7699 case HapticFeedbackConstants.LONG_PRESS: 7700 pattern = mLongPressVibePattern; 7701 break; 7702 case HapticFeedbackConstants.KEYBOARD_TAP: 7703 return VibrationEffect.get(VibrationEffect.EFFECT_CLICK); 7704 case HapticFeedbackConstants.CLOCK_TICK: 7705 pattern = mClockTickVibePattern; 7706 break; 7707 case HapticFeedbackConstants.CALENDAR_DATE: 7708 pattern = mCalendarDateVibePattern; 7709 break; 7710 case HapticFeedbackConstants.SAFE_MODE_DISABLED: 7711 pattern = mSafeModeDisabledVibePattern; 7712 break; 7713 case HapticFeedbackConstants.SAFE_MODE_ENABLED: 7714 pattern = mSafeModeEnabledVibePattern; 7715 break; 7716 case HapticFeedbackConstants.CONTEXT_CLICK: 7717 pattern = mContextClickVibePattern; 7718 break; 7719 default: 7720 return null; 7721 } 7722 if (pattern.length == 0) { 7723 // No vibration 7724 return null; 7725 } else if (pattern.length == 1) { 7726 // One-shot vibration 7727 return VibrationEffect.createOneShot(pattern[0], VibrationEffect.DEFAULT_AMPLITUDE); 7728 } else { 7729 // Pattern vibration 7730 return VibrationEffect.createWaveform(pattern, -1); 7731 } 7732 } 7733 7734 @Override 7735 public void keepScreenOnStartedLw() { 7736 } 7737 7738 @Override 7739 public void keepScreenOnStoppedLw() { 7740 if (isKeyguardShowingAndNotOccluded()) { 7741 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 7742 } 7743 } 7744 7745 private int updateSystemUiVisibilityLw() { 7746 // If there is no window focused, there will be nobody to handle the events 7747 // anyway, so just hang on in whatever state we're in until things settle down. 7748 WindowState winCandidate = mFocusedWindow != null ? mFocusedWindow 7749 : mTopFullscreenOpaqueWindowState; 7750 if (winCandidate == null) { 7751 return 0; 7752 } 7753 if (winCandidate.getAttrs().token == mImmersiveModeConfirmation.getWindowToken()) { 7754 // The immersive mode confirmation should never affect the system bar visibility, 7755 // otherwise it will unhide the navigation bar and hide itself. 7756 winCandidate = isStatusBarKeyguard() ? mStatusBar : mTopFullscreenOpaqueWindowState; 7757 if (winCandidate == null) { 7758 return 0; 7759 } 7760 } 7761 final WindowState win = winCandidate; 7762 if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mKeyguardOccluded) { 7763 // We are updating at a point where the keyguard has gotten 7764 // focus, but we were last in a state where the top window is 7765 // hiding it. This is probably because the keyguard as been 7766 // shown while the top window was displayed, so we want to ignore 7767 // it here because this is just a very transient change and it 7768 // will quickly lose focus once it correctly gets hidden. 7769 return 0; 7770 } 7771 7772 int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null) 7773 & ~mResettingSystemUiFlags 7774 & ~mForceClearedSystemUiFlags; 7775 if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) { 7776 tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS); 7777 } 7778 7779 final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */, 7780 mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState); 7781 final int dockedVisibility = updateLightStatusBarLw(0 /* vis */, 7782 mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState); 7783 mWindowManagerFuncs.getStackBounds(HOME_STACK_ID, mNonDockedStackBounds); 7784 mWindowManagerFuncs.getStackBounds(DOCKED_STACK_ID, mDockedStackBounds); 7785 final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility); 7786 final int diff = visibility ^ mLastSystemUiFlags; 7787 final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags; 7788 final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags; 7789 final boolean needsMenu = win.getNeedsMenuLw(mTopFullscreenOpaqueWindowState); 7790 if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0 && mLastFocusNeedsMenu == needsMenu 7791 && mFocusedApp == win.getAppToken() 7792 && mLastNonDockedStackBounds.equals(mNonDockedStackBounds) 7793 && mLastDockedStackBounds.equals(mDockedStackBounds)) { 7794 return 0; 7795 } 7796 mLastSystemUiFlags = visibility; 7797 mLastFullscreenStackSysUiFlags = fullscreenVisibility; 7798 mLastDockedStackSysUiFlags = dockedVisibility; 7799 mLastFocusNeedsMenu = needsMenu; 7800 mFocusedApp = win.getAppToken(); 7801 final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds); 7802 final Rect dockedStackBounds = new Rect(mDockedStackBounds); 7803 mHandler.post(new Runnable() { 7804 @Override 7805 public void run() { 7806 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 7807 if (statusbar != null) { 7808 statusbar.setSystemUiVisibility(visibility, fullscreenVisibility, 7809 dockedVisibility, 0xffffffff, fullscreenStackBounds, 7810 dockedStackBounds, win.toString()); 7811 statusbar.topAppWindowChanged(needsMenu); 7812 } 7813 } 7814 }); 7815 return diff; 7816 } 7817 7818 private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) { 7819 WindowState statusColorWin = isStatusBarKeyguard() && !mKeyguardOccluded 7820 ? mStatusBar 7821 : opaqueOrDimming; 7822 7823 if (statusColorWin != null) { 7824 if (statusColorWin == opaque) { 7825 // If the top fullscreen-or-dimming window is also the top fullscreen, respect 7826 // its light flag. 7827 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7828 vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null) 7829 & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7830 } else if (statusColorWin != null && statusColorWin.isDimming()) { 7831 // Otherwise if it's dimming, clear the light flag. 7832 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7833 } 7834 } 7835 return vis; 7836 } 7837 7838 private int updateLightNavigationBarLw(int vis, WindowState opaque, 7839 WindowState opaqueOrDimming) { 7840 final WindowState imeWin = mWindowManagerFuncs.getInputMethodWindowLw(); 7841 7842 final WindowState navColorWin; 7843 if (imeWin != null && imeWin.isVisibleLw()) { 7844 navColorWin = imeWin; 7845 } else { 7846 navColorWin = opaqueOrDimming; 7847 } 7848 7849 if (navColorWin != null) { 7850 if (navColorWin == opaque) { 7851 // If the top fullscreen-or-dimming window is also the top fullscreen, respect 7852 // its light flag. 7853 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7854 vis |= PolicyControl.getSystemUiVisibility(navColorWin, null) 7855 & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7856 } else if (navColorWin.isDimming() || navColorWin == imeWin) { 7857 // Otherwise if it's dimming or it's the IME window, clear the light flag. 7858 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; 7859 } 7860 } 7861 return vis; 7862 } 7863 7864 private boolean drawsSystemBarBackground(WindowState win) { 7865 return win == null || (win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; 7866 } 7867 7868 private boolean forcesDrawStatusBarBackground(WindowState win) { 7869 return win == null || (win.getAttrs().privateFlags 7870 & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0; 7871 } 7872 7873 private int updateSystemBarsLw(WindowState win, int oldVis, int vis) { 7874 final boolean dockedStackVisible = mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID); 7875 final boolean freeformStackVisible = 7876 mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID); 7877 final boolean resizing = mWindowManagerInternal.isDockedDividerResizing(); 7878 7879 // We need to force system bars when the docked stack is visible, when the freeform stack 7880 // is visible but also when we are resizing for the transitions when docked stack 7881 // visibility changes. 7882 mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; 7883 final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard; 7884 7885 // apply translucent bar vis flags 7886 WindowState fullscreenTransWin = isStatusBarKeyguard() && !mKeyguardOccluded 7887 ? mStatusBar 7888 : mTopFullscreenOpaqueWindowState; 7889 vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7890 vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7891 final int dockedVis = mStatusBarController.applyTranslucentFlagLw( 7892 mTopDockedOpaqueWindowState, 0, 0); 7893 7894 final boolean fullscreenDrawsStatusBarBackground = 7895 (drawsSystemBarBackground(mTopFullscreenOpaqueWindowState) 7896 && (vis & View.STATUS_BAR_TRANSLUCENT) == 0) 7897 || forcesDrawStatusBarBackground(mTopFullscreenOpaqueWindowState); 7898 final boolean dockedDrawsStatusBarBackground = 7899 (drawsSystemBarBackground(mTopDockedOpaqueWindowState) 7900 && (dockedVis & View.STATUS_BAR_TRANSLUCENT) == 0) 7901 || forcesDrawStatusBarBackground(mTopDockedOpaqueWindowState); 7902 7903 // prevent status bar interaction from clearing certain flags 7904 int type = win.getAttrs().type; 7905 boolean statusBarHasFocus = type == TYPE_STATUS_BAR; 7906 if (statusBarHasFocus && !isStatusBarKeyguard()) { 7907 int flags = View.SYSTEM_UI_FLAG_FULLSCREEN 7908 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 7909 | View.SYSTEM_UI_FLAG_IMMERSIVE 7910 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 7911 | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7912 if (mKeyguardOccluded) { 7913 flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT; 7914 } 7915 vis = (vis & ~flags) | (oldVis & flags); 7916 } 7917 7918 if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) { 7919 vis |= View.STATUS_BAR_TRANSPARENT; 7920 vis &= ~View.STATUS_BAR_TRANSLUCENT; 7921 } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar) 7922 || forceOpaqueStatusBar) { 7923 vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT); 7924 } 7925 7926 vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing); 7927 7928 // update status bar 7929 boolean immersiveSticky = 7930 (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7931 final boolean hideStatusBarWM = 7932 mTopFullscreenOpaqueWindowState != null 7933 && (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null) 7934 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; 7935 final boolean hideStatusBarSysui = 7936 (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 7937 final boolean hideNavBarSysui = 7938 (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; 7939 7940 final boolean transientStatusBarAllowed = mStatusBar != null 7941 && (statusBarHasFocus || (!mForceShowSystemBars 7942 && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky)))); 7943 7944 final boolean transientNavBarAllowed = mNavigationBar != null 7945 && !mForceShowSystemBars && hideNavBarSysui && immersiveSticky; 7946 7947 final long now = SystemClock.uptimeMillis(); 7948 final boolean pendingPanic = mPendingPanicGestureUptime != 0 7949 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION; 7950 if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) { 7951 // The user performed the panic gesture recently, we're about to hide the bars, 7952 // we're no longer on the Keyguard and the screen is ready. We can now request the bars. 7953 mPendingPanicGestureUptime = 0; 7954 mStatusBarController.showTransient(); 7955 if (!isNavBarEmpty(vis)) { 7956 mNavigationBarController.showTransient(); 7957 } 7958 } 7959 7960 final boolean denyTransientStatus = mStatusBarController.isTransientShowRequested() 7961 && !transientStatusBarAllowed && hideStatusBarSysui; 7962 final boolean denyTransientNav = mNavigationBarController.isTransientShowRequested() 7963 && !transientNavBarAllowed; 7964 if (denyTransientStatus || denyTransientNav || mForceShowSystemBars) { 7965 // clear the clearable flags instead 7966 clearClearableFlagsLw(); 7967 vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS; 7968 } 7969 7970 final boolean immersive = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; 7971 immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7972 final boolean navAllowedHidden = immersive || immersiveSticky; 7973 7974 if (hideNavBarSysui && !navAllowedHidden 7975 && getWindowLayerLw(win) > getWindowLayerFromTypeLw(TYPE_INPUT_CONSUMER)) { 7976 // We can't hide the navbar from this window otherwise the input consumer would not get 7977 // the input events. 7978 vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 7979 } 7980 7981 vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis); 7982 7983 // update navigation bar 7984 boolean oldImmersiveMode = isImmersiveMode(oldVis); 7985 boolean newImmersiveMode = isImmersiveMode(vis); 7986 if (win != null && oldImmersiveMode != newImmersiveMode) { 7987 final String pkg = win.getOwningPackage(); 7988 mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode, 7989 isUserSetupComplete(), isNavBarEmpty(win.getSystemUiVisibility())); 7990 } 7991 7992 vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis); 7993 7994 vis = updateLightNavigationBarLw(vis, mTopFullscreenOpaqueWindowState, 7995 mTopFullscreenOpaqueOrDimmingWindowState); 7996 7997 return vis; 7998 } 7999 8000 /** 8001 * @return the current visibility flags with the nav-bar opacity related flags toggled based 8002 * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}. 8003 */ 8004 private int configureNavBarOpacity(int visibility, boolean dockedStackVisible, 8005 boolean freeformStackVisible, boolean isDockedDividerResizing) { 8006 if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { 8007 if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { 8008 visibility = setNavBarOpaqueFlag(visibility); 8009 } 8010 } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { 8011 if (isDockedDividerResizing) { 8012 visibility = setNavBarOpaqueFlag(visibility); 8013 } else if (freeformStackVisible) { 8014 visibility = setNavBarTranslucentFlag(visibility); 8015 } else { 8016 visibility = setNavBarOpaqueFlag(visibility); 8017 } 8018 } 8019 8020 if (!areTranslucentBarsAllowed()) { 8021 visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT; 8022 } 8023 return visibility; 8024 } 8025 8026 private int setNavBarOpaqueFlag(int visibility) { 8027 return visibility &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT); 8028 } 8029 8030 private int setNavBarTranslucentFlag(int visibility) { 8031 visibility &= ~View.NAVIGATION_BAR_TRANSPARENT; 8032 return visibility |= View.NAVIGATION_BAR_TRANSLUCENT; 8033 } 8034 8035 private void clearClearableFlagsLw() { 8036 int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS; 8037 if (newVal != mResettingSystemUiFlags) { 8038 mResettingSystemUiFlags = newVal; 8039 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 8040 } 8041 } 8042 8043 private boolean isImmersiveMode(int vis) { 8044 final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 8045 return mNavigationBar != null 8046 && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 8047 && (vis & flags) != 0 8048 && canHideNavigationBar(); 8049 } 8050 8051 private static boolean isNavBarEmpty(int systemUiFlags) { 8052 final int disableNavigationBar = (View.STATUS_BAR_DISABLE_HOME 8053 | View.STATUS_BAR_DISABLE_BACK 8054 | View.STATUS_BAR_DISABLE_RECENT); 8055 8056 return (systemUiFlags & disableNavigationBar) == disableNavigationBar; 8057 } 8058 8059 /** 8060 * @return whether the navigation or status bar can be made translucent 8061 * 8062 * This should return true unless touch exploration is not enabled or 8063 * R.boolean.config_enableTranslucentDecor is false. 8064 */ 8065 private boolean areTranslucentBarsAllowed() { 8066 return mTranslucentDecorEnabled; 8067 } 8068 8069 // Use this instead of checking config_showNavigationBar so that it can be consistently 8070 // overridden by qemu.hw.mainkeys in the emulator. 8071 @Override 8072 public boolean hasNavigationBar() { 8073 return mHasNavigationBar; 8074 } 8075 8076 @Override 8077 public void setLastInputMethodWindowLw(WindowState ime, WindowState target) { 8078 mLastInputMethodWindow = ime; 8079 mLastInputMethodTargetWindow = target; 8080 } 8081 8082 @Override 8083 public void setDismissImeOnBackKeyPressed(boolean newValue) { 8084 mDismissImeOnBackKeyPressed = newValue; 8085 } 8086 8087 @Override 8088 public int getInputMethodWindowVisibleHeightLw() { 8089 return mDockBottom - mCurBottom; 8090 } 8091 8092 @Override 8093 public void setCurrentUserLw(int newUserId) { 8094 mCurrentUserId = newUserId; 8095 if (mKeyguardDelegate != null) { 8096 mKeyguardDelegate.setCurrentUser(newUserId); 8097 } 8098 if (mAccessibilityShortcutController != null) { 8099 mAccessibilityShortcutController.setCurrentUser(newUserId); 8100 } 8101 StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); 8102 if (statusBar != null) { 8103 statusBar.setCurrentUser(newUserId); 8104 } 8105 setLastInputMethodWindowLw(null, null); 8106 } 8107 8108 @Override 8109 public void setSwitchingUser(boolean switching) { 8110 mKeyguardDelegate.setSwitchingUser(switching); 8111 } 8112 8113 @Override 8114 public boolean canMagnifyWindow(int windowType) { 8115 switch (windowType) { 8116 case WindowManager.LayoutParams.TYPE_INPUT_METHOD: 8117 case WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG: 8118 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR: 8119 case WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY: { 8120 return false; 8121 } 8122 } 8123 return true; 8124 } 8125 8126 @Override 8127 public boolean isTopLevelWindow(int windowType) { 8128 if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW 8129 && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 8130 return (windowType == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG); 8131 } 8132 return true; 8133 } 8134 8135 @Override 8136 public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) { 8137 // For the upside down rotation we don't rotate seamlessly as the navigation 8138 // bar moves position. 8139 // Note most apps (using orientation:sensor or user as opposed to fullSensor) 8140 // will not enter the reverse portrait orientation, so actually the 8141 // orientation won't change at all. 8142 if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) { 8143 return false; 8144 } 8145 // If the navigation bar can't change sides, then it will 8146 // jump when we change orientations and we don't rotate 8147 // seamlessly. 8148 if (!mNavigationBarCanMove) { 8149 return false; 8150 } 8151 int delta = newRotation - oldRotation; 8152 if (delta < 0) delta += 4; 8153 // Likewise we don't rotate seamlessly for 180 degree rotations 8154 // in this case the surfaces never resize, and our logic to 8155 // revert the transformations on size change will fail. We could 8156 // fix this in the future with the "tagged" frames idea. 8157 if (delta == Surface.ROTATION_180) { 8158 return false; 8159 } 8160 8161 final WindowState w = mTopFullscreenOpaqueWindowState; 8162 if (w != mFocusedWindow) { 8163 return false; 8164 } 8165 8166 // We only enable seamless rotation if the top window has requested 8167 // it and is in the fullscreen opaque state. Seamless rotation 8168 // requires freezing various Surface states and won't work well 8169 // with animations, so we disable it in the animation case for now. 8170 if (w != null && !w.isAnimatingLw() && 8171 ((w.getAttrs().rotationAnimation == ROTATION_ANIMATION_JUMPCUT) || 8172 (w.getAttrs().rotationAnimation == ROTATION_ANIMATION_SEAMLESS))) { 8173 return true; 8174 } 8175 return false; 8176 } 8177 8178 @Override 8179 public void dump(String prefix, PrintWriter pw, String[] args) { 8180 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode); 8181 pw.print(" mSystemReady="); pw.print(mSystemReady); 8182 pw.print(" mSystemBooted="); pw.println(mSystemBooted); 8183 pw.print(prefix); pw.print("mLidState="); pw.print(mLidState); 8184 pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation); 8185 pw.print(" mCameraLensCoverState="); pw.print(mCameraLensCoverState); 8186 pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged); 8187 if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0 8188 || mForceClearedSystemUiFlags != 0) { 8189 pw.print(prefix); pw.print("mLastSystemUiFlags=0x"); 8190 pw.print(Integer.toHexString(mLastSystemUiFlags)); 8191 pw.print(" mResettingSystemUiFlags=0x"); 8192 pw.print(Integer.toHexString(mResettingSystemUiFlags)); 8193 pw.print(" mForceClearedSystemUiFlags=0x"); 8194 pw.println(Integer.toHexString(mForceClearedSystemUiFlags)); 8195 } 8196 if (mLastFocusNeedsMenu) { 8197 pw.print(prefix); pw.print("mLastFocusNeedsMenu="); 8198 pw.println(mLastFocusNeedsMenu); 8199 } 8200 pw.print(prefix); pw.print("mWakeGestureEnabledSetting="); 8201 pw.println(mWakeGestureEnabledSetting); 8202 8203 pw.print(prefix); pw.print("mSupportAutoRotation="); pw.println(mSupportAutoRotation); 8204 pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode); 8205 pw.print(" mDockMode="); pw.print(mDockMode); 8206 pw.print(" mEnableCarDockHomeCapture="); pw.print(mEnableCarDockHomeCapture); 8207 pw.print(" mCarDockRotation="); pw.print(mCarDockRotation); 8208 pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation); 8209 pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode); 8210 pw.print(" mUserRotation="); pw.print(mUserRotation); 8211 pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations); 8212 pw.print(prefix); pw.print("mCurrentAppOrientation="); pw.println(mCurrentAppOrientation); 8213 pw.print(prefix); pw.print("mCarDockEnablesAccelerometer="); 8214 pw.print(mCarDockEnablesAccelerometer); 8215 pw.print(" mDeskDockEnablesAccelerometer="); 8216 pw.println(mDeskDockEnablesAccelerometer); 8217 pw.print(prefix); pw.print("mLidKeyboardAccessibility="); 8218 pw.print(mLidKeyboardAccessibility); 8219 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility); 8220 pw.print(" mLidControlsScreenLock="); pw.println(mLidControlsScreenLock); 8221 pw.print(" mLidControlsSleep="); pw.println(mLidControlsSleep); 8222 pw.print(prefix); 8223 pw.print(" mLongPressOnBackBehavior="); pw.println(mLongPressOnBackBehavior); 8224 pw.print(prefix); 8225 pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior); 8226 pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior); 8227 pw.print(prefix); 8228 pw.print("mDoublePressOnPowerBehavior="); pw.print(mDoublePressOnPowerBehavior); 8229 pw.print(" mTriplePressOnPowerBehavior="); pw.println(mTriplePressOnPowerBehavior); 8230 pw.print(prefix); pw.print("mHasSoftInput="); pw.println(mHasSoftInput); 8231 pw.print(prefix); pw.print("mAwake="); pw.println(mAwake); 8232 pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly); 8233 pw.print(" mScreenOnFully="); pw.println(mScreenOnFully); 8234 pw.print(prefix); pw.print("mKeyguardDrawComplete="); pw.print(mKeyguardDrawComplete); 8235 pw.print(" mWindowManagerDrawComplete="); pw.println(mWindowManagerDrawComplete); 8236 pw.print(prefix); pw.print("mOrientationSensorEnabled="); 8237 pw.println(mOrientationSensorEnabled); 8238 pw.print(prefix); pw.print("mOverscanScreen=("); pw.print(mOverscanScreenLeft); 8239 pw.print(","); pw.print(mOverscanScreenTop); 8240 pw.print(") "); pw.print(mOverscanScreenWidth); 8241 pw.print("x"); pw.println(mOverscanScreenHeight); 8242 if (mOverscanLeft != 0 || mOverscanTop != 0 8243 || mOverscanRight != 0 || mOverscanBottom != 0) { 8244 pw.print(prefix); pw.print("mOverscan left="); pw.print(mOverscanLeft); 8245 pw.print(" top="); pw.print(mOverscanTop); 8246 pw.print(" right="); pw.print(mOverscanRight); 8247 pw.print(" bottom="); pw.println(mOverscanBottom); 8248 } 8249 pw.print(prefix); pw.print("mRestrictedOverscanScreen=("); 8250 pw.print(mRestrictedOverscanScreenLeft); 8251 pw.print(","); pw.print(mRestrictedOverscanScreenTop); 8252 pw.print(") "); pw.print(mRestrictedOverscanScreenWidth); 8253 pw.print("x"); pw.println(mRestrictedOverscanScreenHeight); 8254 pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft); 8255 pw.print(","); pw.print(mUnrestrictedScreenTop); 8256 pw.print(") "); pw.print(mUnrestrictedScreenWidth); 8257 pw.print("x"); pw.println(mUnrestrictedScreenHeight); 8258 pw.print(prefix); pw.print("mRestrictedScreen=("); pw.print(mRestrictedScreenLeft); 8259 pw.print(","); pw.print(mRestrictedScreenTop); 8260 pw.print(") "); pw.print(mRestrictedScreenWidth); 8261 pw.print("x"); pw.println(mRestrictedScreenHeight); 8262 pw.print(prefix); pw.print("mStableFullscreen=("); pw.print(mStableFullscreenLeft); 8263 pw.print(","); pw.print(mStableFullscreenTop); 8264 pw.print(")-("); pw.print(mStableFullscreenRight); 8265 pw.print(","); pw.print(mStableFullscreenBottom); pw.println(")"); 8266 pw.print(prefix); pw.print("mStable=("); pw.print(mStableLeft); 8267 pw.print(","); pw.print(mStableTop); 8268 pw.print(")-("); pw.print(mStableRight); 8269 pw.print(","); pw.print(mStableBottom); pw.println(")"); 8270 pw.print(prefix); pw.print("mSystem=("); pw.print(mSystemLeft); 8271 pw.print(","); pw.print(mSystemTop); 8272 pw.print(")-("); pw.print(mSystemRight); 8273 pw.print(","); pw.print(mSystemBottom); pw.println(")"); 8274 pw.print(prefix); pw.print("mCur=("); pw.print(mCurLeft); 8275 pw.print(","); pw.print(mCurTop); 8276 pw.print(")-("); pw.print(mCurRight); 8277 pw.print(","); pw.print(mCurBottom); pw.println(")"); 8278 pw.print(prefix); pw.print("mContent=("); pw.print(mContentLeft); 8279 pw.print(","); pw.print(mContentTop); 8280 pw.print(")-("); pw.print(mContentRight); 8281 pw.print(","); pw.print(mContentBottom); pw.println(")"); 8282 pw.print(prefix); pw.print("mVoiceContent=("); pw.print(mVoiceContentLeft); 8283 pw.print(","); pw.print(mVoiceContentTop); 8284 pw.print(")-("); pw.print(mVoiceContentRight); 8285 pw.print(","); pw.print(mVoiceContentBottom); pw.println(")"); 8286 pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft); 8287 pw.print(","); pw.print(mDockTop); 8288 pw.print(")-("); pw.print(mDockRight); 8289 pw.print(","); pw.print(mDockBottom); pw.println(")"); 8290 pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer); 8291 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer); 8292 pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream); 8293 pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen); 8294 pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken); 8295 if (mLastInputMethodWindow != null) { 8296 pw.print(prefix); pw.print("mLastInputMethodWindow="); 8297 pw.println(mLastInputMethodWindow); 8298 } 8299 if (mLastInputMethodTargetWindow != null) { 8300 pw.print(prefix); pw.print("mLastInputMethodTargetWindow="); 8301 pw.println(mLastInputMethodTargetWindow); 8302 } 8303 pw.print(prefix); pw.print("mDismissImeOnBackKeyPressed="); 8304 pw.println(mDismissImeOnBackKeyPressed); 8305 if (mStatusBar != null) { 8306 pw.print(prefix); pw.print("mStatusBar="); 8307 pw.print(mStatusBar); pw.print(" isStatusBarKeyguard="); 8308 pw.println(isStatusBarKeyguard()); 8309 } 8310 if (mNavigationBar != null) { 8311 pw.print(prefix); pw.print("mNavigationBar="); 8312 pw.println(mNavigationBar); 8313 } 8314 if (mFocusedWindow != null) { 8315 pw.print(prefix); pw.print("mFocusedWindow="); 8316 pw.println(mFocusedWindow); 8317 } 8318 if (mFocusedApp != null) { 8319 pw.print(prefix); pw.print("mFocusedApp="); 8320 pw.println(mFocusedApp); 8321 } 8322 if (mTopFullscreenOpaqueWindowState != null) { 8323 pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState="); 8324 pw.println(mTopFullscreenOpaqueWindowState); 8325 } 8326 if (mTopFullscreenOpaqueOrDimmingWindowState != null) { 8327 pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState="); 8328 pw.println(mTopFullscreenOpaqueOrDimmingWindowState); 8329 } 8330 if (mForcingShowNavBar) { 8331 pw.print(prefix); pw.print("mForcingShowNavBar="); 8332 pw.println(mForcingShowNavBar); pw.print( "mForcingShowNavBarLayer="); 8333 pw.println(mForcingShowNavBarLayer); 8334 } 8335 pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen); 8336 pw.print(" mKeyguardOccluded="); pw.println(mKeyguardOccluded); 8337 pw.print(" mKeyguardOccludedChanged="); pw.println(mKeyguardOccludedChanged); 8338 pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded); 8339 pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); 8340 pw.print(" mForceStatusBarFromKeyguard="); 8341 pw.println(mForceStatusBarFromKeyguard); 8342 pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed); 8343 pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn); 8344 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout); 8345 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive); 8346 pw.print(prefix); pw.print("mEndcallBehavior="); pw.print(mEndcallBehavior); 8347 pw.print(" mIncallPowerBehavior="); pw.print(mIncallPowerBehavior); 8348 pw.print(" mIncallBackBehavior="); pw.print(mIncallBackBehavior); 8349 pw.print(" mLongPressOnHomeBehavior="); pw.println(mLongPressOnHomeBehavior); 8350 pw.print(prefix); pw.print("mLandscapeRotation="); pw.print(mLandscapeRotation); 8351 pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation); 8352 pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation); 8353 pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation); 8354 pw.print(prefix); pw.print("mDemoHdmiRotation="); pw.print(mDemoHdmiRotation); 8355 pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock); 8356 pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation); 8357 if (mHasFeatureLeanback) { 8358 pw.print(prefix); 8359 pw.print("mAccessibilityTvKey1Pressed="); pw.println(mAccessibilityTvKey1Pressed); 8360 pw.print(prefix); 8361 pw.print("mAccessibilityTvKey2Pressed="); pw.println(mAccessibilityTvKey2Pressed); 8362 pw.print(prefix); 8363 pw.print("mAccessibilityTvScheduled="); pw.println(mAccessibilityTvScheduled); 8364 } 8365 8366 mGlobalKeyManager.dump(prefix, pw); 8367 mStatusBarController.dump(pw, prefix); 8368 mNavigationBarController.dump(pw, prefix); 8369 PolicyControl.dump(prefix, pw); 8370 8371 if (mWakeGestureListener != null) { 8372 mWakeGestureListener.dump(pw, prefix); 8373 } 8374 if (mOrientationListener != null) { 8375 mOrientationListener.dump(pw, prefix); 8376 } 8377 if (mBurnInProtectionHelper != null) { 8378 mBurnInProtectionHelper.dump(prefix, pw); 8379 } 8380 if (mKeyguardDelegate != null) { 8381 mKeyguardDelegate.dump(prefix, pw); 8382 } 8383 } 8384} 8385