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