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