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