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