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