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