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