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