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