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