PhoneWindowManager.java revision 90859bc4ce633e2716a4708234278321d74df461
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 2275 if (config.keyboard == Configuration.KEYBOARD_NOKEYS 2276 || (keyboardPresence == PRESENCE_INTERNAL 2277 && isHidden(mLidKeyboardAccessibility))) { 2278 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES; 2279 if (!mHasSoftInput) { 2280 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES; 2281 } 2282 } 2283 2284 if (config.navigation == Configuration.NAVIGATION_NONAV 2285 || (navigationPresence == PRESENCE_INTERNAL 2286 && isHidden(mLidNavigationAccessibility))) { 2287 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES; 2288 } 2289 } 2290 2291 @Override 2292 public void onConfigurationChanged() { 2293 final Resources res = mContext.getResources(); 2294 2295 mStatusBarHeight = 2296 res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); 2297 2298 // Height of the navigation bar when presented horizontally at bottom 2299 mNavigationBarHeightForRotationDefault[mPortraitRotation] = 2300 mNavigationBarHeightForRotationDefault[mUpsideDownRotation] = 2301 res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height); 2302 mNavigationBarHeightForRotationDefault[mLandscapeRotation] = 2303 mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize( 2304 com.android.internal.R.dimen.navigation_bar_height_landscape); 2305 2306 // Width of the navigation bar when presented vertically along one side 2307 mNavigationBarWidthForRotationDefault[mPortraitRotation] = 2308 mNavigationBarWidthForRotationDefault[mUpsideDownRotation] = 2309 mNavigationBarWidthForRotationDefault[mLandscapeRotation] = 2310 mNavigationBarWidthForRotationDefault[mSeascapeRotation] = 2311 res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width); 2312 2313 // Height of the navigation bar when presented horizontally at bottom 2314 mNavigationBarHeightForRotationInCarMode[mPortraitRotation] = 2315 mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] = 2316 res.getDimensionPixelSize( 2317 com.android.internal.R.dimen.navigation_bar_height_car_mode); 2318 mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] = 2319 mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize( 2320 com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode); 2321 2322 // Width of the navigation bar when presented vertically along one side 2323 mNavigationBarWidthForRotationInCarMode[mPortraitRotation] = 2324 mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] = 2325 mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] = 2326 mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] = 2327 res.getDimensionPixelSize( 2328 com.android.internal.R.dimen.navigation_bar_width_car_mode); 2329 } 2330 2331 /** {@inheritDoc} */ 2332 @Override 2333 public int windowTypeToLayerLw(int type) { 2334 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { 2335 return 2; 2336 } 2337 switch (type) { 2338 case TYPE_PRIVATE_PRESENTATION: 2339 return 2; 2340 case TYPE_WALLPAPER: 2341 // wallpaper is at the bottom, though the window manager may move it. 2342 return 2; 2343 case TYPE_DOCK_DIVIDER: 2344 return 2; 2345 case TYPE_QS_DIALOG: 2346 return 2; 2347 case TYPE_PHONE: 2348 return 3; 2349 case TYPE_SEARCH_BAR: 2350 case TYPE_VOICE_INTERACTION_STARTING: 2351 return 4; 2352 case TYPE_VOICE_INTERACTION: 2353 // voice interaction layer is almost immediately above apps. 2354 return 5; 2355 case TYPE_INPUT_CONSUMER: 2356 return 6; 2357 case TYPE_SYSTEM_DIALOG: 2358 return 7; 2359 case TYPE_TOAST: 2360 // toasts and the plugged-in battery thing 2361 return 8; 2362 case TYPE_PRIORITY_PHONE: 2363 // SIM errors and unlock. Not sure if this really should be in a high layer. 2364 return 9; 2365 case TYPE_DREAM: 2366 // used for Dreams (screensavers with TYPE_DREAM windows) 2367 return 10; 2368 case TYPE_SYSTEM_ALERT: 2369 // like the ANR / app crashed dialogs 2370 return 11; 2371 case TYPE_INPUT_METHOD: 2372 // on-screen keyboards and other such input method user interfaces go here. 2373 return 12; 2374 case TYPE_INPUT_METHOD_DIALOG: 2375 // on-screen keyboards and other such input method user interfaces go here. 2376 return 13; 2377 case TYPE_KEYGUARD_SCRIM: 2378 // the safety window that shows behind keyguard while keyguard is starting 2379 return 14; 2380 case TYPE_STATUS_BAR_SUB_PANEL: 2381 return 15; 2382 case TYPE_STATUS_BAR: 2383 return 16; 2384 case TYPE_STATUS_BAR_PANEL: 2385 return 17; 2386 case TYPE_KEYGUARD_DIALOG: 2387 return 18; 2388 case TYPE_VOLUME_OVERLAY: 2389 // the on-screen volume indicator and controller shown when the user 2390 // changes the device volume 2391 return 19; 2392 case TYPE_SYSTEM_OVERLAY: 2393 // the on-screen volume indicator and controller shown when the user 2394 // changes the device volume 2395 return 20; 2396 case TYPE_NAVIGATION_BAR: 2397 // the navigation bar, if available, shows atop most things 2398 return 21; 2399 case TYPE_NAVIGATION_BAR_PANEL: 2400 // some panels (e.g. search) need to show on top of the navigation bar 2401 return 22; 2402 case TYPE_SCREENSHOT: 2403 // screenshot selection layer shouldn't go above system error, but it should cover 2404 // navigation bars at the very least. 2405 return 23; 2406 case TYPE_SYSTEM_ERROR: 2407 // system-level error dialogs 2408 return 24; 2409 case TYPE_MAGNIFICATION_OVERLAY: 2410 // used to highlight the magnified portion of a display 2411 return 25; 2412 case TYPE_DISPLAY_OVERLAY: 2413 // used to simulate secondary display devices 2414 return 26; 2415 case TYPE_DRAG: 2416 // the drag layer: input for drag-and-drop is associated with this window, 2417 // which sits above all other focusable windows 2418 return 27; 2419 case TYPE_ACCESSIBILITY_OVERLAY: 2420 // overlay put by accessibility services to intercept user interaction 2421 return 28; 2422 case TYPE_SECURE_SYSTEM_OVERLAY: 2423 return 29; 2424 case TYPE_BOOT_PROGRESS: 2425 return 30; 2426 case TYPE_POINTER: 2427 // the (mouse) pointer layer 2428 return 31; 2429 } 2430 Log.e(TAG, "Unknown window type: " + type); 2431 return 2; 2432 } 2433 2434 /** {@inheritDoc} */ 2435 @Override 2436 public int subWindowTypeToLayerLw(int type) { 2437 switch (type) { 2438 case TYPE_APPLICATION_PANEL: 2439 case TYPE_APPLICATION_ATTACHED_DIALOG: 2440 return APPLICATION_PANEL_SUBLAYER; 2441 case TYPE_APPLICATION_MEDIA: 2442 return APPLICATION_MEDIA_SUBLAYER; 2443 case TYPE_APPLICATION_MEDIA_OVERLAY: 2444 return APPLICATION_MEDIA_OVERLAY_SUBLAYER; 2445 case TYPE_APPLICATION_SUB_PANEL: 2446 return APPLICATION_SUB_PANEL_SUBLAYER; 2447 case TYPE_APPLICATION_ABOVE_SUB_PANEL: 2448 return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER; 2449 } 2450 Log.e(TAG, "Unknown sub-window type: " + type); 2451 return 0; 2452 } 2453 2454 @Override 2455 public int getMaxWallpaperLayer() { 2456 return windowTypeToLayerLw(TYPE_STATUS_BAR); 2457 } 2458 2459 private int getNavigationBarWidth(int rotation, int uiMode) { 2460 if ((uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_CAR) { 2461 return mNavigationBarWidthForRotationInCarMode[rotation]; 2462 } else { 2463 return mNavigationBarWidthForRotationDefault[rotation]; 2464 } 2465 } 2466 2467 @Override 2468 public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, 2469 int uiMode) { 2470 if (mHasNavigationBar) { 2471 // For a basic navigation bar, when we are in landscape mode we place 2472 // the navigation bar to the side. 2473 if (mNavigationBarCanMove && fullWidth > fullHeight) { 2474 return fullWidth - getNavigationBarWidth(rotation, uiMode); 2475 } 2476 } 2477 return fullWidth; 2478 } 2479 2480 private int getNavigationBarHeight(int rotation, int uiMode) { 2481 if ((uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_CAR) { 2482 return mNavigationBarHeightForRotationInCarMode[rotation]; 2483 } else { 2484 return mNavigationBarHeightForRotationDefault[rotation]; 2485 } 2486 } 2487 2488 @Override 2489 public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, 2490 int uiMode) { 2491 if (mHasNavigationBar) { 2492 // For a basic navigation bar, when we are in portrait mode we place 2493 // the navigation bar to the bottom. 2494 if (!mNavigationBarCanMove || fullWidth < fullHeight) { 2495 return fullHeight - getNavigationBarHeight(rotation, uiMode); 2496 } 2497 } 2498 return fullHeight; 2499 } 2500 2501 @Override 2502 public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) { 2503 return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode); 2504 } 2505 2506 @Override 2507 public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) { 2508 // There is a separate status bar at the top of the display. We don't count that as part 2509 // of the fixed decor, since it can hide; however, for purposes of configurations, 2510 // we do want to exclude it since applications can't generally use that part 2511 // of the screen. 2512 return getNonDecorDisplayHeight( 2513 fullWidth, fullHeight, rotation, uiMode) - mStatusBarHeight; 2514 } 2515 2516 @Override 2517 public boolean isForceHiding(WindowManager.LayoutParams attrs) { 2518 return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || 2519 (isKeyguardHostWindow(attrs) && 2520 (mKeyguardDelegate != null && mKeyguardDelegate.isShowing())) || 2521 (attrs.type == TYPE_KEYGUARD_SCRIM); 2522 } 2523 2524 @Override 2525 public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) { 2526 return attrs.type == TYPE_STATUS_BAR; 2527 } 2528 2529 @Override 2530 public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) { 2531 switch (attrs.type) { 2532 case TYPE_STATUS_BAR: 2533 case TYPE_NAVIGATION_BAR: 2534 case TYPE_WALLPAPER: 2535 case TYPE_DREAM: 2536 case TYPE_KEYGUARD_SCRIM: 2537 return false; 2538 default: 2539 // Hide only windows below the keyguard host window. 2540 return windowTypeToLayerLw(win.getBaseType()) 2541 < windowTypeToLayerLw(TYPE_STATUS_BAR); 2542 } 2543 } 2544 2545 @Override 2546 public WindowState getWinShowWhenLockedLw() { 2547 return mWinShowWhenLocked; 2548 } 2549 2550 /** {@inheritDoc} */ 2551 @Override 2552 public View addStartingWindow(IBinder appToken, String packageName, int theme, 2553 CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, 2554 int icon, int logo, int windowFlags, Configuration overrideConfig) { 2555 if (!SHOW_STARTING_ANIMATIONS) { 2556 return null; 2557 } 2558 if (packageName == null) { 2559 return null; 2560 } 2561 2562 WindowManager wm = null; 2563 View view = null; 2564 2565 try { 2566 Context context = mContext; 2567 if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "addStartingWindow " + packageName 2568 + ": nonLocalizedLabel=" + nonLocalizedLabel + " theme=" 2569 + Integer.toHexString(theme)); 2570 if (theme != context.getThemeResId() || labelRes != 0) { 2571 try { 2572 context = context.createPackageContext(packageName, 0); 2573 context.setTheme(theme); 2574 } catch (PackageManager.NameNotFoundException e) { 2575 // Ignore 2576 } 2577 } 2578 2579 if (overrideConfig != null && overrideConfig != EMPTY) { 2580 if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "addStartingWindow: creating context based" 2581 + " on overrideConfig" + overrideConfig + " for starting window"); 2582 final Context overrideContext = context.createConfigurationContext(overrideConfig); 2583 overrideContext.setTheme(theme); 2584 final TypedArray typedArray = overrideContext.obtainStyledAttributes( 2585 com.android.internal.R.styleable.Window); 2586 final int resId = typedArray.getResourceId(R.styleable.Window_windowBackground, 0); 2587 if (resId != 0 && overrideContext.getDrawable(resId) != null) { 2588 // We want to use the windowBackground for the override context if it is 2589 // available, otherwise we use the default one to make sure a themed starting 2590 // window is displayed for the app. 2591 if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "addStartingWindow: apply overrideConfig" 2592 + overrideConfig + " to starting window resId=" + resId); 2593 context = overrideContext; 2594 } 2595 } 2596 2597 final PhoneWindow win = new PhoneWindow(context); 2598 win.setIsStartingWindow(true); 2599 2600 CharSequence label = context.getResources().getText(labelRes, null); 2601 // Only change the accessibility title if the label is localized 2602 if (label != null) { 2603 win.setTitle(label, true); 2604 } else { 2605 win.setTitle(nonLocalizedLabel, false); 2606 } 2607 2608 win.setType( 2609 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING); 2610 2611 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 2612 // Assumes it's safe to show starting windows of launched apps while 2613 // the keyguard is being hidden. This is okay because starting windows never show 2614 // secret information. 2615 if (mKeyguardHidden) { 2616 windowFlags |= FLAG_SHOW_WHEN_LOCKED; 2617 } 2618 } 2619 2620 // Force the window flags: this is a fake window, so it is not really 2621 // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM 2622 // flag because we do know that the next window will take input 2623 // focus, so we want to get the IME window up on top of us right away. 2624 win.setFlags( 2625 windowFlags| 2626 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| 2627 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| 2628 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, 2629 windowFlags| 2630 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| 2631 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| 2632 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2633 2634 win.setDefaultIcon(icon); 2635 win.setDefaultLogo(logo); 2636 2637 win.setLayout(WindowManager.LayoutParams.MATCH_PARENT, 2638 WindowManager.LayoutParams.MATCH_PARENT); 2639 2640 final WindowManager.LayoutParams params = win.getAttributes(); 2641 params.token = appToken; 2642 params.packageName = packageName; 2643 params.windowAnimations = win.getWindowStyle().getResourceId( 2644 com.android.internal.R.styleable.Window_windowAnimationStyle, 0); 2645 params.privateFlags |= 2646 WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED; 2647 params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 2648 2649 if (!compatInfo.supportsScreen()) { 2650 params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 2651 } 2652 2653 params.setTitle("Starting " + packageName); 2654 2655 wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 2656 view = win.getDecorView(); 2657 2658 if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Adding starting window for " 2659 + packageName + " / " + appToken + ": " + (view.getParent() != null ? view : null)); 2660 2661 wm.addView(view, params); 2662 2663 // Only return the view if it was successfully added to the 2664 // window manager... which we can tell by it having a parent. 2665 return view.getParent() != null ? view : null; 2666 } catch (WindowManager.BadTokenException e) { 2667 // ignore 2668 Log.w(TAG, appToken + " already running, starting window not displayed. " + 2669 e.getMessage()); 2670 } catch (RuntimeException e) { 2671 // don't crash if something else bad happens, for example a 2672 // failure loading resources because we are loading from an app 2673 // on external storage that has been unmounted. 2674 Log.w(TAG, appToken + " failed creating starting window", e); 2675 } finally { 2676 if (view != null && view.getParent() == null) { 2677 Log.w(TAG, "view not successfully added to wm, removing view"); 2678 wm.removeViewImmediate(view); 2679 } 2680 } 2681 2682 return null; 2683 } 2684 2685 /** {@inheritDoc} */ 2686 @Override 2687 public void removeStartingWindow(IBinder appToken, View window) { 2688 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Removing starting window for " + appToken + ": " 2689 + window + " Callers=" + Debug.getCallers(4)); 2690 2691 if (window != null) { 2692 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); 2693 wm.removeView(window); 2694 } 2695 } 2696 2697 /** 2698 * Preflight adding a window to the system. 2699 * 2700 * Currently enforces that three window types are singletons: 2701 * <ul> 2702 * <li>STATUS_BAR_TYPE</li> 2703 * <li>KEYGUARD_TYPE</li> 2704 * </ul> 2705 * 2706 * @param win The window to be added 2707 * @param attrs Information about the window to be added 2708 * 2709 * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons, 2710 * WindowManagerImpl.ADD_MULTIPLE_SINGLETON 2711 */ 2712 @Override 2713 public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) { 2714 switch (attrs.type) { 2715 case TYPE_STATUS_BAR: 2716 mContext.enforceCallingOrSelfPermission( 2717 android.Manifest.permission.STATUS_BAR_SERVICE, 2718 "PhoneWindowManager"); 2719 if (mStatusBar != null) { 2720 if (mStatusBar.isAlive()) { 2721 return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; 2722 } 2723 } 2724 mStatusBar = win; 2725 mStatusBarController.setWindow(win); 2726 break; 2727 case TYPE_NAVIGATION_BAR: 2728 mContext.enforceCallingOrSelfPermission( 2729 android.Manifest.permission.STATUS_BAR_SERVICE, 2730 "PhoneWindowManager"); 2731 if (mNavigationBar != null) { 2732 if (mNavigationBar.isAlive()) { 2733 return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; 2734 } 2735 } 2736 mNavigationBar = win; 2737 mNavigationBarController.setWindow(win); 2738 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar); 2739 break; 2740 case TYPE_NAVIGATION_BAR_PANEL: 2741 case TYPE_STATUS_BAR_PANEL: 2742 case TYPE_STATUS_BAR_SUB_PANEL: 2743 case TYPE_VOICE_INTERACTION_STARTING: 2744 mContext.enforceCallingOrSelfPermission( 2745 android.Manifest.permission.STATUS_BAR_SERVICE, 2746 "PhoneWindowManager"); 2747 break; 2748 case TYPE_KEYGUARD_SCRIM: 2749 if (mKeyguardScrim != null) { 2750 return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON; 2751 } 2752 mKeyguardScrim = win; 2753 break; 2754 } 2755 return WindowManagerGlobal.ADD_OKAY; 2756 } 2757 2758 /** {@inheritDoc} */ 2759 @Override 2760 public void removeWindowLw(WindowState win) { 2761 if (mStatusBar == win) { 2762 mStatusBar = null; 2763 mStatusBarController.setWindow(null); 2764 mKeyguardDelegate.showScrim(); 2765 } else if (mKeyguardScrim == win) { 2766 Log.v(TAG, "Removing keyguard scrim"); 2767 mKeyguardScrim = null; 2768 } if (mNavigationBar == win) { 2769 mNavigationBar = null; 2770 mNavigationBarController.setWindow(null); 2771 } 2772 } 2773 2774 static final boolean PRINT_ANIM = false; 2775 2776 /** {@inheritDoc} */ 2777 @Override 2778 public int selectAnimationLw(WindowState win, int transit) { 2779 if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win 2780 + ": transit=" + transit); 2781 if (win == mStatusBar) { 2782 boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; 2783 if (transit == TRANSIT_EXIT 2784 || transit == TRANSIT_HIDE) { 2785 return isKeyguard ? -1 : R.anim.dock_top_exit; 2786 } else if (transit == TRANSIT_ENTER 2787 || transit == TRANSIT_SHOW) { 2788 return isKeyguard ? -1 : R.anim.dock_top_enter; 2789 } 2790 } else if (win == mNavigationBar) { 2791 if (win.getAttrs().windowAnimations != 0) { 2792 return 0; 2793 } 2794 // This can be on either the bottom or the right or the left. 2795 if (mNavigationBarPosition == NAV_BAR_BOTTOM) { 2796 if (transit == TRANSIT_EXIT 2797 || transit == TRANSIT_HIDE) { 2798 return R.anim.dock_bottom_exit; 2799 } else if (transit == TRANSIT_ENTER 2800 || transit == TRANSIT_SHOW) { 2801 return R.anim.dock_bottom_enter; 2802 } 2803 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) { 2804 if (transit == TRANSIT_EXIT 2805 || transit == TRANSIT_HIDE) { 2806 return R.anim.dock_right_exit; 2807 } else if (transit == TRANSIT_ENTER 2808 || transit == TRANSIT_SHOW) { 2809 return R.anim.dock_right_enter; 2810 } 2811 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 2812 if (transit == TRANSIT_EXIT 2813 || transit == TRANSIT_HIDE) { 2814 return R.anim.dock_left_exit; 2815 } else if (transit == TRANSIT_ENTER 2816 || transit == TRANSIT_SHOW) { 2817 return R.anim.dock_left_enter; 2818 } 2819 } 2820 } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) { 2821 return selectDockedDividerAnimationLw(win, transit); 2822 } 2823 2824 if (transit == TRANSIT_PREVIEW_DONE) { 2825 if (win.hasAppShownWindows()) { 2826 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT"); 2827 return com.android.internal.R.anim.app_starting_exit; 2828 } 2829 } else if (win.getAttrs().type == TYPE_DREAM && mDreamingLockscreen 2830 && transit == TRANSIT_ENTER) { 2831 // Special case: we are animating in a dream, while the keyguard 2832 // is shown. We don't want an animation on the dream, because 2833 // we need it shown immediately with the keyguard animating away 2834 // to reveal it. 2835 return -1; 2836 } 2837 2838 return 0; 2839 } 2840 2841 private int selectDockedDividerAnimationLw(WindowState win, int transit) { 2842 int insets = mWindowManagerFuncs.getDockedDividerInsetsLw(); 2843 2844 // If the divider is behind the navigation bar, don't animate. 2845 final Rect frame = win.getFrameLw(); 2846 final boolean behindNavBar = mNavigationBar != null 2847 && ((mNavigationBarPosition == NAV_BAR_BOTTOM 2848 && frame.top + insets >= mNavigationBar.getFrameLw().top) 2849 || (mNavigationBarPosition == NAV_BAR_RIGHT 2850 && frame.left + insets >= mNavigationBar.getFrameLw().left) 2851 || (mNavigationBarPosition == NAV_BAR_LEFT 2852 && frame.right - insets <= mNavigationBar.getFrameLw().right)); 2853 final boolean landscape = frame.height() > frame.width(); 2854 final boolean offscreenLandscape = landscape && (frame.right - insets <= 0 2855 || frame.left + insets >= win.getDisplayFrameLw().right); 2856 final boolean offscreenPortrait = !landscape && (frame.top - insets <= 0 2857 || frame.bottom + insets >= win.getDisplayFrameLw().bottom); 2858 final boolean offscreen = offscreenLandscape || offscreenPortrait; 2859 if (behindNavBar || offscreen) { 2860 return 0; 2861 } 2862 if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) { 2863 return R.anim.fade_in; 2864 } else if (transit == TRANSIT_EXIT) { 2865 return R.anim.fade_out; 2866 } else { 2867 return 0; 2868 } 2869 } 2870 2871 @Override 2872 public void selectRotationAnimationLw(int anim[]) { 2873 if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen=" 2874 + mTopFullscreenOpaqueWindowState + " rotationAnimation=" 2875 + (mTopFullscreenOpaqueWindowState == null ? 2876 "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation)); 2877 if (mTopFullscreenOpaqueWindowState != null && mTopIsFullscreen) { 2878 switch (mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation) { 2879 case ROTATION_ANIMATION_CROSSFADE: 2880 anim[0] = R.anim.rotation_animation_xfade_exit; 2881 anim[1] = R.anim.rotation_animation_enter; 2882 break; 2883 case ROTATION_ANIMATION_JUMPCUT: 2884 anim[0] = R.anim.rotation_animation_jump_exit; 2885 anim[1] = R.anim.rotation_animation_enter; 2886 break; 2887 case ROTATION_ANIMATION_ROTATE: 2888 default: 2889 anim[0] = anim[1] = 0; 2890 break; 2891 } 2892 } else { 2893 anim[0] = anim[1] = 0; 2894 } 2895 } 2896 2897 @Override 2898 public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId, 2899 boolean forceDefault) { 2900 switch (exitAnimId) { 2901 case R.anim.rotation_animation_xfade_exit: 2902 case R.anim.rotation_animation_jump_exit: 2903 // These are the only cases that matter. 2904 if (forceDefault) { 2905 return false; 2906 } 2907 int anim[] = new int[2]; 2908 selectRotationAnimationLw(anim); 2909 return (exitAnimId == anim[0] && enterAnimId == anim[1]); 2910 default: 2911 return true; 2912 } 2913 } 2914 2915 @Override 2916 public Animation createForceHideEnterAnimation(boolean onWallpaper, 2917 boolean goingToNotificationShade) { 2918 if (goingToNotificationShade) { 2919 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in); 2920 } 2921 2922 AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ? 2923 R.anim.lock_screen_behind_enter_wallpaper : 2924 R.anim.lock_screen_behind_enter); 2925 2926 // TODO: Use XML interpolators when we have log interpolators available in XML. 2927 final List<Animation> animations = set.getAnimations(); 2928 for (int i = animations.size() - 1; i >= 0; --i) { 2929 animations.get(i).setInterpolator(mLogDecelerateInterpolator); 2930 } 2931 2932 return set; 2933 } 2934 2935 2936 @Override 2937 public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade) { 2938 if (goingToNotificationShade) { 2939 return null; 2940 } else { 2941 return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit); 2942 } 2943 } 2944 2945 private static void awakenDreams() { 2946 IDreamManager dreamManager = getDreamManager(); 2947 if (dreamManager != null) { 2948 try { 2949 dreamManager.awaken(); 2950 } catch (RemoteException e) { 2951 // fine, stay asleep then 2952 } 2953 } 2954 } 2955 2956 static IDreamManager getDreamManager() { 2957 return IDreamManager.Stub.asInterface( 2958 ServiceManager.checkService(DreamService.DREAM_SERVICE)); 2959 } 2960 2961 TelecomManager getTelecommService() { 2962 return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 2963 } 2964 2965 static IAudioService getAudioService() { 2966 IAudioService audioService = IAudioService.Stub.asInterface( 2967 ServiceManager.checkService(Context.AUDIO_SERVICE)); 2968 if (audioService == null) { 2969 Log.w(TAG, "Unable to find IAudioService interface."); 2970 } 2971 return audioService; 2972 } 2973 2974 boolean keyguardOn() { 2975 return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode(); 2976 } 2977 2978 private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = { 2979 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 2980 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, 2981 }; 2982 2983 /** {@inheritDoc} */ 2984 @Override 2985 public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) { 2986 final boolean keyguardOn = keyguardOn(); 2987 final int keyCode = event.getKeyCode(); 2988 final int repeatCount = event.getRepeatCount(); 2989 final int metaState = event.getMetaState(); 2990 final int flags = event.getFlags(); 2991 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 2992 final boolean canceled = event.isCanceled(); 2993 2994 if (DEBUG_INPUT) { 2995 Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount=" 2996 + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed 2997 + " canceled=" + canceled); 2998 } 2999 3000 // If we think we might have a volume down & power key chord on the way 3001 // but we're not sure, then tell the dispatcher to wait a little while and 3002 // try again later before dispatching. 3003 if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) { 3004 if (mScreenshotChordVolumeDownKeyTriggered && !mScreenshotChordPowerKeyTriggered) { 3005 final long now = SystemClock.uptimeMillis(); 3006 final long timeoutTime = mScreenshotChordVolumeDownKeyTime 3007 + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS; 3008 if (now < timeoutTime) { 3009 return timeoutTime - now; 3010 } 3011 } 3012 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 3013 && mScreenshotChordVolumeDownKeyConsumed) { 3014 if (!down) { 3015 mScreenshotChordVolumeDownKeyConsumed = false; 3016 } 3017 return -1; 3018 } 3019 } 3020 3021 // Cancel any pending meta actions if we see any other keys being pressed between the down 3022 // of the meta key and its corresponding up. 3023 if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) { 3024 mPendingMetaAction = false; 3025 } 3026 // Any key that is not Alt or Meta cancels Caps Lock combo tracking. 3027 if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) { 3028 mPendingCapsLockToggle = false; 3029 } 3030 3031 // First we always handle the home key here, so applications 3032 // can never break it, although if keyguard is on, we do let 3033 // it handle it, because that gives us the correct 5 second 3034 // timeout. 3035 if (keyCode == KeyEvent.KEYCODE_HOME) { 3036 3037 // If we have released the home key, and didn't do anything else 3038 // while it was pressed, then it is time to go home! 3039 if (!down) { 3040 cancelPreloadRecentApps(); 3041 3042 mHomePressed = false; 3043 if (mHomeConsumed) { 3044 mHomeConsumed = false; 3045 return -1; 3046 } 3047 3048 if (canceled) { 3049 Log.i(TAG, "Ignoring HOME; event canceled."); 3050 return -1; 3051 } 3052 3053 // If an incoming call is ringing, HOME is totally disabled. 3054 // (The user is already on the InCallUI at this point, 3055 // and his ONLY options are to answer or reject the call.) 3056 TelecomManager telecomManager = getTelecommService(); 3057 if (telecomManager != null && telecomManager.isRinging()) { 3058 Log.i(TAG, "Ignoring HOME; there's a ringing incoming call."); 3059 return -1; 3060 } 3061 3062 // Delay handling home if a double-tap is possible. 3063 if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) { 3064 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case 3065 mHomeDoubleTapPending = true; 3066 mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable, 3067 ViewConfiguration.getDoubleTapTimeout()); 3068 return -1; 3069 } 3070 3071 handleShortPressOnHome(); 3072 return -1; 3073 } 3074 3075 // If a system window has focus, then it doesn't make sense 3076 // right now to interact with applications. 3077 WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null; 3078 if (attrs != null) { 3079 final int type = attrs.type; 3080 if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM 3081 || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG 3082 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 3083 // the "app" is keyguard, so give it the key 3084 return 0; 3085 } 3086 final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length; 3087 for (int i=0; i<typeCount; i++) { 3088 if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) { 3089 // don't do anything, but also don't pass it to the app 3090 return -1; 3091 } 3092 } 3093 } 3094 3095 // Remember that home is pressed and handle special actions. 3096 if (repeatCount == 0) { 3097 mHomePressed = true; 3098 if (mHomeDoubleTapPending) { 3099 mHomeDoubleTapPending = false; 3100 mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); 3101 handleDoubleTapOnHome(); 3102 } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI 3103 || mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) { 3104 preloadRecentApps(); 3105 } 3106 } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) { 3107 if (!keyguardOn) { 3108 handleLongPressOnHome(event.getDeviceId()); 3109 } 3110 } 3111 return -1; 3112 } else if (keyCode == KeyEvent.KEYCODE_MENU) { 3113 // Hijack modified menu keys for debugging features 3114 final int chordBug = KeyEvent.META_SHIFT_ON; 3115 3116 if (down && repeatCount == 0) { 3117 if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) { 3118 Intent intent = new Intent(Intent.ACTION_BUG_REPORT); 3119 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, 3120 null, null, null, 0, null, null); 3121 return -1; 3122 } else if (SHOW_PROCESSES_ON_ALT_MENU && 3123 (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) { 3124 Intent service = new Intent(); 3125 service.setClassName(mContext, "com.android.server.LoadAverageService"); 3126 ContentResolver res = mContext.getContentResolver(); 3127 boolean shown = Settings.Global.getInt( 3128 res, Settings.Global.SHOW_PROCESSES, 0) != 0; 3129 if (!shown) { 3130 mContext.startService(service); 3131 } else { 3132 mContext.stopService(service); 3133 } 3134 Settings.Global.putInt( 3135 res, Settings.Global.SHOW_PROCESSES, shown ? 0 : 1); 3136 return -1; 3137 } 3138 } 3139 } else if (keyCode == KeyEvent.KEYCODE_SEARCH) { 3140 if (down) { 3141 if (repeatCount == 0) { 3142 mSearchKeyShortcutPending = true; 3143 mConsumeSearchKeyUp = false; 3144 } 3145 } else { 3146 mSearchKeyShortcutPending = false; 3147 if (mConsumeSearchKeyUp) { 3148 mConsumeSearchKeyUp = false; 3149 return -1; 3150 } 3151 } 3152 return 0; 3153 } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) { 3154 if (!keyguardOn) { 3155 if (down && repeatCount == 0) { 3156 preloadRecentApps(); 3157 } else if (!down) { 3158 toggleRecentApps(); 3159 } 3160 } 3161 return -1; 3162 } else if (keyCode == KeyEvent.KEYCODE_N && event.isMetaPressed()) { 3163 if (down) { 3164 IStatusBarService service = getStatusBarService(); 3165 if (service != null) { 3166 try { 3167 service.expandNotificationsPanel(); 3168 } catch (RemoteException e) { 3169 // do nothing. 3170 } 3171 } 3172 } 3173 } else if (keyCode == KeyEvent.KEYCODE_S && event.isMetaPressed() 3174 && event.isCtrlPressed()) { 3175 if (down && repeatCount == 0) { 3176 int type = event.isShiftPressed() ? TAKE_SCREENSHOT_SELECTED_REGION 3177 : TAKE_SCREENSHOT_FULLSCREEN; 3178 mScreenshotRunnable.setScreenshotType(type); 3179 mHandler.post(mScreenshotRunnable); 3180 return -1; 3181 } 3182 } else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) { 3183 if (down && repeatCount == 0 && !isKeyguardLocked()) { 3184 toggleKeyboardShortcutsMenu(event.getDeviceId()); 3185 } 3186 } else if (keyCode == KeyEvent.KEYCODE_ASSIST) { 3187 if (down) { 3188 if (repeatCount == 0) { 3189 mAssistKeyLongPressed = false; 3190 } else if (repeatCount == 1) { 3191 mAssistKeyLongPressed = true; 3192 if (!keyguardOn) { 3193 launchAssistLongPressAction(); 3194 } 3195 } 3196 } else { 3197 if (mAssistKeyLongPressed) { 3198 mAssistKeyLongPressed = false; 3199 } else { 3200 if (!keyguardOn) { 3201 launchAssistAction(null, event.getDeviceId()); 3202 } 3203 } 3204 } 3205 return -1; 3206 } else if (keyCode == KeyEvent.KEYCODE_VOICE_ASSIST) { 3207 if (!down) { 3208 Intent voiceIntent; 3209 if (!keyguardOn) { 3210 voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH); 3211 } else { 3212 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface( 3213 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 3214 if (dic != null) { 3215 try { 3216 dic.exitIdle("voice-search"); 3217 } catch (RemoteException e) { 3218 } 3219 } 3220 voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 3221 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, true); 3222 } 3223 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 3224 } 3225 } else if (keyCode == KeyEvent.KEYCODE_SYSRQ) { 3226 if (down && repeatCount == 0) { 3227 mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN); 3228 mHandler.post(mScreenshotRunnable); 3229 } 3230 return -1; 3231 } else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP 3232 || keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) { 3233 if (down) { 3234 int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1; 3235 3236 // Disable autobrightness if it's on 3237 int auto = Settings.System.getIntForUser( 3238 mContext.getContentResolver(), 3239 Settings.System.SCREEN_BRIGHTNESS_MODE, 3240 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, 3241 UserHandle.USER_CURRENT_OR_SELF); 3242 if (auto != 0) { 3243 Settings.System.putIntForUser(mContext.getContentResolver(), 3244 Settings.System.SCREEN_BRIGHTNESS_MODE, 3245 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, 3246 UserHandle.USER_CURRENT_OR_SELF); 3247 } 3248 3249 int min = mPowerManager.getMinimumScreenBrightnessSetting(); 3250 int max = mPowerManager.getMaximumScreenBrightnessSetting(); 3251 int step = (max - min + BRIGHTNESS_STEPS - 1) / BRIGHTNESS_STEPS * direction; 3252 int brightness = Settings.System.getIntForUser(mContext.getContentResolver(), 3253 Settings.System.SCREEN_BRIGHTNESS, 3254 mPowerManager.getDefaultScreenBrightnessSetting(), 3255 UserHandle.USER_CURRENT_OR_SELF); 3256 brightness += step; 3257 // Make sure we don't go beyond the limits. 3258 brightness = Math.min(max, brightness); 3259 brightness = Math.max(min, brightness); 3260 3261 Settings.System.putIntForUser(mContext.getContentResolver(), 3262 Settings.System.SCREEN_BRIGHTNESS, brightness, 3263 UserHandle.USER_CURRENT_OR_SELF); 3264 startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG), 3265 UserHandle.CURRENT_OR_SELF); 3266 } 3267 return -1; 3268 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP 3269 || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 3270 || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) { 3271 if (mUseTvRouting) { 3272 // On TVs volume keys never go to the foreground app. 3273 dispatchDirectAudioEvent(event); 3274 return -1; 3275 } 3276 } 3277 3278 // Toggle Caps Lock on META-ALT. 3279 boolean actionTriggered = false; 3280 if (KeyEvent.isModifierKey(keyCode)) { 3281 if (!mPendingCapsLockToggle) { 3282 // Start tracking meta state for combo. 3283 mInitialMetaState = mMetaState; 3284 mPendingCapsLockToggle = true; 3285 } else if (event.getAction() == KeyEvent.ACTION_UP) { 3286 int altOnMask = mMetaState & KeyEvent.META_ALT_MASK; 3287 int metaOnMask = mMetaState & KeyEvent.META_META_MASK; 3288 3289 // Check for Caps Lock toggle 3290 if ((metaOnMask != 0) && (altOnMask != 0)) { 3291 // Check if nothing else is pressed 3292 if (mInitialMetaState == (mMetaState ^ (altOnMask | metaOnMask))) { 3293 // Handle Caps Lock Toggle 3294 mInputManagerInternal.toggleCapsLock(event.getDeviceId()); 3295 actionTriggered = true; 3296 } 3297 } 3298 3299 // Always stop tracking when key goes up. 3300 mPendingCapsLockToggle = false; 3301 } 3302 } 3303 // Store current meta state to be able to evaluate it later. 3304 mMetaState = metaState; 3305 3306 if (actionTriggered) { 3307 return -1; 3308 } 3309 3310 if (KeyEvent.isMetaKey(keyCode)) { 3311 if (down) { 3312 mPendingMetaAction = true; 3313 } else if (mPendingMetaAction) { 3314 launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, event.getDeviceId()); 3315 } 3316 return -1; 3317 } 3318 3319 // Shortcuts are invoked through Search+key, so intercept those here 3320 // Any printing key that is chorded with Search should be consumed 3321 // even if no shortcut was invoked. This prevents text from being 3322 // inadvertently inserted when using a keyboard that has built-in macro 3323 // shortcut keys (that emit Search+x) and some of them are not registered. 3324 if (mSearchKeyShortcutPending) { 3325 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3326 if (kcm.isPrintingKey(keyCode)) { 3327 mConsumeSearchKeyUp = true; 3328 mSearchKeyShortcutPending = false; 3329 if (down && repeatCount == 0 && !keyguardOn) { 3330 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState); 3331 if (shortcutIntent != null) { 3332 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3333 try { 3334 startActivityAsUser(shortcutIntent, UserHandle.CURRENT); 3335 dismissKeyboardShortcutsMenu(); 3336 } catch (ActivityNotFoundException ex) { 3337 Slog.w(TAG, "Dropping shortcut key combination because " 3338 + "the activity to which it is registered was not found: " 3339 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex); 3340 } 3341 } else { 3342 Slog.i(TAG, "Dropping unregistered shortcut key combination: " 3343 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode)); 3344 } 3345 } 3346 return -1; 3347 } 3348 } 3349 3350 // Invoke shortcuts using Meta. 3351 if (down && repeatCount == 0 && !keyguardOn 3352 && (metaState & KeyEvent.META_META_ON) != 0) { 3353 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3354 if (kcm.isPrintingKey(keyCode)) { 3355 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, 3356 metaState & ~(KeyEvent.META_META_ON 3357 | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON)); 3358 if (shortcutIntent != null) { 3359 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3360 try { 3361 startActivityAsUser(shortcutIntent, UserHandle.CURRENT); 3362 dismissKeyboardShortcutsMenu(); 3363 } catch (ActivityNotFoundException ex) { 3364 Slog.w(TAG, "Dropping shortcut key combination because " 3365 + "the activity to which it is registered was not found: " 3366 + "META+" + KeyEvent.keyCodeToString(keyCode), ex); 3367 } 3368 return -1; 3369 } 3370 } 3371 } 3372 3373 // Handle application launch keys. 3374 if (down && repeatCount == 0 && !keyguardOn) { 3375 String category = sApplicationLaunchKeyCategories.get(keyCode); 3376 if (category != null) { 3377 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category); 3378 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3379 try { 3380 startActivityAsUser(intent, UserHandle.CURRENT); 3381 dismissKeyboardShortcutsMenu(); 3382 } catch (ActivityNotFoundException ex) { 3383 Slog.w(TAG, "Dropping application launch key because " 3384 + "the activity to which it is registered was not found: " 3385 + "keyCode=" + keyCode + ", category=" + category, ex); 3386 } 3387 return -1; 3388 } 3389 } 3390 3391 // Display task switcher for ALT-TAB. 3392 if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) { 3393 if (mRecentAppsHeldModifiers == 0 && !keyguardOn && isUserSetupComplete()) { 3394 final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK; 3395 if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)) { 3396 mRecentAppsHeldModifiers = shiftlessModifiers; 3397 showRecentApps(true, false); 3398 return -1; 3399 } 3400 } 3401 } else if (!down && mRecentAppsHeldModifiers != 0 3402 && (metaState & mRecentAppsHeldModifiers) == 0) { 3403 mRecentAppsHeldModifiers = 0; 3404 hideRecentApps(true, false); 3405 } 3406 3407 // Handle input method switching. 3408 if (down && repeatCount == 0 3409 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH 3410 || (keyCode == KeyEvent.KEYCODE_SPACE 3411 && (metaState & KeyEvent.META_META_MASK) != 0))) { 3412 final boolean forwardDirection = (metaState & KeyEvent.META_SHIFT_MASK) == 0; 3413 mWindowManagerFuncs.switchInputMethod(forwardDirection); 3414 return -1; 3415 } 3416 if (mLanguageSwitchKeyPressed && !down 3417 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH 3418 || keyCode == KeyEvent.KEYCODE_SPACE)) { 3419 mLanguageSwitchKeyPressed = false; 3420 return -1; 3421 } 3422 3423 if (isValidGlobalKey(keyCode) 3424 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) { 3425 return -1; 3426 } 3427 3428 if (down) { 3429 long shortcutCode = keyCode; 3430 if (event.isCtrlPressed()) { 3431 shortcutCode |= ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE; 3432 } 3433 3434 if (event.isAltPressed()) { 3435 shortcutCode |= ((long) KeyEvent.META_ALT_ON) << Integer.SIZE; 3436 } 3437 3438 if (event.isShiftPressed()) { 3439 shortcutCode |= ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE; 3440 } 3441 3442 if (event.isMetaPressed()) { 3443 shortcutCode |= ((long) KeyEvent.META_META_ON) << Integer.SIZE; 3444 } 3445 3446 IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode); 3447 if (shortcutService != null) { 3448 try { 3449 if (isUserSetupComplete()) { 3450 shortcutService.notifyShortcutKeyPressed(shortcutCode); 3451 } 3452 } catch (RemoteException e) { 3453 mShortcutKeyServices.delete(shortcutCode); 3454 } 3455 return -1; 3456 } 3457 } 3458 3459 // Reserve all the META modifier combos for system behavior 3460 if ((metaState & KeyEvent.META_META_ON) != 0) { 3461 return -1; 3462 } 3463 3464 // Let the application handle the key. 3465 return 0; 3466 } 3467 3468 /** {@inheritDoc} */ 3469 @Override 3470 public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) { 3471 // Note: This method is only called if the initial down was unhandled. 3472 if (DEBUG_INPUT) { 3473 Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction() 3474 + ", flags=" + event.getFlags() 3475 + ", keyCode=" + event.getKeyCode() 3476 + ", scanCode=" + event.getScanCode() 3477 + ", metaState=" + event.getMetaState() 3478 + ", repeatCount=" + event.getRepeatCount() 3479 + ", policyFlags=" + policyFlags); 3480 } 3481 3482 KeyEvent fallbackEvent = null; 3483 if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 3484 final KeyCharacterMap kcm = event.getKeyCharacterMap(); 3485 final int keyCode = event.getKeyCode(); 3486 final int metaState = event.getMetaState(); 3487 final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN 3488 && event.getRepeatCount() == 0; 3489 3490 // Check for fallback actions specified by the key character map. 3491 final FallbackAction fallbackAction; 3492 if (initialDown) { 3493 fallbackAction = kcm.getFallbackAction(keyCode, metaState); 3494 } else { 3495 fallbackAction = mFallbackActions.get(keyCode); 3496 } 3497 3498 if (fallbackAction != null) { 3499 if (DEBUG_INPUT) { 3500 Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode 3501 + " metaState=" + Integer.toHexString(fallbackAction.metaState)); 3502 } 3503 3504 final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK; 3505 fallbackEvent = KeyEvent.obtain( 3506 event.getDownTime(), event.getEventTime(), 3507 event.getAction(), fallbackAction.keyCode, 3508 event.getRepeatCount(), fallbackAction.metaState, 3509 event.getDeviceId(), event.getScanCode(), 3510 flags, event.getSource(), null); 3511 3512 if (!interceptFallback(win, fallbackEvent, policyFlags)) { 3513 fallbackEvent.recycle(); 3514 fallbackEvent = null; 3515 } 3516 3517 if (initialDown) { 3518 mFallbackActions.put(keyCode, fallbackAction); 3519 } else if (event.getAction() == KeyEvent.ACTION_UP) { 3520 mFallbackActions.remove(keyCode); 3521 fallbackAction.recycle(); 3522 } 3523 } 3524 } 3525 3526 if (DEBUG_INPUT) { 3527 if (fallbackEvent == null) { 3528 Slog.d(TAG, "No fallback."); 3529 } else { 3530 Slog.d(TAG, "Performing fallback: " + fallbackEvent); 3531 } 3532 } 3533 return fallbackEvent; 3534 } 3535 3536 private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) { 3537 int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags); 3538 if ((actions & ACTION_PASS_TO_USER) != 0) { 3539 long delayMillis = interceptKeyBeforeDispatching( 3540 win, fallbackEvent, policyFlags); 3541 if (delayMillis == 0) { 3542 return true; 3543 } 3544 } 3545 return false; 3546 } 3547 3548 @Override 3549 public void registerShortcutKey(long shortcutCode, IShortcutService shortcutService) 3550 throws RemoteException { 3551 synchronized (mLock) { 3552 IShortcutService service = mShortcutKeyServices.get(shortcutCode); 3553 if (service != null && service.asBinder().pingBinder()) { 3554 throw new RemoteException("Key already exists."); 3555 } 3556 3557 mShortcutKeyServices.put(shortcutCode, shortcutService); 3558 } 3559 } 3560 3561 private void launchAssistLongPressAction() { 3562 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); 3563 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 3564 3565 // launch the search activity 3566 Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); 3567 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3568 try { 3569 // TODO: This only stops the factory-installed search manager. 3570 // Need to formalize an API to handle others 3571 SearchManager searchManager = getSearchManager(); 3572 if (searchManager != null) { 3573 searchManager.stopSearch(); 3574 } 3575 startActivityAsUser(intent, UserHandle.CURRENT); 3576 } catch (ActivityNotFoundException e) { 3577 Slog.w(TAG, "No activity to handle assist long press action.", e); 3578 } 3579 } 3580 3581 private void launchAssistAction(String hint, int deviceId) { 3582 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); 3583 if (!isUserSetupComplete()) { 3584 // Disable opening assist window during setup 3585 return; 3586 } 3587 Bundle args = null; 3588 if (deviceId > Integer.MIN_VALUE) { 3589 args = new Bundle(); 3590 args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, deviceId); 3591 } 3592 if ((mContext.getResources().getConfiguration().uiMode 3593 & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) { 3594 // On TV, use legacy handling until assistants are implemented in the proper way. 3595 ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 3596 .launchLegacyAssist(hint, UserHandle.myUserId(), args); 3597 } else { 3598 if (hint != null) { 3599 if (args == null) { 3600 args = new Bundle(); 3601 } 3602 args.putBoolean(hint, true); 3603 } 3604 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3605 if (statusbar != null) { 3606 statusbar.startAssist(args); 3607 } 3608 } 3609 } 3610 3611 private void startActivityAsUser(Intent intent, UserHandle handle) { 3612 if (isUserSetupComplete()) { 3613 mContext.startActivityAsUser(intent, handle); 3614 } else { 3615 Slog.i(TAG, "Not starting activity because user setup is in progress: " + intent); 3616 } 3617 } 3618 3619 private SearchManager getSearchManager() { 3620 if (mSearchManager == null) { 3621 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 3622 } 3623 return mSearchManager; 3624 } 3625 3626 private void preloadRecentApps() { 3627 mPreloadedRecentApps = true; 3628 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3629 if (statusbar != null) { 3630 statusbar.preloadRecentApps(); 3631 } 3632 } 3633 3634 private void cancelPreloadRecentApps() { 3635 if (mPreloadedRecentApps) { 3636 mPreloadedRecentApps = false; 3637 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3638 if (statusbar != null) { 3639 statusbar.cancelPreloadRecentApps(); 3640 } 3641 } 3642 } 3643 3644 private void toggleRecentApps() { 3645 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 3646 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3647 if (statusbar != null) { 3648 statusbar.toggleRecentApps(); 3649 } 3650 } 3651 3652 @Override 3653 public void showRecentApps(boolean fromHome) { 3654 mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS); 3655 mHandler.obtainMessage(MSG_DISPATCH_SHOW_RECENTS, fromHome ? 1 : 0, 0).sendToTarget(); 3656 } 3657 3658 private void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) { 3659 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 3660 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3661 if (statusbar != null) { 3662 statusbar.showRecentApps(triggeredFromAltTab, fromHome); 3663 } 3664 } 3665 3666 private void toggleKeyboardShortcutsMenu(int deviceId) { 3667 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3668 if (statusbar != null) { 3669 statusbar.toggleKeyboardShortcutsMenu(deviceId); 3670 } 3671 } 3672 3673 private void dismissKeyboardShortcutsMenu() { 3674 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3675 if (statusbar != null) { 3676 statusbar.dismissKeyboardShortcutsMenu(); 3677 } 3678 } 3679 3680 private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) { 3681 mPreloadedRecentApps = false; // preloading no longer needs to be canceled 3682 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 3683 if (statusbar != null) { 3684 statusbar.hideRecentApps(triggeredFromAltTab, triggeredFromHome); 3685 } 3686 } 3687 3688 void launchHomeFromHotKey() { 3689 launchHomeFromHotKey(true /* awakenFromDreams */, true /*respectKeyguard*/); 3690 } 3691 3692 /** 3693 * A home key -> launch home action was detected. Take the appropriate action 3694 * given the situation with the keyguard. 3695 */ 3696 void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) { 3697 if (respectKeyguard) { 3698 if (isKeyguardShowingAndNotOccluded()) { 3699 // don't launch home if keyguard showing 3700 return; 3701 } 3702 3703 if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) { 3704 // when in keyguard restricted mode, must first verify unlock 3705 // before launching home 3706 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() { 3707 @Override 3708 public void onKeyguardExitResult(boolean success) { 3709 if (success) { 3710 try { 3711 ActivityManagerNative.getDefault().stopAppSwitches(); 3712 } catch (RemoteException e) { 3713 } 3714 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 3715 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); 3716 } 3717 } 3718 }); 3719 return; 3720 } 3721 } 3722 3723 // no keyguard stuff to worry about, just launch home! 3724 try { 3725 ActivityManagerNative.getDefault().stopAppSwitches(); 3726 } catch (RemoteException e) { 3727 } 3728 if (mRecentsVisible) { 3729 // Hide Recents and notify it to launch Home 3730 if (awakenFromDreams) { 3731 awakenDreams(); 3732 } 3733 hideRecentApps(false, true); 3734 } else { 3735 // Otherwise, just launch Home 3736 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); 3737 startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); 3738 } 3739 } 3740 3741 private final Runnable mClearHideNavigationFlag = new Runnable() { 3742 @Override 3743 public void run() { 3744 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 3745 // Clear flags. 3746 mForceClearedSystemUiFlags &= 3747 ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 3748 } 3749 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 3750 } 3751 }; 3752 3753 /** 3754 * Input handler used while nav bar is hidden. Captures any touch on the screen, 3755 * to determine when the nav bar should be shown and prevent applications from 3756 * receiving those touches. 3757 */ 3758 final class HideNavInputEventReceiver extends InputEventReceiver { 3759 public HideNavInputEventReceiver(InputChannel inputChannel, Looper looper) { 3760 super(inputChannel, looper); 3761 } 3762 3763 @Override 3764 public void onInputEvent(InputEvent event) { 3765 boolean handled = false; 3766 try { 3767 if (event instanceof MotionEvent 3768 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { 3769 final MotionEvent motionEvent = (MotionEvent)event; 3770 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 3771 // When the user taps down, we re-show the nav bar. 3772 boolean changed = false; 3773 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 3774 if (mInputConsumer == null) { 3775 return; 3776 } 3777 // Any user activity always causes us to show the 3778 // navigation controls, if they had been hidden. 3779 // We also clear the low profile and only content 3780 // flags so that tapping on the screen will atomically 3781 // restore all currently hidden screen decorations. 3782 int newVal = mResettingSystemUiFlags | 3783 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | 3784 View.SYSTEM_UI_FLAG_LOW_PROFILE | 3785 View.SYSTEM_UI_FLAG_FULLSCREEN; 3786 if (mResettingSystemUiFlags != newVal) { 3787 mResettingSystemUiFlags = newVal; 3788 changed = true; 3789 } 3790 // We don't allow the system's nav bar to be hidden 3791 // again for 1 second, to prevent applications from 3792 // spamming us and keeping it from being shown. 3793 newVal = mForceClearedSystemUiFlags | 3794 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; 3795 if (mForceClearedSystemUiFlags != newVal) { 3796 mForceClearedSystemUiFlags = newVal; 3797 changed = true; 3798 mHandler.postDelayed(mClearHideNavigationFlag, 1000); 3799 } 3800 } 3801 if (changed) { 3802 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 3803 } 3804 } 3805 } 3806 } finally { 3807 finishInputEvent(event, handled); 3808 } 3809 } 3810 } 3811 final InputEventReceiver.Factory mHideNavInputEventReceiverFactory = 3812 new InputEventReceiver.Factory() { 3813 @Override 3814 public InputEventReceiver createInputEventReceiver( 3815 InputChannel inputChannel, Looper looper) { 3816 return new HideNavInputEventReceiver(inputChannel, looper); 3817 } 3818 }; 3819 3820 @Override 3821 public int adjustSystemUiVisibilityLw(int visibility) { 3822 mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); 3823 mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); 3824 mRecentsVisible = (visibility & View.RECENT_APPS_VISIBLE) > 0; 3825 mTvPictureInPictureVisible = (visibility & View.TV_PICTURE_IN_PICTURE_VISIBLE) > 0; 3826 3827 // Reset any bits in mForceClearingStatusBarVisibility that 3828 // are now clear. 3829 mResettingSystemUiFlags &= visibility; 3830 // Clear any bits in the new visibility that are currently being 3831 // force cleared, before reporting it. 3832 return visibility & ~mResettingSystemUiFlags 3833 & ~mForceClearedSystemUiFlags; 3834 } 3835 3836 @Override 3837 public boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds, 3838 int displayRotation, int displayWidth, int displayHeight, Rect outContentInsets, 3839 Rect outStableInsets, Rect outOutsets) { 3840 final int fl = PolicyControl.getWindowFlags(null, attrs); 3841 final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs); 3842 final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility); 3843 3844 final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl); 3845 if (useOutsets) { 3846 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); 3847 if (outset > 0) { 3848 if (displayRotation == Surface.ROTATION_0) { 3849 outOutsets.bottom += outset; 3850 } else if (displayRotation == Surface.ROTATION_90) { 3851 outOutsets.right += outset; 3852 } else if (displayRotation == Surface.ROTATION_180) { 3853 outOutsets.top += outset; 3854 } else if (displayRotation == Surface.ROTATION_270) { 3855 outOutsets.left += outset; 3856 } 3857 } 3858 } 3859 3860 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) 3861 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { 3862 int availRight, availBottom; 3863 if (canHideNavigationBar() && 3864 (systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { 3865 availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 3866 availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 3867 } else { 3868 availRight = mRestrictedScreenLeft + mRestrictedScreenWidth; 3869 availBottom = mRestrictedScreenTop + mRestrictedScreenHeight; 3870 } 3871 if ((systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 3872 if ((fl & FLAG_FULLSCREEN) != 0) { 3873 outContentInsets.set(mStableFullscreenLeft, mStableFullscreenTop, 3874 availRight - mStableFullscreenRight, 3875 availBottom - mStableFullscreenBottom); 3876 } else { 3877 outContentInsets.set(mStableLeft, mStableTop, 3878 availRight - mStableRight, availBottom - mStableBottom); 3879 } 3880 } else if ((fl & FLAG_FULLSCREEN) != 0 || (fl & FLAG_LAYOUT_IN_OVERSCAN) != 0) { 3881 outContentInsets.setEmpty(); 3882 } else if ((systemUiVisibility & (View.SYSTEM_UI_FLAG_FULLSCREEN 3883 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)) == 0) { 3884 outContentInsets.set(mCurLeft, mCurTop, 3885 availRight - mCurRight, availBottom - mCurBottom); 3886 } else { 3887 outContentInsets.set(mCurLeft, mCurTop, 3888 availRight - mCurRight, availBottom - mCurBottom); 3889 } 3890 3891 outStableInsets.set(mStableLeft, mStableTop, 3892 availRight - mStableRight, availBottom - mStableBottom); 3893 if (taskBounds != null) { 3894 calculateRelevantTaskInsets(taskBounds, outContentInsets, 3895 displayWidth, displayHeight); 3896 calculateRelevantTaskInsets(taskBounds, outStableInsets, 3897 displayWidth, displayHeight); 3898 } 3899 return mForceShowSystemBars; 3900 } 3901 outContentInsets.setEmpty(); 3902 outStableInsets.setEmpty(); 3903 return mForceShowSystemBars; 3904 } 3905 3906 /** 3907 * For any given task bounds, the insets relevant for these bounds given the insets relevant 3908 * for the entire display. 3909 */ 3910 private void calculateRelevantTaskInsets(Rect taskBounds, Rect inOutInsets, int displayWidth, 3911 int displayHeight) { 3912 mTmpRect.set(0, 0, displayWidth, displayHeight); 3913 mTmpRect.inset(inOutInsets); 3914 mTmpRect.intersect(taskBounds); 3915 int leftInset = mTmpRect.left - taskBounds.left; 3916 int topInset = mTmpRect.top - taskBounds.top; 3917 int rightInset = taskBounds.right - mTmpRect.right; 3918 int bottomInset = taskBounds.bottom - mTmpRect.bottom; 3919 inOutInsets.set(leftInset, topInset, rightInset, bottomInset); 3920 } 3921 3922 private boolean shouldUseOutsets(WindowManager.LayoutParams attrs, int fl) { 3923 return attrs.type == TYPE_WALLPAPER || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN 3924 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0; 3925 } 3926 3927 /** {@inheritDoc} */ 3928 @Override 3929 public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight, 3930 int displayRotation, int uiMode) { 3931 mDisplayRotation = displayRotation; 3932 final int overscanLeft, overscanTop, overscanRight, overscanBottom; 3933 if (isDefaultDisplay) { 3934 switch (displayRotation) { 3935 case Surface.ROTATION_90: 3936 overscanLeft = mOverscanTop; 3937 overscanTop = mOverscanRight; 3938 overscanRight = mOverscanBottom; 3939 overscanBottom = mOverscanLeft; 3940 break; 3941 case Surface.ROTATION_180: 3942 overscanLeft = mOverscanRight; 3943 overscanTop = mOverscanBottom; 3944 overscanRight = mOverscanLeft; 3945 overscanBottom = mOverscanTop; 3946 break; 3947 case Surface.ROTATION_270: 3948 overscanLeft = mOverscanBottom; 3949 overscanTop = mOverscanLeft; 3950 overscanRight = mOverscanTop; 3951 overscanBottom = mOverscanRight; 3952 break; 3953 default: 3954 overscanLeft = mOverscanLeft; 3955 overscanTop = mOverscanTop; 3956 overscanRight = mOverscanRight; 3957 overscanBottom = mOverscanBottom; 3958 break; 3959 } 3960 } else { 3961 overscanLeft = 0; 3962 overscanTop = 0; 3963 overscanRight = 0; 3964 overscanBottom = 0; 3965 } 3966 mOverscanScreenLeft = mRestrictedOverscanScreenLeft = 0; 3967 mOverscanScreenTop = mRestrictedOverscanScreenTop = 0; 3968 mOverscanScreenWidth = mRestrictedOverscanScreenWidth = displayWidth; 3969 mOverscanScreenHeight = mRestrictedOverscanScreenHeight = displayHeight; 3970 mSystemLeft = 0; 3971 mSystemTop = 0; 3972 mSystemRight = displayWidth; 3973 mSystemBottom = displayHeight; 3974 mUnrestrictedScreenLeft = overscanLeft; 3975 mUnrestrictedScreenTop = overscanTop; 3976 mUnrestrictedScreenWidth = displayWidth - overscanLeft - overscanRight; 3977 mUnrestrictedScreenHeight = displayHeight - overscanTop - overscanBottom; 3978 mRestrictedScreenLeft = mUnrestrictedScreenLeft; 3979 mRestrictedScreenTop = mUnrestrictedScreenTop; 3980 mRestrictedScreenWidth = mSystemGestures.screenWidth = mUnrestrictedScreenWidth; 3981 mRestrictedScreenHeight = mSystemGestures.screenHeight = mUnrestrictedScreenHeight; 3982 mDockLeft = mContentLeft = mVoiceContentLeft = mStableLeft = mStableFullscreenLeft 3983 = mCurLeft = mUnrestrictedScreenLeft; 3984 mDockTop = mContentTop = mVoiceContentTop = mStableTop = mStableFullscreenTop 3985 = mCurTop = mUnrestrictedScreenTop; 3986 mDockRight = mContentRight = mVoiceContentRight = mStableRight = mStableFullscreenRight 3987 = mCurRight = displayWidth - overscanRight; 3988 mDockBottom = mContentBottom = mVoiceContentBottom = mStableBottom = mStableFullscreenBottom 3989 = mCurBottom = displayHeight - overscanBottom; 3990 mDockLayer = 0x10000000; 3991 mStatusBarLayer = -1; 3992 3993 // start with the current dock rect, which will be (0,0,displayWidth,displayHeight) 3994 final Rect pf = mTmpParentFrame; 3995 final Rect df = mTmpDisplayFrame; 3996 final Rect of = mTmpOverscanFrame; 3997 final Rect vf = mTmpVisibleFrame; 3998 final Rect dcf = mTmpDecorFrame; 3999 pf.left = df.left = of.left = vf.left = mDockLeft; 4000 pf.top = df.top = of.top = vf.top = mDockTop; 4001 pf.right = df.right = of.right = vf.right = mDockRight; 4002 pf.bottom = df.bottom = of.bottom = vf.bottom = mDockBottom; 4003 dcf.setEmpty(); // Decor frame N/A for system bars. 4004 4005 if (isDefaultDisplay) { 4006 // For purposes of putting out fake window up to steal focus, we will 4007 // drive nav being hidden only by whether it is requested. 4008 final int sysui = mLastSystemUiFlags; 4009 boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0; 4010 boolean navTranslucent = (sysui 4011 & (View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT)) != 0; 4012 boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; 4013 boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 4014 boolean navAllowedHidden = immersive || immersiveSticky; 4015 navTranslucent &= !immersiveSticky; // transient trumps translucent 4016 boolean isKeyguardShowing = isStatusBarKeyguard() && !mHideLockScreen; 4017 if (!isKeyguardShowing) { 4018 navTranslucent &= areTranslucentBarsAllowed(); 4019 } 4020 boolean statusBarExpandedNotKeyguard = !isKeyguardShowing && mStatusBar != null 4021 && mStatusBar.getAttrs().height == MATCH_PARENT 4022 && mStatusBar.getAttrs().width == MATCH_PARENT; 4023 4024 // When the navigation bar isn't visible, we put up a fake 4025 // input window to catch all touch events. This way we can 4026 // detect when the user presses anywhere to bring back the nav 4027 // bar and ensure the application doesn't see the event. 4028 if (navVisible || navAllowedHidden) { 4029 if (mInputConsumer != null) { 4030 mHandler.sendMessage( 4031 mHandler.obtainMessage(MSG_DISPOSE_INPUT_CONSUMER, mInputConsumer)); 4032 mInputConsumer = null; 4033 } 4034 } else if (mInputConsumer == null) { 4035 mInputConsumer = mWindowManagerFuncs.addInputConsumer(mHandler.getLooper(), 4036 mHideNavInputEventReceiverFactory); 4037 } 4038 4039 // For purposes of positioning and showing the nav bar, if we have 4040 // decided that it can't be hidden (because of the screen aspect ratio), 4041 // then take that into account. 4042 navVisible |= !canHideNavigationBar(); 4043 4044 boolean updateSysUiVisibility = layoutNavigationBar(displayWidth, displayHeight, 4045 displayRotation, uiMode, overscanLeft, overscanRight, overscanBottom, dcf, navVisible, navTranslucent, 4046 navAllowedHidden, statusBarExpandedNotKeyguard); 4047 if (DEBUG_LAYOUT) Slog.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)", 4048 mDockLeft, mDockTop, mDockRight, mDockBottom)); 4049 updateSysUiVisibility |= layoutStatusBar(pf, df, of, vf, dcf, sysui, isKeyguardShowing); 4050 if (updateSysUiVisibility) { 4051 updateSystemUiVisibilityLw(); 4052 } 4053 } 4054 } 4055 4056 private boolean layoutStatusBar(Rect pf, Rect df, Rect of, Rect vf, Rect dcf, int sysui, 4057 boolean isKeyguardShowing) { 4058 // decide where the status bar goes ahead of time 4059 if (mStatusBar != null) { 4060 // apply any navigation bar insets 4061 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4062 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4063 pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft; 4064 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight 4065 + mUnrestrictedScreenTop; 4066 vf.left = mStableLeft; 4067 vf.top = mStableTop; 4068 vf.right = mStableRight; 4069 vf.bottom = mStableBottom; 4070 4071 mStatusBarLayer = mStatusBar.getSurfaceLayer(); 4072 4073 // Let the status bar determine its size. 4074 mStatusBar.computeFrameLw(pf /* parentFrame */, df /* displayFrame */, 4075 vf /* overlayFrame */, vf /* contentFrame */, vf /* visibleFrame */, 4076 dcf /* decorFrame */, vf /* stableFrame */, vf /* outsetFrame */); 4077 4078 // For layout, the status bar is always at the top with our fixed height. 4079 mStableTop = mUnrestrictedScreenTop + mStatusBarHeight; 4080 4081 boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0; 4082 boolean statusBarTranslucent = (sysui 4083 & (View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT)) != 0; 4084 if (!isKeyguardShowing) { 4085 statusBarTranslucent &= areTranslucentBarsAllowed(); 4086 } 4087 4088 // If the status bar is hidden, we don't want to cause 4089 // windows behind it to scroll. 4090 if (mStatusBar.isVisibleLw() && !statusBarTransient) { 4091 // Status bar may go away, so the screen area it occupies 4092 // is available to apps but just covering them when the 4093 // status bar is visible. 4094 mDockTop = mUnrestrictedScreenTop + mStatusBarHeight; 4095 4096 mContentTop = mVoiceContentTop = mCurTop = mDockTop; 4097 mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; 4098 mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; 4099 mContentRight = mVoiceContentRight = mCurRight = mDockRight; 4100 4101 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " + 4102 String.format( 4103 "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]", 4104 mDockLeft, mDockTop, mDockRight, mDockBottom, 4105 mContentLeft, mContentTop, mContentRight, mContentBottom, 4106 mCurLeft, mCurTop, mCurRight, mCurBottom)); 4107 } 4108 if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw() 4109 && !statusBarTransient && !statusBarTranslucent 4110 && !mStatusBarController.wasRecentlyTranslucent()) { 4111 // If the opaque status bar is currently requested to be visible, 4112 // and not in the process of animating on or off, then 4113 // we can tell the app that it is covered by it. 4114 mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight; 4115 } 4116 if (mStatusBarController.checkHiddenLw()) { 4117 return true; 4118 } 4119 } 4120 return false; 4121 } 4122 4123 private boolean layoutNavigationBar(int displayWidth, int displayHeight, int displayRotation, 4124 int uiMode, int overscanLeft, int overscanRight, int overscanBottom, Rect dcf, 4125 boolean navVisible, boolean navTranslucent, boolean navAllowedHidden, 4126 boolean statusBarExpandedNotKeyguard) { 4127 if (mNavigationBar != null) { 4128 boolean transientNavBarShowing = mNavigationBarController.isTransientShowing(); 4129 // Force the navigation bar to its appropriate place and 4130 // size. We need to do this directly, instead of relying on 4131 // it to bubble up from the nav bar, because this needs to 4132 // change atomically with screen rotations. 4133 mNavigationBarPosition = navigationBarPosition(displayWidth, displayHeight, 4134 displayRotation); 4135 if (mNavigationBarPosition == NAV_BAR_BOTTOM) { 4136 // It's a system nav bar or a portrait screen; nav bar goes on bottom. 4137 int top = displayHeight - overscanBottom 4138 - getNavigationBarHeight(displayRotation, uiMode); 4139 mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom); 4140 mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top; 4141 if (transientNavBarShowing) { 4142 mNavigationBarController.setBarShowingLw(true); 4143 } else if (navVisible) { 4144 mNavigationBarController.setBarShowingLw(true); 4145 mDockBottom = mTmpNavigationFrame.top; 4146 mRestrictedScreenHeight = mDockBottom - mRestrictedScreenTop; 4147 mRestrictedOverscanScreenHeight = mDockBottom - mRestrictedOverscanScreenTop; 4148 } else { 4149 // We currently want to hide the navigation UI - unless we expanded the status 4150 // bar. 4151 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4152 } 4153 if (navVisible && !navTranslucent && !navAllowedHidden 4154 && !mNavigationBar.isAnimatingLw() 4155 && !mNavigationBarController.wasRecentlyTranslucent()) { 4156 // If the opaque nav bar is currently requested to be visible, 4157 // and not in the process of animating on or off, then 4158 // we can tell the app that it is covered by it. 4159 mSystemBottom = mTmpNavigationFrame.top; 4160 } 4161 } else if (mNavigationBarPosition == NAV_BAR_RIGHT) { 4162 // Landscape screen; nav bar goes to the right. 4163 int left = displayWidth - overscanRight 4164 - getNavigationBarWidth(displayRotation, uiMode); 4165 mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight); 4166 mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left; 4167 if (transientNavBarShowing) { 4168 mNavigationBarController.setBarShowingLw(true); 4169 } else if (navVisible) { 4170 mNavigationBarController.setBarShowingLw(true); 4171 mDockRight = mTmpNavigationFrame.left; 4172 mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft; 4173 mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft; 4174 } else { 4175 // We currently want to hide the navigation UI - unless we expanded the status 4176 // bar. 4177 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4178 } 4179 if (navVisible && !navTranslucent && !navAllowedHidden 4180 && !mNavigationBar.isAnimatingLw() 4181 && !mNavigationBarController.wasRecentlyTranslucent()) { 4182 // If the nav bar is currently requested to be visible, 4183 // and not in the process of animating on or off, then 4184 // we can tell the app that it is covered by it. 4185 mSystemRight = mTmpNavigationFrame.left; 4186 } 4187 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 4188 // Seascape screen; nav bar goes to the left. 4189 int right = overscanLeft + getNavigationBarWidth(displayRotation, uiMode); 4190 mTmpNavigationFrame.set(overscanLeft, 0, right, displayHeight); 4191 mStableLeft = mStableFullscreenLeft = mTmpNavigationFrame.right; 4192 if (transientNavBarShowing) { 4193 mNavigationBarController.setBarShowingLw(true); 4194 } else if (navVisible) { 4195 mNavigationBarController.setBarShowingLw(true); 4196 mDockLeft = mTmpNavigationFrame.right; 4197 // TODO: not so sure about those: 4198 mRestrictedScreenLeft = mRestrictedOverscanScreenLeft = mDockLeft; 4199 mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft; 4200 mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft; 4201 } else { 4202 // We currently want to hide the navigation UI - unless we expanded the status 4203 // bar. 4204 mNavigationBarController.setBarShowingLw(statusBarExpandedNotKeyguard); 4205 } 4206 if (navVisible && !navTranslucent && !navAllowedHidden 4207 && !mNavigationBar.isAnimatingLw() 4208 && !mNavigationBarController.wasRecentlyTranslucent()) { 4209 // If the nav bar is currently requested to be visible, 4210 // and not in the process of animating on or off, then 4211 // we can tell the app that it is covered by it. 4212 mSystemLeft = mTmpNavigationFrame.right; 4213 } 4214 } 4215 // Make sure the content and current rectangles are updated to 4216 // account for the restrictions from the navigation bar. 4217 mContentTop = mVoiceContentTop = mCurTop = mDockTop; 4218 mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; 4219 mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; 4220 mContentRight = mVoiceContentRight = mCurRight = mDockRight; 4221 mStatusBarLayer = mNavigationBar.getSurfaceLayer(); 4222 // And compute the final frame. 4223 mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, 4224 mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf, 4225 mTmpNavigationFrame, mTmpNavigationFrame); 4226 if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame); 4227 if (mNavigationBarController.checkHiddenLw()) { 4228 return true; 4229 } 4230 } 4231 return false; 4232 } 4233 4234 private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) { 4235 if (mNavigationBarCanMove && displayWidth > displayHeight) { 4236 if (displayRotation == Surface.ROTATION_270) { 4237 return NAV_BAR_LEFT; 4238 } else { 4239 return NAV_BAR_RIGHT; 4240 } 4241 } 4242 return NAV_BAR_BOTTOM; 4243 } 4244 4245 /** {@inheritDoc} */ 4246 @Override 4247 public int getSystemDecorLayerLw() { 4248 if (mStatusBar != null && mStatusBar.isVisibleLw()) { 4249 return mStatusBar.getSurfaceLayer(); 4250 } 4251 4252 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) { 4253 return mNavigationBar.getSurfaceLayer(); 4254 } 4255 4256 return 0; 4257 } 4258 4259 @Override 4260 public void getContentRectLw(Rect r) { 4261 r.set(mContentLeft, mContentTop, mContentRight, mContentBottom); 4262 } 4263 4264 void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached, 4265 boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf) { 4266 if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { 4267 // Here's a special case: if this attached window is a panel that is 4268 // above the dock window, and the window it is attached to is below 4269 // the dock window, then the frames we computed for the window it is 4270 // attached to can not be used because the dock is effectively part 4271 // of the underlying window and the attached window is floating on top 4272 // of the whole thing. So, we ignore the attached window and explicitly 4273 // compute the frames that would be appropriate without the dock. 4274 df.left = of.left = cf.left = vf.left = mDockLeft; 4275 df.top = of.top = cf.top = vf.top = mDockTop; 4276 df.right = of.right = cf.right = vf.right = mDockRight; 4277 df.bottom = of.bottom = cf.bottom = vf.bottom = mDockBottom; 4278 } else { 4279 // The effective display frame of the attached window depends on 4280 // whether it is taking care of insetting its content. If not, 4281 // we need to use the parent's content frame so that the entire 4282 // window is positioned within that content. Otherwise we can use 4283 // the overscan frame and let the attached window take care of 4284 // positioning its content appropriately. 4285 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4286 // Set the content frame of the attached window to the parent's decor frame 4287 // (same as content frame when IME isn't present) if specifically requested by 4288 // setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag. 4289 // Otherwise, use the overscan frame. 4290 cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0 4291 ? attached.getContentFrameLw() : attached.getOverscanFrameLw()); 4292 } else { 4293 // If the window is resizing, then we want to base the content 4294 // frame on our attached content frame to resize... however, 4295 // things can be tricky if the attached window is NOT in resize 4296 // mode, in which case its content frame will be larger. 4297 // Ungh. So to deal with that, make sure the content frame 4298 // we end up using is not covering the IM dock. 4299 cf.set(attached.getContentFrameLw()); 4300 if (attached.isVoiceInteraction()) { 4301 if (cf.left < mVoiceContentLeft) cf.left = mVoiceContentLeft; 4302 if (cf.top < mVoiceContentTop) cf.top = mVoiceContentTop; 4303 if (cf.right > mVoiceContentRight) cf.right = mVoiceContentRight; 4304 if (cf.bottom > mVoiceContentBottom) cf.bottom = mVoiceContentBottom; 4305 } else if (attached.getSurfaceLayer() < mDockLayer) { 4306 if (cf.left < mContentLeft) cf.left = mContentLeft; 4307 if (cf.top < mContentTop) cf.top = mContentTop; 4308 if (cf.right > mContentRight) cf.right = mContentRight; 4309 if (cf.bottom > mContentBottom) cf.bottom = mContentBottom; 4310 } 4311 } 4312 df.set(insetDecors ? attached.getDisplayFrameLw() : cf); 4313 of.set(insetDecors ? attached.getOverscanFrameLw() : cf); 4314 vf.set(attached.getVisibleFrameLw()); 4315 } 4316 // The LAYOUT_IN_SCREEN flag is used to determine whether the attached 4317 // window should be positioned relative to its parent or the entire 4318 // screen. 4319 pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 4320 ? attached.getFrameLw() : df); 4321 } 4322 4323 private void applyStableConstraints(int sysui, int fl, Rect r) { 4324 if ((sysui & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { 4325 // If app is requesting a stable layout, don't let the 4326 // content insets go below the stable values. 4327 if ((fl & FLAG_FULLSCREEN) != 0) { 4328 if (r.left < mStableFullscreenLeft) r.left = mStableFullscreenLeft; 4329 if (r.top < mStableFullscreenTop) r.top = mStableFullscreenTop; 4330 if (r.right > mStableFullscreenRight) r.right = mStableFullscreenRight; 4331 if (r.bottom > mStableFullscreenBottom) r.bottom = mStableFullscreenBottom; 4332 } else { 4333 if (r.left < mStableLeft) r.left = mStableLeft; 4334 if (r.top < mStableTop) r.top = mStableTop; 4335 if (r.right > mStableRight) r.right = mStableRight; 4336 if (r.bottom > mStableBottom) r.bottom = mStableBottom; 4337 } 4338 } 4339 } 4340 4341 private boolean canReceiveInput(WindowState win) { 4342 boolean notFocusable = 4343 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0; 4344 boolean altFocusableIm = 4345 (win.getAttrs().flags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0; 4346 boolean notFocusableForIm = notFocusable ^ altFocusableIm; 4347 return !notFocusableForIm; 4348 } 4349 4350 /** {@inheritDoc} */ 4351 @Override 4352 public void layoutWindowLw(WindowState win, WindowState attached) { 4353 // We've already done the navigation bar and status bar. If the status bar can receive 4354 // input, we need to layout it again to accomodate for the IME window. 4355 if ((win == mStatusBar && !canReceiveInput(win)) || win == mNavigationBar) { 4356 return; 4357 } 4358 final WindowManager.LayoutParams attrs = win.getAttrs(); 4359 final boolean isDefaultDisplay = win.isDefaultDisplay(); 4360 final boolean needsToOffsetInputMethodTarget = isDefaultDisplay && 4361 (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null); 4362 if (needsToOffsetInputMethodTarget) { 4363 if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state"); 4364 offsetInputMethodWindowLw(mLastInputMethodWindow); 4365 } 4366 4367 final int fl = PolicyControl.getWindowFlags(win, attrs); 4368 final int pfl = attrs.privateFlags; 4369 final int sim = attrs.softInputMode; 4370 final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null); 4371 4372 final Rect pf = mTmpParentFrame; 4373 final Rect df = mTmpDisplayFrame; 4374 final Rect of = mTmpOverscanFrame; 4375 final Rect cf = mTmpContentFrame; 4376 final Rect vf = mTmpVisibleFrame; 4377 final Rect dcf = mTmpDecorFrame; 4378 final Rect sf = mTmpStableFrame; 4379 Rect osf = null; 4380 dcf.setEmpty(); 4381 4382 final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar 4383 && mNavigationBar != null && mNavigationBar.isVisibleLw()); 4384 4385 final int adjust = sim & SOFT_INPUT_MASK_ADJUST; 4386 4387 if (isDefaultDisplay) { 4388 sf.set(mStableLeft, mStableTop, mStableRight, mStableBottom); 4389 } else { 4390 sf.set(mOverscanLeft, mOverscanTop, mOverscanRight, mOverscanBottom); 4391 } 4392 4393 if (!isDefaultDisplay) { 4394 if (attached != null) { 4395 // If this window is attached to another, our display 4396 // frame is the same as the one we are attached to. 4397 setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf); 4398 } else { 4399 // Give the window full screen. 4400 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 4401 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 4402 pf.right = df.right = of.right = cf.right 4403 = mOverscanScreenLeft + mOverscanScreenWidth; 4404 pf.bottom = df.bottom = of.bottom = cf.bottom 4405 = mOverscanScreenTop + mOverscanScreenHeight; 4406 } 4407 } else if (attrs.type == TYPE_INPUT_METHOD) { 4408 pf.left = df.left = of.left = cf.left = vf.left = mDockLeft; 4409 pf.top = df.top = of.top = cf.top = vf.top = mDockTop; 4410 pf.right = df.right = of.right = cf.right = vf.right = mDockRight; 4411 // IM dock windows layout below the nav bar... 4412 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4413 // ...with content insets above the nav bar 4414 cf.bottom = vf.bottom = mStableBottom; 4415 if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) { 4416 // The status bar forces the navigation bar while it's visible. Make sure the IME 4417 // avoids the navigation bar in that case. 4418 if (mNavigationBarPosition == NAV_BAR_RIGHT) { 4419 pf.right = df.right = of.right = cf.right = vf.right = mStableRight; 4420 } else if (mNavigationBarPosition == NAV_BAR_LEFT) { 4421 pf.left = df.left = of.left = cf.left = vf.left = mStableLeft; 4422 } 4423 } 4424 // IM dock windows always go to the bottom of the screen. 4425 attrs.gravity = Gravity.BOTTOM; 4426 mDockLayer = win.getSurfaceLayer(); 4427 } else if (attrs.type == TYPE_VOICE_INTERACTION) { 4428 pf.left = df.left = of.left = mUnrestrictedScreenLeft; 4429 pf.top = df.top = of.top = mUnrestrictedScreenTop; 4430 pf.right = df.right = of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4431 pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4432 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4433 cf.left = mDockLeft; 4434 cf.top = mDockTop; 4435 cf.right = mDockRight; 4436 cf.bottom = mDockBottom; 4437 } else { 4438 cf.left = mContentLeft; 4439 cf.top = mContentTop; 4440 cf.right = mContentRight; 4441 cf.bottom = mContentBottom; 4442 } 4443 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 4444 vf.left = mCurLeft; 4445 vf.top = mCurTop; 4446 vf.right = mCurRight; 4447 vf.bottom = mCurBottom; 4448 } else { 4449 vf.set(cf); 4450 } 4451 } else if (attrs.type == TYPE_WALLPAPER) { 4452 layoutWallpaper(win, pf, df, of, cf); 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 ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0 4677 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 4678 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 4679 // Asking to layout into the overscan region, so give it that pure 4680 // unrestricted area. 4681 pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; 4682 pf.top = df.top = of.top = cf.top = mOverscanScreenTop; 4683 pf.right = df.right = of.right = cf.right 4684 = mOverscanScreenLeft + mOverscanScreenWidth; 4685 pf.bottom = df.bottom = of.bottom = cf.bottom 4686 = mOverscanScreenTop + mOverscanScreenHeight; 4687 } else if (canHideNavigationBar() 4688 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 4689 && (attrs.type == TYPE_STATUS_BAR 4690 || attrs.type == TYPE_TOAST 4691 || attrs.type == TYPE_DOCK_DIVIDER 4692 || attrs.type == TYPE_VOICE_INTERACTION_STARTING 4693 || (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW 4694 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) { 4695 // Asking for layout as if the nav bar is hidden, lets the 4696 // application extend into the unrestricted screen area. We 4697 // only do this for application windows (or toasts) to ensure no window that 4698 // can be above the nav bar can do this. 4699 // XXX This assumes that an app asking for this will also 4700 // ask for layout in only content. We can't currently figure out 4701 // what the screen would be if only laying out to hide the nav bar. 4702 pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft; 4703 pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; 4704 pf.right = df.right = of.right = cf.right = mUnrestrictedScreenLeft 4705 + mUnrestrictedScreenWidth; 4706 pf.bottom = df.bottom = of.bottom = cf.bottom = mUnrestrictedScreenTop 4707 + mUnrestrictedScreenHeight; 4708 } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) { 4709 pf.left = df.left = of.left = mRestrictedScreenLeft; 4710 pf.top = df.top = of.top = mRestrictedScreenTop; 4711 pf.right = df.right = of.right = mRestrictedScreenLeft + mRestrictedScreenWidth; 4712 pf.bottom = df.bottom = of.bottom = mRestrictedScreenTop 4713 + mRestrictedScreenHeight; 4714 if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4715 cf.left = mDockLeft; 4716 cf.top = mDockTop; 4717 cf.right = mDockRight; 4718 cf.bottom = mDockBottom; 4719 } else { 4720 cf.left = mContentLeft; 4721 cf.top = mContentTop; 4722 cf.right = mContentRight; 4723 cf.bottom = mContentBottom; 4724 } 4725 } else { 4726 pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; 4727 pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; 4728 pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft 4729 + mRestrictedScreenWidth; 4730 pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop 4731 + mRestrictedScreenHeight; 4732 } 4733 4734 applyStableConstraints(sysUiFl, fl, cf); 4735 4736 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 4737 vf.left = mCurLeft; 4738 vf.top = mCurTop; 4739 vf.right = mCurRight; 4740 vf.bottom = mCurBottom; 4741 } else { 4742 vf.set(cf); 4743 } 4744 } else if (attached != null) { 4745 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 4746 "): attached to " + attached); 4747 // A child window should be placed inside of the same visible 4748 // frame that its parent had. 4749 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, of, cf, vf); 4750 } else { 4751 if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() + 4752 "): normal window"); 4753 // Otherwise, a normal window must be placed inside the content 4754 // of all screen decorations. 4755 if (attrs.type == TYPE_STATUS_BAR_PANEL || attrs.type == TYPE_VOLUME_OVERLAY) { 4756 // Status bar panels and the volume dialog are the only windows who can go on 4757 // top of the status bar. They are protected by the STATUS_BAR_SERVICE 4758 // permission, so they have the same privileges as the status 4759 // bar itself. 4760 pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; 4761 pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; 4762 pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft 4763 + mRestrictedScreenWidth; 4764 pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop 4765 + mRestrictedScreenHeight; 4766 } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT) { 4767 // These dialogs are stable to interim decor changes. 4768 pf.left = df.left = of.left = cf.left = mStableLeft; 4769 pf.top = df.top = of.top = cf.top = mStableTop; 4770 pf.right = df.right = of.right = cf.right = mStableRight; 4771 pf.bottom = df.bottom = of.bottom = cf.bottom = mStableBottom; 4772 } else { 4773 pf.left = mContentLeft; 4774 pf.top = mContentTop; 4775 pf.right = mContentRight; 4776 pf.bottom = mContentBottom; 4777 if (win.isVoiceInteraction()) { 4778 df.left = of.left = cf.left = mVoiceContentLeft; 4779 df.top = of.top = cf.top = mVoiceContentTop; 4780 df.right = of.right = cf.right = mVoiceContentRight; 4781 df.bottom = of.bottom = cf.bottom = mVoiceContentBottom; 4782 } else if (adjust != SOFT_INPUT_ADJUST_RESIZE) { 4783 df.left = of.left = cf.left = mDockLeft; 4784 df.top = of.top = cf.top = mDockTop; 4785 df.right = of.right = cf.right = mDockRight; 4786 df.bottom = of.bottom = cf.bottom = mDockBottom; 4787 } else { 4788 df.left = of.left = cf.left = mContentLeft; 4789 df.top = of.top = cf.top = mContentTop; 4790 df.right = of.right = cf.right = mContentRight; 4791 df.bottom = of.bottom = cf.bottom = mContentBottom; 4792 } 4793 if (adjust != SOFT_INPUT_ADJUST_NOTHING) { 4794 vf.left = mCurLeft; 4795 vf.top = mCurTop; 4796 vf.right = mCurRight; 4797 vf.bottom = mCurBottom; 4798 } else { 4799 vf.set(cf); 4800 } 4801 } 4802 } 4803 } 4804 4805 // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it. 4806 // Also, we don't allow windows in multi-window mode to extend out of the screen. 4807 if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR 4808 && !win.isInMultiWindowMode()) { 4809 df.left = df.top = -10000; 4810 df.right = df.bottom = 10000; 4811 if (attrs.type != TYPE_WALLPAPER) { 4812 of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000; 4813 of.right = of.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000; 4814 } 4815 } 4816 4817 // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we 4818 // need to provide information to the clients that want to pretend that you can draw there. 4819 // We only want to apply outsets to certain types of windows. For example, we never want to 4820 // apply the outsets to floating dialogs, because they wouldn't make sense there. 4821 final boolean useOutsets = shouldUseOutsets(attrs, fl); 4822 if (isDefaultDisplay && useOutsets) { 4823 osf = mTmpOutsetFrame; 4824 osf.set(cf.left, cf.top, cf.right, cf.bottom); 4825 int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); 4826 if (outset > 0) { 4827 int rotation = mDisplayRotation; 4828 if (rotation == Surface.ROTATION_0) { 4829 osf.bottom += outset; 4830 } else if (rotation == Surface.ROTATION_90) { 4831 osf.right += outset; 4832 } else if (rotation == Surface.ROTATION_180) { 4833 osf.top -= outset; 4834 } else if (rotation == Surface.ROTATION_270) { 4835 osf.left -= outset; 4836 } 4837 if (DEBUG_LAYOUT) Slog.v(TAG, "applying bottom outset of " + outset 4838 + " with rotation " + rotation + ", result: " + osf); 4839 } 4840 } 4841 4842 if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle() 4843 + ": sim=#" + Integer.toHexString(sim) 4844 + " attach=" + attached + " type=" + attrs.type 4845 + String.format(" flags=0x%08x", fl) 4846 + " pf=" + pf.toShortString() + " df=" + df.toShortString() 4847 + " of=" + of.toShortString() 4848 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString() 4849 + " dcf=" + dcf.toShortString() 4850 + " sf=" + sf.toShortString() 4851 + " osf=" + (osf == null ? "null" : osf.toShortString())); 4852 4853 win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf); 4854 4855 // Dock windows carve out the bottom of the screen, so normal windows 4856 // can't appear underneath them. 4857 if (attrs.type == TYPE_INPUT_METHOD && win.isVisibleOrBehindKeyguardLw() 4858 && win.isDisplayedLw() && !win.getGivenInsetsPendingLw()) { 4859 setLastInputMethodWindowLw(null, null); 4860 offsetInputMethodWindowLw(win); 4861 } 4862 if (attrs.type == TYPE_VOICE_INTERACTION && win.isVisibleOrBehindKeyguardLw() 4863 && !win.getGivenInsetsPendingLw()) { 4864 offsetVoiceInputWindowLw(win); 4865 } 4866 } 4867 4868 private void layoutWallpaper(WindowState win, Rect pf, Rect df, Rect of, Rect cf) { 4869 4870 // The wallpaper also has Real Ultimate Power, but we want to tell 4871 // it about the overscan area. 4872 pf.left = df.left = mOverscanScreenLeft; 4873 pf.top = df.top = mOverscanScreenTop; 4874 pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; 4875 pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; 4876 of.left = cf.left = mUnrestrictedScreenLeft; 4877 of.top = cf.top = mUnrestrictedScreenTop; 4878 of.right = cf.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; 4879 of.bottom = cf.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; 4880 } 4881 4882 private void offsetInputMethodWindowLw(WindowState win) { 4883 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top); 4884 top += win.getGivenContentInsetsLw().top; 4885 if (mContentBottom > top) { 4886 mContentBottom = top; 4887 } 4888 if (mVoiceContentBottom > top) { 4889 mVoiceContentBottom = top; 4890 } 4891 top = win.getVisibleFrameLw().top; 4892 top += win.getGivenVisibleInsetsLw().top; 4893 if (mCurBottom > top) { 4894 mCurBottom = top; 4895 } 4896 if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom=" 4897 + mDockBottom + " mContentBottom=" 4898 + mContentBottom + " mCurBottom=" + mCurBottom); 4899 } 4900 4901 private void offsetVoiceInputWindowLw(WindowState win) { 4902 int top = Math.max(win.getDisplayFrameLw().top, win.getContentFrameLw().top); 4903 top += win.getGivenContentInsetsLw().top; 4904 if (mVoiceContentBottom > top) { 4905 mVoiceContentBottom = top; 4906 } 4907 } 4908 4909 /** {@inheritDoc} */ 4910 @Override 4911 public void finishLayoutLw() { 4912 return; 4913 } 4914 4915 /** {@inheritDoc} */ 4916 @Override 4917 public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { 4918 mTopFullscreenOpaqueWindowState = null; 4919 mTopFullscreenOpaqueOrDimmingWindowState = null; 4920 mTopDockedOpaqueWindowState = null; 4921 mTopDockedOpaqueOrDimmingWindowState = null; 4922 mAppsToBeHidden.clear(); 4923 mAppsThatDismissKeyguard.clear(); 4924 mForceStatusBar = false; 4925 mForceStatusBarFromKeyguard = false; 4926 mForceStatusBarTransparent = false; 4927 mForcingShowNavBar = false; 4928 mForcingShowNavBarLayer = -1; 4929 4930 mHideLockScreen = false; 4931 mAllowLockscreenWhenOn = false; 4932 mDismissKeyguard = DISMISS_KEYGUARD_NONE; 4933 mShowingLockscreen = false; 4934 mShowingDream = false; 4935 mWinShowWhenLocked = null; 4936 mKeyguardSecure = isKeyguardSecure(mCurrentUserId); 4937 mKeyguardSecureIncludingHidden = mKeyguardSecure 4938 && (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()); 4939 } 4940 4941 /** {@inheritDoc} */ 4942 @Override 4943 public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs, 4944 WindowState attached) { 4945 if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw=" 4946 + win.isVisibleOrBehindKeyguardLw()); 4947 final int fl = PolicyControl.getWindowFlags(win, attrs); 4948 if (mTopFullscreenOpaqueWindowState == null 4949 && win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD) { 4950 mForcingShowNavBar = true; 4951 mForcingShowNavBarLayer = win.getSurfaceLayer(); 4952 } 4953 if (attrs.type == TYPE_STATUS_BAR) { 4954 if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 4955 mForceStatusBarFromKeyguard = true; 4956 mShowingLockscreen = true; 4957 } 4958 if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) { 4959 mForceStatusBarTransparent = true; 4960 } 4961 } 4962 4963 boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW 4964 && attrs.type < FIRST_SYSTEM_WINDOW; 4965 final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0; 4966 final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0; 4967 final int stackId = win.getStackId(); 4968 if (mTopFullscreenOpaqueWindowState == null && 4969 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) { 4970 if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) { 4971 if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 4972 mForceStatusBarFromKeyguard = true; 4973 } else { 4974 mForceStatusBar = true; 4975 } 4976 } 4977 if (attrs.type == TYPE_DREAM) { 4978 // If the lockscreen was showing when the dream started then wait 4979 // for the dream to draw before hiding the lockscreen. 4980 if (!mDreamingLockscreen 4981 || (win.isVisibleLw() && win.hasDrawnLw())) { 4982 mShowingDream = true; 4983 appWindow = true; 4984 } 4985 } 4986 4987 final IApplicationToken appToken = win.getAppToken(); 4988 4989 // For app windows that are not attached, we decide if all windows in the app they 4990 // represent should be hidden or if we should hide the lockscreen. For attached app 4991 // windows we defer the decision to the window it is attached to. 4992 if (appWindow && attached == null) { 4993 if (showWhenLocked) { 4994 // Remove any previous windows with the same appToken. 4995 mAppsToBeHidden.remove(appToken); 4996 mAppsThatDismissKeyguard.remove(appToken); 4997 if (mAppsToBeHidden.isEmpty()) { 4998 if (dismissKeyguard && !mKeyguardSecure) { 4999 mAppsThatDismissKeyguard.add(appToken); 5000 } else if (win.isDrawnLw() || win.hasAppShownWindows()) { 5001 mWinShowWhenLocked = win; 5002 mHideLockScreen = true; 5003 mForceStatusBarFromKeyguard = false; 5004 } 5005 } 5006 } else if (dismissKeyguard) { 5007 if (mKeyguardSecure) { 5008 mAppsToBeHidden.add(appToken); 5009 } else { 5010 mAppsToBeHidden.remove(appToken); 5011 } 5012 mAppsThatDismissKeyguard.add(appToken); 5013 } else { 5014 mAppsToBeHidden.add(appToken); 5015 } 5016 if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) { 5017 if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win); 5018 mTopFullscreenOpaqueWindowState = win; 5019 if (mTopFullscreenOpaqueOrDimmingWindowState == null) { 5020 mTopFullscreenOpaqueOrDimmingWindowState = win; 5021 } 5022 if (!mAppsThatDismissKeyguard.isEmpty() && 5023 mDismissKeyguard == DISMISS_KEYGUARD_NONE) { 5024 if (DEBUG_LAYOUT) Slog.v(TAG, 5025 "Setting mDismissKeyguard true by win " + win); 5026 mDismissKeyguard = (mWinDismissingKeyguard == win 5027 && mSecureDismissingKeyguard == mKeyguardSecure) 5028 ? DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START; 5029 mWinDismissingKeyguard = win; 5030 mSecureDismissingKeyguard = mKeyguardSecure; 5031 mForceStatusBarFromKeyguard = mShowingLockscreen && mKeyguardSecure; 5032 } else if (mAppsToBeHidden.isEmpty() && showWhenLocked 5033 && (win.isDrawnLw() || win.hasAppShownWindows())) { 5034 if (DEBUG_LAYOUT) Slog.v(TAG, 5035 "Setting mHideLockScreen to true by win " + win); 5036 mHideLockScreen = true; 5037 mForceStatusBarFromKeyguard = false; 5038 } 5039 if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { 5040 mAllowLockscreenWhenOn = true; 5041 } 5042 } 5043 5044 if (!mKeyguardHidden && mWinShowWhenLocked != null && 5045 mWinShowWhenLocked.getAppToken() != win.getAppToken() && 5046 (attrs.flags & FLAG_SHOW_WHEN_LOCKED) == 0) { 5047 win.hideLw(false); 5048 } 5049 } 5050 } else if (mTopFullscreenOpaqueWindowState == null && mWinShowWhenLocked == null) { 5051 // No TopFullscreenOpaqueWindow is showing, but we found a SHOW_WHEN_LOCKED window 5052 // that is being hidden in an animation - keep the 5053 // keyguard hidden until the new window shows up and 5054 // we know whether to show the keyguard or not. 5055 if (win.isAnimatingLw() && appWindow && showWhenLocked && mKeyguardHidden) { 5056 mHideLockScreen = true; 5057 mWinShowWhenLocked = win; 5058 } 5059 } 5060 5061 final boolean reallyVisible = win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw(); 5062 5063 // Voice interaction overrides both top fullscreen and top docked. 5064 if (reallyVisible && win.getAttrs().type == TYPE_VOICE_INTERACTION) { 5065 if (mTopFullscreenOpaqueWindowState == null) { 5066 mTopFullscreenOpaqueWindowState = win; 5067 if (mTopFullscreenOpaqueOrDimmingWindowState == null) { 5068 mTopFullscreenOpaqueOrDimmingWindowState = win; 5069 } 5070 } 5071 if (mTopDockedOpaqueWindowState == null) { 5072 mTopDockedOpaqueWindowState = win; 5073 if (mTopDockedOpaqueOrDimmingWindowState == null) { 5074 mTopDockedOpaqueOrDimmingWindowState = win; 5075 } 5076 } 5077 } 5078 5079 // Keep track of the window if it's dimming but not necessarily fullscreen. 5080 if (mTopFullscreenOpaqueOrDimmingWindowState == null && reallyVisible 5081 && win.isDimming() && StackId.normallyFullscreenWindows(stackId)) { 5082 mTopFullscreenOpaqueOrDimmingWindowState = win; 5083 } 5084 5085 // We need to keep track of the top "fullscreen" opaque window for the docked stack 5086 // separately, because both the "real fullscreen" opaque window and the one for the docked 5087 // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR. 5088 if (mTopDockedOpaqueWindowState == null && reallyVisible && appWindow && attached == null 5089 && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) { 5090 mTopDockedOpaqueWindowState = win; 5091 if (mTopDockedOpaqueOrDimmingWindowState == null) { 5092 mTopDockedOpaqueOrDimmingWindowState = win; 5093 } 5094 } 5095 5096 // Also keep track of any windows that are dimming but not necessarily fullscreen in the 5097 // docked stack. 5098 if (mTopDockedOpaqueOrDimmingWindowState == null && reallyVisible && win.isDimming() 5099 && stackId == DOCKED_STACK_ID) { 5100 mTopDockedOpaqueOrDimmingWindowState = win; 5101 } 5102 } 5103 5104 private boolean isFullscreen(WindowManager.LayoutParams attrs) { 5105 return attrs.x == 0 && attrs.y == 0 5106 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT 5107 && attrs.height == WindowManager.LayoutParams.MATCH_PARENT; 5108 } 5109 5110 /** {@inheritDoc} */ 5111 @Override 5112 public int finishPostLayoutPolicyLw() { 5113 if (mWinShowWhenLocked != null && mTopFullscreenOpaqueWindowState != null && 5114 mWinShowWhenLocked.getAppToken() != mTopFullscreenOpaqueWindowState.getAppToken() 5115 && isKeyguardLocked()) { 5116 // A dialog is dismissing the keyguard. Put the wallpaper behind it and hide the 5117 // fullscreen window. 5118 // TODO: Make sure FLAG_SHOW_WALLPAPER is restored when dialog is dismissed. Or not. 5119 mWinShowWhenLocked.getAttrs().flags |= FLAG_SHOW_WALLPAPER; 5120 mTopFullscreenOpaqueWindowState.hideLw(false); 5121 mTopFullscreenOpaqueWindowState = mWinShowWhenLocked; 5122 } 5123 5124 int changes = 0; 5125 boolean topIsFullscreen = false; 5126 5127 final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null) 5128 ? mTopFullscreenOpaqueWindowState.getAttrs() 5129 : null; 5130 5131 // If we are not currently showing a dream then remember the current 5132 // lockscreen state. We will use this to determine whether the dream 5133 // started while the lockscreen was showing and remember this state 5134 // while the dream is showing. 5135 if (!mShowingDream) { 5136 mDreamingLockscreen = mShowingLockscreen; 5137 if (mDreamingSleepTokenNeeded) { 5138 mDreamingSleepTokenNeeded = false; 5139 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget(); 5140 } 5141 } else { 5142 if (!mDreamingSleepTokenNeeded) { 5143 mDreamingSleepTokenNeeded = true; 5144 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 1, 1).sendToTarget(); 5145 } 5146 } 5147 5148 if (mStatusBar != null) { 5149 if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar 5150 + " forcefkg=" + mForceStatusBarFromKeyguard 5151 + " top=" + mTopFullscreenOpaqueWindowState); 5152 boolean shouldBeTransparent = mForceStatusBarTransparent 5153 && !mForceStatusBar 5154 && !mForceStatusBarFromKeyguard; 5155 if (!shouldBeTransparent) { 5156 mStatusBarController.setShowTransparent(false /* transparent */); 5157 } else if (!mStatusBar.isVisibleLw()) { 5158 mStatusBarController.setShowTransparent(true /* transparent */); 5159 } 5160 5161 WindowManager.LayoutParams statusBarAttrs = mStatusBar.getAttrs(); 5162 boolean statusBarExpanded = statusBarAttrs.height == MATCH_PARENT 5163 && statusBarAttrs.width == MATCH_PARENT; 5164 if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent 5165 || statusBarExpanded) { 5166 if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced"); 5167 if (mStatusBarController.setBarShowingLw(true)) { 5168 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5169 } 5170 // Maintain fullscreen layout until incoming animation is complete. 5171 topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw(); 5172 // Transient status bar on the lockscreen is not allowed 5173 if (mForceStatusBarFromKeyguard && mStatusBarController.isTransientShowing()) { 5174 mStatusBarController.updateVisibilityLw(false /*transientAllowed*/, 5175 mLastSystemUiFlags, mLastSystemUiFlags); 5176 } 5177 if (statusBarExpanded && mNavigationBar != null) { 5178 if (mNavigationBarController.setBarShowingLw(true)) { 5179 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5180 } 5181 } 5182 } else if (mTopFullscreenOpaqueWindowState != null) { 5183 final int fl = PolicyControl.getWindowFlags(null, lp); 5184 if (localLOGV) { 5185 Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() 5186 + " shown position: " 5187 + mTopFullscreenOpaqueWindowState.getShownPositionLw()); 5188 Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs() 5189 + " lp.flags=0x" + Integer.toHexString(fl)); 5190 } 5191 topIsFullscreen = (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0 5192 || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 5193 // The subtle difference between the window for mTopFullscreenOpaqueWindowState 5194 // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window 5195 // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the 5196 // case though. 5197 if (mStatusBarController.isTransientShowing()) { 5198 if (mStatusBarController.setBarShowingLw(true)) { 5199 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5200 } 5201 } else if (topIsFullscreen 5202 && !mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID) 5203 && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID)) { 5204 if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar"); 5205 if (mStatusBarController.setBarShowingLw(false)) { 5206 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5207 } else { 5208 if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding"); 5209 } 5210 } else { 5211 if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen"); 5212 if (mStatusBarController.setBarShowingLw(true)) { 5213 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5214 } 5215 } 5216 } 5217 } 5218 5219 if (mTopIsFullscreen != topIsFullscreen) { 5220 if (!topIsFullscreen) { 5221 // Force another layout when status bar becomes fully shown. 5222 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5223 } 5224 mTopIsFullscreen = topIsFullscreen; 5225 } 5226 5227 // Hide the key guard if a visible window explicitly specifies that it wants to be 5228 // displayed when the screen is locked. 5229 if (mKeyguardDelegate != null && mStatusBar != null) { 5230 if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard=" 5231 + mHideLockScreen); 5232 if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardSecure) { 5233 mKeyguardHidden = true; 5234 if (setKeyguardOccludedLw(true)) { 5235 changes |= FINISH_LAYOUT_REDO_LAYOUT 5236 | FINISH_LAYOUT_REDO_CONFIG 5237 | FINISH_LAYOUT_REDO_WALLPAPER; 5238 } 5239 if (mKeyguardDelegate.isShowing()) { 5240 mHandler.post(new Runnable() { 5241 @Override 5242 public void run() { 5243 mKeyguardDelegate.keyguardDone(false, false); 5244 } 5245 }); 5246 } 5247 } else if (mHideLockScreen) { 5248 mKeyguardHidden = true; 5249 mWinDismissingKeyguard = null; 5250 if (setKeyguardOccludedLw(true)) { 5251 changes |= FINISH_LAYOUT_REDO_LAYOUT 5252 | FINISH_LAYOUT_REDO_CONFIG 5253 | FINISH_LAYOUT_REDO_WALLPAPER; 5254 } 5255 } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) { 5256 mKeyguardHidden = false; 5257 if (setKeyguardOccludedLw(false)) { 5258 changes |= FINISH_LAYOUT_REDO_LAYOUT 5259 | FINISH_LAYOUT_REDO_CONFIG 5260 | FINISH_LAYOUT_REDO_WALLPAPER; 5261 } 5262 if (mDismissKeyguard == DISMISS_KEYGUARD_START) { 5263 // Only launch the next keyguard unlock window once per window. 5264 mHandler.post(new Runnable() { 5265 @Override 5266 public void run() { 5267 mKeyguardDelegate.dismiss(); 5268 } 5269 }); 5270 } 5271 } else { 5272 mWinDismissingKeyguard = null; 5273 mSecureDismissingKeyguard = false; 5274 mKeyguardHidden = false; 5275 if (setKeyguardOccludedLw(false)) { 5276 changes |= FINISH_LAYOUT_REDO_LAYOUT 5277 | FINISH_LAYOUT_REDO_CONFIG 5278 | FINISH_LAYOUT_REDO_WALLPAPER; 5279 } 5280 } 5281 } 5282 5283 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5284 // If the navigation bar has been hidden or shown, we need to do another 5285 // layout pass to update that window. 5286 changes |= FINISH_LAYOUT_REDO_LAYOUT; 5287 } 5288 5289 // update since mAllowLockscreenWhenOn might have changed 5290 updateLockScreenTimeout(); 5291 return changes; 5292 } 5293 5294 /** 5295 * Updates the occluded state of the Keyguard. 5296 * 5297 * @return Whether the flags have changed and we have to redo the layout. 5298 */ 5299 private boolean setKeyguardOccludedLw(boolean isOccluded) { 5300 boolean wasOccluded = mKeyguardOccluded; 5301 boolean showing = mKeyguardDelegate.isShowing(); 5302 if (wasOccluded && !isOccluded && showing) { 5303 mKeyguardOccluded = false; 5304 mKeyguardDelegate.setOccluded(false); 5305 mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD; 5306 return true; 5307 } else if (!wasOccluded && isOccluded && showing) { 5308 mKeyguardOccluded = true; 5309 mKeyguardDelegate.setOccluded(true); 5310 mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD; 5311 mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER; 5312 return true; 5313 } else { 5314 return false; 5315 } 5316 } 5317 5318 private boolean isStatusBarKeyguard() { 5319 return mStatusBar != null 5320 && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; 5321 } 5322 5323 @Override 5324 public boolean allowAppAnimationsLw() { 5325 if (isStatusBarKeyguard() || mShowingDream) { 5326 // If keyguard or dreams is currently visible, no reason to animate behind it. 5327 return false; 5328 } 5329 return true; 5330 } 5331 5332 @Override 5333 public int focusChangedLw(WindowState lastFocus, WindowState newFocus) { 5334 mFocusedWindow = newFocus; 5335 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) { 5336 // If the navigation bar has been hidden or shown, we need to do another 5337 // layout pass to update that window. 5338 return FINISH_LAYOUT_REDO_LAYOUT; 5339 } 5340 return 0; 5341 } 5342 5343 /** {@inheritDoc} */ 5344 @Override 5345 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { 5346 // lid changed state 5347 final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED; 5348 if (newLidState == mLidState) { 5349 return; 5350 } 5351 5352 mLidState = newLidState; 5353 applyLidSwitchState(); 5354 updateRotation(true); 5355 5356 if (lidOpen) { 5357 wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch, 5358 "android.policy:LID"); 5359 } else if (!mLidControlsSleep) { 5360 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 5361 } 5362 } 5363 5364 @Override 5365 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) { 5366 int lensCoverState = lensCovered ? CAMERA_LENS_COVERED : CAMERA_LENS_UNCOVERED; 5367 if (mCameraLensCoverState == lensCoverState) { 5368 return; 5369 } 5370 if (mCameraLensCoverState == CAMERA_LENS_COVERED && 5371 lensCoverState == CAMERA_LENS_UNCOVERED) { 5372 Intent intent; 5373 final boolean keyguardActive = mKeyguardDelegate == null ? false : 5374 mKeyguardDelegate.isShowing(); 5375 if (keyguardActive) { 5376 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); 5377 } else { 5378 intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); 5379 } 5380 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens, 5381 "android.policy:CAMERA_COVER"); 5382 startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); 5383 } 5384 mCameraLensCoverState = lensCoverState; 5385 } 5386 5387 void setHdmiPlugged(boolean plugged) { 5388 if (mHdmiPlugged != plugged) { 5389 mHdmiPlugged = plugged; 5390 updateRotation(true, true); 5391 Intent intent = new Intent(ACTION_HDMI_PLUGGED); 5392 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 5393 intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged); 5394 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 5395 } 5396 } 5397 5398 void initializeHdmiState() { 5399 boolean plugged = false; 5400 // watch for HDMI plug messages if the hdmi switch exists 5401 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) { 5402 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi"); 5403 5404 final String filename = "/sys/class/switch/hdmi/state"; 5405 FileReader reader = null; 5406 try { 5407 reader = new FileReader(filename); 5408 char[] buf = new char[15]; 5409 int n = reader.read(buf); 5410 if (n > 1) { 5411 plugged = 0 != Integer.parseInt(new String(buf, 0, n-1)); 5412 } 5413 } catch (IOException ex) { 5414 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5415 } catch (NumberFormatException ex) { 5416 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex); 5417 } finally { 5418 if (reader != null) { 5419 try { 5420 reader.close(); 5421 } catch (IOException ex) { 5422 } 5423 } 5424 } 5425 } 5426 // This dance forces the code in setHdmiPlugged to run. 5427 // Always do this so the sticky intent is stuck (to false) if there is no hdmi. 5428 mHdmiPlugged = !plugged; 5429 setHdmiPlugged(!mHdmiPlugged); 5430 } 5431 5432 final Object mScreenshotLock = new Object(); 5433 ServiceConnection mScreenshotConnection = null; 5434 5435 final Runnable mScreenshotTimeout = new Runnable() { 5436 @Override public void run() { 5437 synchronized (mScreenshotLock) { 5438 if (mScreenshotConnection != null) { 5439 mContext.unbindService(mScreenshotConnection); 5440 mScreenshotConnection = null; 5441 notifyScreenshotError(); 5442 } 5443 } 5444 } 5445 }; 5446 5447 // Assume this is called from the Handler thread. 5448 private void takeScreenshot(final int screenshotType) { 5449 synchronized (mScreenshotLock) { 5450 if (mScreenshotConnection != null) { 5451 return; 5452 } 5453 final ComponentName serviceComponent = new ComponentName(SYSUI_PACKAGE, 5454 SYSUI_SCREENSHOT_SERVICE); 5455 final Intent serviceIntent = new Intent(); 5456 serviceIntent.setComponent(serviceComponent); 5457 ServiceConnection conn = new ServiceConnection() { 5458 @Override 5459 public void onServiceConnected(ComponentName name, IBinder service) { 5460 synchronized (mScreenshotLock) { 5461 if (mScreenshotConnection != this) { 5462 return; 5463 } 5464 Messenger messenger = new Messenger(service); 5465 Message msg = Message.obtain(null, screenshotType); 5466 final ServiceConnection myConn = this; 5467 Handler h = new Handler(mHandler.getLooper()) { 5468 @Override 5469 public void handleMessage(Message msg) { 5470 synchronized (mScreenshotLock) { 5471 if (mScreenshotConnection == myConn) { 5472 mContext.unbindService(mScreenshotConnection); 5473 mScreenshotConnection = null; 5474 mHandler.removeCallbacks(mScreenshotTimeout); 5475 } 5476 } 5477 } 5478 }; 5479 msg.replyTo = new Messenger(h); 5480 msg.arg1 = msg.arg2 = 0; 5481 if (mStatusBar != null && mStatusBar.isVisibleLw()) 5482 msg.arg1 = 1; 5483 if (mNavigationBar != null && mNavigationBar.isVisibleLw()) 5484 msg.arg2 = 1; 5485 try { 5486 messenger.send(msg); 5487 } catch (RemoteException e) { 5488 } 5489 } 5490 } 5491 5492 @Override 5493 public void onServiceDisconnected(ComponentName name) { 5494 notifyScreenshotError(); 5495 } 5496 }; 5497 if (mContext.bindServiceAsUser(serviceIntent, conn, 5498 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, 5499 UserHandle.CURRENT)) { 5500 mScreenshotConnection = conn; 5501 mHandler.postDelayed(mScreenshotTimeout, 10000); 5502 } 5503 } 5504 } 5505 5506 /** 5507 * Notifies the screenshot service to show an error. 5508 */ 5509 private void notifyScreenshotError() { 5510 // If the service process is killed, then ask it to clean up after itself 5511 final ComponentName errorComponent = new ComponentName(SYSUI_PACKAGE, 5512 SYSUI_SCREENSHOT_ERROR_RECEIVER); 5513 Intent errorIntent = new Intent(Intent.ACTION_USER_PRESENT); 5514 errorIntent.setComponent(errorComponent); 5515 errorIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | 5516 Intent.FLAG_RECEIVER_FOREGROUND); 5517 mContext.sendBroadcastAsUser(errorIntent, UserHandle.CURRENT); 5518 } 5519 5520 /** {@inheritDoc} */ 5521 @Override 5522 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { 5523 if (!mSystemBooted) { 5524 // If we have not yet booted, don't let key events do anything. 5525 return 0; 5526 } 5527 5528 final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0; 5529 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; 5530 final boolean canceled = event.isCanceled(); 5531 final int keyCode = event.getKeyCode(); 5532 5533 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0; 5534 5535 // If screen is off then we treat the case where the keyguard is open but hidden 5536 // the same as if it were open and in front. 5537 // This will prevent any keys other than the power button from waking the screen 5538 // when the keyguard is hidden by another activity. 5539 final boolean keyguardActive = (mKeyguardDelegate == null ? false : 5540 (interactive ? 5541 isKeyguardShowingAndNotOccluded() : 5542 mKeyguardDelegate.isShowing())); 5543 5544 if (DEBUG_INPUT) { 5545 Log.d(TAG, "interceptKeyTq keycode=" + keyCode 5546 + " interactive=" + interactive + " keyguardActive=" + keyguardActive 5547 + " policyFlags=" + Integer.toHexString(policyFlags)); 5548 } 5549 5550 // Basic policy based on interactive state. 5551 int result; 5552 boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 5553 || event.isWakeKey(); 5554 if (interactive || (isInjected && !isWakeKey)) { 5555 // When the device is interactive or the key is injected pass the 5556 // key to the application. 5557 result = ACTION_PASS_TO_USER; 5558 isWakeKey = false; 5559 } else if (!interactive && shouldDispatchInputWhenNonInteractive()) { 5560 // If we're currently dozing with the screen on and the keyguard showing, pass the key 5561 // to the application but preserve its wake key status to make sure we still move 5562 // from dozing to fully interactive if we would normally go from off to fully 5563 // interactive. 5564 result = ACTION_PASS_TO_USER; 5565 } else { 5566 // When the screen is off and the key is not injected, determine whether 5567 // to wake the device but don't pass the key to the application. 5568 result = 0; 5569 if (isWakeKey && (!down || !isWakeKeyWhenScreenOff(keyCode))) { 5570 isWakeKey = false; 5571 } 5572 } 5573 5574 // If the key would be handled globally, just return the result, don't worry about special 5575 // key processing. 5576 if (isValidGlobalKey(keyCode) 5577 && mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) { 5578 if (isWakeKey) { 5579 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 5580 } 5581 return result; 5582 } 5583 5584 boolean useHapticFeedback = down 5585 && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0 5586 && event.getRepeatCount() == 0; 5587 5588 // Handle special keys. 5589 switch (keyCode) { 5590 case KeyEvent.KEYCODE_BACK: { 5591 if (down) { 5592 mBackKeyHandled = false; 5593 if (hasLongPressOnBackBehavior()) { 5594 Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS); 5595 msg.setAsynchronous(true); 5596 mHandler.sendMessageDelayed(msg, 5597 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 5598 } 5599 } else { 5600 boolean handled = mBackKeyHandled; 5601 5602 // Reset back key state 5603 cancelPendingBackKeyAction(); 5604 5605 // Don't pass back press to app if we've already handled it 5606 if (handled) { 5607 result &= ~ACTION_PASS_TO_USER; 5608 } 5609 } 5610 break; 5611 } 5612 5613 case KeyEvent.KEYCODE_VOLUME_DOWN: 5614 case KeyEvent.KEYCODE_VOLUME_UP: 5615 case KeyEvent.KEYCODE_VOLUME_MUTE: { 5616 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 5617 if (down) { 5618 if (interactive && !mScreenshotChordVolumeDownKeyTriggered 5619 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5620 mScreenshotChordVolumeDownKeyTriggered = true; 5621 mScreenshotChordVolumeDownKeyTime = event.getDownTime(); 5622 mScreenshotChordVolumeDownKeyConsumed = false; 5623 cancelPendingPowerKeyAction(); 5624 interceptScreenshotChord(); 5625 } 5626 } else { 5627 mScreenshotChordVolumeDownKeyTriggered = false; 5628 cancelPendingScreenshotChordAction(); 5629 } 5630 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 5631 if (down) { 5632 if (interactive && !mScreenshotChordVolumeUpKeyTriggered 5633 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 5634 mScreenshotChordVolumeUpKeyTriggered = true; 5635 cancelPendingPowerKeyAction(); 5636 cancelPendingScreenshotChordAction(); 5637 } 5638 } else { 5639 mScreenshotChordVolumeUpKeyTriggered = false; 5640 cancelPendingScreenshotChordAction(); 5641 } 5642 } 5643 if (down) { 5644 TelecomManager telecomManager = getTelecommService(); 5645 if (telecomManager != null) { 5646 if (telecomManager.isRinging()) { 5647 // If an incoming call is ringing, either VOLUME key means 5648 // "silence ringer". We handle these keys here, rather than 5649 // in the InCallScreen, to make sure we'll respond to them 5650 // even if the InCallScreen hasn't come to the foreground yet. 5651 // Look for the DOWN event here, to agree with the "fallback" 5652 // behavior in the InCallScreen. 5653 Log.i(TAG, "interceptKeyBeforeQueueing:" 5654 + " VOLUME key-down while ringing: Silence ringer!"); 5655 5656 // Silence the ringer. (It's safe to call this 5657 // even if the ringer has already been silenced.) 5658 telecomManager.silenceRinger(); 5659 5660 // And *don't* pass this key thru to the current activity 5661 // (which is probably the InCallScreen.) 5662 result &= ~ACTION_PASS_TO_USER; 5663 break; 5664 } 5665 if (telecomManager.isInCall() 5666 && (result & ACTION_PASS_TO_USER) == 0) { 5667 // If we are in call but we decided not to pass the key to 5668 // the application, just pass it to the session service. 5669 5670 MediaSessionLegacyHelper.getHelper(mContext) 5671 .sendVolumeKeyEvent(event, false); 5672 break; 5673 } 5674 } 5675 } 5676 if (mUseTvRouting) { 5677 // On TVs, defer special key handlings to 5678 // {@link interceptKeyBeforeDispatching()}. 5679 result |= ACTION_PASS_TO_USER; 5680 } else if ((result & ACTION_PASS_TO_USER) == 0) { 5681 // If we aren't passing to the user and no one else 5682 // handled it send it to the session manager to 5683 // figure out. 5684 MediaSessionLegacyHelper.getHelper(mContext) 5685 .sendVolumeKeyEvent(event, true); 5686 } 5687 break; 5688 } 5689 5690 case KeyEvent.KEYCODE_ENDCALL: { 5691 result &= ~ACTION_PASS_TO_USER; 5692 if (down) { 5693 TelecomManager telecomManager = getTelecommService(); 5694 boolean hungUp = false; 5695 if (telecomManager != null) { 5696 hungUp = telecomManager.endCall(); 5697 } 5698 if (interactive && !hungUp) { 5699 mEndCallKeyHandled = false; 5700 mHandler.postDelayed(mEndCallLongPress, 5701 ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); 5702 } else { 5703 mEndCallKeyHandled = true; 5704 } 5705 } else { 5706 if (!mEndCallKeyHandled) { 5707 mHandler.removeCallbacks(mEndCallLongPress); 5708 if (!canceled) { 5709 if ((mEndcallBehavior 5710 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) { 5711 if (goHome()) { 5712 break; 5713 } 5714 } 5715 if ((mEndcallBehavior 5716 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { 5717 mPowerManager.goToSleep(event.getEventTime(), 5718 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); 5719 isWakeKey = false; 5720 } 5721 } 5722 } 5723 } 5724 break; 5725 } 5726 5727 case KeyEvent.KEYCODE_POWER: { 5728 result &= ~ACTION_PASS_TO_USER; 5729 isWakeKey = false; // wake-up will be handled separately 5730 if (down) { 5731 interceptPowerKeyDown(event, interactive); 5732 } else { 5733 interceptPowerKeyUp(event, interactive, canceled); 5734 } 5735 break; 5736 } 5737 5738 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN: 5739 // fall through 5740 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP: 5741 // fall through 5742 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT: 5743 // fall through 5744 case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: { 5745 result &= ~ACTION_PASS_TO_USER; 5746 interceptSystemNavigationKey(event); 5747 break; 5748 } 5749 5750 case KeyEvent.KEYCODE_SLEEP: { 5751 result &= ~ACTION_PASS_TO_USER; 5752 isWakeKey = false; 5753 if (!mPowerManager.isInteractive()) { 5754 useHapticFeedback = false; // suppress feedback if already non-interactive 5755 } 5756 if (down) { 5757 sleepPress(event.getEventTime()); 5758 } else { 5759 sleepRelease(event.getEventTime()); 5760 } 5761 break; 5762 } 5763 5764 case KeyEvent.KEYCODE_SOFT_SLEEP: { 5765 result &= ~ACTION_PASS_TO_USER; 5766 isWakeKey = false; 5767 if (!down) { 5768 mPowerManagerInternal.setUserInactiveOverrideFromWindowManager(); 5769 } 5770 break; 5771 } 5772 5773 case KeyEvent.KEYCODE_WAKEUP: { 5774 result &= ~ACTION_PASS_TO_USER; 5775 isWakeKey = true; 5776 break; 5777 } 5778 5779 case KeyEvent.KEYCODE_MEDIA_PLAY: 5780 case KeyEvent.KEYCODE_MEDIA_PAUSE: 5781 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 5782 case KeyEvent.KEYCODE_HEADSETHOOK: 5783 case KeyEvent.KEYCODE_MUTE: 5784 case KeyEvent.KEYCODE_MEDIA_STOP: 5785 case KeyEvent.KEYCODE_MEDIA_NEXT: 5786 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 5787 case KeyEvent.KEYCODE_MEDIA_REWIND: 5788 case KeyEvent.KEYCODE_MEDIA_RECORD: 5789 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 5790 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: { 5791 if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) { 5792 // If the global session is active pass all media keys to it 5793 // instead of the active window. 5794 result &= ~ACTION_PASS_TO_USER; 5795 } 5796 if ((result & ACTION_PASS_TO_USER) == 0) { 5797 // Only do this if we would otherwise not pass it to the user. In that 5798 // case, the PhoneWindow class will do the same thing, except it will 5799 // only do it if the showing app doesn't process the key on its own. 5800 // Note that we need to make a copy of the key event here because the 5801 // original key event will be recycled when we return. 5802 mBroadcastWakeLock.acquire(); 5803 Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK, 5804 new KeyEvent(event)); 5805 msg.setAsynchronous(true); 5806 msg.sendToTarget(); 5807 } 5808 break; 5809 } 5810 5811 case KeyEvent.KEYCODE_CALL: { 5812 if (down) { 5813 TelecomManager telecomManager = getTelecommService(); 5814 if (telecomManager != null) { 5815 if (telecomManager.isRinging()) { 5816 Log.i(TAG, "interceptKeyBeforeQueueing:" 5817 + " CALL key-down while ringing: Answer the call!"); 5818 telecomManager.acceptRingingCall(); 5819 5820 // And *don't* pass this key thru to the current activity 5821 // (which is presumably the InCallScreen.) 5822 result &= ~ACTION_PASS_TO_USER; 5823 } 5824 } 5825 } 5826 break; 5827 } 5828 case KeyEvent.KEYCODE_VOICE_ASSIST: { 5829 // Only do this if we would otherwise not pass it to the user. In that case, 5830 // interceptKeyBeforeDispatching would apply a similar but different policy in 5831 // order to invoke voice assist actions. Note that we need to make a copy of the 5832 // key event here because the original key event will be recycled when we return. 5833 if ((result & ACTION_PASS_TO_USER) == 0 && !down) { 5834 mBroadcastWakeLock.acquire(); 5835 Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK, 5836 keyguardActive ? 1 : 0, 0); 5837 msg.setAsynchronous(true); 5838 msg.sendToTarget(); 5839 } 5840 break; 5841 } 5842 case KeyEvent.KEYCODE_WINDOW: { 5843 if (mShortPressWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) { 5844 if (mTvPictureInPictureVisible) { 5845 // Consumes the key only if picture-in-picture is visible 5846 // to show picture-in-picture control menu. 5847 // This gives a chance to the foreground activity 5848 // to customize PIP key behavior. 5849 if (!down) { 5850 showTvPictureInPictureMenu(event); 5851 } 5852 result &= ~ACTION_PASS_TO_USER; 5853 } 5854 } 5855 break; 5856 } 5857 } 5858 5859 if (useHapticFeedback) { 5860 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); 5861 } 5862 5863 if (isWakeKey) { 5864 wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY"); 5865 } 5866 5867 return result; 5868 } 5869 5870 /** 5871 * Handle statusbar expansion events. 5872 * @param event 5873 */ 5874 private void interceptSystemNavigationKey(KeyEvent event) { 5875 if (event.getAction() == KeyEvent.ACTION_UP && areSystemNavigationKeysEnabled()) { 5876 IStatusBarService sbar = getStatusBarService(); 5877 if (sbar != null) { 5878 try { 5879 sbar.handleSystemNavigationKey(event.getKeyCode()); 5880 } catch (RemoteException e1) { 5881 // oops, no statusbar. Ignore event. 5882 } 5883 } 5884 } 5885 } 5886 5887 /** 5888 * Returns true if the key can have global actions attached to it. 5889 * We reserve all power management keys for the system since they require 5890 * very careful handling. 5891 */ 5892 private static boolean isValidGlobalKey(int keyCode) { 5893 switch (keyCode) { 5894 case KeyEvent.KEYCODE_POWER: 5895 case KeyEvent.KEYCODE_WAKEUP: 5896 case KeyEvent.KEYCODE_SLEEP: 5897 return false; 5898 default: 5899 return true; 5900 } 5901 } 5902 5903 /** 5904 * When the screen is off we ignore some keys that might otherwise typically 5905 * be considered wake keys. We filter them out here. 5906 * 5907 * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it 5908 * is always considered a wake key. 5909 */ 5910 private boolean isWakeKeyWhenScreenOff(int keyCode) { 5911 switch (keyCode) { 5912 // ignore volume keys unless docked 5913 case KeyEvent.KEYCODE_VOLUME_UP: 5914 case KeyEvent.KEYCODE_VOLUME_DOWN: 5915 case KeyEvent.KEYCODE_VOLUME_MUTE: 5916 return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED; 5917 5918 // ignore media and camera keys 5919 case KeyEvent.KEYCODE_MUTE: 5920 case KeyEvent.KEYCODE_HEADSETHOOK: 5921 case KeyEvent.KEYCODE_MEDIA_PLAY: 5922 case KeyEvent.KEYCODE_MEDIA_PAUSE: 5923 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 5924 case KeyEvent.KEYCODE_MEDIA_STOP: 5925 case KeyEvent.KEYCODE_MEDIA_NEXT: 5926 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 5927 case KeyEvent.KEYCODE_MEDIA_REWIND: 5928 case KeyEvent.KEYCODE_MEDIA_RECORD: 5929 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 5930 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: 5931 case KeyEvent.KEYCODE_CAMERA: 5932 return false; 5933 } 5934 return true; 5935 } 5936 5937 5938 /** {@inheritDoc} */ 5939 @Override 5940 public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) { 5941 if ((policyFlags & FLAG_WAKE) != 0) { 5942 if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion, 5943 "android.policy:MOTION")) { 5944 return 0; 5945 } 5946 } 5947 5948 if (shouldDispatchInputWhenNonInteractive()) { 5949 return ACTION_PASS_TO_USER; 5950 } 5951 5952 // If we have not passed the action up and we are in theater mode without dreaming, 5953 // there will be no dream to intercept the touch and wake into ambient. The device should 5954 // wake up in this case. 5955 if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) { 5956 wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming, 5957 "android.policy:MOTION"); 5958 } 5959 5960 return 0; 5961 } 5962 5963 private boolean shouldDispatchInputWhenNonInteractive() { 5964 final boolean displayOff = (mDisplay == null || mDisplay.getState() == Display.STATE_OFF); 5965 5966 if (displayOff && !mHasFeatureWatch) { 5967 return false; 5968 } 5969 5970 // Send events to keyguard while the screen is on and it's showing. 5971 if (isKeyguardShowingAndNotOccluded() && !displayOff) { 5972 return true; 5973 } 5974 5975 // Send events to a dozing dream even if the screen is off since the dream 5976 // is in control of the state of the screen. 5977 IDreamManager dreamManager = getDreamManager(); 5978 5979 try { 5980 if (dreamManager != null && dreamManager.isDreaming()) { 5981 return true; 5982 } 5983 } catch (RemoteException e) { 5984 Slog.e(TAG, "RemoteException when checking if dreaming", e); 5985 } 5986 5987 // Otherwise, consume events since the user can't see what is being 5988 // interacted with. 5989 return false; 5990 } 5991 5992 private void dispatchDirectAudioEvent(KeyEvent event) { 5993 if (event.getAction() != KeyEvent.ACTION_DOWN) { 5994 return; 5995 } 5996 int keyCode = event.getKeyCode(); 5997 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 5998 | AudioManager.FLAG_FROM_KEY; 5999 String pkgName = mContext.getOpPackageName(); 6000 switch (keyCode) { 6001 case KeyEvent.KEYCODE_VOLUME_UP: 6002 try { 6003 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 6004 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6005 } catch (RemoteException e) { 6006 Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e); 6007 } 6008 break; 6009 case KeyEvent.KEYCODE_VOLUME_DOWN: 6010 try { 6011 getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 6012 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6013 } catch (RemoteException e) { 6014 Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e); 6015 } 6016 break; 6017 case KeyEvent.KEYCODE_VOLUME_MUTE: 6018 try { 6019 if (event.getRepeatCount() == 0) { 6020 getAudioService().adjustSuggestedStreamVolume( 6021 AudioManager.ADJUST_TOGGLE_MUTE, 6022 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG); 6023 } 6024 } catch (RemoteException e) { 6025 Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e); 6026 } 6027 break; 6028 } 6029 } 6030 6031 void dispatchMediaKeyWithWakeLock(KeyEvent event) { 6032 if (DEBUG_INPUT) { 6033 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event); 6034 } 6035 6036 if (mHavePendingMediaKeyRepeatWithWakeLock) { 6037 if (DEBUG_INPUT) { 6038 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat"); 6039 } 6040 6041 mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK); 6042 mHavePendingMediaKeyRepeatWithWakeLock = false; 6043 mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock 6044 } 6045 6046 dispatchMediaKeyWithWakeLockToAudioService(event); 6047 6048 if (event.getAction() == KeyEvent.ACTION_DOWN 6049 && event.getRepeatCount() == 0) { 6050 mHavePendingMediaKeyRepeatWithWakeLock = true; 6051 6052 Message msg = mHandler.obtainMessage( 6053 MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event); 6054 msg.setAsynchronous(true); 6055 mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout()); 6056 } else { 6057 mBroadcastWakeLock.release(); 6058 } 6059 } 6060 6061 void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) { 6062 mHavePendingMediaKeyRepeatWithWakeLock = false; 6063 6064 KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event, 6065 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS); 6066 if (DEBUG_INPUT) { 6067 Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent); 6068 } 6069 6070 dispatchMediaKeyWithWakeLockToAudioService(repeatEvent); 6071 mBroadcastWakeLock.release(); 6072 } 6073 6074 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) { 6075 if (ActivityManagerNative.isSystemReady()) { 6076 MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true); 6077 } 6078 } 6079 6080 void launchVoiceAssistWithWakeLock(boolean keyguardActive) { 6081 IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface( 6082 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 6083 if (dic != null) { 6084 try { 6085 dic.exitIdle("voice-search"); 6086 } catch (RemoteException e) { 6087 } 6088 } 6089 Intent voiceIntent = 6090 new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE); 6091 voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE, keyguardActive); 6092 startActivityAsUser(voiceIntent, UserHandle.CURRENT_OR_SELF); 6093 mBroadcastWakeLock.release(); 6094 } 6095 6096 BroadcastReceiver mDockReceiver = new BroadcastReceiver() { 6097 @Override 6098 public void onReceive(Context context, Intent intent) { 6099 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 6100 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 6101 Intent.EXTRA_DOCK_STATE_UNDOCKED); 6102 } else { 6103 try { 6104 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface( 6105 ServiceManager.getService(Context.UI_MODE_SERVICE)); 6106 mUiMode = uiModeService.getCurrentModeType(); 6107 } catch (RemoteException e) { 6108 } 6109 } 6110 updateRotation(true); 6111 synchronized (mLock) { 6112 updateOrientationListenerLp(); 6113 } 6114 } 6115 }; 6116 6117 BroadcastReceiver mDreamReceiver = new BroadcastReceiver() { 6118 @Override 6119 public void onReceive(Context context, Intent intent) { 6120 if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) { 6121 if (mKeyguardDelegate != null) { 6122 mKeyguardDelegate.onDreamingStarted(); 6123 } 6124 } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) { 6125 if (mKeyguardDelegate != null) { 6126 mKeyguardDelegate.onDreamingStopped(); 6127 } 6128 } 6129 } 6130 }; 6131 6132 BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() { 6133 @Override 6134 public void onReceive(Context context, Intent intent) { 6135 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 6136 // tickle the settings observer: this first ensures that we're 6137 // observing the relevant settings for the newly-active user, 6138 // and then updates our own bookkeeping based on the now- 6139 // current user. 6140 mSettingsObserver.onChange(false); 6141 6142 // force a re-application of focused window sysui visibility. 6143 // the window may never have been shown for this user 6144 // e.g. the keyguard when going through the new-user setup flow 6145 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6146 mLastSystemUiFlags = 0; 6147 updateSystemUiVisibilityLw(); 6148 } 6149 } 6150 } 6151 }; 6152 6153 private final Runnable mHiddenNavPanic = new Runnable() { 6154 @Override 6155 public void run() { 6156 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6157 if (!isUserSetupComplete()) { 6158 // Swipe-up for navigation bar is disabled during setup 6159 return; 6160 } 6161 mPendingPanicGestureUptime = SystemClock.uptimeMillis(); 6162 mNavigationBarController.showTransient(); 6163 } 6164 } 6165 }; 6166 6167 private void requestTransientBars(WindowState swipeTarget) { 6168 synchronized (mWindowManagerFuncs.getWindowManagerLock()) { 6169 if (!isUserSetupComplete()) { 6170 // Swipe-up for navigation bar is disabled during setup 6171 return; 6172 } 6173 boolean sb = mStatusBarController.checkShowTransientBarLw(); 6174 boolean nb = mNavigationBarController.checkShowTransientBarLw(); 6175 if (sb || nb) { 6176 // Don't show status bar when swiping on already visible navigation bar 6177 if (!nb && swipeTarget == mNavigationBar) { 6178 if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target"); 6179 return; 6180 } 6181 if (sb) mStatusBarController.showTransient(); 6182 if (nb) mNavigationBarController.showTransient(); 6183 mImmersiveModeConfirmation.confirmCurrentPrompt(); 6184 updateSystemUiVisibilityLw(); 6185 } 6186 } 6187 } 6188 6189 // Called on the PowerManager's Notifier thread. 6190 @Override 6191 public void startedGoingToSleep(int why) { 6192 if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")"); 6193 mCameraGestureTriggeredDuringGoingToSleep = false; 6194 mGoingToSleep = true; 6195 if (mKeyguardDelegate != null) { 6196 mKeyguardDelegate.onStartedGoingToSleep(why); 6197 } 6198 } 6199 6200 // Called on the PowerManager's Notifier thread. 6201 @Override 6202 public void finishedGoingToSleep(int why) { 6203 EventLog.writeEvent(70000, 0); 6204 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")"); 6205 MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000); 6206 6207 mGoingToSleep = false; 6208 6209 // We must get this work done here because the power manager will drop 6210 // the wake lock and let the system suspend once this function returns. 6211 synchronized (mLock) { 6212 mAwake = false; 6213 updateWakeGestureListenerLp(); 6214 updateOrientationListenerLp(); 6215 updateLockScreenTimeout(); 6216 } 6217 if (mKeyguardDelegate != null) { 6218 mKeyguardDelegate.onFinishedGoingToSleep(why, 6219 mCameraGestureTriggeredDuringGoingToSleep); 6220 } 6221 mCameraGestureTriggeredDuringGoingToSleep = false; 6222 } 6223 6224 // Called on the PowerManager's Notifier thread. 6225 @Override 6226 public void startedWakingUp() { 6227 EventLog.writeEvent(70000, 1); 6228 if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up..."); 6229 6230 // Since goToSleep performs these functions synchronously, we must 6231 // do the same here. We cannot post this work to a handler because 6232 // that might cause it to become reordered with respect to what 6233 // may happen in a future call to goToSleep. 6234 synchronized (mLock) { 6235 mAwake = true; 6236 6237 updateWakeGestureListenerLp(); 6238 updateOrientationListenerLp(); 6239 updateLockScreenTimeout(); 6240 } 6241 6242 if (mKeyguardDelegate != null) { 6243 mKeyguardDelegate.onStartedWakingUp(); 6244 } 6245 } 6246 6247 // Called on the PowerManager's Notifier thread. 6248 @Override 6249 public void finishedWakingUp() { 6250 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up..."); 6251 } 6252 6253 private void wakeUpFromPowerKey(long eventTime) { 6254 wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER"); 6255 } 6256 6257 private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) { 6258 final boolean theaterModeEnabled = isTheaterModeEnabled(); 6259 if (!wakeInTheaterMode && theaterModeEnabled) { 6260 return false; 6261 } 6262 6263 if (theaterModeEnabled) { 6264 Settings.Global.putInt(mContext.getContentResolver(), 6265 Settings.Global.THEATER_MODE_ON, 0); 6266 } 6267 6268 mPowerManager.wakeUp(wakeTime, reason); 6269 return true; 6270 } 6271 6272 private void finishKeyguardDrawn() { 6273 synchronized (mLock) { 6274 if (!mScreenOnEarly || mKeyguardDrawComplete) { 6275 return; // We are not awake yet or we have already informed of this event. 6276 } 6277 6278 mKeyguardDrawComplete = true; 6279 if (mKeyguardDelegate != null) { 6280 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6281 } 6282 mWindowManagerDrawComplete = false; 6283 } 6284 6285 // ... eventually calls finishWindowsDrawn which will finalize our screen turn on 6286 // as well as enabling the orientation change logic/sensor. 6287 mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, 6288 WAITING_FOR_DRAWN_TIMEOUT); 6289 } 6290 6291 // Called on the DisplayManager's DisplayPowerController thread. 6292 @Override 6293 public void screenTurnedOff() { 6294 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off..."); 6295 6296 updateScreenOffSleepToken(true); 6297 synchronized (mLock) { 6298 mScreenOnEarly = false; 6299 mScreenOnFully = false; 6300 mKeyguardDrawComplete = false; 6301 mWindowManagerDrawComplete = false; 6302 mScreenOnListener = null; 6303 updateOrientationListenerLp(); 6304 6305 if (mKeyguardDelegate != null) { 6306 mKeyguardDelegate.onScreenTurnedOff(); 6307 } 6308 } 6309 } 6310 6311 // Called on the DisplayManager's DisplayPowerController thread. 6312 @Override 6313 public void screenTurningOn(final ScreenOnListener screenOnListener) { 6314 if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on..."); 6315 6316 updateScreenOffSleepToken(false); 6317 synchronized (mLock) { 6318 mScreenOnEarly = true; 6319 mScreenOnFully = false; 6320 mKeyguardDrawComplete = false; 6321 mWindowManagerDrawComplete = false; 6322 mScreenOnListener = screenOnListener; 6323 6324 if (mKeyguardDelegate != null) { 6325 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); 6326 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000); 6327 mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); 6328 } else { 6329 if (DEBUG_WAKEUP) Slog.d(TAG, 6330 "null mKeyguardDelegate: setting mKeyguardDrawComplete."); 6331 finishKeyguardDrawn(); 6332 } 6333 } 6334 } 6335 6336 // Called on the DisplayManager's DisplayPowerController thread. 6337 @Override 6338 public void screenTurnedOn() { 6339 synchronized (mLock) { 6340 if (mKeyguardDelegate != null) { 6341 mKeyguardDelegate.onScreenTurnedOn(); 6342 } 6343 } 6344 } 6345 6346 private void finishWindowsDrawn() { 6347 synchronized (mLock) { 6348 if (!mScreenOnEarly || mWindowManagerDrawComplete) { 6349 return; // Screen is not turned on or we did already handle this case earlier. 6350 } 6351 6352 mWindowManagerDrawComplete = true; 6353 } 6354 6355 finishScreenTurningOn(); 6356 } 6357 6358 private void finishScreenTurningOn() { 6359 synchronized (mLock) { 6360 // We have just finished drawing screen content. Since the orientation listener 6361 // gets only installed when all windows are drawn, we try to install it again. 6362 updateOrientationListenerLp(); 6363 } 6364 final ScreenOnListener listener; 6365 final boolean enableScreen; 6366 synchronized (mLock) { 6367 if (DEBUG_WAKEUP) Slog.d(TAG, 6368 "finishScreenTurningOn: mAwake=" + mAwake 6369 + ", mScreenOnEarly=" + mScreenOnEarly 6370 + ", mScreenOnFully=" + mScreenOnFully 6371 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete 6372 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete); 6373 6374 if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete 6375 || (mAwake && !mKeyguardDrawComplete)) { 6376 return; // spurious or not ready yet 6377 } 6378 6379 if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on..."); 6380 listener = mScreenOnListener; 6381 mScreenOnListener = null; 6382 mScreenOnFully = true; 6383 6384 // Remember the first time we draw the keyguard so we know when we're done with 6385 // the main part of booting and can enable the screen and hide boot messages. 6386 if (!mKeyguardDrawnOnce && mAwake) { 6387 mKeyguardDrawnOnce = true; 6388 enableScreen = true; 6389 if (mBootMessageNeedsHiding) { 6390 mBootMessageNeedsHiding = false; 6391 hideBootMessages(); 6392 } 6393 } else { 6394 enableScreen = false; 6395 } 6396 } 6397 6398 if (listener != null) { 6399 listener.onScreenOn(); 6400 } 6401 6402 if (enableScreen) { 6403 try { 6404 mWindowManager.enableScreenIfNeeded(); 6405 } catch (RemoteException unhandled) { 6406 } 6407 } 6408 } 6409 6410 private void handleHideBootMessage() { 6411 synchronized (mLock) { 6412 if (!mKeyguardDrawnOnce) { 6413 mBootMessageNeedsHiding = true; 6414 return; // keyguard hasn't drawn the first time yet, not done booting 6415 } 6416 } 6417 6418 if (mBootMsgDialog != null) { 6419 if (DEBUG_WAKEUP) Slog.d(TAG, "handleHideBootMessage: dismissing"); 6420 mBootMsgDialog.dismiss(); 6421 mBootMsgDialog = null; 6422 } 6423 } 6424 6425 @Override 6426 public boolean isScreenOn() { 6427 return mScreenOnFully; 6428 } 6429 6430 /** {@inheritDoc} */ 6431 @Override 6432 public void enableKeyguard(boolean enabled) { 6433 if (mKeyguardDelegate != null) { 6434 mKeyguardDelegate.setKeyguardEnabled(enabled); 6435 } 6436 } 6437 6438 /** {@inheritDoc} */ 6439 @Override 6440 public void exitKeyguardSecurely(OnKeyguardExitResult callback) { 6441 if (mKeyguardDelegate != null) { 6442 mKeyguardDelegate.verifyUnlock(callback); 6443 } 6444 } 6445 6446 private boolean isKeyguardShowingAndNotOccluded() { 6447 if (mKeyguardDelegate == null) return false; 6448 return mKeyguardDelegate.isShowing() && !mKeyguardOccluded; 6449 } 6450 6451 /** {@inheritDoc} */ 6452 @Override 6453 public boolean isKeyguardLocked() { 6454 return keyguardOn(); 6455 } 6456 6457 /** {@inheritDoc} */ 6458 @Override 6459 public boolean isKeyguardSecure(int userId) { 6460 if (mKeyguardDelegate == null) return false; 6461 return mKeyguardDelegate.isSecure(userId); 6462 } 6463 6464 /** {@inheritDoc} */ 6465 @Override 6466 public boolean isKeyguardShowingOrOccluded() { 6467 return mKeyguardDelegate == null ? false : mKeyguardDelegate.isShowing(); 6468 } 6469 6470 /** {@inheritDoc} */ 6471 @Override 6472 public boolean inKeyguardRestrictedKeyInputMode() { 6473 if (mKeyguardDelegate == null) return false; 6474 return mKeyguardDelegate.isInputRestricted(); 6475 } 6476 6477 @Override 6478 public void dismissKeyguardLw() { 6479 if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 6480 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw"); 6481 mHandler.post(new Runnable() { 6482 @Override 6483 public void run() { 6484 // ask the keyguard to prompt the user to authenticate if necessary 6485 mKeyguardDelegate.dismiss(); 6486 } 6487 }); 6488 } 6489 } 6490 6491 @Override 6492 public void notifyActivityDrawnForKeyguardLw() { 6493 if (mKeyguardDelegate != null) { 6494 mHandler.post(new Runnable() { 6495 @Override 6496 public void run() { 6497 mKeyguardDelegate.onActivityDrawn(); 6498 } 6499 }); 6500 } 6501 } 6502 6503 @Override 6504 public boolean isKeyguardDrawnLw() { 6505 synchronized (mLock) { 6506 return mKeyguardDrawnOnce; 6507 } 6508 } 6509 6510 @Override 6511 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 6512 if (mKeyguardDelegate != null) { 6513 if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation"); 6514 mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration); 6515 } 6516 } 6517 6518 @Override 6519 public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6520 Rect outInsets) { 6521 outInsets.setEmpty(); 6522 6523 // Navigation bar and status bar. 6524 getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, outInsets); 6525 if (mStatusBar != null) { 6526 outInsets.top = mStatusBarHeight; 6527 } 6528 } 6529 6530 @Override 6531 public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight, 6532 Rect outInsets) { 6533 outInsets.setEmpty(); 6534 6535 // Only navigation bar 6536 if (mNavigationBar != null) { 6537 int position = navigationBarPosition(displayWidth, displayHeight, displayRotation); 6538 if (position == NAV_BAR_BOTTOM) { 6539 outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode); 6540 } else if (position == NAV_BAR_RIGHT) { 6541 outInsets.right = getNavigationBarWidth(displayRotation, mUiMode); 6542 } else if (position == NAV_BAR_LEFT) { 6543 outInsets.left = getNavigationBarWidth(displayRotation, mUiMode); 6544 } 6545 } 6546 } 6547 6548 @Override 6549 public boolean isNavBarForcedShownLw(WindowState windowState) { 6550 return mForceShowSystemBars; 6551 } 6552 6553 @Override 6554 public boolean isDockSideAllowed(int dockSide) { 6555 6556 // We do not allow all dock sides at which the navigation bar touches the docked stack. 6557 if (!mNavigationBarCanMove) { 6558 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT; 6559 } else { 6560 return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT; 6561 } 6562 } 6563 6564 void sendCloseSystemWindows() { 6565 PhoneWindow.sendCloseSystemWindows(mContext, null); 6566 } 6567 6568 void sendCloseSystemWindows(String reason) { 6569 PhoneWindow.sendCloseSystemWindows(mContext, reason); 6570 } 6571 6572 @Override 6573 public int rotationForOrientationLw(int orientation, int lastRotation) { 6574 if (false) { 6575 Slog.v(TAG, "rotationForOrientationLw(orient=" 6576 + orientation + ", last=" + lastRotation 6577 + "); user=" + mUserRotation + " " 6578 + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) 6579 ? "USER_ROTATION_LOCKED" : "") 6580 ); 6581 } 6582 6583 if (mForceDefaultOrientation) { 6584 return Surface.ROTATION_0; 6585 } 6586 6587 synchronized (mLock) { 6588 int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1 6589 if (sensorRotation < 0) { 6590 sensorRotation = lastRotation; 6591 } 6592 6593 final int preferredRotation; 6594 if (mLidState == LID_OPEN && mLidOpenRotation >= 0) { 6595 // Ignore sensor when lid switch is open and rotation is forced. 6596 preferredRotation = mLidOpenRotation; 6597 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR 6598 && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) { 6599 // Ignore sensor when in car dock unless explicitly enabled. 6600 // This case can override the behavior of NOSENSOR, and can also 6601 // enable 180 degree rotation while docked. 6602 preferredRotation = mCarDockEnablesAccelerometer 6603 ? sensorRotation : mCarDockRotation; 6604 } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK 6605 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK 6606 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK) 6607 && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) { 6608 // Ignore sensor when in desk dock unless explicitly enabled. 6609 // This case can override the behavior of NOSENSOR, and can also 6610 // enable 180 degree rotation while docked. 6611 preferredRotation = mDeskDockEnablesAccelerometer 6612 ? sensorRotation : mDeskDockRotation; 6613 } else if (mHdmiPlugged && mDemoHdmiRotationLock) { 6614 // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled. 6615 // Note that the dock orientation overrides the HDMI orientation. 6616 preferredRotation = mDemoHdmiRotation; 6617 } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED 6618 && mUndockedHdmiRotation >= 0) { 6619 // Ignore sensor when plugged into HDMI and an undocked orientation has 6620 // been specified in the configuration (only for legacy devices without 6621 // full multi-display support). 6622 // Note that the dock orientation overrides the HDMI orientation. 6623 preferredRotation = mUndockedHdmiRotation; 6624 } else if (mDemoRotationLock) { 6625 // Ignore sensor when demo rotation lock is enabled. 6626 // Note that the dock orientation and HDMI rotation lock override this. 6627 preferredRotation = mDemoRotation; 6628 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) { 6629 // Application just wants to remain locked in the last rotation. 6630 preferredRotation = lastRotation; 6631 } else if (!mSupportAutoRotation) { 6632 // If we don't support auto-rotation then bail out here and ignore 6633 // the sensor and any rotation lock settings. 6634 preferredRotation = -1; 6635 } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE 6636 && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER 6637 || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 6638 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE 6639 || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT 6640 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER)) 6641 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR 6642 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 6643 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE 6644 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { 6645 // Otherwise, use sensor only if requested by the application or enabled 6646 // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR. 6647 if (mAllowAllRotations < 0) { 6648 // Can't read this during init() because the context doesn't 6649 // have display metrics at that time so we cannot determine 6650 // tablet vs. phone then. 6651 mAllowAllRotations = mContext.getResources().getBoolean( 6652 com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0; 6653 } 6654 if (sensorRotation != Surface.ROTATION_180 6655 || mAllowAllRotations == 1 6656 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR 6657 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) { 6658 preferredRotation = sensorRotation; 6659 } else { 6660 preferredRotation = lastRotation; 6661 } 6662 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED 6663 && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { 6664 // Apply rotation lock. Does not apply to NOSENSOR. 6665 // The idea is that the user rotation expresses a weak preference for the direction 6666 // of gravity and as NOSENSOR is never affected by gravity, then neither should 6667 // NOSENSOR be affected by rotation lock (although it will be affected by docks). 6668 preferredRotation = mUserRotation; 6669 } else { 6670 // No overriding preference. 6671 // We will do exactly what the application asked us to do. 6672 preferredRotation = -1; 6673 } 6674 6675 switch (orientation) { 6676 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 6677 // Return portrait unless overridden. 6678 if (isAnyPortrait(preferredRotation)) { 6679 return preferredRotation; 6680 } 6681 return mPortraitRotation; 6682 6683 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 6684 // Return landscape unless overridden. 6685 if (isLandscapeOrSeascape(preferredRotation)) { 6686 return preferredRotation; 6687 } 6688 return mLandscapeRotation; 6689 6690 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 6691 // Return reverse portrait unless overridden. 6692 if (isAnyPortrait(preferredRotation)) { 6693 return preferredRotation; 6694 } 6695 return mUpsideDownRotation; 6696 6697 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 6698 // Return seascape unless overridden. 6699 if (isLandscapeOrSeascape(preferredRotation)) { 6700 return preferredRotation; 6701 } 6702 return mSeascapeRotation; 6703 6704 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 6705 case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE: 6706 // Return either landscape rotation. 6707 if (isLandscapeOrSeascape(preferredRotation)) { 6708 return preferredRotation; 6709 } 6710 if (isLandscapeOrSeascape(lastRotation)) { 6711 return lastRotation; 6712 } 6713 return mLandscapeRotation; 6714 6715 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 6716 case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT: 6717 // Return either portrait rotation. 6718 if (isAnyPortrait(preferredRotation)) { 6719 return preferredRotation; 6720 } 6721 if (isAnyPortrait(lastRotation)) { 6722 return lastRotation; 6723 } 6724 return mPortraitRotation; 6725 6726 default: 6727 // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR, 6728 // just return the preferred orientation we already calculated. 6729 if (preferredRotation >= 0) { 6730 return preferredRotation; 6731 } 6732 return Surface.ROTATION_0; 6733 } 6734 } 6735 } 6736 6737 @Override 6738 public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) { 6739 switch (orientation) { 6740 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: 6741 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: 6742 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: 6743 return isAnyPortrait(rotation); 6744 6745 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: 6746 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: 6747 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: 6748 return isLandscapeOrSeascape(rotation); 6749 6750 default: 6751 return true; 6752 } 6753 } 6754 6755 @Override 6756 public void setRotationLw(int rotation) { 6757 mOrientationListener.setCurrentRotation(rotation); 6758 } 6759 6760 private boolean isLandscapeOrSeascape(int rotation) { 6761 return rotation == mLandscapeRotation || rotation == mSeascapeRotation; 6762 } 6763 6764 private boolean isAnyPortrait(int rotation) { 6765 return rotation == mPortraitRotation || rotation == mUpsideDownRotation; 6766 } 6767 6768 @Override 6769 public int getUserRotationMode() { 6770 return Settings.System.getIntForUser(mContext.getContentResolver(), 6771 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ? 6772 WindowManagerPolicy.USER_ROTATION_FREE : 6773 WindowManagerPolicy.USER_ROTATION_LOCKED; 6774 } 6775 6776 // User rotation: to be used when all else fails in assigning an orientation to the device 6777 @Override 6778 public void setUserRotationMode(int mode, int rot) { 6779 ContentResolver res = mContext.getContentResolver(); 6780 6781 // mUserRotationMode and mUserRotation will be assigned by the content observer 6782 if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) { 6783 Settings.System.putIntForUser(res, 6784 Settings.System.USER_ROTATION, 6785 rot, 6786 UserHandle.USER_CURRENT); 6787 Settings.System.putIntForUser(res, 6788 Settings.System.ACCELEROMETER_ROTATION, 6789 0, 6790 UserHandle.USER_CURRENT); 6791 } else { 6792 Settings.System.putIntForUser(res, 6793 Settings.System.ACCELEROMETER_ROTATION, 6794 1, 6795 UserHandle.USER_CURRENT); 6796 } 6797 } 6798 6799 @Override 6800 public void setSafeMode(boolean safeMode) { 6801 mSafeMode = safeMode; 6802 performHapticFeedbackLw(null, safeMode 6803 ? HapticFeedbackConstants.SAFE_MODE_ENABLED 6804 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true); 6805 } 6806 6807 static long[] getLongIntArray(Resources r, int resid) { 6808 int[] ar = r.getIntArray(resid); 6809 if (ar == null) { 6810 return null; 6811 } 6812 long[] out = new long[ar.length]; 6813 for (int i=0; i<ar.length; i++) { 6814 out[i] = ar[i]; 6815 } 6816 return out; 6817 } 6818 6819 /** {@inheritDoc} */ 6820 @Override 6821 public void systemReady() { 6822 mKeyguardDelegate = new KeyguardServiceDelegate(mContext); 6823 mKeyguardDelegate.onSystemReady(); 6824 6825 readCameraLensCoverState(); 6826 updateUiMode(); 6827 boolean bindKeyguardNow; 6828 synchronized (mLock) { 6829 updateOrientationListenerLp(); 6830 mSystemReady = true; 6831 mHandler.post(new Runnable() { 6832 @Override 6833 public void run() { 6834 updateSettings(); 6835 } 6836 }); 6837 6838 bindKeyguardNow = mDeferBindKeyguard; 6839 if (bindKeyguardNow) { 6840 // systemBooted ran but wasn't able to bind to the Keyguard, we'll do it now. 6841 mDeferBindKeyguard = false; 6842 } 6843 } 6844 6845 if (bindKeyguardNow) { 6846 mKeyguardDelegate.bindService(mContext); 6847 mKeyguardDelegate.onBootCompleted(); 6848 } 6849 mSystemGestures.systemReady(); 6850 mImmersiveModeConfirmation.systemReady(); 6851 } 6852 6853 /** {@inheritDoc} */ 6854 @Override 6855 public void systemBooted() { 6856 boolean bindKeyguardNow = false; 6857 synchronized (mLock) { 6858 // Time to bind Keyguard; take care to only bind it once, either here if ready or 6859 // in systemReady if not. 6860 if (mKeyguardDelegate != null) { 6861 bindKeyguardNow = true; 6862 } else { 6863 // Because mKeyguardDelegate is null, we know that the synchronized block in 6864 // systemReady didn't run yet and setting this will actually have an effect. 6865 mDeferBindKeyguard = true; 6866 } 6867 } 6868 if (bindKeyguardNow) { 6869 mKeyguardDelegate.bindService(mContext); 6870 mKeyguardDelegate.onBootCompleted(); 6871 } 6872 synchronized (mLock) { 6873 mSystemBooted = true; 6874 } 6875 startedWakingUp(); 6876 screenTurningOn(null); 6877 screenTurnedOn(); 6878 } 6879 6880 ProgressDialog mBootMsgDialog = null; 6881 6882 /** {@inheritDoc} */ 6883 @Override 6884 public void showBootMessage(final CharSequence msg, final boolean always) { 6885 mHandler.post(new Runnable() { 6886 @Override public void run() { 6887 if (mBootMsgDialog == null) { 6888 int theme; 6889 if (mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION)) { 6890 theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert; 6891 } else { 6892 theme = 0; 6893 } 6894 6895 mBootMsgDialog = new ProgressDialog(mContext, theme) { 6896 // This dialog will consume all events coming in to 6897 // it, to avoid it trying to do things too early in boot. 6898 @Override public boolean dispatchKeyEvent(KeyEvent event) { 6899 return true; 6900 } 6901 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) { 6902 return true; 6903 } 6904 @Override public boolean dispatchTouchEvent(MotionEvent ev) { 6905 return true; 6906 } 6907 @Override public boolean dispatchTrackballEvent(MotionEvent ev) { 6908 return true; 6909 } 6910 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) { 6911 return true; 6912 } 6913 @Override public boolean dispatchPopulateAccessibilityEvent( 6914 AccessibilityEvent event) { 6915 return true; 6916 } 6917 }; 6918 if (mContext.getPackageManager().isUpgrade()) { 6919 mBootMsgDialog.setTitle(R.string.android_upgrading_title); 6920 } else { 6921 mBootMsgDialog.setTitle(R.string.android_start_title); 6922 } 6923 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 6924 mBootMsgDialog.setIndeterminate(true); 6925 mBootMsgDialog.getWindow().setType( 6926 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS); 6927 mBootMsgDialog.getWindow().addFlags( 6928 WindowManager.LayoutParams.FLAG_DIM_BEHIND 6929 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 6930 mBootMsgDialog.getWindow().setDimAmount(1); 6931 WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes(); 6932 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 6933 mBootMsgDialog.getWindow().setAttributes(lp); 6934 mBootMsgDialog.setCancelable(false); 6935 mBootMsgDialog.show(); 6936 } 6937 mBootMsgDialog.setMessage(msg); 6938 } 6939 }); 6940 } 6941 6942 /** {@inheritDoc} */ 6943 @Override 6944 public void hideBootMessages() { 6945 mHandler.sendEmptyMessage(MSG_HIDE_BOOT_MESSAGE); 6946 } 6947 6948 /** {@inheritDoc} */ 6949 @Override 6950 public void userActivity() { 6951 // *************************************** 6952 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE 6953 // *************************************** 6954 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER 6955 // WITH ITS LOCKS HELD. 6956 // 6957 // This code must be VERY careful about the locks 6958 // it acquires. 6959 // In fact, the current code acquires way too many, 6960 // and probably has lurking deadlocks. 6961 6962 synchronized (mScreenLockTimeout) { 6963 if (mLockScreenTimerActive) { 6964 // reset the timer 6965 mHandler.removeCallbacks(mScreenLockTimeout); 6966 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 6967 } 6968 } 6969 } 6970 6971 class ScreenLockTimeout implements Runnable { 6972 Bundle options; 6973 6974 @Override 6975 public void run() { 6976 synchronized (this) { 6977 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard"); 6978 if (mKeyguardDelegate != null) { 6979 mKeyguardDelegate.doKeyguardTimeout(options); 6980 } 6981 mLockScreenTimerActive = false; 6982 options = null; 6983 } 6984 } 6985 6986 public void setLockOptions(Bundle options) { 6987 this.options = options; 6988 } 6989 } 6990 6991 ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout(); 6992 6993 @Override 6994 public void lockNow(Bundle options) { 6995 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); 6996 mHandler.removeCallbacks(mScreenLockTimeout); 6997 if (options != null) { 6998 // In case multiple calls are made to lockNow, we don't wipe out the options 6999 // until the runnable actually executes. 7000 mScreenLockTimeout.setLockOptions(options); 7001 } 7002 mHandler.post(mScreenLockTimeout); 7003 } 7004 7005 private void updateLockScreenTimeout() { 7006 synchronized (mScreenLockTimeout) { 7007 boolean enable = (mAllowLockscreenWhenOn && mAwake && 7008 mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId)); 7009 if (mLockScreenTimerActive != enable) { 7010 if (enable) { 7011 if (localLOGV) Log.v(TAG, "setting lockscreen timer"); 7012 mHandler.removeCallbacks(mScreenLockTimeout); // remove any pending requests 7013 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); 7014 } else { 7015 if (localLOGV) Log.v(TAG, "clearing lockscreen timer"); 7016 mHandler.removeCallbacks(mScreenLockTimeout); 7017 } 7018 mLockScreenTimerActive = enable; 7019 } 7020 } 7021 } 7022 7023 private void updateDreamingSleepToken(boolean acquire) { 7024 if (acquire) { 7025 if (mDreamingSleepToken == null) { 7026 mDreamingSleepToken = mActivityManagerInternal.acquireSleepToken("Dream"); 7027 } 7028 } else { 7029 if (mDreamingSleepToken != null) { 7030 mDreamingSleepToken.release(); 7031 mDreamingSleepToken = null; 7032 } 7033 } 7034 } 7035 7036 private void updateScreenOffSleepToken(boolean acquire) { 7037 if (acquire) { 7038 if (mScreenOffSleepToken == null) { 7039 mScreenOffSleepToken = mActivityManagerInternal.acquireSleepToken("ScreenOff"); 7040 } 7041 } else { 7042 if (mScreenOffSleepToken != null) { 7043 mScreenOffSleepToken.release(); 7044 mScreenOffSleepToken = null; 7045 } 7046 } 7047 } 7048 7049 /** {@inheritDoc} */ 7050 @Override 7051 public void enableScreenAfterBoot() { 7052 readLidState(); 7053 applyLidSwitchState(); 7054 updateRotation(true); 7055 } 7056 7057 private void applyLidSwitchState() { 7058 if (mLidState == LID_CLOSED && mLidControlsSleep) { 7059 mPowerManager.goToSleep(SystemClock.uptimeMillis(), 7060 PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH, 7061 PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); 7062 } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) { 7063 mWindowManagerFuncs.lockDeviceNow(); 7064 } 7065 7066 synchronized (mLock) { 7067 updateWakeGestureListenerLp(); 7068 } 7069 } 7070 7071 void updateUiMode() { 7072 if (mUiModeManager == null) { 7073 mUiModeManager = IUiModeManager.Stub.asInterface( 7074 ServiceManager.getService(Context.UI_MODE_SERVICE)); 7075 } 7076 try { 7077 mUiMode = mUiModeManager.getCurrentModeType(); 7078 } catch (RemoteException e) { 7079 } 7080 } 7081 7082 void updateRotation(boolean alwaysSendConfiguration) { 7083 try { 7084 //set orientation on WindowManager 7085 mWindowManager.updateRotation(alwaysSendConfiguration, false); 7086 } catch (RemoteException e) { 7087 // Ignore 7088 } 7089 } 7090 7091 void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { 7092 try { 7093 //set orientation on WindowManager 7094 mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout); 7095 } catch (RemoteException e) { 7096 // Ignore 7097 } 7098 } 7099 7100 /** 7101 * Return an Intent to launch the currently active dock app as home. Returns 7102 * null if the standard home should be launched, which is the case if any of the following is 7103 * true: 7104 * <ul> 7105 * <li>The device is not in either car mode or desk mode 7106 * <li>The device is in car mode but mEnableCarDockHomeCapture is false 7107 * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false 7108 * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME 7109 * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME 7110 * </ul> 7111 * @return A dock intent. 7112 */ 7113 Intent createHomeDockIntent() { 7114 Intent intent = null; 7115 7116 // What home does is based on the mode, not the dock state. That 7117 // is, when in car mode you should be taken to car home regardless 7118 // of whether we are actually in a car dock. 7119 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) { 7120 if (mEnableCarDockHomeCapture) { 7121 intent = mCarDockIntent; 7122 } 7123 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) { 7124 if (ENABLE_DESK_DOCK_HOME_CAPTURE) { 7125 intent = mDeskDockIntent; 7126 } 7127 } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH 7128 && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK 7129 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK 7130 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) { 7131 // Always launch dock home from home when watch is docked, if it exists. 7132 intent = mDeskDockIntent; 7133 } 7134 7135 if (intent == null) { 7136 return null; 7137 } 7138 7139 ActivityInfo ai = null; 7140 ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser( 7141 intent, 7142 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, 7143 mCurrentUserId); 7144 if (info != null) { 7145 ai = info.activityInfo; 7146 } 7147 if (ai != null 7148 && ai.metaData != null 7149 && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) { 7150 intent = new Intent(intent); 7151 intent.setClassName(ai.packageName, ai.name); 7152 return intent; 7153 } 7154 7155 return null; 7156 } 7157 7158 void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) { 7159 if (awakenFromDreams) { 7160 awakenDreams(); 7161 } 7162 7163 Intent dock = createHomeDockIntent(); 7164 if (dock != null) { 7165 try { 7166 if (fromHomeKey) { 7167 dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7168 } 7169 startActivityAsUser(dock, UserHandle.CURRENT); 7170 return; 7171 } catch (ActivityNotFoundException e) { 7172 } 7173 } 7174 7175 Intent intent; 7176 7177 if (fromHomeKey) { 7178 intent = new Intent(mHomeIntent); 7179 intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); 7180 } else { 7181 intent = mHomeIntent; 7182 } 7183 7184 startActivityAsUser(intent, UserHandle.CURRENT); 7185 } 7186 7187 /** 7188 * goes to the home screen 7189 * @return whether it did anything 7190 */ 7191 boolean goHome() { 7192 if (!isUserSetupComplete()) { 7193 Slog.i(TAG, "Not going home because user setup is in progress."); 7194 return false; 7195 } 7196 if (false) { 7197 // This code always brings home to the front. 7198 try { 7199 ActivityManagerNative.getDefault().stopAppSwitches(); 7200 } catch (RemoteException e) { 7201 } 7202 sendCloseSystemWindows(); 7203 startDockOrHome(false /*fromHomeKey*/, true /* awakenFromDreams */); 7204 } else { 7205 // This code brings home to the front or, if it is already 7206 // at the front, puts the device to sleep. 7207 try { 7208 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) { 7209 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry. 7210 Log.d(TAG, "UTS-TEST-MODE"); 7211 } else { 7212 ActivityManagerNative.getDefault().stopAppSwitches(); 7213 sendCloseSystemWindows(); 7214 Intent dock = createHomeDockIntent(); 7215 if (dock != null) { 7216 int result = ActivityManagerNative.getDefault() 7217 .startActivityAsUser(null, null, dock, 7218 dock.resolveTypeIfNeeded(mContext.getContentResolver()), 7219 null, null, 0, 7220 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7221 null, null, UserHandle.USER_CURRENT); 7222 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7223 return false; 7224 } 7225 } 7226 } 7227 int result = ActivityManagerNative.getDefault() 7228 .startActivityAsUser(null, null, mHomeIntent, 7229 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()), 7230 null, null, 0, 7231 ActivityManager.START_FLAG_ONLY_IF_NEEDED, 7232 null, null, UserHandle.USER_CURRENT); 7233 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) { 7234 return false; 7235 } 7236 } catch (RemoteException ex) { 7237 // bummer, the activity manager, which is in this process, is dead 7238 } 7239 } 7240 return true; 7241 } 7242 7243 @Override 7244 public void setCurrentOrientationLw(int newOrientation) { 7245 synchronized (mLock) { 7246 if (newOrientation != mCurrentAppOrientation) { 7247 mCurrentAppOrientation = newOrientation; 7248 updateOrientationListenerLp(); 7249 } 7250 } 7251 } 7252 7253 private void performAuditoryFeedbackForAccessibilityIfNeed() { 7254 if (!isGlobalAccessibilityGestureEnabled()) { 7255 return; 7256 } 7257 AudioManager audioManager = (AudioManager) mContext.getSystemService( 7258 Context.AUDIO_SERVICE); 7259 if (audioManager.isSilentMode()) { 7260 return; 7261 } 7262 Ringtone ringTone = RingtoneManager.getRingtone(mContext, 7263 Settings.System.DEFAULT_NOTIFICATION_URI); 7264 ringTone.setStreamType(AudioManager.STREAM_MUSIC); 7265 ringTone.play(); 7266 } 7267 7268 private boolean isTheaterModeEnabled() { 7269 return Settings.Global.getInt(mContext.getContentResolver(), 7270 Settings.Global.THEATER_MODE_ON, 0) == 1; 7271 } 7272 7273 private boolean isGlobalAccessibilityGestureEnabled() { 7274 return Settings.Global.getInt(mContext.getContentResolver(), 7275 Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1; 7276 } 7277 7278 private boolean areSystemNavigationKeysEnabled() { 7279 return Settings.Global.getInt(mContext.getContentResolver(), 7280 Settings.Global.SYSTEM_NAVIGATION_KEYS_ENABLED, 1) == 1; 7281 } 7282 7283 @Override 7284 public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) { 7285 if (!mVibrator.hasVibrator()) { 7286 return false; 7287 } 7288 final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(), 7289 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0; 7290 if (hapticsDisabled && !always) { 7291 return false; 7292 } 7293 long[] pattern = null; 7294 switch (effectId) { 7295 case HapticFeedbackConstants.LONG_PRESS: 7296 pattern = mLongPressVibePattern; 7297 break; 7298 case HapticFeedbackConstants.VIRTUAL_KEY: 7299 pattern = mVirtualKeyVibePattern; 7300 break; 7301 case HapticFeedbackConstants.KEYBOARD_TAP: 7302 pattern = mKeyboardTapVibePattern; 7303 break; 7304 case HapticFeedbackConstants.CLOCK_TICK: 7305 pattern = mClockTickVibePattern; 7306 break; 7307 case HapticFeedbackConstants.CALENDAR_DATE: 7308 pattern = mCalendarDateVibePattern; 7309 break; 7310 case HapticFeedbackConstants.SAFE_MODE_DISABLED: 7311 pattern = mSafeModeDisabledVibePattern; 7312 break; 7313 case HapticFeedbackConstants.SAFE_MODE_ENABLED: 7314 pattern = mSafeModeEnabledVibePattern; 7315 break; 7316 case HapticFeedbackConstants.CONTEXT_CLICK: 7317 pattern = mContextClickVibePattern; 7318 break; 7319 default: 7320 return false; 7321 } 7322 int owningUid; 7323 String owningPackage; 7324 if (win != null) { 7325 owningUid = win.getOwningUid(); 7326 owningPackage = win.getOwningPackage(); 7327 } else { 7328 owningUid = android.os.Process.myUid(); 7329 owningPackage = mContext.getOpPackageName(); 7330 } 7331 if (pattern.length == 1) { 7332 // One-shot vibration 7333 mVibrator.vibrate(owningUid, owningPackage, pattern[0], VIBRATION_ATTRIBUTES); 7334 } else { 7335 // Pattern vibration 7336 mVibrator.vibrate(owningUid, owningPackage, pattern, -1, VIBRATION_ATTRIBUTES); 7337 } 7338 return true; 7339 } 7340 7341 @Override 7342 public void keepScreenOnStartedLw() { 7343 } 7344 7345 @Override 7346 public void keepScreenOnStoppedLw() { 7347 if (isKeyguardShowingAndNotOccluded()) { 7348 mPowerManager.userActivity(SystemClock.uptimeMillis(), false); 7349 } 7350 } 7351 7352 private int updateSystemUiVisibilityLw() { 7353 // If there is no window focused, there will be nobody to handle the events 7354 // anyway, so just hang on in whatever state we're in until things settle down. 7355 final WindowState win = mFocusedWindow != null ? mFocusedWindow 7356 : mTopFullscreenOpaqueWindowState; 7357 if (win == null) { 7358 return 0; 7359 } 7360 if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mHideLockScreen == true) { 7361 // We are updating at a point where the keyguard has gotten 7362 // focus, but we were last in a state where the top window is 7363 // hiding it. This is probably because the keyguard as been 7364 // shown while the top window was displayed, so we want to ignore 7365 // it here because this is just a very transient change and it 7366 // will quickly lose focus once it correctly gets hidden. 7367 return 0; 7368 } 7369 7370 int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null) 7371 & ~mResettingSystemUiFlags 7372 & ~mForceClearedSystemUiFlags; 7373 if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) { 7374 tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS); 7375 } 7376 7377 final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */, 7378 mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState); 7379 final int dockedVisibility = updateLightStatusBarLw(0 /* vis */, 7380 mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState); 7381 mWindowManagerFuncs.getStackBounds(HOME_STACK_ID, mNonDockedStackBounds); 7382 mWindowManagerFuncs.getStackBounds(DOCKED_STACK_ID, mDockedStackBounds); 7383 final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility); 7384 final int diff = visibility ^ mLastSystemUiFlags; 7385 final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags; 7386 final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags; 7387 final boolean needsMenu = win.getNeedsMenuLw(mTopFullscreenOpaqueWindowState); 7388 if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0 && mLastFocusNeedsMenu == needsMenu 7389 && mFocusedApp == win.getAppToken() 7390 && mLastNonDockedStackBounds.equals(mNonDockedStackBounds) 7391 && mLastDockedStackBounds.equals(mDockedStackBounds)) { 7392 return 0; 7393 } 7394 mLastSystemUiFlags = visibility; 7395 mLastFullscreenStackSysUiFlags = fullscreenVisibility; 7396 mLastDockedStackSysUiFlags = dockedVisibility; 7397 mLastFocusNeedsMenu = needsMenu; 7398 mFocusedApp = win.getAppToken(); 7399 final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds); 7400 final Rect dockedStackBounds = new Rect(mDockedStackBounds); 7401 mHandler.post(new Runnable() { 7402 @Override 7403 public void run() { 7404 StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); 7405 if (statusbar != null) { 7406 statusbar.setSystemUiVisibility(visibility, fullscreenVisibility, 7407 dockedVisibility, 0xffffffff, fullscreenStackBounds, 7408 dockedStackBounds, win.toString()); 7409 statusbar.topAppWindowChanged(needsMenu); 7410 } 7411 } 7412 }); 7413 return diff; 7414 } 7415 7416 private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) { 7417 WindowState statusColorWin = isStatusBarKeyguard() && !mHideLockScreen 7418 ? mStatusBar 7419 : opaqueOrDimming; 7420 7421 if (statusColorWin != null) { 7422 if (statusColorWin == opaque) { 7423 // If the top fullscreen-or-dimming window is also the top fullscreen, respect 7424 // its light flag. 7425 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7426 vis |= PolicyControl.getSystemUiVisibility(statusColorWin, null) 7427 & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7428 } else if (statusColorWin != null && statusColorWin.isDimming()) { 7429 // Otherwise if it's dimming, clear the light flag. 7430 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7431 } 7432 } 7433 return vis; 7434 } 7435 7436 private boolean drawsSystemBarBackground(WindowState win) { 7437 return win == null || (win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; 7438 } 7439 7440 private boolean forcesDrawStatusBarBackground(WindowState win) { 7441 return win == null || (win.getAttrs().privateFlags 7442 & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0; 7443 } 7444 7445 private int updateSystemBarsLw(WindowState win, int oldVis, int vis) { 7446 final boolean dockedStackVisible = mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID); 7447 final boolean freeformStackVisible = 7448 mWindowManagerInternal.isStackVisible(FREEFORM_WORKSPACE_STACK_ID); 7449 final boolean resizing = mWindowManagerInternal.isDockedDividerResizing(); 7450 7451 // We need to force system bars when the docked stack is visible, when the freeform stack 7452 // is visible but also when we are resizing for the transitions when docked stack 7453 // visibility changes. 7454 mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; 7455 final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard; 7456 7457 // apply translucent bar vis flags 7458 WindowState fullscreenTransWin = isStatusBarKeyguard() && !mHideLockScreen 7459 ? mStatusBar 7460 : mTopFullscreenOpaqueWindowState; 7461 vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7462 vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis); 7463 final int dockedVis = mStatusBarController.applyTranslucentFlagLw( 7464 mTopDockedOpaqueWindowState, 0, 0); 7465 7466 final boolean fullscreenDrawsStatusBarBackground = 7467 (drawsSystemBarBackground(mTopFullscreenOpaqueWindowState) 7468 && (vis & View.STATUS_BAR_TRANSLUCENT) == 0) 7469 || forcesDrawStatusBarBackground(mTopFullscreenOpaqueWindowState); 7470 final boolean dockedDrawsStatusBarBackground = 7471 (drawsSystemBarBackground(mTopDockedOpaqueWindowState) 7472 && (dockedVis & View.STATUS_BAR_TRANSLUCENT) == 0) 7473 || forcesDrawStatusBarBackground(mTopDockedOpaqueWindowState); 7474 7475 // prevent status bar interaction from clearing certain flags 7476 int type = win.getAttrs().type; 7477 boolean statusBarHasFocus = type == TYPE_STATUS_BAR; 7478 if (statusBarHasFocus && !isStatusBarKeyguard()) { 7479 int flags = View.SYSTEM_UI_FLAG_FULLSCREEN 7480 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 7481 | View.SYSTEM_UI_FLAG_IMMERSIVE 7482 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 7483 | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; 7484 if (mHideLockScreen) { 7485 flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT; 7486 } 7487 vis = (vis & ~flags) | (oldVis & flags); 7488 } 7489 7490 if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) { 7491 vis |= View.STATUS_BAR_TRANSPARENT; 7492 vis &= ~View.STATUS_BAR_TRANSLUCENT; 7493 } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar) 7494 || forceOpaqueStatusBar) { 7495 vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT); 7496 } 7497 7498 vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing); 7499 7500 // update status bar 7501 boolean immersiveSticky = 7502 (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7503 final boolean hideStatusBarWM = 7504 mTopFullscreenOpaqueWindowState != null 7505 && (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null) 7506 & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; 7507 final boolean hideStatusBarSysui = 7508 (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0; 7509 final boolean hideNavBarSysui = 7510 (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; 7511 7512 final boolean transientStatusBarAllowed = mStatusBar != null 7513 && (statusBarHasFocus || (!mForceShowSystemBars 7514 && (hideStatusBarWM || (hideStatusBarSysui && immersiveSticky)))); 7515 7516 final boolean transientNavBarAllowed = mNavigationBar != null 7517 && !mForceShowSystemBars && hideNavBarSysui && immersiveSticky; 7518 7519 final long now = SystemClock.uptimeMillis(); 7520 final boolean pendingPanic = mPendingPanicGestureUptime != 0 7521 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION; 7522 if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) { 7523 // The user performed the panic gesture recently, we're about to hide the bars, 7524 // we're no longer on the Keyguard and the screen is ready. We can now request the bars. 7525 mPendingPanicGestureUptime = 0; 7526 mStatusBarController.showTransient(); 7527 mNavigationBarController.showTransient(); 7528 } 7529 7530 final boolean denyTransientStatus = mStatusBarController.isTransientShowRequested() 7531 && !transientStatusBarAllowed && hideStatusBarSysui; 7532 final boolean denyTransientNav = mNavigationBarController.isTransientShowRequested() 7533 && !transientNavBarAllowed; 7534 if (denyTransientStatus || denyTransientNav || mForceShowSystemBars) { 7535 // clear the clearable flags instead 7536 clearClearableFlagsLw(); 7537 vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS; 7538 } 7539 7540 final boolean immersive = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; 7541 immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; 7542 final boolean navAllowedHidden = immersive || immersiveSticky; 7543 7544 if (hideNavBarSysui && !navAllowedHidden && windowTypeToLayerLw(win.getBaseType()) 7545 > windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) { 7546 // We can't hide the navbar from this window otherwise the input consumer would not get 7547 // the input events. 7548 vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 7549 } 7550 7551 vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis); 7552 7553 // update navigation bar 7554 boolean oldImmersiveMode = isImmersiveMode(oldVis); 7555 boolean newImmersiveMode = isImmersiveMode(vis); 7556 if (win != null && oldImmersiveMode != newImmersiveMode) { 7557 final String pkg = win.getOwningPackage(); 7558 mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode, 7559 isUserSetupComplete()); 7560 } 7561 7562 vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis); 7563 7564 return vis; 7565 } 7566 7567 /** 7568 * @return the current visibility flags with the nav-bar opacity related flags toggled based 7569 * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}. 7570 */ 7571 private int configureNavBarOpacity(int visibility, boolean dockedStackVisible, 7572 boolean freeformStackVisible, boolean isDockedDividerResizing) { 7573 if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { 7574 if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { 7575 visibility = setNavBarOpaqueFlag(visibility); 7576 } 7577 } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { 7578 if (isDockedDividerResizing) { 7579 visibility = setNavBarOpaqueFlag(visibility); 7580 } else if (freeformStackVisible) { 7581 visibility = setNavBarTranslucentFlag(visibility); 7582 } else { 7583 visibility = setNavBarOpaqueFlag(visibility); 7584 } 7585 } 7586 7587 if (!areTranslucentBarsAllowed()) { 7588 visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT; 7589 } 7590 return visibility; 7591 } 7592 7593 private int setNavBarOpaqueFlag(int visibility) { 7594 return visibility &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT); 7595 } 7596 7597 private int setNavBarTranslucentFlag(int visibility) { 7598 visibility &= ~View.NAVIGATION_BAR_TRANSPARENT; 7599 return visibility |= View.NAVIGATION_BAR_TRANSLUCENT; 7600 } 7601 7602 private void clearClearableFlagsLw() { 7603 int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS; 7604 if (newVal != mResettingSystemUiFlags) { 7605 mResettingSystemUiFlags = newVal; 7606 mWindowManagerFuncs.reevaluateStatusBarVisibility(); 7607 } 7608 } 7609 7610 private boolean isImmersiveMode(int vis) { 7611 final int flags = View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 7612 return mNavigationBar != null 7613 && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 7614 && (vis & flags) != 0 7615 && canHideNavigationBar(); 7616 } 7617 7618 /** 7619 * @return whether the navigation or status bar can be made translucent 7620 * 7621 * This should return true unless touch exploration is not enabled or 7622 * R.boolean.config_enableTranslucentDecor is false. 7623 */ 7624 private boolean areTranslucentBarsAllowed() { 7625 return mTranslucentDecorEnabled; 7626 } 7627 7628 // Use this instead of checking config_showNavigationBar so that it can be consistently 7629 // overridden by qemu.hw.mainkeys in the emulator. 7630 @Override 7631 public boolean hasNavigationBar() { 7632 return mHasNavigationBar; 7633 } 7634 7635 @Override 7636 public void setLastInputMethodWindowLw(WindowState ime, WindowState target) { 7637 mLastInputMethodWindow = ime; 7638 mLastInputMethodTargetWindow = target; 7639 } 7640 7641 @Override 7642 public int getInputMethodWindowVisibleHeightLw() { 7643 return mDockBottom - mCurBottom; 7644 } 7645 7646 @Override 7647 public void setCurrentUserLw(int newUserId) { 7648 mCurrentUserId = newUserId; 7649 if (mKeyguardDelegate != null) { 7650 mKeyguardDelegate.setCurrentUser(newUserId); 7651 } 7652 StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); 7653 if (statusBar != null) { 7654 statusBar.setCurrentUser(newUserId); 7655 } 7656 setLastInputMethodWindowLw(null, null); 7657 } 7658 7659 @Override 7660 public boolean canMagnifyWindow(int windowType) { 7661 switch (windowType) { 7662 case WindowManager.LayoutParams.TYPE_INPUT_METHOD: 7663 case WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG: 7664 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR: 7665 case WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY: { 7666 return false; 7667 } 7668 } 7669 return true; 7670 } 7671 7672 @Override 7673 public boolean isTopLevelWindow(int windowType) { 7674 if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW 7675 && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 7676 return (windowType == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG); 7677 } 7678 return true; 7679 } 7680 7681 @Override 7682 public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) { 7683 // For the upside down rotation we don't rotate seamlessly as the navigation 7684 // bar moves position. 7685 // Note most apps (using orientation:sensor or user as opposed to fullSensor) 7686 // will not enter the reverse portrait orientation, so actually the 7687 // orientation won't change at all. 7688 if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) { 7689 return false; 7690 } 7691 int delta = newRotation - oldRotation; 7692 if (delta < 0) delta += 4; 7693 // Likewise we don't rotate seamlessly for 180 degree rotations 7694 // in this case the surfaces never resize, and our logic to 7695 // revert the transformations on size change will fail. We could 7696 // fix this in the future with the "tagged" frames idea. 7697 if (delta == Surface.ROTATION_180) { 7698 return false; 7699 } 7700 7701 if (mTopFullscreenOpaqueWindowState != null && mTopIsFullscreen && 7702 mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation == 7703 ROTATION_ANIMATION_JUMPCUT) { 7704 return true; 7705 } 7706 return false; 7707 } 7708 7709 @Override 7710 public void dump(String prefix, PrintWriter pw, String[] args) { 7711 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode); 7712 pw.print(" mSystemReady="); pw.print(mSystemReady); 7713 pw.print(" mSystemBooted="); pw.println(mSystemBooted); 7714 pw.print(prefix); pw.print("mLidState="); pw.print(mLidState); 7715 pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation); 7716 pw.print(" mCameraLensCoverState="); pw.print(mCameraLensCoverState); 7717 pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged); 7718 if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0 7719 || mForceClearedSystemUiFlags != 0) { 7720 pw.print(prefix); pw.print("mLastSystemUiFlags=0x"); 7721 pw.print(Integer.toHexString(mLastSystemUiFlags)); 7722 pw.print(" mResettingSystemUiFlags=0x"); 7723 pw.print(Integer.toHexString(mResettingSystemUiFlags)); 7724 pw.print(" mForceClearedSystemUiFlags=0x"); 7725 pw.println(Integer.toHexString(mForceClearedSystemUiFlags)); 7726 } 7727 if (mLastFocusNeedsMenu) { 7728 pw.print(prefix); pw.print("mLastFocusNeedsMenu="); 7729 pw.println(mLastFocusNeedsMenu); 7730 } 7731 pw.print(prefix); pw.print("mWakeGestureEnabledSetting="); 7732 pw.println(mWakeGestureEnabledSetting); 7733 7734 pw.print(prefix); pw.print("mSupportAutoRotation="); pw.println(mSupportAutoRotation); 7735 pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode); 7736 pw.print(" mDockMode="); pw.print(mDockMode); 7737 pw.print(" mEnableCarDockHomeCapture="); pw.print(mEnableCarDockHomeCapture); 7738 pw.print(" mCarDockRotation="); pw.print(mCarDockRotation); 7739 pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation); 7740 pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode); 7741 pw.print(" mUserRotation="); pw.print(mUserRotation); 7742 pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations); 7743 pw.print(prefix); pw.print("mCurrentAppOrientation="); pw.println(mCurrentAppOrientation); 7744 pw.print(prefix); pw.print("mCarDockEnablesAccelerometer="); 7745 pw.print(mCarDockEnablesAccelerometer); 7746 pw.print(" mDeskDockEnablesAccelerometer="); 7747 pw.println(mDeskDockEnablesAccelerometer); 7748 pw.print(prefix); pw.print("mLidKeyboardAccessibility="); 7749 pw.print(mLidKeyboardAccessibility); 7750 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility); 7751 pw.print(" mLidControlsScreenLock="); pw.println(mLidControlsScreenLock); 7752 pw.print(" mLidControlsSleep="); pw.println(mLidControlsSleep); 7753 pw.print(prefix); 7754 pw.print(" mLongPressOnBackBehavior="); pw.println(mLongPressOnBackBehavior); 7755 pw.print(prefix); 7756 pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior); 7757 pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior); 7758 pw.print(prefix); 7759 pw.print("mDoublePressOnPowerBehavior="); pw.print(mDoublePressOnPowerBehavior); 7760 pw.print(" mTriplePressOnPowerBehavior="); pw.println(mTriplePressOnPowerBehavior); 7761 pw.print(prefix); pw.print("mHasSoftInput="); pw.println(mHasSoftInput); 7762 pw.print(prefix); pw.print("mAwake="); pw.println(mAwake); 7763 pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly); 7764 pw.print(" mScreenOnFully="); pw.println(mScreenOnFully); 7765 pw.print(prefix); pw.print("mKeyguardDrawComplete="); pw.print(mKeyguardDrawComplete); 7766 pw.print(" mWindowManagerDrawComplete="); pw.println(mWindowManagerDrawComplete); 7767 pw.print(prefix); pw.print("mOrientationSensorEnabled="); 7768 pw.println(mOrientationSensorEnabled); 7769 pw.print(prefix); pw.print("mOverscanScreen=("); pw.print(mOverscanScreenLeft); 7770 pw.print(","); pw.print(mOverscanScreenTop); 7771 pw.print(") "); pw.print(mOverscanScreenWidth); 7772 pw.print("x"); pw.println(mOverscanScreenHeight); 7773 if (mOverscanLeft != 0 || mOverscanTop != 0 7774 || mOverscanRight != 0 || mOverscanBottom != 0) { 7775 pw.print(prefix); pw.print("mOverscan left="); pw.print(mOverscanLeft); 7776 pw.print(" top="); pw.print(mOverscanTop); 7777 pw.print(" right="); pw.print(mOverscanRight); 7778 pw.print(" bottom="); pw.println(mOverscanBottom); 7779 } 7780 pw.print(prefix); pw.print("mRestrictedOverscanScreen=("); 7781 pw.print(mRestrictedOverscanScreenLeft); 7782 pw.print(","); pw.print(mRestrictedOverscanScreenTop); 7783 pw.print(") "); pw.print(mRestrictedOverscanScreenWidth); 7784 pw.print("x"); pw.println(mRestrictedOverscanScreenHeight); 7785 pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft); 7786 pw.print(","); pw.print(mUnrestrictedScreenTop); 7787 pw.print(") "); pw.print(mUnrestrictedScreenWidth); 7788 pw.print("x"); pw.println(mUnrestrictedScreenHeight); 7789 pw.print(prefix); pw.print("mRestrictedScreen=("); pw.print(mRestrictedScreenLeft); 7790 pw.print(","); pw.print(mRestrictedScreenTop); 7791 pw.print(") "); pw.print(mRestrictedScreenWidth); 7792 pw.print("x"); pw.println(mRestrictedScreenHeight); 7793 pw.print(prefix); pw.print("mStableFullscreen=("); pw.print(mStableFullscreenLeft); 7794 pw.print(","); pw.print(mStableFullscreenTop); 7795 pw.print(")-("); pw.print(mStableFullscreenRight); 7796 pw.print(","); pw.print(mStableFullscreenBottom); pw.println(")"); 7797 pw.print(prefix); pw.print("mStable=("); pw.print(mStableLeft); 7798 pw.print(","); pw.print(mStableTop); 7799 pw.print(")-("); pw.print(mStableRight); 7800 pw.print(","); pw.print(mStableBottom); pw.println(")"); 7801 pw.print(prefix); pw.print("mSystem=("); pw.print(mSystemLeft); 7802 pw.print(","); pw.print(mSystemTop); 7803 pw.print(")-("); pw.print(mSystemRight); 7804 pw.print(","); pw.print(mSystemBottom); pw.println(")"); 7805 pw.print(prefix); pw.print("mCur=("); pw.print(mCurLeft); 7806 pw.print(","); pw.print(mCurTop); 7807 pw.print(")-("); pw.print(mCurRight); 7808 pw.print(","); pw.print(mCurBottom); pw.println(")"); 7809 pw.print(prefix); pw.print("mContent=("); pw.print(mContentLeft); 7810 pw.print(","); pw.print(mContentTop); 7811 pw.print(")-("); pw.print(mContentRight); 7812 pw.print(","); pw.print(mContentBottom); pw.println(")"); 7813 pw.print(prefix); pw.print("mVoiceContent=("); pw.print(mVoiceContentLeft); 7814 pw.print(","); pw.print(mVoiceContentTop); 7815 pw.print(")-("); pw.print(mVoiceContentRight); 7816 pw.print(","); pw.print(mVoiceContentBottom); pw.println(")"); 7817 pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft); 7818 pw.print(","); pw.print(mDockTop); 7819 pw.print(")-("); pw.print(mDockRight); 7820 pw.print(","); pw.print(mDockBottom); pw.println(")"); 7821 pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer); 7822 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer); 7823 pw.print(prefix); pw.print("mShowingLockscreen="); pw.print(mShowingLockscreen); 7824 pw.print(" mShowingDream="); pw.print(mShowingDream); 7825 pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen); 7826 pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken); 7827 if (mLastInputMethodWindow != null) { 7828 pw.print(prefix); pw.print("mLastInputMethodWindow="); 7829 pw.println(mLastInputMethodWindow); 7830 } 7831 if (mLastInputMethodTargetWindow != null) { 7832 pw.print(prefix); pw.print("mLastInputMethodTargetWindow="); 7833 pw.println(mLastInputMethodTargetWindow); 7834 } 7835 if (mStatusBar != null) { 7836 pw.print(prefix); pw.print("mStatusBar="); 7837 pw.print(mStatusBar); pw.print(" isStatusBarKeyguard="); 7838 pw.println(isStatusBarKeyguard()); 7839 } 7840 if (mNavigationBar != null) { 7841 pw.print(prefix); pw.print("mNavigationBar="); 7842 pw.println(mNavigationBar); 7843 } 7844 if (mFocusedWindow != null) { 7845 pw.print(prefix); pw.print("mFocusedWindow="); 7846 pw.println(mFocusedWindow); 7847 } 7848 if (mFocusedApp != null) { 7849 pw.print(prefix); pw.print("mFocusedApp="); 7850 pw.println(mFocusedApp); 7851 } 7852 if (mWinDismissingKeyguard != null) { 7853 pw.print(prefix); pw.print("mWinDismissingKeyguard="); 7854 pw.println(mWinDismissingKeyguard); 7855 } 7856 if (mTopFullscreenOpaqueWindowState != null) { 7857 pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState="); 7858 pw.println(mTopFullscreenOpaqueWindowState); 7859 } 7860 if (mTopFullscreenOpaqueOrDimmingWindowState != null) { 7861 pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState="); 7862 pw.println(mTopFullscreenOpaqueOrDimmingWindowState); 7863 } 7864 if (mForcingShowNavBar) { 7865 pw.print(prefix); pw.print("mForcingShowNavBar="); 7866 pw.println(mForcingShowNavBar); pw.print( "mForcingShowNavBarLayer="); 7867 pw.println(mForcingShowNavBarLayer); 7868 } 7869 pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen); 7870 pw.print(" mHideLockScreen="); pw.println(mHideLockScreen); 7871 pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); 7872 pw.print(" mForceStatusBarFromKeyguard="); 7873 pw.println(mForceStatusBarFromKeyguard); 7874 pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard); 7875 pw.print(" mWinDismissingKeyguard="); pw.print(mWinDismissingKeyguard); 7876 pw.print(" mHomePressed="); pw.println(mHomePressed); 7877 pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn); 7878 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout); 7879 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive); 7880 pw.print(prefix); pw.print("mEndcallBehavior="); pw.print(mEndcallBehavior); 7881 pw.print(" mIncallPowerBehavior="); pw.print(mIncallPowerBehavior); 7882 pw.print(" mLongPressOnHomeBehavior="); pw.println(mLongPressOnHomeBehavior); 7883 pw.print(prefix); pw.print("mLandscapeRotation="); pw.print(mLandscapeRotation); 7884 pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation); 7885 pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation); 7886 pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation); 7887 pw.print(prefix); pw.print("mDemoHdmiRotation="); pw.print(mDemoHdmiRotation); 7888 pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock); 7889 pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation); 7890 7891 mGlobalKeyManager.dump(prefix, pw); 7892 mStatusBarController.dump(pw, prefix); 7893 mNavigationBarController.dump(pw, prefix); 7894 PolicyControl.dump(prefix, pw); 7895 7896 if (mWakeGestureListener != null) { 7897 mWakeGestureListener.dump(pw, prefix); 7898 } 7899 if (mOrientationListener != null) { 7900 mOrientationListener.dump(pw, prefix); 7901 } 7902 if (mBurnInProtectionHelper != null) { 7903 mBurnInProtectionHelper.dump(prefix, pw); 7904 } 7905 if (mKeyguardDelegate != null) { 7906 mKeyguardDelegate.dump(prefix, pw); 7907 } 7908 } 7909} 7910