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