blob: 4785abd07c8a5fecdccb1301d137e3bbf051589f [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16package com.android.internal.policy.impl;
17
Dianne Hackborna4972e92012-03-14 10:38:05 -070018import android.app.ActivityManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080019import android.app.ActivityManagerNative;
Dianne Hackborn78968392010-03-04 20:47:56 -080020import android.app.IUiModeManager;
Dianne Hackborn661cd522011-08-22 00:26:20 -070021import android.app.ProgressDialog;
Jeff Brownde7a8ea2012-06-13 18:28:57 -070022import android.app.SearchManager;
Dianne Hackborn78968392010-03-04 20:47:56 -080023import android.app.UiModeManager;
Dianne Hackborn39c2d712009-09-22 11:41:31 -070024import android.content.ActivityNotFoundException;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080025import android.content.BroadcastReceiver;
Daniel Sandler0601eb72011-04-13 01:01:32 -040026import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080027import android.content.ContentResolver;
28import android.content.Context;
29import android.content.Intent;
Mike Lockwood1753f7f2009-08-24 14:49:07 -070030import android.content.IntentFilter;
Winson Chung9112ec32011-06-27 13:15:32 -070031import android.content.ServiceConnection;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080032import android.content.pm.ActivityInfo;
33import android.content.pm.PackageManager;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070034import android.content.res.CompatibilityInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080035import android.content.res.Configuration;
36import android.content.res.Resources;
Craig Mautner8e4df6c2012-05-23 16:57:23 -070037import android.content.res.TypedArray;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080038import android.database.ContentObserver;
Dianne Hackbornc777e072010-02-12 13:07:59 -080039import android.graphics.PixelFormat;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080040import android.graphics.Rect;
Michael Jurka7a348952012-02-27 13:07:58 -080041import android.media.AudioManager;
42import android.media.IAudioService;
Daniel Sandler7e37df52011-11-16 22:08:23 -080043import android.os.BatteryManager;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070044import android.os.Bundle;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080045import android.os.Handler;
46import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070047import android.os.IRemoteCallback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080048import android.os.LocalPowerManager;
Jeff Brown32cbc38552011-12-01 14:01:49 -080049import android.os.Looper;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070050import android.os.Message;
51import android.os.Messenger;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080052import android.os.PowerManager;
53import android.os.RemoteException;
54import android.os.ServiceManager;
55import android.os.SystemClock;
56import android.os.SystemProperties;
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -080057import android.os.UEventObserver;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080058import android.os.Vibrator;
59import android.provider.Settings;
60
Jim Millere6ad1a82010-08-20 19:25:39 -070061import com.android.internal.R;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080062import com.android.internal.policy.PolicyManager;
Joe Onorato0cbda992010-05-02 16:28:15 -070063import com.android.internal.statusbar.IStatusBarService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080064import com.android.internal.telephony.ITelephony;
Dianne Hackborn6019c9d2010-03-01 21:43:11 -080065import com.android.internal.widget.PointerLocationView;
66
Daniel Sandler7d276c32012-01-30 14:33:52 -050067import android.service.dreams.IDreamManager;
Michael Jurka7a348952012-02-27 13:07:58 -080068import android.speech.RecognizerIntent;
Dianne Hackborn81e56d52011-05-26 00:55:58 -070069import android.util.DisplayMetrics;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080070import android.util.EventLog;
71import android.util.Log;
Jeff Browna41ca772010-08-11 14:46:32 -070072import android.util.Slog;
Jeff Brown6651a632011-11-28 12:59:11 -080073import android.util.SparseArray;
Dianne Hackbornf87d1962012-04-04 12:48:24 -070074import android.view.Display;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080075import android.view.Gravity;
76import android.view.HapticFeedbackConstants;
Dianne Hackborne0f085d2011-11-30 18:41:15 -080077import android.view.IApplicationToken;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080078import android.view.IWindowManager;
Jeff Browna41ca772010-08-11 14:46:32 -070079import android.view.InputChannel;
Jeff Brown4d396052010-10-29 21:50:21 -070080import android.view.InputDevice;
Jeff Brown4952dfd2011-11-30 19:23:22 -080081import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -080082import android.view.InputEventReceiver;
Jeff Brown6b53e8d2010-11-10 16:03:06 -080083import android.view.KeyCharacterMap;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080084import android.view.KeyEvent;
85import android.view.MotionEvent;
86import android.view.WindowOrientationListener;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080087import android.view.Surface;
88import android.view.View;
89import android.view.ViewConfiguration;
90import android.view.Window;
91import android.view.WindowManager;
92import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
93import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
94import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
95import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
96import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
97import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -070098import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Dianne Hackborn39c2d712009-09-22 11:41:31 -070099import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
Mike Lockwood28569302010-01-28 11:54:40 -0500100import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800101import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
102import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
Dianne Hackborndea3ef72010-10-28 14:24:22 -0700103import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800104import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
105import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
Dianne Hackborn5cb8d792009-05-21 17:34:15 -0700106import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800107import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
108import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
109import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
Christopher Tatea53146c2010-09-07 11:57:52 -0700110import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
Daniel Sandler7d276c32012-01-30 14:33:52 -0500111import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700112import static android.view.WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800113import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;
114import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
115import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
116import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
117import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
Jeff Brown3b2b3542010-10-15 00:54:27 -0700118import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800119import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
120import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
Joe Onorato29fc2c92010-11-24 10:26:50 -0800121import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
Dianne Hackborn6a294ce2009-12-03 11:37:44 -0800122import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800123import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
124import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
125import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
126import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
127import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
128import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700129import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -0700130import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Jeff Brown83c09682010-12-23 17:50:18 -0800131import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400132import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
Jim Millere898ac52012-04-06 17:10:57 -0700133import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700134import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800135import android.view.WindowManagerImpl;
136import android.view.WindowManagerPolicy;
Jeff Brownac143512012-04-05 18:57:33 -0700137import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
138import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
139import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
Jeff Brown6f2fba42011-02-19 01:08:02 -0800140import android.view.KeyCharacterMap.FallbackAction;
Dianne Hackborn295e3c22011-08-25 13:19:08 -0700141import android.view.accessibility.AccessibilityEvent;
Dianne Hackborn01ad2f42009-09-24 19:24:56 -0700142import android.view.animation.Animation;
143import android.view.animation.AnimationUtils;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800144
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800145import java.io.File;
Joe Onoratodc100302011-01-11 17:07:41 -0800146import java.io.FileReader;
147import java.io.IOException;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800148import java.io.PrintWriter;
Dianne Hackborn08743722009-12-21 12:16:51 -0800149
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800150/**
The Android Open Source Project0727d222009-03-11 12:11:58 -0700151 * WindowManagerPolicy implementation for the Android phone UI. This
152 * introduces a new method suffix, Lp, for an internal lock of the
153 * PhoneWindowManager. This is used to protect some internal state, and
154 * can be acquired with either thw Lw and Li lock held, so has the restrictions
155 * of both of those when held.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800156 */
157public class PhoneWindowManager implements WindowManagerPolicy {
158 static final String TAG = "WindowManager";
159 static final boolean DEBUG = false;
Joe Onorato43a17652011-04-06 19:22:23 -0700160 static final boolean localLOGV = false;
The Android Open Source Project11267662009-03-18 17:39:47 -0700161 static final boolean DEBUG_LAYOUT = false;
Jeff Brown40013652012-05-16 21:22:36 -0700162 static final boolean DEBUG_INPUT = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800163 static final boolean SHOW_STARTING_ANIMATIONS = true;
164 static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
Joe Onoratod208e702010-10-08 16:22:43 -0400165
Daniel Sandler11ddf532011-11-16 11:10:03 -0800166 // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
167 // No longer recommended for desk docks; still useful in car docks.
168 static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
169 static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
170
Daniel Sandler7e37df52011-11-16 22:08:23 -0800171 // Should screen savers use their own timeout, or the SCREEN_OFF_TIMEOUT?
172 static final boolean SEPARATE_TIMEOUT_FOR_SCREEN_SAVER = false;
173
Joe Onoratod208e702010-10-08 16:22:43 -0400174 static final int LONG_PRESS_POWER_NOTHING = 0;
175 static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
176 static final int LONG_PRESS_POWER_SHUT_OFF = 2;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700177
178 // These need to match the documentation/constant in
179 // core/res/res/values/config.xml
Joe Onorato46b0d682010-11-22 17:37:27 -0800180 static final int LONG_PRESS_HOME_NOTHING = 0;
181 static final int LONG_PRESS_HOME_RECENT_DIALOG = 1;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700182 static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2;
Joe Onorato46b0d682010-11-22 17:37:27 -0800183
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -0700184 // wallpaper is at the bottom, though the window manager may move it.
Dianne Hackborn3c3bd442009-08-19 17:09:46 -0700185 static final int WALLPAPER_LAYER = 2;
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -0700186 static final int APPLICATION_LAYER = 2;
187 static final int PHONE_LAYER = 3;
188 static final int SEARCH_BAR_LAYER = 4;
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700189 static final int SYSTEM_DIALOG_LAYER = 5;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800190 // toasts and the plugged-in battery thing
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700191 static final int TOAST_LAYER = 6;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800192 // SIM errors and unlock. Not sure if this really should be in a high layer.
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700193 static final int PRIORITY_PHONE_LAYER = 7;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800194 // like the ANR / app crashed dialogs
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700195 static final int SYSTEM_ALERT_LAYER = 8;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800196 // on-screen keyboards and other such input method user interfaces go here.
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700197 static final int INPUT_METHOD_LAYER = 9;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800198 // on-screen keyboards and other such input method user interfaces go here.
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700199 static final int INPUT_METHOD_DIALOG_LAYER = 10;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800200 // the keyguard; nothing on top of these can take focus, since they are
201 // responsible for power management when displayed.
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700202 static final int KEYGUARD_LAYER = 11;
203 static final int KEYGUARD_DIALOG_LAYER = 12;
Daniel Sandler7d276c32012-01-30 14:33:52 -0500204 // used for Dreams (screensavers with TYPE_DREAM windows)
205 static final int SCREENSAVER_LAYER = 13;
206 static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
207 static final int STATUS_BAR_LAYER = 15;
208 static final int STATUS_BAR_PANEL_LAYER = 16;
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700209 // the on-screen volume indicator and controller shown when the user
210 // changes the device volume
Daniel Sandler7d276c32012-01-30 14:33:52 -0500211 static final int VOLUME_OVERLAY_LAYER = 17;
Jeff Brownbfcb60a2011-09-08 18:51:14 -0700212 // things in here CAN NOT take focus, but are shown on top of everything else.
Daniel Sandler7d276c32012-01-30 14:33:52 -0500213 static final int SYSTEM_OVERLAY_LAYER = 18;
Jeff Brownbfcb60a2011-09-08 18:51:14 -0700214 // the navigation bar, if available, shows atop most things
Daniel Sandler7d276c32012-01-30 14:33:52 -0500215 static final int NAVIGATION_BAR_LAYER = 19;
Jim Millere898ac52012-04-06 17:10:57 -0700216 // some panels (e.g. search) need to show on top of the navigation bar
217 static final int NAVIGATION_BAR_PANEL_LAYER = 20;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700218 // system-level error dialogs
Jim Millere898ac52012-04-06 17:10:57 -0700219 static final int SYSTEM_ERROR_LAYER = 21;
Christopher Tatea53146c2010-09-07 11:57:52 -0700220 // the drag layer: input for drag-and-drop is associated with this window,
221 // which sits above all other focusable windows
Jim Millere898ac52012-04-06 17:10:57 -0700222 static final int DRAG_LAYER = 22;
223 static final int SECURE_SYSTEM_OVERLAY_LAYER = 23;
224 static final int BOOT_PROGRESS_LAYER = 24;
Jeff Brown83c09682010-12-23 17:50:18 -0800225 // the (mouse) pointer layer
Jim Millere898ac52012-04-06 17:10:57 -0700226 static final int POINTER_LAYER = 25;
227 static final int HIDDEN_NAV_CONSUMER_LAYER = 26;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800228
Dianne Hackborn5cb8d792009-05-21 17:34:15 -0700229 static final int APPLICATION_MEDIA_SUBLAYER = -2;
230 static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800231 static final int APPLICATION_PANEL_SUBLAYER = 1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800232 static final int APPLICATION_SUB_PANEL_SUBLAYER = 2;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800233
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800234 static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
235 static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
236 static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
Joe Onoratof275f0c2009-11-24 16:11:13 -0500237 static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
Jeff Brownde7a8ea2012-06-13 18:28:57 -0700238 static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800239
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700240 /**
241 * These are the system UI flags that, when changing, can cause the layout
242 * of the screen to change.
243 */
244 static final int SYSTEM_UI_CHANGING_LAYOUT =
245 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
246
Jeff Brown6651a632011-11-28 12:59:11 -0800247 /* Table of Application Launch keys. Maps from key codes to intent categories.
248 *
249 * These are special keys that are used to launch particular kinds of applications,
250 * such as a web browser. HID defines nearly a hundred of them in the Consumer (0x0C)
251 * usage page. We don't support quite that many yet...
252 */
253 static SparseArray<String> sApplicationLaunchKeyCategories;
254 static {
255 sApplicationLaunchKeyCategories = new SparseArray<String>();
256 sApplicationLaunchKeyCategories.append(
257 KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER);
258 sApplicationLaunchKeyCategories.append(
259 KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL);
260 sApplicationLaunchKeyCategories.append(
261 KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS);
262 sApplicationLaunchKeyCategories.append(
263 KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR);
264 sApplicationLaunchKeyCategories.append(
265 KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC);
266 sApplicationLaunchKeyCategories.append(
267 KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
268 }
269
Dianne Hackborndf89e652011-10-06 22:35:11 -0700270 /**
271 * Lock protecting internal state. Must not call out into window
272 * manager with lock held. (This lock will be acquired in places
273 * where the window manager is calling in with its own lock held.)
274 */
The Android Open Source Project0727d222009-03-11 12:11:58 -0700275 final Object mLock = new Object();
Dianne Hackborndf89e652011-10-06 22:35:11 -0700276
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800277 Context mContext;
278 IWindowManager mWindowManager;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700279 WindowManagerFuncs mWindowManagerFuncs;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800280 LocalPowerManager mPowerManager;
Joe Onorato93056472010-09-10 10:30:46 -0400281 IStatusBarService mStatusBarService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800282 Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
Jeff Brownde7a8ea2012-06-13 18:28:57 -0700283 SearchManager mSearchManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800284
Dianne Hackborn181ceb52009-08-27 22:16:40 -0700285 // Vibrator pattern for haptic feedback of a long press.
286 long[] mLongPressVibePattern;
287
288 // Vibrator pattern for haptic feedback of virtual key press.
289 long[] mVirtualKeyVibePattern;
290
Amith Yamasanic33cb712010-02-10 15:21:49 -0800291 // Vibrator pattern for a short vibration.
292 long[] mKeyboardTapVibePattern;
293
Dianne Hackbornb1a79802009-09-29 15:18:31 -0700294 // Vibrator pattern for haptic feedback during boot when safe mode is disabled.
295 long[] mSafeModeDisabledVibePattern;
296
297 // Vibrator pattern for haptic feedback during boot when safe mode is enabled.
298 long[] mSafeModeEnabledVibePattern;
Romain Guy8154cd32010-03-29 14:41:15 -0700299
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800300 /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */
301 boolean mEnableShiftMenuBugReports = false;
Mike Lockwoodd747dc82011-09-13 16:28:22 -0400302
303 boolean mHeadless;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800304 boolean mSafeMode;
305 WindowState mStatusBar = null;
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700306 boolean mHasSystemNavBar;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700307 int mStatusBarHeight;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400308 WindowState mNavigationBar = null;
Daniel Sandler36412a72011-08-04 09:35:13 -0400309 boolean mHasNavigationBar = false;
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700310 boolean mCanHideNavigationBar = false;
Daniel Sandler4a066c52012-04-20 14:49:13 -0400311 boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side?
312 boolean mNavigationBarOnBottom = true; // is the navigation bar on the bottom *right now*?
313 int[] mNavigationBarHeightForRotation = new int[4];
314 int[] mNavigationBarWidthForRotation = new int[4];
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400315
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800316 WindowState mKeyguard = null;
317 KeyguardViewMediator mKeyguardMediator;
318 GlobalActions mGlobalActions;
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700319 volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
320 boolean mPendingPowerKeyUpCanceled;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800321 Handler mHandler;
satok1bc0a492012-04-25 22:47:12 +0900322 WindowState mLastInputMethodWindow = null;
323 WindowState mLastInputMethodTargetWindow = null;
Jeff Brown4aed78b2011-01-14 17:36:55 -0800324
Jeff Brown68b909d2011-12-07 16:36:01 -0800325 static final int RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS = 0;
326 static final int RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW = 1;
Jeff Brown602ab322012-05-16 13:33:47 -0700327 static final int RECENT_APPS_BEHAVIOR_DISMISS = 2;
328 static final int RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH = 3;
Jeff Brown68b909d2011-12-07 16:36:01 -0800329
330 RecentApplicationsDialog mRecentAppsDialog;
331 int mRecentAppsDialogHeldModifiers;
Jeff Browncf39bdf2012-05-18 14:41:19 -0700332 boolean mLanguageSwitchKeyPressed;
Jeff Brown68b909d2011-12-07 16:36:01 -0800333
Jeff Brown2e7760e2012-04-11 15:14:55 -0700334 int mLidState = LID_ABSENT;
Jeff Browndaa37532012-05-01 15:54:03 -0700335 boolean mHaveBuiltInKeyboard;
Jeff Brown4aed78b2011-01-14 17:36:55 -0800336
Dianne Hackbornc777e072010-02-12 13:07:59 -0800337 boolean mSystemReady;
Dianne Hackbornba24e4d2011-09-01 11:17:06 -0700338 boolean mSystemBooted;
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800339 boolean mHdmiPlugged;
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700340 int mExternalDisplayWidth;
341 int mExternalDisplayHeight;
Joe Onorato44fcb832011-12-14 20:59:30 -0800342 int mUiMode;
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700343 int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700344 int mLidOpenRotation;
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400345 int mCarDockRotation;
346 int mDeskDockRotation;
Erik Gilling9a41ef82011-09-26 19:21:03 -0700347 int mHdmiRotation;
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400348
349 int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
350 int mUserRotation = Surface.ROTATION_0;
Jeff Brown207673cd2012-06-05 17:47:11 -0700351 boolean mAccelerometerDefault;
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400352
Jeff Brownd3187e32011-09-21 19:26:44 -0700353 int mAllowAllRotations = -1;
Mike Lockwoode9867d22009-09-20 01:59:02 -0400354 boolean mCarDockEnablesAccelerometer;
355 boolean mDeskDockEnablesAccelerometer;
Dianne Hackborn2862fff2009-09-15 22:56:29 -0700356 int mLidKeyboardAccessibility;
357 int mLidNavigationAccessibility;
Jeff Brownc458ce92012-04-30 14:58:40 -0700358 boolean mLidControlsSleep;
Joe Onoratod208e702010-10-08 16:22:43 -0400359 int mLongPressOnPowerBehavior = -1;
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -0700360 boolean mScreenOnEarly = false;
361 boolean mScreenOnFully = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800362 boolean mOrientationSensorEnabled = false;
363 int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800364 boolean mHasSoftInput = false;
365
Jeff Brown70825162012-03-28 17:27:48 -0700366 int mPointerLocationMode = 0; // guarded by mLock
Joe Onorato664644d2011-01-23 17:53:23 -0800367
368 // The last window we were told about in focusChanged.
369 WindowState mFocusedWindow;
Dianne Hackborne0f085d2011-11-30 18:41:15 -0800370 IApplicationToken mFocusedApp;
Joe Onorato664644d2011-01-23 17:53:23 -0800371
Jeff Brown70825162012-03-28 17:27:48 -0700372 private static final class PointerLocationInputEventReceiver extends InputEventReceiver {
373 private final PointerLocationView mView;
374
375 public PointerLocationInputEventReceiver(InputChannel inputChannel, Looper looper,
376 PointerLocationView view) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800377 super(inputChannel, looper);
Jeff Brown70825162012-03-28 17:27:48 -0700378 mView = view;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800379 }
380
Jeff Browna41ca772010-08-11 14:46:32 -0700381 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800382 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700383 boolean handled = false;
384 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800385 if (event instanceof MotionEvent
386 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
387 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown70825162012-03-28 17:27:48 -0700388 mView.addPointerEvent(motionEvent);
389 handled = true;
Jeff Brown93ed4e32010-09-23 13:51:48 -0700390 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700391 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800392 finishInputEvent(event, handled);
Jeff Browna41ca772010-08-11 14:46:32 -0700393 }
394 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800395 }
Jeff Brown70825162012-03-28 17:27:48 -0700396
397 // Pointer location view state, only modified on the mHandler Looper.
Jeff Brown32cbc38552011-12-01 14:01:49 -0800398 PointerLocationInputEventReceiver mPointerLocationInputEventReceiver;
Jeff Brown70825162012-03-28 17:27:48 -0700399 PointerLocationView mPointerLocationView;
400 InputChannel mPointerLocationInputChannel;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800401
Joe Onorato29fc2c92010-11-24 10:26:50 -0800402 // The current size of the screen; really; (ir)regardless of whether the status
403 // bar can be hidden or not
404 int mUnrestrictedScreenLeft, mUnrestrictedScreenTop;
405 int mUnrestrictedScreenWidth, mUnrestrictedScreenHeight;
Dianne Hackborn82de1ae2010-10-28 11:28:39 -0700406 // The current size of the screen; these may be different than (0,0)-(dw,dh)
407 // if the status bar can't be hidden; in that case it effectively carves out
408 // that area of the display from all other windows.
Joe Onorato29fc2c92010-11-24 10:26:50 -0800409 int mRestrictedScreenLeft, mRestrictedScreenTop;
410 int mRestrictedScreenWidth, mRestrictedScreenHeight;
Dianne Hackborn5c58de32012-04-28 19:52:37 -0700411 // During layout, the current screen borders accounting for any currently
412 // visible system UI elements.
413 int mSystemLeft, mSystemTop, mSystemRight, mSystemBottom;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700414 // For applications requesting stable content insets, these are them.
415 int mStableLeft, mStableTop, mStableRight, mStableBottom;
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -0700416 // For applications requesting stable content insets but have also set the
417 // fullscreen window flag, these are the stable dimensions without the status bar.
418 int mStableFullscreenLeft, mStableFullscreenTop;
419 int mStableFullscreenRight, mStableFullscreenBottom;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800420 // During layout, the current screen borders with all outer decoration
421 // (status bar, input method dock) accounted for.
422 int mCurLeft, mCurTop, mCurRight, mCurBottom;
423 // During layout, the frame in which content should be displayed
424 // to the user, accounting for all screen decoration except for any
425 // space they deem as available for other content. This is usually
426 // the same as mCur*, but may be larger if the screen decor has supplied
427 // content insets.
428 int mContentLeft, mContentTop, mContentRight, mContentBottom;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -0800429 // During layout, the current screen borders along which input method
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800430 // windows are placed.
431 int mDockLeft, mDockTop, mDockRight, mDockBottom;
432 // During layout, the layer at which the doc window is placed.
433 int mDockLayer;
Dianne Hackborn5c58de32012-04-28 19:52:37 -0700434 // During layout, this is the layer of the status bar.
435 int mStatusBarLayer;
Dianne Hackborne26ab702011-10-16 13:21:33 -0700436 int mLastSystemUiFlags;
437 // Bits that we are in the process of clearing, so we want to prevent
438 // them from being set by applications until everything has been updated
439 // to have them clear.
440 int mResettingSystemUiFlags = 0;
441 // Bits that we are currently always keeping cleared.
442 int mForceClearedSystemUiFlags = 0;
Dianne Hackborn4eff8d32011-11-10 19:38:40 -0800443 // What we last reported to system UI about whether the compatibility
444 // menu needs to be displayed.
445 boolean mLastFocusNeedsMenu = false;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700446
447 FakeWindow mHideNavFakeWindow = null;
448
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800449 static final Rect mTmpParentFrame = new Rect();
450 static final Rect mTmpDisplayFrame = new Rect();
451 static final Rect mTmpContentFrame = new Rect();
452 static final Rect mTmpVisibleFrame = new Rect();
Dianne Hackborn1f903c32011-09-13 19:18:06 -0700453 static final Rect mTmpNavigationFrame = new Rect();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800454
455 WindowState mTopFullscreenOpaqueWindowState;
Joe Onorato93056472010-09-10 10:30:46 -0400456 boolean mTopIsFullscreen;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800457 boolean mForceStatusBar;
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700458 boolean mHideLockScreen;
459 boolean mDismissKeyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800460 boolean mHomePressed;
Michael Jurka7f2668c2012-03-27 07:49:52 -0700461 boolean mHomeLongPressed;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800462 Intent mHomeIntent;
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700463 Intent mCarDockIntent;
464 Intent mDeskDockIntent;
Jeff Brownfd23e3e2012-05-09 13:34:28 -0700465 boolean mSearchKeyShortcutPending;
466 boolean mConsumeSearchKeyUp;
Jeff Brownde7a8ea2012-06-13 18:28:57 -0700467 boolean mAssistKeyLongPressed;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800468
Mike Lockwood28569302010-01-28 11:54:40 -0500469 // support for activating the lock screen while the screen is on
470 boolean mAllowLockscreenWhenOn;
471 int mLockScreenTimeout;
472 boolean mLockScreenTimerActive;
473
Daniel Sandler0601eb72011-04-13 01:01:32 -0400474 // visual screen saver support
Daniel Sandler7d276c32012-01-30 14:33:52 -0500475 boolean mScreenSaverFeatureAvailable;
Daniel Sandlere5f2cfe2011-11-02 23:30:58 -0400476 int mScreenSaverTimeout = 0;
Daniel Sandler2d545362011-11-17 10:38:37 -0800477 boolean mScreenSaverEnabledByUser = false;
478 boolean mScreenSaverMayRun = true; // false if a wakelock is held
Daniel Sandler7e37df52011-11-16 22:08:23 -0800479 boolean mPluggedIn;
Daniel Sandler0601eb72011-04-13 01:01:32 -0400480
David Brownbaf8d092010-03-08 21:52:59 -0800481 // Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.)
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800482 int mEndcallBehavior;
David Brownbaf8d092010-03-08 21:52:59 -0800483
484 // Behavior of POWER button while in-call and screen on.
485 // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.)
486 int mIncallPowerBehavior;
487
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700488 Display mDisplay;
489
Dianne Hackborn9d132642011-04-21 17:26:39 -0700490 int mLandscapeRotation = 0; // default landscape rotation
491 int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
492 int mPortraitRotation = 0; // default portrait rotation
493 int mUpsideDownRotation = 0; // "other" portrait rotation
Mitsuru Oshima831d0d92009-06-16 18:27:18 -0700494
Joe Onorato46b0d682010-11-22 17:37:27 -0800495 // What we do when the user long presses on home
496 private int mLongPressOnHomeBehavior = -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800497
Winson Chung9112ec32011-06-27 13:15:32 -0700498 // Screenshot trigger states
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700499 // Time to volume and power must be pressed within this interval of each other.
500 private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
Christopher Tatee90585f2012-03-05 18:56:25 -0800501 private boolean mScreenshotChordEnabled;
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700502 private boolean mVolumeDownKeyTriggered;
503 private long mVolumeDownKeyTime;
504 private boolean mVolumeDownKeyConsumedByScreenshotChord;
505 private boolean mVolumeUpKeyTriggered;
506 private boolean mPowerKeyTriggered;
507 private long mPowerKeyTime;
Winson Chung9112ec32011-06-27 13:15:32 -0700508
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800509 ShortcutManager mShortcutManager;
510 PowerManager.WakeLock mBroadcastWakeLock;
Jeff Brown40013652012-05-16 21:22:36 -0700511 boolean mHavePendingMediaKeyRepeatWithWakeLock;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800512
Jeff Brownfd23e3e2012-05-09 13:34:28 -0700513 // Fallback actions by key code.
514 private final SparseArray<KeyCharacterMap.FallbackAction> mFallbackActions =
515 new SparseArray<KeyCharacterMap.FallbackAction>();
Jeff Brown49ed71d2010-12-06 17:13:33 -0800516
Jeff Brown70825162012-03-28 17:27:48 -0700517 private static final int MSG_ENABLE_POINTER_LOCATION = 1;
518 private static final int MSG_DISABLE_POINTER_LOCATION = 2;
Jeff Brown40013652012-05-16 21:22:36 -0700519 private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
520 private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
Jeff Brown70825162012-03-28 17:27:48 -0700521
522 private class PolicyHandler extends Handler {
523 @Override
524 public void handleMessage(Message msg) {
525 switch (msg.what) {
526 case MSG_ENABLE_POINTER_LOCATION:
527 enablePointerLocation();
528 break;
529 case MSG_DISABLE_POINTER_LOCATION:
530 disablePointerLocation();
531 break;
Jeff Brown40013652012-05-16 21:22:36 -0700532 case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK:
533 dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj);
534 break;
535 case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
536 dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
537 break;
Jeff Brown70825162012-03-28 17:27:48 -0700538 }
539 }
540 }
541
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800542 private UEventObserver mHDMIObserver = new UEventObserver() {
543 @Override
544 public void onUEvent(UEventObserver.UEvent event) {
545 setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
546 }
547 };
548
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800549 class SettingsObserver extends ContentObserver {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800550 SettingsObserver(Handler handler) {
551 super(handler);
552 }
David Brownbaf8d092010-03-08 21:52:59 -0800553
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800554 void observe() {
555 ContentResolver resolver = mContext.getContentResolver();
556 resolver.registerContentObserver(Settings.System.getUriFor(
557 Settings.System.END_BUTTON_BEHAVIOR), false, this);
David Brownbaf8d092010-03-08 21:52:59 -0800558 resolver.registerContentObserver(Settings.Secure.getUriFor(
559 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800560 resolver.registerContentObserver(Settings.System.getUriFor(
561 Settings.System.ACCELEROMETER_ROTATION), false, this);
Mike Lockwood28569302010-01-28 11:54:40 -0500562 resolver.registerContentObserver(Settings.System.getUriFor(
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400563 Settings.System.USER_ROTATION), false, this);
564 resolver.registerContentObserver(Settings.System.getUriFor(
Mike Lockwood28569302010-01-28 11:54:40 -0500565 Settings.System.SCREEN_OFF_TIMEOUT), false, this);
Dianne Hackbornc777e072010-02-12 13:07:59 -0800566 resolver.registerContentObserver(Settings.System.getUriFor(
567 Settings.System.POINTER_LOCATION), false, this);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800568 resolver.registerContentObserver(Settings.Secure.getUriFor(
569 Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
Dianne Hackborn03759ed2009-03-27 16:04:08 -0700570 resolver.registerContentObserver(Settings.System.getUriFor(
571 "fancy_rotation_anim"), false, this);
Daniel Sandler2d545362011-11-17 10:38:37 -0800572 resolver.registerContentObserver(Settings.Secure.getUriFor(
573 Settings.Secure.SCREENSAVER_ENABLED), false, this);
Daniel Sandler7e37df52011-11-16 22:08:23 -0800574 if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
575 resolver.registerContentObserver(Settings.Secure.getUriFor(
Daniel Sandler2d545362011-11-17 10:38:37 -0800576 "screensaver_timeout"), false, this);
Daniel Sandler7e37df52011-11-16 22:08:23 -0800577 } // otherwise SCREEN_OFF_TIMEOUT will do nicely
Dianne Hackbornc777e072010-02-12 13:07:59 -0800578 updateSettings();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800579 }
580
581 @Override public void onChange(boolean selfChange) {
Dianne Hackbornc777e072010-02-12 13:07:59 -0800582 updateSettings();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700583 updateRotation(false);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800584 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800585 }
586
587 class MyOrientationListener extends WindowOrientationListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800588 MyOrientationListener(Context context) {
589 super(context);
590 }
591
592 @Override
Jeff Brownc0347aa2011-09-23 17:26:09 -0700593 public void onProposedRotationChanged(int rotation) {
594 if (localLOGV) Log.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -0700595 updateRotation(false);
596 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800597 }
598 MyOrientationListener mOrientationListener;
599
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -0700600 /*
601 * We always let the sensor be switched on by default except when
602 * the user has explicitly disabled sensor based rotation or when the
603 * screen is switched off.
604 */
The Android Open Source Project0727d222009-03-11 12:11:58 -0700605 boolean needSensorRunningLp() {
Dianne Hackborne5439f22010-10-02 16:53:50 -0700606 if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
607 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
608 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
609 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800610 // If the application has explicitly requested to follow the
611 // orientation, then we need to turn the sensor or.
612 return true;
613 }
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700614 if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) ||
Jeff Brown1a693182011-11-08 14:44:16 -0800615 (mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
616 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
617 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) {
Mike Lockwoode9867d22009-09-20 01:59:02 -0400618 // enable accelerometer if we are docked in a dock that enables accelerometer
619 // orientation management,
620 return true;
621 }
Jeff Brown207673cd2012-06-05 17:47:11 -0700622 if (mUserRotationMode == USER_ROTATION_LOCKED) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800623 // If the setting for using the sensor by default is enabled, then
624 // we will always leave it on. Note that the user could go to
625 // a window that forces an orientation that does not use the
626 // sensor and in theory we could turn it off... however, when next
627 // turning it on we won't have a good value for the current
628 // orientation for a little bit, which can cause orientation
629 // changes to lag, so we'd like to keep it always on. (It will
630 // still be turned off when the screen is off.)
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -0700631 return false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800632 }
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -0700633 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800634 }
635
636 /*
637 * Various use cases for invoking this function
638 * screen turning off, should always disable listeners if already enabled
639 * screen turned on and current app has sensor based orientation, enable listeners
640 * if not already enabled
641 * screen turned on and current app does not have sensor orientation, disable listeners if
642 * already enabled
643 * screen turning on and current app has sensor based orientation, enable listeners if needed
644 * screen turning on and current app has nosensor based orientation, do nothing
645 */
The Android Open Source Project0727d222009-03-11 12:11:58 -0700646 void updateOrientationListenerLp() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800647 if (!mOrientationListener.canDetectOrientation()) {
648 // If sensor is turned off or nonexistent for some reason
649 return;
650 }
651 //Could have been invoked due to screen turning on or off or
652 //change of the currently visible window's orientation
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -0700653 if (localLOGV) Log.v(TAG, "Screen status="+mScreenOnEarly+
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800654 ", current orientation="+mCurrentAppOrientation+
655 ", SensorEnabled="+mOrientationSensorEnabled);
656 boolean disable = true;
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -0700657 if (mScreenOnEarly) {
The Android Open Source Project0727d222009-03-11 12:11:58 -0700658 if (needSensorRunningLp()) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800659 disable = false;
660 //enable listener if not already enabled
The Android Open Source Project0727d222009-03-11 12:11:58 -0700661 if (!mOrientationSensorEnabled) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800662 mOrientationListener.enable();
Dianne Hackborn05726582009-09-22 17:28:24 -0700663 if(localLOGV) Log.v(TAG, "Enabling listeners");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800664 mOrientationSensorEnabled = true;
665 }
666 }
667 }
668 //check if sensors need to be disabled
The Android Open Source Project0727d222009-03-11 12:11:58 -0700669 if (disable && mOrientationSensorEnabled) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800670 mOrientationListener.disable();
Dianne Hackborn05726582009-09-22 17:28:24 -0700671 if(localLOGV) Log.v(TAG, "Disabling listeners");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800672 mOrientationSensorEnabled = false;
673 }
674 }
675
Jeff Brown4d396052010-10-29 21:50:21 -0700676 private void interceptPowerKeyDown(boolean handled) {
677 mPowerKeyHandled = handled;
678 if (!handled) {
679 mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
680 }
681 }
682
683 private boolean interceptPowerKeyUp(boolean canceled) {
684 if (!mPowerKeyHandled) {
685 mHandler.removeCallbacks(mPowerLongPress);
686 return !canceled;
Jeff Brown4d396052010-10-29 21:50:21 -0700687 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700688 return false;
689 }
690
691 private void cancelPendingPowerKeyAction() {
692 if (!mPowerKeyHandled) {
693 mHandler.removeCallbacks(mPowerLongPress);
694 }
Jeff Brownff204712011-10-25 21:27:54 -0700695 if (mPowerKeyTriggered) {
696 mPendingPowerKeyUpCanceled = true;
697 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700698 }
699
700 private void interceptScreenshotChord() {
Christopher Tatee90585f2012-03-05 18:56:25 -0800701 if (mScreenshotChordEnabled
702 && mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) {
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700703 final long now = SystemClock.uptimeMillis();
704 if (now <= mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
705 && now <= mPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
706 mVolumeDownKeyConsumedByScreenshotChord = true;
707 cancelPendingPowerKeyAction();
708
709 mHandler.postDelayed(mScreenshotChordLongPress,
710 ViewConfiguration.getGlobalActionKeyTimeout());
711 }
712 }
713 }
714
715 private void cancelPendingScreenshotChordAction() {
716 mHandler.removeCallbacks(mScreenshotChordLongPress);
Jeff Brown4d396052010-10-29 21:50:21 -0700717 }
718
719 private final Runnable mPowerLongPress = new Runnable() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800720 public void run() {
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700721 // The context isn't read
722 if (mLongPressOnPowerBehavior < 0) {
723 mLongPressOnPowerBehavior = mContext.getResources().getInteger(
724 com.android.internal.R.integer.config_longPressOnPowerBehavior);
Joe Onoratod208e702010-10-08 16:22:43 -0400725 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700726 switch (mLongPressOnPowerBehavior) {
727 case LONG_PRESS_POWER_NOTHING:
728 break;
729 case LONG_PRESS_POWER_GLOBAL_ACTIONS:
730 mPowerKeyHandled = true;
731 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
732 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
733 showGlobalActionsDialog();
734 break;
735 case LONG_PRESS_POWER_SHUT_OFF:
736 mPowerKeyHandled = true;
737 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
738 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
Jeff Brown7304c342012-05-11 18:42:42 -0700739 mWindowManagerFuncs.shutdown();
Jeff Brownd5bb82d2011-10-12 13:57:59 -0700740 break;
741 }
742 }
743 };
744
745 private final Runnable mScreenshotChordLongPress = new Runnable() {
746 public void run() {
747 takeScreenshot();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800748 }
749 };
750
751 void showGlobalActionsDialog() {
752 if (mGlobalActions == null) {
Jeff Brown7304c342012-05-11 18:42:42 -0700753 mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800754 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700755 final boolean keyguardShowing = keyguardIsShowingTq();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800756 mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
757 if (keyguardShowing) {
758 // since it took two seconds of long press to bring this up,
759 // poke the wake lock so they have some time to see the dialog.
760 mKeyguardMediator.pokeWakelock();
761 }
762 }
763
764 boolean isDeviceProvisioned() {
765 return Settings.Secure.getInt(
766 mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
767 }
768
Patrick Dubroyece94522011-02-23 18:35:01 -0800769 private void handleLongPressOnHome() {
Jim Milleree969aa2010-08-26 20:17:43 -0700770 // We can't initialize this in init() since the configuration hasn't been loaded yet.
Joe Onorato46b0d682010-11-22 17:37:27 -0800771 if (mLongPressOnHomeBehavior < 0) {
772 mLongPressOnHomeBehavior
Joe Onorato50262e52010-11-26 14:04:54 -0800773 = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior);
Joe Onorato46b0d682010-11-22 17:37:27 -0800774 if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
Michael Jurka3b1fc472011-06-13 10:54:40 -0700775 mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
Joe Onorato46b0d682010-11-22 17:37:27 -0800776 mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
777 }
778 }
779
780 if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
781 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
782 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
Patrick Dubroyece94522011-02-23 18:35:01 -0800783
784 // Eat the longpress so it won't dismiss the recent apps dialog when
785 // the user lets go of the home key
Michael Jurka7f2668c2012-03-27 07:49:52 -0700786 mHomeLongPressed = true;
Jim Milleree969aa2010-08-26 20:17:43 -0700787 }
Patrick Dubroyece94522011-02-23 18:35:01 -0800788
Joe Onorato46b0d682010-11-22 17:37:27 -0800789 if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
Jeff Brown68b909d2011-12-07 16:36:01 -0800790 showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
Michael Jurka3b1fc472011-06-13 10:54:40 -0700791 } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
Jim Millere6ad1a82010-08-20 19:25:39 -0700792 try {
Michael Jurka3b1fc472011-06-13 10:54:40 -0700793 mStatusBarService.toggleRecentApps();
794 } catch (RemoteException e) {
795 Slog.e(TAG, "RemoteException when showing recent apps", e);
Jim Millere6ad1a82010-08-20 19:25:39 -0700796 }
797 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800798 }
Patrick Dubroyece94522011-02-23 18:35:01 -0800799
800 /**
Jeff Brown68b909d2011-12-07 16:36:01 -0800801 * Create (if necessary) and show or dismiss the recent apps dialog according
802 * according to the requested behavior.
Patrick Dubroyece94522011-02-23 18:35:01 -0800803 */
Jeff Brown68b909d2011-12-07 16:36:01 -0800804 void showOrHideRecentAppsDialog(final int behavior) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700805 mHandler.post(new Runnable() {
806 @Override
807 public void run() {
808 if (mRecentAppsDialog == null) {
Jeff Brown54875002011-04-06 15:33:01 -0700809 mRecentAppsDialog = new RecentApplicationsDialog(mContext);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700810 }
Jeff Brown54875002011-04-06 15:33:01 -0700811 if (mRecentAppsDialog.isShowing()) {
Jeff Brown68b909d2011-12-07 16:36:01 -0800812 switch (behavior) {
813 case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
Jeff Brown602ab322012-05-16 13:33:47 -0700814 case RECENT_APPS_BEHAVIOR_DISMISS:
Jeff Brown68b909d2011-12-07 16:36:01 -0800815 mRecentAppsDialog.dismiss();
816 break;
817 case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
818 mRecentAppsDialog.dismissAndSwitch();
819 break;
820 case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
821 default:
822 break;
Jeff Brown54875002011-04-06 15:33:01 -0700823 }
824 } else {
Jeff Brown68b909d2011-12-07 16:36:01 -0800825 switch (behavior) {
826 case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
827 mRecentAppsDialog.show();
828 break;
829 case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
830 try {
831 mWindowManager.setInTouchMode(false);
832 } catch (RemoteException e) {
833 }
834 mRecentAppsDialog.show();
835 break;
Jeff Brown602ab322012-05-16 13:33:47 -0700836 case RECENT_APPS_BEHAVIOR_DISMISS:
Jeff Brown68b909d2011-12-07 16:36:01 -0800837 case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
838 default:
839 break;
840 }
Jeff Brown54875002011-04-06 15:33:01 -0700841 }
Jeff Brownda3d5a92011-03-29 15:11:34 -0700842 }
843 });
Patrick Dubroyece94522011-02-23 18:35:01 -0800844 }
Jeff Brownda3d5a92011-03-29 15:11:34 -0700845
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800846 /** {@inheritDoc} */
847 public void init(Context context, IWindowManager windowManager,
Dianne Hackborndf89e652011-10-06 22:35:11 -0700848 WindowManagerFuncs windowManagerFuncs,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800849 LocalPowerManager powerManager) {
850 mContext = context;
851 mWindowManager = windowManager;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700852 mWindowManagerFuncs = windowManagerFuncs;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800853 mPowerManager = powerManager;
Mike Lockwoodd747dc82011-09-13 16:28:22 -0400854 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
855 if (!mHeadless) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700856 // don't create KeyguardViewMediator if headless
857 mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
858 }
Jeff Brown70825162012-03-28 17:27:48 -0700859 mHandler = new PolicyHandler();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800860 mOrientationListener = new MyOrientationListener(mContext);
Jeff Brownc0347aa2011-09-23 17:26:09 -0700861 try {
862 mOrientationListener.setCurrentRotation(windowManager.getRotation());
863 } catch (RemoteException ex) { }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800864 SettingsObserver settingsObserver = new SettingsObserver(mHandler);
865 settingsObserver.observe();
866 mShortcutManager = new ShortcutManager(context, mHandler);
867 mShortcutManager.observe();
Joe Onorato44fcb832011-12-14 20:59:30 -0800868 mUiMode = context.getResources().getInteger(
869 com.android.internal.R.integer.config_defaultUiModeType);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800870 mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
871 mHomeIntent.addCategory(Intent.CATEGORY_HOME);
872 mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
873 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700874 mCarDockIntent = new Intent(Intent.ACTION_MAIN, null);
875 mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
876 mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
877 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
878 mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null);
879 mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK);
880 mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
881 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Jim Millere6ad1a82010-08-20 19:25:39 -0700882
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800883 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
884 mBroadcastWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
885 "PhoneWindowManager.mBroadcastWakeLock");
886 mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
Dianne Hackborn2862fff2009-09-15 22:56:29 -0700887 mLidOpenRotation = readRotation(
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400888 com.android.internal.R.integer.config_lidOpenRotation);
889 mCarDockRotation = readRotation(
890 com.android.internal.R.integer.config_carDockRotation);
891 mDeskDockRotation = readRotation(
892 com.android.internal.R.integer.config_deskDockRotation);
Mike Lockwoode9867d22009-09-20 01:59:02 -0400893 mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
894 com.android.internal.R.bool.config_carDockEnablesAccelerometer);
895 mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
896 com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
Dianne Hackborn2862fff2009-09-15 22:56:29 -0700897 mLidKeyboardAccessibility = mContext.getResources().getInteger(
898 com.android.internal.R.integer.config_lidKeyboardAccessibility);
899 mLidNavigationAccessibility = mContext.getResources().getInteger(
900 com.android.internal.R.integer.config_lidNavigationAccessibility);
Jeff Brownc458ce92012-04-30 14:58:40 -0700901 mLidControlsSleep = mContext.getResources().getBoolean(
902 com.android.internal.R.bool.config_lidControlsSleep);
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700903 // register for dock events
Dianne Hackborn78968392010-03-04 20:47:56 -0800904 IntentFilter filter = new IntentFilter();
905 filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
906 filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
907 filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE);
908 filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE);
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700909 filter.addAction(Intent.ACTION_DOCK_EVENT);
910 Intent intent = context.registerReceiver(mDockReceiver, filter);
911 if (intent != null) {
912 // Retrieve current sticky dock event broadcast.
913 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
914 Intent.EXTRA_DOCK_STATE_UNDOCKED);
915 }
Daniel Sandler7e37df52011-11-16 22:08:23 -0800916
917 // watch the plug to know whether to trigger the screen saver
918 filter = new IntentFilter();
919 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
920 intent = context.registerReceiver(mPowerReceiver, filter);
921 if (intent != null) {
922 mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
923 }
924
Jeff Brownc2346132012-04-13 01:55:38 -0700925 mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
Dianne Hackbornb1a79802009-09-29 15:18:31 -0700926 mLongPressVibePattern = getLongIntArray(mContext.getResources(),
927 com.android.internal.R.array.config_longPressVibePattern);
928 mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(),
929 com.android.internal.R.array.config_virtualKeyVibePattern);
Amith Yamasanic33cb712010-02-10 15:21:49 -0800930 mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(),
931 com.android.internal.R.array.config_keyboardTapVibePattern);
Dianne Hackbornb1a79802009-09-29 15:18:31 -0700932 mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
933 com.android.internal.R.array.config_safeModeDisabledVibePattern);
934 mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
935 com.android.internal.R.array.config_safeModeEnabledVibePattern);
Daniel Sandler40427442010-07-16 11:44:52 -0400936
Christopher Tatee90585f2012-03-05 18:56:25 -0800937 mScreenshotChordEnabled = mContext.getResources().getBoolean(
938 com.android.internal.R.bool.config_enableScreenshotChord);
939
Joe Onoratoea495d42011-04-06 11:41:11 -0700940 // Controls rotation and the like.
941 initializeHdmiState();
Dianne Hackborn40011092011-09-22 13:37:48 -0700942
943 // Match current screen state.
944 if (mPowerManager.isScreenOn()) {
945 screenTurningOn(null);
946 } else {
947 screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
948 }
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700949 }
950
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700951 public void setInitialDisplaySize(Display display, int width, int height) {
952 mDisplay = display;
953
954 int shortSize, longSize;
Dianne Hackborn9d132642011-04-21 17:26:39 -0700955 if (width > height) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700956 shortSize = height;
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700957 longSize = width;
Dianne Hackborn9d132642011-04-21 17:26:39 -0700958 mLandscapeRotation = Surface.ROTATION_0;
959 mSeascapeRotation = Surface.ROTATION_180;
960 if (mContext.getResources().getBoolean(
961 com.android.internal.R.bool.config_reverseDefaultRotation)) {
962 mPortraitRotation = Surface.ROTATION_90;
963 mUpsideDownRotation = Surface.ROTATION_270;
964 } else {
965 mPortraitRotation = Surface.ROTATION_270;
966 mUpsideDownRotation = Surface.ROTATION_90;
967 }
968 } else {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700969 shortSize = width;
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700970 longSize = height;
Dianne Hackborn9d132642011-04-21 17:26:39 -0700971 mPortraitRotation = Surface.ROTATION_0;
972 mUpsideDownRotation = Surface.ROTATION_180;
973 if (mContext.getResources().getBoolean(
974 com.android.internal.R.bool.config_reverseDefaultRotation)) {
975 mLandscapeRotation = Surface.ROTATION_270;
976 mSeascapeRotation = Surface.ROTATION_90;
977 } else {
978 mLandscapeRotation = Surface.ROTATION_90;
979 mSeascapeRotation = Surface.ROTATION_270;
980 }
981 }
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700982
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700983 mExternalDisplayWidth = mDisplay.getRawExternalWidth();
984 mExternalDisplayHeight = mDisplay.getRawExternalHeight();
985
986 mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
987 com.android.internal.R.dimen.status_bar_height);
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700988
Daniel Sandler9f65c4c2012-04-26 01:35:35 -0400989 // Height of the navigation bar when presented horizontally at bottom
990 mNavigationBarHeightForRotation[mPortraitRotation] =
991 mNavigationBarHeightForRotation[mUpsideDownRotation] =
Daniel Sandler4a066c52012-04-20 14:49:13 -0400992 mContext.getResources().getDimensionPixelSize(
993 com.android.internal.R.dimen.navigation_bar_height);
Daniel Sandler9f65c4c2012-04-26 01:35:35 -0400994 mNavigationBarHeightForRotation[mLandscapeRotation] =
995 mNavigationBarHeightForRotation[mSeascapeRotation] =
996 mContext.getResources().getDimensionPixelSize(
997 com.android.internal.R.dimen.navigation_bar_height_landscape);
998
999 // Width of the navigation bar when presented vertically along one side
1000 mNavigationBarWidthForRotation[mPortraitRotation] =
1001 mNavigationBarWidthForRotation[mUpsideDownRotation] =
1002 mNavigationBarWidthForRotation[mLandscapeRotation] =
1003 mNavigationBarWidthForRotation[mSeascapeRotation] =
Daniel Sandler4a066c52012-04-20 14:49:13 -04001004 mContext.getResources().getDimensionPixelSize(
1005 com.android.internal.R.dimen.navigation_bar_width);
1006
1007 // SystemUI (status bar) layout policy
Daniel Sandler631cb3d52011-06-03 01:25:43 -04001008 int shortSizeDp = shortSize
1009 * DisplayMetrics.DENSITY_DEFAULT
1010 / DisplayMetrics.DENSITY_DEVICE;
Daniel Sandler4a066c52012-04-20 14:49:13 -04001011
1012 if (shortSizeDp < 600) {
1013 // 0-599dp: "phone" UI with a separate status & navigation bar
1014 mHasSystemNavBar = false;
1015 mNavigationBarCanMove = true;
1016 } else if (shortSizeDp < 720) {
1017 // 600-719dp: "phone" UI with modifications for larger screens
1018 mHasSystemNavBar = false;
1019 mNavigationBarCanMove = false;
1020 } else {
1021 // 720dp: "tablet" UI with a single combined status & navigation bar
1022 mHasSystemNavBar = true;
1023 mNavigationBarCanMove = false;
1024 }
Daniel Sandler36412a72011-08-04 09:35:13 -04001025
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001026 if (!mHasSystemNavBar) {
1027 mHasNavigationBar = mContext.getResources().getBoolean(
1028 com.android.internal.R.bool.config_showNavigationBar);
1029 // Allow a system property to override this. Used by the emulator.
1030 // See also hasNavigationBar().
1031 String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
1032 if (! "".equals(navBarOverride)) {
1033 if (navBarOverride.equals("1")) mHasNavigationBar = false;
1034 else if (navBarOverride.equals("0")) mHasNavigationBar = true;
1035 }
1036 } else {
1037 mHasNavigationBar = false;
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04001038 }
1039
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001040 if (mHasSystemNavBar) {
1041 // The system bar is always at the bottom. If you are watching
1042 // a video in landscape, we don't need to hide it if we can still
1043 // show a 16:9 aspect ratio with it.
1044 int longSizeDp = longSize
1045 * DisplayMetrics.DENSITY_DEFAULT
1046 / DisplayMetrics.DENSITY_DEVICE;
Daniel Sandler4a066c52012-04-20 14:49:13 -04001047 int barHeightDp = mNavigationBarHeightForRotation[mLandscapeRotation]
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001048 * DisplayMetrics.DENSITY_DEFAULT
1049 / DisplayMetrics.DENSITY_DEVICE;
1050 int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp;
1051 // We have computed the aspect ratio with the bar height taken
1052 // out to be 16:aspect. If this is less than 9, then hiding
1053 // the navigation bar will provide more useful space for wide
1054 // screen movies.
1055 mCanHideNavigationBar = aspect < 9;
1056 } else if (mHasNavigationBar) {
1057 // The navigation bar is at the right in landscape; it seems always
1058 // useful to hide it for showing a video.
1059 mCanHideNavigationBar = true;
1060 } else {
1061 mCanHideNavigationBar = false;
1062 }
Erik Gilling9a41ef82011-09-26 19:21:03 -07001063
1064 if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
1065 mHdmiRotation = mPortraitRotation;
1066 } else {
1067 mHdmiRotation = mLandscapeRotation;
1068 }
Dianne Hackborn9d132642011-04-21 17:26:39 -07001069 }
1070
Dianne Hackbornc777e072010-02-12 13:07:59 -08001071 public void updateSettings() {
1072 ContentResolver resolver = mContext.getContentResolver();
1073 boolean updateRotation = false;
Dianne Hackbornc777e072010-02-12 13:07:59 -08001074 synchronized (mLock) {
1075 mEndcallBehavior = Settings.System.getInt(resolver,
David Brownbaf8d092010-03-08 21:52:59 -08001076 Settings.System.END_BUTTON_BEHAVIOR,
1077 Settings.System.END_BUTTON_BEHAVIOR_DEFAULT);
1078 mIncallPowerBehavior = Settings.Secure.getInt(resolver,
1079 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
1080 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04001081
Jeff Brown207673cd2012-06-05 17:47:11 -07001082 // Configure rotation lock.
1083 int userRotation = Settings.System.getInt(resolver,
1084 Settings.System.USER_ROTATION, Surface.ROTATION_0);
1085 if (mUserRotation != userRotation) {
1086 mUserRotation = userRotation;
1087 updateRotation = true;
1088 }
1089 int userRotationMode = Settings.System.getInt(resolver,
1090 Settings.System.ACCELEROMETER_ROTATION, 0) != 0 ?
1091 WindowManagerPolicy.USER_ROTATION_FREE :
1092 WindowManagerPolicy.USER_ROTATION_LOCKED;
1093 if (mUserRotationMode != userRotationMode) {
1094 mUserRotationMode = userRotationMode;
1095 updateRotation = true;
Dianne Hackbornc777e072010-02-12 13:07:59 -08001096 updateOrientationListenerLp();
1097 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04001098
Dianne Hackbornc777e072010-02-12 13:07:59 -08001099 if (mSystemReady) {
1100 int pointerLocation = Settings.System.getInt(resolver,
1101 Settings.System.POINTER_LOCATION, 0);
1102 if (mPointerLocationMode != pointerLocation) {
1103 mPointerLocationMode = pointerLocation;
Jeff Brown70825162012-03-28 17:27:48 -07001104 mHandler.sendEmptyMessage(pointerLocation != 0 ?
1105 MSG_ENABLE_POINTER_LOCATION : MSG_DISABLE_POINTER_LOCATION);
Dianne Hackbornc777e072010-02-12 13:07:59 -08001106 }
1107 }
1108 // use screen off timeout setting as the timeout for the lockscreen
1109 mLockScreenTimeout = Settings.System.getInt(resolver,
1110 Settings.System.SCREEN_OFF_TIMEOUT, 0);
1111 String imId = Settings.Secure.getString(resolver,
1112 Settings.Secure.DEFAULT_INPUT_METHOD);
1113 boolean hasSoftInput = imId != null && imId.length() > 0;
1114 if (mHasSoftInput != hasSoftInput) {
1115 mHasSoftInput = hasSoftInput;
1116 updateRotation = true;
1117 }
Daniel Sandler0601eb72011-04-13 01:01:32 -04001118
Daniel Sandler7d276c32012-01-30 14:33:52 -05001119 // dreams
1120 mScreenSaverFeatureAvailable = mContext.getResources().getBoolean(
1121 com.android.internal.R.bool.config_enableDreams);
1122
Daniel Sandler2d545362011-11-17 10:38:37 -08001123 mScreenSaverEnabledByUser = 0 != Settings.Secure.getInt(resolver,
1124 Settings.Secure.SCREENSAVER_ENABLED, 1);
1125
Daniel Sandler7e37df52011-11-16 22:08:23 -08001126 if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
1127 mScreenSaverTimeout = Settings.Secure.getInt(resolver,
Daniel Sandler2d545362011-11-17 10:38:37 -08001128 "screensaver_timeout", 0);
Daniel Sandler7e37df52011-11-16 22:08:23 -08001129 } else {
1130 mScreenSaverTimeout = Settings.System.getInt(resolver,
1131 Settings.System.SCREEN_OFF_TIMEOUT, 0);
1132 if (mScreenSaverTimeout > 0) {
1133 // We actually want to activate the screensaver just before the
1134 // power manager's screen timeout
1135 mScreenSaverTimeout -= 5000;
1136 }
1137 }
Dianne Hackbornc777e072010-02-12 13:07:59 -08001138 }
1139 if (updateRotation) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07001140 updateRotation(true);
Dianne Hackbornc777e072010-02-12 13:07:59 -08001141 }
Jeff Brown70825162012-03-28 17:27:48 -07001142 }
1143
1144 private void enablePointerLocation() {
1145 if (mPointerLocationView == null) {
1146 mPointerLocationView = new PointerLocationView(mContext);
1147 mPointerLocationView.setPrintCoords(false);
1148
Dianne Hackbornc777e072010-02-12 13:07:59 -08001149 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
1150 WindowManager.LayoutParams.MATCH_PARENT,
1151 WindowManager.LayoutParams.MATCH_PARENT);
Jeff Brown3b2b3542010-10-15 00:54:27 -07001152 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brownbfcb60a2011-09-08 18:51:14 -07001153 lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
1154 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
1155 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
1156 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
Dianne Hackbornc777e072010-02-12 13:07:59 -08001157 lp.format = PixelFormat.TRANSLUCENT;
1158 lp.setTitle("PointerLocation");
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001159 WindowManager wm = (WindowManager)
Dianne Hackbornc777e072010-02-12 13:07:59 -08001160 mContext.getSystemService(Context.WINDOW_SERVICE);
Jeff Browncc4f7db2011-08-30 20:34:48 -07001161 lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
Jeff Brown70825162012-03-28 17:27:48 -07001162 wm.addView(mPointerLocationView, lp);
1163
Jeff Brownac143512012-04-05 18:57:33 -07001164 mPointerLocationInputChannel =
1165 mWindowManagerFuncs.monitorInput("PointerLocationView");
1166 mPointerLocationInputEventReceiver =
1167 new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
1168 Looper.myLooper(), mPointerLocationView);
Dianne Hackbornc777e072010-02-12 13:07:59 -08001169 }
Dianne Hackbornc777e072010-02-12 13:07:59 -08001170 }
Jeff Brown70825162012-03-28 17:27:48 -07001171
1172 private void disablePointerLocation() {
1173 if (mPointerLocationInputEventReceiver != null) {
1174 mPointerLocationInputEventReceiver.dispose();
1175 mPointerLocationInputEventReceiver = null;
1176 }
1177
1178 if (mPointerLocationInputChannel != null) {
1179 mPointerLocationInputChannel.dispose();
1180 mPointerLocationInputChannel = null;
1181 }
1182
1183 if (mPointerLocationView != null) {
1184 WindowManager wm = (WindowManager)
1185 mContext.getSystemService(Context.WINDOW_SERVICE);
1186 wm.removeView(mPointerLocationView);
1187 mPointerLocationView = null;
1188 }
1189 }
1190
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04001191 private int readRotation(int resID) {
Mike Lockwood1753f7f2009-08-24 14:49:07 -07001192 try {
1193 int rotation = mContext.getResources().getInteger(resID);
1194 switch (rotation) {
1195 case 0:
1196 return Surface.ROTATION_0;
1197 case 90:
1198 return Surface.ROTATION_90;
1199 case 180:
1200 return Surface.ROTATION_180;
1201 case 270:
1202 return Surface.ROTATION_270;
Mike Lockwood1753f7f2009-08-24 14:49:07 -07001203 }
1204 } catch (Resources.NotFoundException e) {
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04001205 // fall through
Mike Lockwood1753f7f2009-08-24 14:49:07 -07001206 }
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04001207 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001208 }
1209
1210 /** {@inheritDoc} */
1211 public int checkAddPermission(WindowManager.LayoutParams attrs) {
1212 int type = attrs.type;
Mitsuru Oshima831d0d92009-06-16 18:27:18 -07001213
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001214 if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
1215 || type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
1216 return WindowManagerImpl.ADD_OKAY;
1217 }
1218 String permission = null;
1219 switch (type) {
1220 case TYPE_TOAST:
1221 // XXX right now the app process has complete control over
1222 // this... should introduce a token to let the system
1223 // monitor/control what they are doing.
1224 break;
Daniel Sandler7d276c32012-01-30 14:33:52 -05001225 case TYPE_DREAM:
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001226 case TYPE_INPUT_METHOD:
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -07001227 case TYPE_WALLPAPER:
1228 // The window manager will check these.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001229 break;
1230 case TYPE_PHONE:
1231 case TYPE_PRIORITY_PHONE:
1232 case TYPE_SYSTEM_ALERT:
1233 case TYPE_SYSTEM_ERROR:
1234 case TYPE_SYSTEM_OVERLAY:
1235 permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW;
1236 break;
1237 default:
1238 permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
1239 }
1240 if (permission != null) {
1241 if (mContext.checkCallingOrSelfPermission(permission)
1242 != PackageManager.PERMISSION_GRANTED) {
1243 return WindowManagerImpl.ADD_PERMISSION_DENIED;
1244 }
1245 }
1246 return WindowManagerImpl.ADD_OKAY;
1247 }
1248
1249 public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) {
1250 switch (attrs.type) {
1251 case TYPE_SYSTEM_OVERLAY:
Jeff Brown3b2b3542010-10-15 00:54:27 -07001252 case TYPE_SECURE_SYSTEM_OVERLAY:
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001253 case TYPE_TOAST:
1254 // These types of windows can't receive input events.
1255 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
1256 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Jeff Brownbfcb60a2011-09-08 18:51:14 -07001257 attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001258 break;
1259 }
1260 }
1261
1262 void readLidState() {
Jeff Brown2e7760e2012-04-11 15:14:55 -07001263 mLidState = mWindowManagerFuncs.getLidState();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001264 }
1265
Jeff Browndaa37532012-05-01 15:54:03 -07001266 private boolean isHidden(int accessibilityMode) {
1267 switch (accessibilityMode) {
1268 case 1:
1269 return mLidState == LID_CLOSED;
1270 case 2:
1271 return mLidState == LID_OPEN;
1272 default:
1273 return false;
Dianne Hackborn2862fff2009-09-15 22:56:29 -07001274 }
Dianne Hackborn2862fff2009-09-15 22:56:29 -07001275 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08001276
Jeff Browndaa37532012-05-01 15:54:03 -07001277 private boolean isBuiltInKeyboardVisible() {
1278 return mHaveBuiltInKeyboard && !isHidden(mLidKeyboardAccessibility);
Jeff Brownc458ce92012-04-30 14:58:40 -07001279 }
1280
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001281 /** {@inheritDoc} */
Jeff Browndaa37532012-05-01 15:54:03 -07001282 public void adjustConfigurationLw(Configuration config, int keyboardPresence,
1283 int navigationPresence) {
1284 mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0;
1285
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001286 readLidState();
Jeff Brownc458ce92012-04-30 14:58:40 -07001287 applyLidSwitchState();
Jeff Brownd04a88c2011-01-16 14:05:47 -08001288
Jeff Browndaa37532012-05-01 15:54:03 -07001289 if (config.keyboard == Configuration.KEYBOARD_NOKEYS
1290 || (keyboardPresence == PRESENCE_INTERNAL
1291 && isHidden(mLidKeyboardAccessibility))) {
Jeff Brownd04a88c2011-01-16 14:05:47 -08001292 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
Jeff Browndaa37532012-05-01 15:54:03 -07001293 if (!mHasSoftInput) {
1294 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
1295 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08001296 }
1297
Jeff Browndaa37532012-05-01 15:54:03 -07001298 if (config.navigation == Configuration.NAVIGATION_NONAV
1299 || (navigationPresence == PRESENCE_INTERNAL
1300 && isHidden(mLidNavigationAccessibility))) {
Jeff Brownd04a88c2011-01-16 14:05:47 -08001301 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES;
Jeff Brownd04a88c2011-01-16 14:05:47 -08001302 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001303 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08001304
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001305 /** {@inheritDoc} */
1306 public int windowTypeToLayerLw(int type) {
1307 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
1308 return APPLICATION_LAYER;
1309 }
1310 switch (type) {
1311 case TYPE_STATUS_BAR:
1312 return STATUS_BAR_LAYER;
1313 case TYPE_STATUS_BAR_PANEL:
1314 return STATUS_BAR_PANEL_LAYER;
Joe Onorato29fc2c92010-11-24 10:26:50 -08001315 case TYPE_STATUS_BAR_SUB_PANEL:
1316 return STATUS_BAR_SUB_PANEL_LAYER;
Dianne Hackborn6a294ce2009-12-03 11:37:44 -08001317 case TYPE_SYSTEM_DIALOG:
1318 return SYSTEM_DIALOG_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001319 case TYPE_SEARCH_BAR:
1320 return SEARCH_BAR_LAYER;
1321 case TYPE_PHONE:
1322 return PHONE_LAYER;
1323 case TYPE_KEYGUARD:
1324 return KEYGUARD_LAYER;
1325 case TYPE_KEYGUARD_DIALOG:
1326 return KEYGUARD_DIALOG_LAYER;
1327 case TYPE_SYSTEM_ALERT:
1328 return SYSTEM_ALERT_LAYER;
1329 case TYPE_SYSTEM_ERROR:
1330 return SYSTEM_ERROR_LAYER;
1331 case TYPE_INPUT_METHOD:
1332 return INPUT_METHOD_LAYER;
1333 case TYPE_INPUT_METHOD_DIALOG:
1334 return INPUT_METHOD_DIALOG_LAYER;
Dianne Hackborne8ecde12011-08-03 18:55:19 -07001335 case TYPE_VOLUME_OVERLAY:
1336 return VOLUME_OVERLAY_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001337 case TYPE_SYSTEM_OVERLAY:
1338 return SYSTEM_OVERLAY_LAYER;
Jeff Brown3b2b3542010-10-15 00:54:27 -07001339 case TYPE_SECURE_SYSTEM_OVERLAY:
1340 return SECURE_SYSTEM_OVERLAY_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001341 case TYPE_PRIORITY_PHONE:
1342 return PRIORITY_PHONE_LAYER;
1343 case TYPE_TOAST:
1344 return TOAST_LAYER;
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -07001345 case TYPE_WALLPAPER:
1346 return WALLPAPER_LAYER;
Christopher Tatea53146c2010-09-07 11:57:52 -07001347 case TYPE_DRAG:
1348 return DRAG_LAYER;
Jeff Brown83c09682010-12-23 17:50:18 -08001349 case TYPE_POINTER:
1350 return POINTER_LAYER;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001351 case TYPE_NAVIGATION_BAR:
1352 return NAVIGATION_BAR_LAYER;
Jim Millere898ac52012-04-06 17:10:57 -07001353 case TYPE_NAVIGATION_BAR_PANEL:
1354 return NAVIGATION_BAR_PANEL_LAYER;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001355 case TYPE_BOOT_PROGRESS:
1356 return BOOT_PROGRESS_LAYER;
Dianne Hackborndf89e652011-10-06 22:35:11 -07001357 case TYPE_HIDDEN_NAV_CONSUMER:
1358 return HIDDEN_NAV_CONSUMER_LAYER;
Daniel Sandler7d276c32012-01-30 14:33:52 -05001359 case TYPE_DREAM:
1360 return SCREENSAVER_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001361 }
1362 Log.e(TAG, "Unknown window type: " + type);
1363 return APPLICATION_LAYER;
1364 }
1365
1366 /** {@inheritDoc} */
1367 public int subWindowTypeToLayerLw(int type) {
1368 switch (type) {
1369 case TYPE_APPLICATION_PANEL:
1370 case TYPE_APPLICATION_ATTACHED_DIALOG:
1371 return APPLICATION_PANEL_SUBLAYER;
1372 case TYPE_APPLICATION_MEDIA:
1373 return APPLICATION_MEDIA_SUBLAYER;
Dianne Hackborn5cb8d792009-05-21 17:34:15 -07001374 case TYPE_APPLICATION_MEDIA_OVERLAY:
1375 return APPLICATION_MEDIA_OVERLAY_SUBLAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001376 case TYPE_APPLICATION_SUB_PANEL:
1377 return APPLICATION_SUB_PANEL_SUBLAYER;
1378 }
1379 Log.e(TAG, "Unknown sub-window type: " + type);
1380 return 0;
1381 }
1382
Dianne Hackbornabe0da02009-09-18 01:55:39 -07001383 public int getMaxWallpaperLayer() {
1384 return STATUS_BAR_LAYER;
1385 }
1386
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001387 public boolean hasSystemNavBar() {
1388 return mHasSystemNavBar;
Dianne Hackborn81e56d52011-05-26 00:55:58 -07001389 }
1390
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001391 public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) {
Dianne Hackborn077ee852012-04-09 16:27:07 -07001392 if (mHasNavigationBar) {
1393 // For a basic navigation bar, when we are in landscape mode we place
1394 // the navigation bar to the side.
Daniel Sandler4a066c52012-04-20 14:49:13 -04001395 if (mNavigationBarCanMove && fullWidth > fullHeight) {
1396 return fullWidth - mNavigationBarWidthForRotation[rotation];
Dianne Hackborn077ee852012-04-09 16:27:07 -07001397 }
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001398 }
1399 return fullWidth;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001400 }
1401
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001402 public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
Dianne Hackborn077ee852012-04-09 16:27:07 -07001403 if (mHasSystemNavBar) {
1404 // For the system navigation bar, we always place it at the bottom.
Daniel Sandler4a066c52012-04-20 14:49:13 -04001405 return fullHeight - mNavigationBarHeightForRotation[rotation];
Dianne Hackborn077ee852012-04-09 16:27:07 -07001406 }
1407 if (mHasNavigationBar) {
1408 // For a basic navigation bar, when we are in portrait mode we place
1409 // the navigation bar to the bottom.
Daniel Sandler4a066c52012-04-20 14:49:13 -04001410 if (!mNavigationBarCanMove || fullWidth < fullHeight) {
1411 return fullHeight - mNavigationBarHeightForRotation[rotation];
Dianne Hackborn077ee852012-04-09 16:27:07 -07001412 }
1413 }
1414 return fullHeight;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001415 }
1416
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001417 public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation) {
1418 return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001419 }
1420
Dianne Hackborn1f903c32011-09-13 19:18:06 -07001421 public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation) {
Dianne Hackborn077ee852012-04-09 16:27:07 -07001422 // If we don't have a system nav bar, then there is a separate status
1423 // bar at the top of the display. We don't count that as part of the
1424 // fixed decor, since it can hide; however, for purposes of configurations,
1425 // we do want to exclude it since applications can't generally use that part
1426 // of the screen.
1427 if (!mHasSystemNavBar) {
1428 return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation) - mStatusBarHeight;
1429 }
1430 return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001431 }
1432
Dianne Hackborn01ad2f42009-09-24 19:24:56 -07001433 public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
1434 return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD;
1435 }
1436
1437 public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
1438 return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001439 && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
Dianne Hackborn01ad2f42009-09-24 19:24:56 -07001440 && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER;
1441 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001442
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001443 /** {@inheritDoc} */
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001444 @Override
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001445 public View addStartingWindow(IBinder appToken, String packageName, int theme,
1446 CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
1447 int icon, int windowFlags) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001448 if (!SHOW_STARTING_ANIMATIONS) {
1449 return null;
1450 }
1451 if (packageName == null) {
1452 return null;
1453 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001454
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001455 try {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001456 Context context = mContext;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001457 //Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel="
1458 // + nonLocalizedLabel + " theme=" + Integer.toHexString(theme));
Dianne Hackborn247fe742011-01-08 17:25:57 -08001459 if (theme != context.getThemeResId() || labelRes != 0) {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001460 try {
1461 context = context.createPackageContext(packageName, 0);
Dianne Hackborn247fe742011-01-08 17:25:57 -08001462 context.setTheme(theme);
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001463 } catch (PackageManager.NameNotFoundException e) {
1464 // Ignore
1465 }
1466 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001467
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001468 Window win = PolicyManager.makeNewWindow(context);
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001469 final TypedArray ta = win.getWindowStyle();
1470 if (ta.getBoolean(
1471 com.android.internal.R.styleable.Window_windowDisablePreview, false)
1472 || ta.getBoolean(
1473 com.android.internal.R.styleable.Window_windowShowWallpaper,false)) {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001474 return null;
1475 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001476
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001477 Resources r = context.getResources();
1478 win.setTitle(r.getText(labelRes, nonLocalizedLabel));
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001479
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001480 win.setType(
1481 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
1482 // Force the window flags: this is a fake window, so it is not really
1483 // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM
1484 // flag because we do know that the next window will take input
1485 // focus, so we want to get the IME window up on top of us right away.
1486 win.setFlags(
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08001487 windowFlags|
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001488 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
1489 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
1490 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08001491 windowFlags|
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001492 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
1493 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
1494 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001495
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001496 if (!compatInfo.supportsScreen()) {
1497 win.addFlags(WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW);
1498 }
1499
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001500 win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001501 WindowManager.LayoutParams.MATCH_PARENT);
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001502
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001503 final WindowManager.LayoutParams params = win.getAttributes();
1504 params.token = appToken;
1505 params.packageName = packageName;
1506 params.windowAnimations = win.getWindowStyle().getResourceId(
1507 com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
Dianne Hackborn5d927c22011-09-02 12:22:18 -07001508 params.privateFlags |=
1509 WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001510 params.setTitle("Starting " + packageName);
1511
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001512 WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001513 View view = win.getDecorView();
1514
1515 if (win.isFloating()) {
1516 // Whoops, there is no way to display an animation/preview
1517 // of such a thing! After all that work... let's skip it.
1518 // (Note that we must do this here because it is in
1519 // getDecorView() where the theme is evaluated... maybe
1520 // we should peek the floating attribute from the theme
1521 // earlier.)
1522 return null;
1523 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001524
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001525 if (localLOGV) Log.v(
1526 TAG, "Adding starting window for " + packageName
1527 + " / " + appToken + ": "
1528 + (view.getParent() != null ? view : null));
1529
1530 wm.addView(view, params);
1531
1532 // Only return the view if it was successfully added to the
1533 // window manager... which we can tell by it having a parent.
1534 return view.getParent() != null ? view : null;
1535 } catch (WindowManagerImpl.BadTokenException e) {
1536 // ignore
1537 Log.w(TAG, appToken + " already running, starting window not displayed");
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001538 } catch (RuntimeException e) {
1539 // don't crash if something else bad happens, for example a
1540 // failure loading resources because we are loading from an app
1541 // on external storage that has been unmounted.
1542 Log.w(TAG, appToken + " failed creating starting window", e);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001543 }
1544
1545 return null;
1546 }
1547
1548 /** {@inheritDoc} */
1549 public void removeStartingWindow(IBinder appToken, View window) {
1550 // RuntimeException e = new RuntimeException();
1551 // Log.i(TAG, "remove " + appToken + " " + window, e);
1552
1553 if (localLOGV) Log.v(
1554 TAG, "Removing starting window for " + appToken + ": " + window);
1555
1556 if (window != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001557 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001558 wm.removeView(window);
1559 }
1560 }
1561
1562 /**
1563 * Preflight adding a window to the system.
1564 *
1565 * Currently enforces that three window types are singletons:
1566 * <ul>
1567 * <li>STATUS_BAR_TYPE</li>
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001568 * <li>KEYGUARD_TYPE</li>
1569 * </ul>
1570 *
1571 * @param win The window to be added
1572 * @param attrs Information about the window to be added
1573 *
1574 * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons, WindowManagerImpl.ADD_MULTIPLE_SINGLETON
1575 */
1576 public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
1577 switch (attrs.type) {
1578 case TYPE_STATUS_BAR:
Joe Onorato8bc6c512010-06-04 16:21:12 -04001579 mContext.enforceCallingOrSelfPermission(
1580 android.Manifest.permission.STATUS_BAR_SERVICE,
1581 "PhoneWindowManager");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001582 if (mStatusBar != null) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001583 if (mStatusBar.isAlive()) {
1584 return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
1585 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001586 }
1587 mStatusBar = win;
1588 break;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001589 case TYPE_NAVIGATION_BAR:
1590 mContext.enforceCallingOrSelfPermission(
1591 android.Manifest.permission.STATUS_BAR_SERVICE,
1592 "PhoneWindowManager");
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001593 if (mNavigationBar != null) {
1594 if (mNavigationBar.isAlive()) {
1595 return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
1596 }
1597 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001598 mNavigationBar = win;
1599 if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
1600 break;
Jim Millere898ac52012-04-06 17:10:57 -07001601 case TYPE_NAVIGATION_BAR_PANEL:
1602 mContext.enforceCallingOrSelfPermission(
1603 android.Manifest.permission.STATUS_BAR_SERVICE,
1604 "PhoneWindowManager");
1605 break;
Dianne Hackborn08743722009-12-21 12:16:51 -08001606 case TYPE_STATUS_BAR_PANEL:
Joe Onorato8bc6c512010-06-04 16:21:12 -04001607 mContext.enforceCallingOrSelfPermission(
1608 android.Manifest.permission.STATUS_BAR_SERVICE,
1609 "PhoneWindowManager");
Dianne Hackborn08743722009-12-21 12:16:51 -08001610 break;
Joe Onorato29fc2c92010-11-24 10:26:50 -08001611 case TYPE_STATUS_BAR_SUB_PANEL:
1612 mContext.enforceCallingOrSelfPermission(
1613 android.Manifest.permission.STATUS_BAR_SERVICE,
1614 "PhoneWindowManager");
Joe Onorato29fc2c92010-11-24 10:26:50 -08001615 break;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001616 case TYPE_KEYGUARD:
1617 if (mKeyguard != null) {
1618 return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
1619 }
1620 mKeyguard = win;
1621 break;
1622 }
1623 return WindowManagerImpl.ADD_OKAY;
1624 }
1625
1626 /** {@inheritDoc} */
1627 public void removeWindowLw(WindowState win) {
1628 if (mStatusBar == win) {
1629 mStatusBar = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001630 } else if (mKeyguard == win) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001631 mKeyguard = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001632 } else if (mNavigationBar == win) {
1633 mNavigationBar = null;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001634 }
1635 }
1636
1637 static final boolean PRINT_ANIM = false;
1638
1639 /** {@inheritDoc} */
1640 public int selectAnimationLw(WindowState win, int transit) {
1641 if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
1642 + ": transit=" + transit);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07001643 if (win == mStatusBar) {
1644 if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
1645 return R.anim.dock_top_exit;
1646 } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
1647 return R.anim.dock_top_enter;
1648 }
1649 } else if (win == mNavigationBar) {
1650 // This can be on either the bottom or the right.
1651 if (mNavigationBarOnBottom) {
1652 if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
1653 return R.anim.dock_bottom_exit;
1654 } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
1655 return R.anim.dock_bottom_enter;
1656 }
1657 } else {
1658 if (transit == TRANSIT_EXIT || transit == TRANSIT_HIDE) {
1659 return R.anim.dock_right_exit;
1660 } else if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
1661 return R.anim.dock_right_enter;
1662 }
1663 }
1664 } if (transit == TRANSIT_PREVIEW_DONE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001665 if (win.hasAppShownWindows()) {
1666 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");
1667 return com.android.internal.R.anim.app_starting_exit;
1668 }
1669 }
1670
1671 return 0;
1672 }
1673
Dianne Hackborn0c2acff2012-04-12 15:17:07 -07001674 public Animation createForceHideEnterAnimation(boolean onWallpaper) {
1675 return AnimationUtils.loadAnimation(mContext, onWallpaper
1676 ? com.android.internal.R.anim.lock_screen_wallpaper_behind_enter
1677 : com.android.internal.R.anim.lock_screen_behind_enter);
Dianne Hackborn01ad2f42009-09-24 19:24:56 -07001678 }
1679
Jeff Brown4d396052010-10-29 21:50:21 -07001680 static ITelephony getTelephonyService() {
Mike Lockwoodf5f4ec92011-11-08 14:05:31 -08001681 return ITelephony.Stub.asInterface(
Jeff Brown4d396052010-10-29 21:50:21 -07001682 ServiceManager.checkService(Context.TELEPHONY_SERVICE));
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001683 }
1684
Jeff Brown4d396052010-10-29 21:50:21 -07001685 static IAudioService getAudioService() {
1686 IAudioService audioService = IAudioService.Stub.asInterface(
1687 ServiceManager.checkService(Context.AUDIO_SERVICE));
1688 if (audioService == null) {
1689 Log.w(TAG, "Unable to find IAudioService interface.");
1690 }
1691 return audioService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001692 }
1693
1694 boolean keyguardOn() {
1695 return keyguardIsShowingTq() || inKeyguardRestrictedKeyInputMode();
1696 }
1697
1698 private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
1699 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
1700 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
1701 };
1702
1703 /** {@inheritDoc} */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001704 @Override
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001705 public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001706 final boolean keyguardOn = keyguardOn();
Jeff Brown1f245102010-11-18 20:53:46 -08001707 final int keyCode = event.getKeyCode();
1708 final int repeatCount = event.getRepeatCount();
1709 final int metaState = event.getMetaState();
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001710 final int flags = event.getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08001711 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
1712 final boolean canceled = event.isCanceled();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001713
Jeff Brown40013652012-05-16 21:22:36 -07001714 if (DEBUG_INPUT) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001715 Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
Jeff Brownfd23e3e2012-05-09 13:34:28 -07001716 + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
1717 + " canceled=" + canceled);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001718 }
1719
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001720 // If we think we might have a volume down & power key chord on the way
1721 // but we're not sure, then tell the dispatcher to wait a little while and
1722 // try again later before dispatching.
Christopher Tatee90585f2012-03-05 18:56:25 -08001723 if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001724 if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {
1725 final long now = SystemClock.uptimeMillis();
1726 final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
1727 if (now < timeoutTime) {
1728 return timeoutTime - now;
1729 }
1730 }
1731 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
1732 && mVolumeDownKeyConsumedByScreenshotChord) {
1733 if (!down) {
1734 mVolumeDownKeyConsumedByScreenshotChord = false;
1735 }
1736 return -1;
1737 }
1738 }
1739
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001740 // First we always handle the home key here, so applications
1741 // can never break it, although if keyguard is on, we do let
1742 // it handle it, because that gives us the correct 5 second
1743 // timeout.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001744 if (keyCode == KeyEvent.KEYCODE_HOME) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001745
Jeff Brown49ed71d2010-12-06 17:13:33 -08001746 // If we have released the home key, and didn't do anything else
1747 // while it was pressed, then it is time to go home!
Michael Jurka7f2668c2012-03-27 07:49:52 -07001748 if (!down) {
1749 final boolean homeWasLongPressed = mHomeLongPressed;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001750 mHomePressed = false;
Michael Jurka7f2668c2012-03-27 07:49:52 -07001751 mHomeLongPressed = false;
1752 if (!homeWasLongPressed) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08001753 try {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001754 mStatusBarService.cancelPreloadRecentApps();
1755 } catch (RemoteException e) {
1756 Slog.e(TAG, "RemoteException when showing recent apps", e);
Jeff Brown49ed71d2010-12-06 17:13:33 -08001757 }
1758
Michael Jurka7f2668c2012-03-27 07:49:52 -07001759 mHomePressed = false;
1760 if (!canceled) {
1761 // If an incoming call is ringing, HOME is totally disabled.
1762 // (The user is already on the InCallScreen at this point,
1763 // and his ONLY options are to answer or reject the call.)
1764 boolean incomingRinging = false;
1765 try {
1766 ITelephony telephonyService = getTelephonyService();
1767 if (telephonyService != null) {
1768 incomingRinging = telephonyService.isRinging();
1769 }
1770 } catch (RemoteException ex) {
1771 Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
1772 }
1773
1774 if (incomingRinging) {
1775 Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
1776 } else {
1777 launchHomeFromHotKey();
1778 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08001779 } else {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001780 Log.i(TAG, "Ignoring HOME; event canceled.");
Jeff Brown49ed71d2010-12-06 17:13:33 -08001781 }
Michael Jurka7f2668c2012-03-27 07:49:52 -07001782 return -1;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001783 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08001784 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001785
1786 // If a system window has focus, then it doesn't make sense
1787 // right now to interact with applications.
1788 WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
1789 if (attrs != null) {
1790 final int type = attrs.type;
1791 if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
1792 || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
1793 // the "app" is keyguard, so give it the key
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001794 return 0;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001795 }
1796 final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
1797 for (int i=0; i<typeCount; i++) {
1798 if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
1799 // don't do anything, but also don't pass it to the app
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001800 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001801 }
1802 }
1803 }
Jeff Brown98392ef2011-09-12 18:24:59 -07001804 if (down) {
Michael Jurka40040332012-05-29 08:25:32 -07001805 if (!mHomePressed && mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
Michael Jurka7f2668c2012-03-27 07:49:52 -07001806 try {
1807 mStatusBarService.preloadRecentApps();
1808 } catch (RemoteException e) {
1809 Slog.e(TAG, "RemoteException when preloading recent apps", e);
1810 }
1811 }
Jeff Brown98392ef2011-09-12 18:24:59 -07001812 if (repeatCount == 0) {
1813 mHomePressed = true;
1814 } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
1815 if (!keyguardOn) {
1816 handleLongPressOnHome();
1817 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001818 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001819 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001820 return -1;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001821 } else if (keyCode == KeyEvent.KEYCODE_MENU) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001822 // Hijack modified menu keys for debugging features
1823 final int chordBug = KeyEvent.META_SHIFT_ON;
1824
1825 if (down && repeatCount == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001826 if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001827 Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
1828 mContext.sendOrderedBroadcast(intent, null);
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001829 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001830 } else if (SHOW_PROCESSES_ON_ALT_MENU &&
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001831 (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001832 Intent service = new Intent();
1833 service.setClassName(mContext, "com.android.server.LoadAverageService");
1834 ContentResolver res = mContext.getContentResolver();
1835 boolean shown = Settings.System.getInt(
1836 res, Settings.System.SHOW_PROCESSES, 0) != 0;
1837 if (!shown) {
1838 mContext.startService(service);
1839 } else {
1840 mContext.stopService(service);
1841 }
1842 Settings.System.putInt(
1843 res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1);
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001844 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001845 }
1846 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001847 } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001848 if (down) {
1849 if (repeatCount == 0) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07001850 mSearchKeyShortcutPending = true;
1851 mConsumeSearchKeyUp = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001852 }
Jeff Brownfd23e3e2012-05-09 13:34:28 -07001853 } else {
1854 mSearchKeyShortcutPending = false;
1855 if (mConsumeSearchKeyUp) {
1856 mConsumeSearchKeyUp = false;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001857 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001858 }
1859 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001860 return 0;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001861 } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
Jeff Brown602ab322012-05-16 13:33:47 -07001862 if (down && repeatCount == 0 && !keyguardOn) {
Jeff Brown68b909d2011-12-07 16:36:01 -08001863 showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
Jeff Brown49ed71d2010-12-06 17:13:33 -08001864 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001865 return -1;
Jeff Brownde7a8ea2012-06-13 18:28:57 -07001866 } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
1867 if (down) {
1868 if (repeatCount == 0) {
1869 mAssistKeyLongPressed = false;
1870 } else if (repeatCount == 1) {
1871 mAssistKeyLongPressed = true;
1872 if (!keyguardOn) {
1873 launchAssistLongPressAction();
1874 }
1875 }
1876 } else {
1877 if (mAssistKeyLongPressed) {
1878 mAssistKeyLongPressed = false;
1879 } else {
1880 if (!keyguardOn) {
1881 launchAssistAction();
1882 }
1883 }
1884 }
1885 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001886 }
Jeff Browncaab4d02010-12-09 22:13:41 -08001887
Jeff Brownc1fb48d2010-12-08 16:52:09 -08001888 // Shortcuts are invoked through Search+key, so intercept those here
Jeff Browncaab4d02010-12-09 22:13:41 -08001889 // Any printing key that is chorded with Search should be consumed
1890 // even if no shortcut was invoked. This prevents text from being
1891 // inadvertently inserted when using a keyboard that has built-in macro
1892 // shortcut keys (that emit Search+x) and some of them are not registered.
Jeff Brownfd23e3e2012-05-09 13:34:28 -07001893 if (mSearchKeyShortcutPending) {
Jeff Browncaab4d02010-12-09 22:13:41 -08001894 final KeyCharacterMap kcm = event.getKeyCharacterMap();
1895 if (kcm.isPrintingKey(keyCode)) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07001896 mConsumeSearchKeyUp = true;
1897 mSearchKeyShortcutPending = false;
Jeff Browncaab4d02010-12-09 22:13:41 -08001898 if (down && repeatCount == 0 && !keyguardOn) {
1899 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
1900 if (shortcutIntent != null) {
1901 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Jeff Brownf0a3cc52011-01-26 18:42:46 -08001902 try {
1903 mContext.startActivity(shortcutIntent);
1904 } catch (ActivityNotFoundException ex) {
1905 Slog.w(TAG, "Dropping shortcut key combination because "
1906 + "the activity to which it is registered was not found: "
Jeff Brownfd23e3e2012-05-09 13:34:28 -07001907 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode), ex);
Jeff Brownf0a3cc52011-01-26 18:42:46 -08001908 }
Jeff Browncaab4d02010-12-09 22:13:41 -08001909 } else {
1910 Slog.i(TAG, "Dropping unregistered shortcut key combination: "
Jeff Brownfd23e3e2012-05-09 13:34:28 -07001911 + "SEARCH+" + KeyEvent.keyCodeToString(keyCode));
Jeff Brown49ed71d2010-12-06 17:13:33 -08001912 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001913 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001914 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001915 }
1916 }
1917
Jeff Brown68b909d2011-12-07 16:36:01 -08001918 // Invoke shortcuts using Meta.
Jeff Brown602ab322012-05-16 13:33:47 -07001919 if (down && repeatCount == 0 && !keyguardOn
Jeff Brown68b909d2011-12-07 16:36:01 -08001920 && (metaState & KeyEvent.META_META_ON) != 0) {
1921 final KeyCharacterMap kcm = event.getKeyCharacterMap();
Jeff Brown602ab322012-05-16 13:33:47 -07001922 if (kcm.isPrintingKey(keyCode)) {
1923 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
1924 metaState & ~(KeyEvent.META_META_ON
1925 | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
1926 if (shortcutIntent != null) {
1927 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1928 try {
1929 mContext.startActivity(shortcutIntent);
1930 } catch (ActivityNotFoundException ex) {
1931 Slog.w(TAG, "Dropping shortcut key combination because "
1932 + "the activity to which it is registered was not found: "
1933 + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
1934 }
1935 return -1;
Jeff Brown68b909d2011-12-07 16:36:01 -08001936 }
Jeff Brown68b909d2011-12-07 16:36:01 -08001937 }
1938 }
1939
Jeff Brown6651a632011-11-28 12:59:11 -08001940 // Handle application launch keys.
Jeff Brown602ab322012-05-16 13:33:47 -07001941 if (down && repeatCount == 0 && !keyguardOn) {
Jeff Brown6651a632011-11-28 12:59:11 -08001942 String category = sApplicationLaunchKeyCategories.get(keyCode);
1943 if (category != null) {
Dianne Hackbornf5b86712011-12-05 17:42:41 -08001944 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
Jeff Brown6651a632011-11-28 12:59:11 -08001945 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1946 try {
1947 mContext.startActivity(intent);
1948 } catch (ActivityNotFoundException ex) {
1949 Slog.w(TAG, "Dropping application launch key because "
1950 + "the activity to which it is registered was not found: "
1951 + "keyCode=" + keyCode + ", category=" + category, ex);
1952 }
Jeff Brown68b909d2011-12-07 16:36:01 -08001953 return -1;
Jeff Brown6651a632011-11-28 12:59:11 -08001954 }
1955 }
1956
Jeff Brown68b909d2011-12-07 16:36:01 -08001957 // Display task switcher for ALT-TAB or Meta-TAB.
1958 if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
Jeff Brown602ab322012-05-16 13:33:47 -07001959 if (mRecentAppsDialogHeldModifiers == 0 && !keyguardOn) {
Jeff Brown68b909d2011-12-07 16:36:01 -08001960 final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
1961 if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
1962 || KeyEvent.metaStateHasModifiers(
1963 shiftlessModifiers, KeyEvent.META_META_ON)) {
1964 mRecentAppsDialogHeldModifiers = shiftlessModifiers;
1965 showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW);
1966 return -1;
1967 }
1968 }
1969 } else if (!down && mRecentAppsDialogHeldModifiers != 0
1970 && (metaState & mRecentAppsDialogHeldModifiers) == 0) {
1971 mRecentAppsDialogHeldModifiers = 0;
Jeff Brown602ab322012-05-16 13:33:47 -07001972 showOrHideRecentAppsDialog(keyguardOn ? RECENT_APPS_BEHAVIOR_DISMISS :
1973 RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
Jeff Brown68b909d2011-12-07 16:36:01 -08001974 }
1975
Jeff Browncf39bdf2012-05-18 14:41:19 -07001976 // Handle keyboard language switching.
1977 if (down && repeatCount == 0
1978 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH
1979 || (keyCode == KeyEvent.KEYCODE_SPACE
1980 && (metaState & KeyEvent.META_CTRL_MASK) != 0))) {
1981 int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
1982 mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
1983 return -1;
1984 }
1985 if (mLanguageSwitchKeyPressed && !down
1986 && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH
1987 || keyCode == KeyEvent.KEYCODE_SPACE)) {
1988 mLanguageSwitchKeyPressed = false;
1989 return -1;
1990 }
1991
Jeff Brown68b909d2011-12-07 16:36:01 -08001992 // Let the application handle the key.
Jeff Brownd5bb82d2011-10-12 13:57:59 -07001993 return 0;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001994 }
1995
Jeff Brown3915bb82010-11-05 15:02:16 -07001996 /** {@inheritDoc} */
1997 @Override
Jeff Brown49ed71d2010-12-06 17:13:33 -08001998 public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
Jeff Brown54875002011-04-06 15:33:01 -07001999 // Note: This method is only called if the initial down was unhandled.
Jeff Brown40013652012-05-16 21:22:36 -07002000 if (DEBUG_INPUT) {
Jeff Brown1f245102010-11-18 20:53:46 -08002001 Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction()
2002 + ", flags=" + event.getFlags()
2003 + ", keyCode=" + event.getKeyCode()
2004 + ", scanCode=" + event.getScanCode()
2005 + ", metaState=" + event.getMetaState()
2006 + ", repeatCount=" + event.getRepeatCount()
2007 + ", policyFlags=" + policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -07002008 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08002009
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002010 KeyEvent fallbackEvent = null;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002011 if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
2012 final KeyCharacterMap kcm = event.getKeyCharacterMap();
Jeff Brownc1fb48d2010-12-08 16:52:09 -08002013 final int keyCode = event.getKeyCode();
2014 final int metaState = event.getMetaState();
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002015 final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
2016 && event.getRepeatCount() == 0;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002017
Jeff Brown54875002011-04-06 15:33:01 -07002018 // Check for fallback actions specified by the key character map.
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002019 final FallbackAction fallbackAction;
2020 if (initialDown) {
2021 fallbackAction = kcm.getFallbackAction(keyCode, metaState);
2022 } else {
2023 fallbackAction = mFallbackActions.get(keyCode);
2024 }
2025
2026 if (fallbackAction != null) {
Jeff Brown40013652012-05-16 21:22:36 -07002027 if (DEBUG_INPUT) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002028 Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode
2029 + " metaState=" + Integer.toHexString(fallbackAction.metaState));
Jeff Brown49ed71d2010-12-06 17:13:33 -08002030 }
2031
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002032 final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
2033 fallbackEvent = KeyEvent.obtain(
Jeff Brown49ed71d2010-12-06 17:13:33 -08002034 event.getDownTime(), event.getEventTime(),
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002035 event.getAction(), fallbackAction.keyCode,
2036 event.getRepeatCount(), fallbackAction.metaState,
Jeff Brown49ed71d2010-12-06 17:13:33 -08002037 event.getDeviceId(), event.getScanCode(),
2038 flags, event.getSource(), null);
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002039
2040 if (!interceptFallback(win, fallbackEvent, policyFlags)) {
2041 fallbackEvent.recycle();
2042 fallbackEvent = null;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002043 }
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002044
2045 if (initialDown) {
2046 mFallbackActions.put(keyCode, fallbackAction);
2047 } else if (event.getAction() == KeyEvent.ACTION_UP) {
2048 mFallbackActions.remove(keyCode);
2049 fallbackAction.recycle();
2050 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08002051 }
2052 }
2053
Jeff Brown40013652012-05-16 21:22:36 -07002054 if (DEBUG_INPUT) {
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002055 if (fallbackEvent == null) {
2056 Slog.d(TAG, "No fallback.");
2057 } else {
2058 Slog.d(TAG, "Performing fallback: " + fallbackEvent);
2059 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08002060 }
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002061 return fallbackEvent;
Jeff Brown3915bb82010-11-05 15:02:16 -07002062 }
2063
Jeff Brownfd23e3e2012-05-09 13:34:28 -07002064 private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) {
2065 int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true);
2066 if ((actions & ACTION_PASS_TO_USER) != 0) {
2067 long delayMillis = interceptKeyBeforeDispatching(
2068 win, fallbackEvent, policyFlags);
2069 if (delayMillis == 0) {
2070 return true;
2071 }
2072 }
2073 return false;
Jeff Brown6f2fba42011-02-19 01:08:02 -08002074 }
2075
Jeff Brownde7a8ea2012-06-13 18:28:57 -07002076 private void launchAssistLongPressAction() {
2077 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
2078 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
2079
2080 // launch the search activity
2081 Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
2082 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2083 try {
Jim Miller45308b12012-06-18 19:23:39 -07002084 // TODO: This only stops the factory-installed search manager.
2085 // Need to formalize an API to handle others
Jeff Brownde7a8ea2012-06-13 18:28:57 -07002086 SearchManager searchManager = getSearchManager();
2087 if (searchManager != null) {
2088 searchManager.stopSearch();
2089 }
2090 mContext.startActivity(intent);
2091 } catch (ActivityNotFoundException e) {
2092 Slog.w(TAG, "No activity to handle assist long press action.", e);
2093 }
2094 }
2095
2096 private void launchAssistAction() {
2097 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
Jim Miller45308b12012-06-18 19:23:39 -07002098 Intent intent = SearchManager.getAssistIntent(mContext);
2099 if (intent != null) {
2100 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
2101 | Intent.FLAG_ACTIVITY_SINGLE_TOP
2102 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
2103 try {
2104 mContext.startActivity(intent);
2105 } catch (ActivityNotFoundException e) {
2106 Slog.w(TAG, "No activity to handle assist action.", e);
Jeff Brownde7a8ea2012-06-13 18:28:57 -07002107 }
2108 }
2109 }
2110
2111 private SearchManager getSearchManager() {
2112 if (mSearchManager == null) {
2113 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
2114 }
2115 return mSearchManager;
2116 }
2117
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002118 /**
2119 * A home key -> launch home action was detected. Take the appropriate action
2120 * given the situation with the keyguard.
2121 */
2122 void launchHomeFromHotKey() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07002123 if (mKeyguardMediator != null && mKeyguardMediator.isShowingAndNotHidden()) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002124 // don't launch home if keyguard showing
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002125 } else if (!mHideLockScreen && mKeyguardMediator.isInputRestricted()) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002126 // when in keyguard restricted mode, must first verify unlock
2127 // before launching home
2128 mKeyguardMediator.verifyUnlock(new OnKeyguardExitResult() {
2129 public void onKeyguardExitResult(boolean success) {
2130 if (success) {
Dianne Hackborn256dd3b2009-05-19 18:51:21 -07002131 try {
2132 ActivityManagerNative.getDefault().stopAppSwitches();
2133 } catch (RemoteException e) {
2134 }
Joe Onoratof275f0c2009-11-24 16:11:13 -05002135 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002136 startDockOrHome();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002137 }
2138 }
2139 });
2140 } else {
2141 // no keyguard stuff to worry about, just launch home!
Dianne Hackborn256dd3b2009-05-19 18:51:21 -07002142 try {
2143 ActivityManagerNative.getDefault().stopAppSwitches();
2144 } catch (RemoteException e) {
2145 }
Joe Onoratof275f0c2009-11-24 16:11:13 -05002146 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002147 startDockOrHome();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002148 }
2149 }
2150
Dianne Hackborne26ab702011-10-16 13:21:33 -07002151 /**
2152 * A delayed callback use to determine when it is okay to re-allow applications
2153 * to use certain system UI flags. This is used to prevent applications from
2154 * spamming system UI changes that prevent the navigation bar from being shown.
2155 */
2156 final Runnable mAllowSystemUiDelay = new Runnable() {
2157 @Override public void run() {
2158 }
2159 };
2160
2161 /**
2162 * Input handler used while nav bar is hidden. Captures any touch on the screen,
2163 * to determine when the nav bar should be shown and prevent applications from
2164 * receiving those touches.
2165 */
Jeff Brown32cbc38552011-12-01 14:01:49 -08002166 final class HideNavInputEventReceiver extends InputEventReceiver {
2167 public HideNavInputEventReceiver(InputChannel inputChannel, Looper looper) {
2168 super(inputChannel, looper);
2169 }
2170
Dianne Hackborndf89e652011-10-06 22:35:11 -07002171 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -08002172 public void onInputEvent(InputEvent event) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07002173 boolean handled = false;
2174 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -08002175 if (event instanceof MotionEvent
2176 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
2177 final MotionEvent motionEvent = (MotionEvent)event;
2178 if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07002179 // When the user taps down, we re-show the nav bar.
2180 boolean changed = false;
2181 synchronized (mLock) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002182 // Any user activity always causes us to show the
2183 // navigation controls, if they had been hidden.
2184 // We also clear the low profile and only content
2185 // flags so that tapping on the screen will atomically
2186 // restore all currently hidden screen decorations.
2187 int newVal = mResettingSystemUiFlags |
2188 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
2189 View.SYSTEM_UI_FLAG_LOW_PROFILE |
2190 View.SYSTEM_UI_FLAG_FULLSCREEN;
Dianne Hackborne26ab702011-10-16 13:21:33 -07002191 if (mResettingSystemUiFlags != newVal) {
2192 mResettingSystemUiFlags = newVal;
Dianne Hackborndf89e652011-10-06 22:35:11 -07002193 changed = true;
2194 }
Dianne Hackborne26ab702011-10-16 13:21:33 -07002195 // We don't allow the system's nav bar to be hidden
2196 // again for 1 second, to prevent applications from
2197 // spamming us and keeping it from being shown.
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002198 newVal = mForceClearedSystemUiFlags |
2199 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
Dianne Hackborne26ab702011-10-16 13:21:33 -07002200 if (mForceClearedSystemUiFlags != newVal) {
2201 mForceClearedSystemUiFlags = newVal;
2202 changed = true;
2203 mHandler.postDelayed(new Runnable() {
2204 @Override public void run() {
2205 synchronized (mLock) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002206 // Clear flags.
Dianne Hackborne26ab702011-10-16 13:21:33 -07002207 mForceClearedSystemUiFlags &=
2208 ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
2209 }
2210 mWindowManagerFuncs.reevaluateStatusBarVisibility();
2211 }
2212 }, 1000);
2213 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07002214 }
2215 if (changed) {
2216 mWindowManagerFuncs.reevaluateStatusBarVisibility();
2217 }
2218 }
2219 }
2220 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -08002221 finishInputEvent(event, handled);
Dianne Hackborndf89e652011-10-06 22:35:11 -07002222 }
2223 }
Jeff Brown32cbc38552011-12-01 14:01:49 -08002224 }
2225 final InputEventReceiver.Factory mHideNavInputEventReceiverFactory =
2226 new InputEventReceiver.Factory() {
2227 @Override
2228 public InputEventReceiver createInputEventReceiver(
2229 InputChannel inputChannel, Looper looper) {
2230 return new HideNavInputEventReceiver(inputChannel, looper);
2231 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07002232 };
2233
2234 @Override
2235 public int adjustSystemUiVisibilityLw(int visibility) {
2236 // Reset any bits in mForceClearingStatusBarVisibility that
2237 // are now clear.
Dianne Hackborne26ab702011-10-16 13:21:33 -07002238 mResettingSystemUiFlags &= visibility;
Dianne Hackborndf89e652011-10-06 22:35:11 -07002239 // Clear any bits in the new visibility that are currently being
2240 // force cleared, before reporting it.
Dianne Hackborne26ab702011-10-16 13:21:33 -07002241 return visibility & ~mResettingSystemUiFlags
2242 & ~mForceClearedSystemUiFlags;
Dianne Hackborndf89e652011-10-06 22:35:11 -07002243 }
2244
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002245 public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) {
2246 final int fl = attrs.flags;
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002247 final int systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002248
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002249 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR))
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002250 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002251 int availRight, availBottom;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002252 if (mCanHideNavigationBar &&
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002253 (systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002254 availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
2255 availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
2256 } else {
2257 availRight = mRestrictedScreenLeft + mRestrictedScreenWidth;
2258 availBottom = mRestrictedScreenTop + mRestrictedScreenHeight;
2259 }
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002260 if ((systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) {
2261 if ((fl & FLAG_FULLSCREEN) != 0) {
2262 contentInset.set(mStableFullscreenLeft, mStableFullscreenTop,
2263 availRight - mStableFullscreenRight,
2264 availBottom - mStableFullscreenBottom);
2265 } else {
2266 contentInset.set(mStableLeft, mStableTop,
2267 availRight - mStableRight, availBottom - mStableBottom);
2268 }
2269 } else if ((fl & FLAG_FULLSCREEN) != 0) {
2270 contentInset.setEmpty();
2271 } else if ((systemUiVisibility & (View.SYSTEM_UI_FLAG_FULLSCREEN
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002272 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)) == 0) {
2273 contentInset.set(mCurLeft, mCurTop,
2274 availRight - mCurRight, availBottom - mCurBottom);
2275 } else {
2276 contentInset.set(mCurLeft, mCurTop,
2277 availRight - mCurRight, availBottom - mCurBottom);
2278 }
2279 return;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002280 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002281 contentInset.setEmpty();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002282 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002283
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002284 /** {@inheritDoc} */
Dianne Hackborn1f903c32011-09-13 19:18:06 -07002285 public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotation) {
Joe Onorato29fc2c92010-11-24 10:26:50 -08002286 mUnrestrictedScreenLeft = mUnrestrictedScreenTop = 0;
2287 mUnrestrictedScreenWidth = displayWidth;
2288 mUnrestrictedScreenHeight = displayHeight;
2289 mRestrictedScreenLeft = mRestrictedScreenTop = 0;
2290 mRestrictedScreenWidth = displayWidth;
2291 mRestrictedScreenHeight = displayHeight;
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002292 mDockLeft = mContentLeft = mStableLeft = mStableFullscreenLeft
2293 = mSystemLeft = mCurLeft = 0;
2294 mDockTop = mContentTop = mStableTop = mStableFullscreenTop
2295 = mSystemTop = mCurTop = 0;
2296 mDockRight = mContentRight = mStableRight = mStableFullscreenRight
2297 = mSystemRight = mCurRight = displayWidth;
2298 mDockBottom = mContentBottom = mStableBottom = mStableFullscreenBottom
2299 = mSystemBottom = mCurBottom = displayHeight;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002300 mDockLayer = 0x10000000;
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002301 mStatusBarLayer = -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002302
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002303 // start with the current dock rect, which will be (0,0,displayWidth,displayHeight)
2304 final Rect pf = mTmpParentFrame;
2305 final Rect df = mTmpDisplayFrame;
2306 final Rect vf = mTmpVisibleFrame;
2307 pf.left = df.left = vf.left = mDockLeft;
2308 pf.top = df.top = vf.top = mDockTop;
2309 pf.right = df.right = vf.right = mDockRight;
2310 pf.bottom = df.bottom = vf.bottom = mDockBottom;
2311
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002312 // For purposes of putting out fake window up to steal focus, we will
2313 // drive nav being hidden only by whether it is requested.
2314 boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
Dianne Hackborne26ab702011-10-16 13:21:33 -07002315
2316 // When the navigation bar isn't visible, we put up a fake
2317 // input window to catch all touch events. This way we can
2318 // detect when the user presses anywhere to bring back the nav
2319 // bar and ensure the application doesn't see the event.
2320 if (navVisible) {
2321 if (mHideNavFakeWindow != null) {
2322 mHideNavFakeWindow.dismiss();
2323 mHideNavFakeWindow = null;
2324 }
2325 } else if (mHideNavFakeWindow == null) {
2326 mHideNavFakeWindow = mWindowManagerFuncs.addFakeWindow(
Jeff Brown32cbc38552011-12-01 14:01:49 -08002327 mHandler.getLooper(), mHideNavInputEventReceiverFactory,
Dianne Hackborne26ab702011-10-16 13:21:33 -07002328 "hidden nav", WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER,
2329 0, false, false, true);
2330 }
2331
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002332 // For purposes of positioning and showing the nav bar, if we have
2333 // decided that it can't be hidden (because of the screen aspect ratio),
2334 // then take that into account.
2335 navVisible |= !mCanHideNavigationBar;
2336
2337 if (mNavigationBar != null) {
2338 // Force the navigation bar to its appropriate place and
2339 // size. We need to do this directly, instead of relying on
2340 // it to bubble up from the nav bar, because this needs to
2341 // change atomically with screen rotations.
Daniel Sandler4a066c52012-04-20 14:49:13 -04002342 mNavigationBarOnBottom = (!mNavigationBarCanMove || displayWidth < displayHeight);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002343 if (mNavigationBarOnBottom) {
2344 // It's a system nav bar or a portrait screen; nav bar goes on bottom.
Daniel Sandler4a066c52012-04-20 14:49:13 -04002345 int top = displayHeight - mNavigationBarHeightForRotation[displayRotation];
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002346 if (mHdmiPlugged) {
Daniel Sandlerb30cd0a2012-05-31 10:46:18 -04002347 // Move the nav bar up if the external display is the same aspect ratio
2348 // but shorter. This avoids clipping on the external display.
2349 boolean sameAspect = mExternalDisplayHeight > 0 && displayHeight > 0
2350 && ((float) mExternalDisplayWidth / mExternalDisplayHeight > 1)
2351 == ((float) displayWidth / displayHeight > 1);
2352 if (sameAspect && top > mExternalDisplayHeight) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002353 top = mExternalDisplayHeight;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002354 }
2355 }
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002356 mTmpNavigationFrame.set(0, top, displayWidth, displayHeight);
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002357 mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002358 if (navVisible) {
2359 mNavigationBar.showLw(true);
2360 mDockBottom = mTmpNavigationFrame.top;
2361 mRestrictedScreenHeight = mDockBottom - mDockTop;
2362 } else {
2363 // We currently want to hide the navigation UI.
2364 mNavigationBar.hideLw(true);
2365 }
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002366 if (navVisible && !mNavigationBar.isAnimatingLw()) {
2367 // If the nav bar is currently requested to be visible,
2368 // and not in the process of animating on or off, then
2369 // we can tell the app that it is covered by it.
2370 mSystemBottom = mTmpNavigationFrame.top;
2371 }
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002372 } else {
2373 // Landscape screen; nav bar goes to the right.
Daniel Sandler4a066c52012-04-20 14:49:13 -04002374 int left = displayWidth - mNavigationBarWidthForRotation[displayRotation];
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002375 if (mHdmiPlugged) {
2376 if (left > mExternalDisplayWidth) {
2377 left = mExternalDisplayWidth;
2378 }
2379 }
2380 mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight);
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002381 mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002382 if (navVisible) {
2383 mNavigationBar.showLw(true);
2384 mDockRight = mTmpNavigationFrame.left;
2385 mRestrictedScreenWidth = mDockRight - mDockLeft;
2386 } else {
2387 // We currently want to hide the navigation UI.
2388 mNavigationBar.hideLw(true);
2389 }
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002390 if (navVisible && !mNavigationBar.isAnimatingLw()) {
2391 // If the nav bar is currently requested to be visible,
2392 // and not in the process of animating on or off, then
2393 // we can tell the app that it is covered by it.
2394 mSystemRight = mTmpNavigationFrame.left;
2395 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002396 }
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002397 // Make sure the content and current rectangles are updated to
2398 // account for the restrictions from the navigation bar.
2399 mContentTop = mCurTop = mDockTop;
2400 mContentBottom = mCurBottom = mDockBottom;
2401 mContentLeft = mCurLeft = mDockLeft;
2402 mContentRight = mCurRight = mDockRight;
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002403 mStatusBarLayer = mNavigationBar.getSurfaceLayer();
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002404 // And compute the final frame.
2405 mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002406 mTmpNavigationFrame, mTmpNavigationFrame);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002407 if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
2408 }
2409 if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
2410 mDockLeft, mDockTop, mDockRight, mDockBottom));
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002411
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002412 // decide where the status bar goes ahead of time
2413 if (mStatusBar != null) {
2414 // apply any navigation bar insets
Dianne Hackborn98014352012-04-05 18:31:41 -07002415 pf.left = df.left = mUnrestrictedScreenLeft;
2416 pf.top = df.top = mUnrestrictedScreenTop;
2417 pf.right = df.right = mUnrestrictedScreenWidth - mUnrestrictedScreenLeft;
2418 pf.bottom = df.bottom = mUnrestrictedScreenHeight - mUnrestrictedScreenTop;
2419 vf.left = mStableLeft;
2420 vf.top = mStableTop;
2421 vf.right = mStableRight;
2422 vf.bottom = mStableBottom;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002423
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002424 mStatusBarLayer = mStatusBar.getSurfaceLayer();
2425
Dianne Hackbornde368ff2012-04-10 18:35:54 -07002426 // Let the status bar determine its size.
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002427 mStatusBar.computeFrameLw(pf, df, vf, vf);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002428
Dianne Hackbornde368ff2012-04-10 18:35:54 -07002429 // For layout, the status bar is always at the top with our fixed height.
2430 mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002431
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002432 // If the status bar is hidden, we don't want to cause
2433 // windows behind it to scroll.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002434 if (mStatusBar.isVisibleLw()) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002435 // Status bar may go away, so the screen area it occupies
2436 // is available to apps but just covering them when the
2437 // status bar is visible.
Dianne Hackbornde368ff2012-04-10 18:35:54 -07002438 mDockTop = mUnrestrictedScreenTop + mStatusBarHeight;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002439
2440 mContentTop = mCurTop = mDockTop;
2441 mContentBottom = mCurBottom = mDockBottom;
2442 mContentLeft = mCurLeft = mDockLeft;
2443 mContentRight = mCurRight = mDockRight;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002444
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002445 if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
2446 String.format(
2447 "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
2448 mDockLeft, mDockTop, mDockRight, mDockBottom,
2449 mContentLeft, mContentTop, mContentRight, mContentBottom,
2450 mCurLeft, mCurTop, mCurRight, mCurBottom));
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002451 }
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002452 if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw()) {
2453 // If the status bar is currently requested to be visible,
2454 // and not in the process of animating on or off, then
2455 // we can tell the app that it is covered by it.
2456 mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
2457 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002458 }
2459 }
2460
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002461 /** {@inheritDoc} */
2462 public int getSystemDecorRectLw(Rect systemRect) {
2463 systemRect.left = mSystemLeft;
2464 systemRect.top = mSystemTop;
2465 systemRect.right = mSystemRight;
2466 systemRect.bottom = mSystemBottom;
2467 if (mStatusBar != null) return mStatusBar.getSurfaceLayer();
2468 if (mNavigationBar != null) return mNavigationBar.getSurfaceLayer();
2469 return 0;
2470 }
2471
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002472 void setAttachedWindowFrames(WindowState win, int fl, int adjust,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002473 WindowState attached, boolean insetDecors, Rect pf, Rect df, Rect cf, Rect vf) {
2474 if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) {
2475 // Here's a special case: if this attached window is a panel that is
2476 // above the dock window, and the window it is attached to is below
2477 // the dock window, then the frames we computed for the window it is
2478 // attached to can not be used because the dock is effectively part
2479 // of the underlying window and the attached window is floating on top
2480 // of the whole thing. So, we ignore the attached window and explicitly
2481 // compute the frames that would be appropriate without the dock.
2482 df.left = cf.left = vf.left = mDockLeft;
2483 df.top = cf.top = vf.top = mDockTop;
2484 df.right = cf.right = vf.right = mDockRight;
2485 df.bottom = cf.bottom = vf.bottom = mDockBottom;
2486 } else {
2487 // The effective display frame of the attached window depends on
2488 // whether it is taking care of insetting its content. If not,
2489 // we need to use the parent's content frame so that the entire
2490 // window is positioned within that content. Otherwise we can use
2491 // the display frame and let the attached window take care of
2492 // positioning its content appropriately.
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002493 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002494 cf.set(attached.getDisplayFrameLw());
2495 } else {
2496 // If the window is resizing, then we want to base the content
2497 // frame on our attached content frame to resize... however,
2498 // things can be tricky if the attached window is NOT in resize
2499 // mode, in which case its content frame will be larger.
2500 // Ungh. So to deal with that, make sure the content frame
2501 // we end up using is not covering the IM dock.
2502 cf.set(attached.getContentFrameLw());
2503 if (attached.getSurfaceLayer() < mDockLayer) {
2504 if (cf.left < mContentLeft) cf.left = mContentLeft;
2505 if (cf.top < mContentTop) cf.top = mContentTop;
2506 if (cf.right > mContentRight) cf.right = mContentRight;
2507 if (cf.bottom > mContentBottom) cf.bottom = mContentBottom;
2508 }
2509 }
2510 df.set(insetDecors ? attached.getDisplayFrameLw() : cf);
2511 vf.set(attached.getVisibleFrameLw());
2512 }
2513 // The LAYOUT_IN_SCREEN flag is used to determine whether the attached
2514 // window should be positioned relative to its parent or the entire
2515 // screen.
2516 pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0
2517 ? attached.getFrameLw() : df);
2518 }
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002519
2520 private void applyStableConstraints(int sysui, int fl, Rect r) {
2521 if ((sysui & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) {
2522 // If app is requesting a stable layout, don't let the
2523 // content insets go below the stable values.
2524 if ((fl & FLAG_FULLSCREEN) != 0) {
2525 if (r.left < mStableFullscreenLeft) r.left = mStableFullscreenLeft;
2526 if (r.top < mStableFullscreenTop) r.top = mStableFullscreenTop;
2527 if (r.right > mStableFullscreenRight) r.right = mStableFullscreenRight;
2528 if (r.bottom > mStableFullscreenBottom) r.bottom = mStableFullscreenBottom;
2529 } else {
2530 if (r.left < mStableLeft) r.left = mStableLeft;
2531 if (r.top < mStableTop) r.top = mStableTop;
2532 if (r.right > mStableRight) r.right = mStableRight;
2533 if (r.bottom > mStableBottom) r.bottom = mStableBottom;
2534 }
2535 }
2536 }
2537
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002538 /** {@inheritDoc} */
Dianne Hackborn0ecadf72009-03-31 18:00:37 -07002539 public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
2540 WindowState attached) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002541 // we've already done the status bar
Dianne Hackborn1f903c32011-09-13 19:18:06 -07002542 if (win == mStatusBar || win == mNavigationBar) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002543 return;
2544 }
satok1bc0a492012-04-25 22:47:12 +09002545 final boolean needsToOffsetInputMethodTarget =
2546 (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null);
2547 if (needsToOffsetInputMethodTarget) {
2548 if (DEBUG_LAYOUT) {
2549 Slog.i(TAG, "Offset ime target window by the last ime window state");
2550 }
2551 offsetInputMethodWindowLw(mLastInputMethodWindow);
2552 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002553
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002554 final int fl = attrs.flags;
2555 final int sim = attrs.softInputMode;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002556 final int sysUiFl = win.getSystemUiVisibility();
2557
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002558 final Rect pf = mTmpParentFrame;
2559 final Rect df = mTmpDisplayFrame;
2560 final Rect cf = mTmpContentFrame;
2561 final Rect vf = mTmpVisibleFrame;
2562
Daniel Sandler36412a72011-08-04 09:35:13 -04002563 final boolean hasNavBar = (mHasNavigationBar
2564 && mNavigationBar != null && mNavigationBar.isVisibleLw());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002565
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002566 if (attrs.type == TYPE_INPUT_METHOD) {
2567 pf.left = df.left = cf.left = vf.left = mDockLeft;
2568 pf.top = df.top = cf.top = vf.top = mDockTop;
2569 pf.right = df.right = cf.right = vf.right = mDockRight;
2570 pf.bottom = df.bottom = cf.bottom = vf.bottom = mDockBottom;
2571 // IM dock windows always go to the bottom of the screen.
2572 attrs.gravity = Gravity.BOTTOM;
2573 mDockLayer = win.getSurfaceLayer();
2574 } else {
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002575 final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
2576
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07002577 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002578 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)
2579 && (sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002580 if (DEBUG_LAYOUT)
2581 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle()
2582 + "): IN_SCREEN, INSET_DECOR, !FULLSCREEN");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002583 // This is the case for a normal activity window: we want it
2584 // to cover all of the screen space, and it can take care of
2585 // moving its contents to account for screen decorations that
2586 // intrude into that space.
2587 if (attached != null) {
2588 // If this window is attached to another, our display
2589 // frame is the same as the one we are attached to.
2590 setAttachedWindowFrames(win, fl, sim, attached, true, pf, df, cf, vf);
2591 } else {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002592 if (attrs.type == TYPE_STATUS_BAR_PANEL
2593 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
Joe Onorato29fc2c92010-11-24 10:26:50 -08002594 // Status bar panels are the only windows who can go on top of
2595 // the status bar. They are protected by the STATUS_BAR_SERVICE
2596 // permission, so they have the same privileges as the status
2597 // bar itself.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002598 //
Daniel Sandler8e8b4152011-07-21 01:16:43 -04002599 // However, they should still dodge the navigation bar if it exists.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002600
2601 pf.left = df.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
Joe Onorato29fc2c92010-11-24 10:26:50 -08002602 pf.top = df.top = mUnrestrictedScreenTop;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002603 pf.right = df.right = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04002604 ? mRestrictedScreenLeft+mRestrictedScreenWidth
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002605 : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
2606 pf.bottom = df.bottom = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04002607 ? mRestrictedScreenTop+mRestrictedScreenHeight
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002608 : mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
2609
Daniel Sandler8e8b4152011-07-21 01:16:43 -04002610 if (DEBUG_LAYOUT) {
2611 Log.v(TAG, String.format(
2612 "Laying out status bar window: (%d,%d - %d,%d)",
2613 pf.left, pf.top, pf.right, pf.bottom));
2614 }
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002615 } else if (mCanHideNavigationBar
2616 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002617 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
2618 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
2619 // Asking for layout as if the nav bar is hidden, lets the
2620 // application extend into the unrestricted screen area. We
2621 // only do this for application windows to ensure no window that
2622 // can be above the nav bar can do this.
2623 pf.left = df.left = mUnrestrictedScreenLeft;
2624 pf.top = df.top = mUnrestrictedScreenTop;
2625 pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
2626 pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
Joe Onorato29fc2c92010-11-24 10:26:50 -08002627 } else {
2628 pf.left = df.left = mRestrictedScreenLeft;
2629 pf.top = df.top = mRestrictedScreenTop;
2630 pf.right = df.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
2631 pf.bottom = df.bottom = mRestrictedScreenTop+mRestrictedScreenHeight;
2632 }
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002633 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002634 cf.left = mDockLeft;
2635 cf.top = mDockTop;
2636 cf.right = mDockRight;
2637 cf.bottom = mDockBottom;
2638 } else {
2639 cf.left = mContentLeft;
2640 cf.top = mContentTop;
2641 cf.right = mContentRight;
2642 cf.bottom = mContentBottom;
2643 }
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002644 applyStableConstraints(sysUiFl, fl, cf);
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002645 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
2646 vf.left = mCurLeft;
2647 vf.top = mCurTop;
2648 vf.right = mCurRight;
2649 vf.bottom = mCurBottom;
2650 } else {
2651 vf.set(cf);
2652 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002653 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002654 } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0 || (sysUiFl
2655 & (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
2656 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002657 if (DEBUG_LAYOUT)
2658 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002659 // A window that has requested to fill the entire screen just
2660 // gets everything, period.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002661 if (attrs.type == TYPE_STATUS_BAR_PANEL
2662 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
2663 pf.left = df.left = cf.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
Joe Onorato29fc2c92010-11-24 10:26:50 -08002664 pf.top = df.top = cf.top = mUnrestrictedScreenTop;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002665 pf.right = df.right = cf.right = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04002666 ? mRestrictedScreenLeft+mRestrictedScreenWidth
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002667 : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
2668 pf.bottom = df.bottom = cf.bottom = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04002669 ? mRestrictedScreenTop+mRestrictedScreenHeight
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002670 : mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
Daniel Sandler36412a72011-08-04 09:35:13 -04002671 if (DEBUG_LAYOUT) {
2672 Log.v(TAG, String.format(
2673 "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
2674 pf.left, pf.top, pf.right, pf.bottom));
2675 }
Jim Millere898ac52012-04-06 17:10:57 -07002676 } else if (attrs.type == TYPE_NAVIGATION_BAR
2677 || attrs.type == TYPE_NAVIGATION_BAR_PANEL) {
Daniel Sandler8e8b4152011-07-21 01:16:43 -04002678 // The navigation bar has Real Ultimate Power.
2679 pf.left = df.left = mUnrestrictedScreenLeft;
2680 pf.top = df.top = mUnrestrictedScreenTop;
2681 pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
2682 pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
2683 if (DEBUG_LAYOUT) {
2684 Log.v(TAG, String.format(
2685 "Laying out navigation bar window: (%d,%d - %d,%d)",
2686 pf.left, pf.top, pf.right, pf.bottom));
2687 }
Dianne Hackborn01011c32012-02-21 13:54:21 -08002688 } else if ((attrs.type == TYPE_SECURE_SYSTEM_OVERLAY
2689 || attrs.type == TYPE_BOOT_PROGRESS)
Jeff Brownbfcb60a2011-09-08 18:51:14 -07002690 && ((fl & FLAG_FULLSCREEN) != 0)) {
2691 // Fullscreen secure system overlays get what they ask for.
2692 pf.left = df.left = mUnrestrictedScreenLeft;
2693 pf.top = df.top = mUnrestrictedScreenTop;
2694 pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
2695 pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
Dianne Hackborn01011c32012-02-21 13:54:21 -08002696 } else if (attrs.type == TYPE_BOOT_PROGRESS) {
2697 // Boot progress screen always covers entire display.
2698 pf.left = df.left = cf.left = mUnrestrictedScreenLeft;
2699 pf.top = df.top = cf.top = mUnrestrictedScreenTop;
2700 pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
2701 pf.bottom = df.bottom = cf.bottom
2702 = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002703 } else if (mCanHideNavigationBar
2704 && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002705 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
2706 && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
2707 // Asking for layout as if the nav bar is hidden, lets the
2708 // application extend into the unrestricted screen area. We
2709 // only do this for application windows to ensure no window that
2710 // can be above the nav bar can do this.
2711 // XXX This assumes that an app asking for this will also
2712 // ask for layout in only content. We can't currently figure out
2713 // what the screen would be if only laying out to hide the nav bar.
2714 pf.left = df.left = cf.left = mUnrestrictedScreenLeft;
2715 pf.top = df.top = cf.top = mUnrestrictedScreenTop;
2716 pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
2717 pf.bottom = df.bottom = cf.bottom
2718 = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
Joe Onorato29fc2c92010-11-24 10:26:50 -08002719 } else {
2720 pf.left = df.left = cf.left = mRestrictedScreenLeft;
2721 pf.top = df.top = cf.top = mRestrictedScreenTop;
2722 pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
2723 pf.bottom = df.bottom = cf.bottom
2724 = mRestrictedScreenTop+mRestrictedScreenHeight;
2725 }
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07002726 applyStableConstraints(sysUiFl, fl, cf);
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002727 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
2728 vf.left = mCurLeft;
2729 vf.top = mCurTop;
2730 vf.right = mCurRight;
2731 vf.bottom = mCurBottom;
2732 } else {
2733 vf.set(cf);
2734 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002735 } else if (attached != null) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002736 if (DEBUG_LAYOUT)
2737 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): attached to " + attached);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002738 // A child window should be placed inside of the same visible
2739 // frame that its parent had.
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002740 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002741 } else {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002742 if (DEBUG_LAYOUT)
2743 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): normal window");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002744 // Otherwise, a normal window must be placed inside the content
2745 // of all screen decorations.
Dianne Hackborna239c842011-06-01 12:28:20 -07002746 if (attrs.type == TYPE_STATUS_BAR_PANEL) {
2747 // Status bar panels are the only windows who can go on top of
2748 // the status bar. They are protected by the STATUS_BAR_SERVICE
2749 // permission, so they have the same privileges as the status
2750 // bar itself.
Dianne Hackborn7d049322011-06-14 15:00:32 -07002751 pf.left = df.left = cf.left = mRestrictedScreenLeft;
2752 pf.top = df.top = cf.top = mRestrictedScreenTop;
2753 pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
2754 pf.bottom = df.bottom = cf.bottom
2755 = mRestrictedScreenTop+mRestrictedScreenHeight;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002756 } else {
Dianne Hackborna239c842011-06-01 12:28:20 -07002757 pf.left = mContentLeft;
2758 pf.top = mContentTop;
2759 pf.right = mContentRight;
2760 pf.bottom = mContentBottom;
2761 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
2762 df.left = cf.left = mDockLeft;
2763 df.top = cf.top = mDockTop;
2764 df.right = cf.right = mDockRight;
2765 df.bottom = cf.bottom = mDockBottom;
2766 } else {
2767 df.left = cf.left = mContentLeft;
2768 df.top = cf.top = mContentTop;
2769 df.right = cf.right = mContentRight;
2770 df.bottom = cf.bottom = mContentBottom;
2771 }
2772 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
2773 vf.left = mCurLeft;
2774 vf.top = mCurTop;
2775 vf.right = mCurRight;
2776 vf.bottom = mCurBottom;
2777 } else {
2778 vf.set(cf);
2779 }
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002780 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002781 }
2782 }
2783
2784 if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0) {
2785 df.left = df.top = cf.left = cf.top = vf.left = vf.top = -10000;
2786 df.right = df.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000;
2787 }
2788
The Android Open Source Project11267662009-03-18 17:39:47 -07002789 if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle()
2790 + ": sim=#" + Integer.toHexString(sim)
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002791 + " attach=" + attached + " type=" + attrs.type
2792 + String.format(" flags=0x%08x", fl)
The Android Open Source Project11267662009-03-18 17:39:47 -07002793 + " pf=" + pf.toShortString() + " df=" + df.toShortString()
2794 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString());
2795
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002796 win.computeFrameLw(pf, df, cf, vf);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002797
2798 // Dock windows carve out the bottom of the screen, so normal windows
2799 // can't appear underneath them.
2800 if (attrs.type == TYPE_INPUT_METHOD && !win.getGivenInsetsPendingLw()) {
satok1bc0a492012-04-25 22:47:12 +09002801 setLastInputMethodWindowLw(null, null);
2802 offsetInputMethodWindowLw(win);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002803 }
2804 }
2805
satok1bc0a492012-04-25 22:47:12 +09002806 private void offsetInputMethodWindowLw(WindowState win) {
2807 int top = win.getContentFrameLw().top;
2808 top += win.getGivenContentInsetsLw().top;
2809 if (mContentBottom > top) {
2810 mContentBottom = top;
2811 }
2812 top = win.getVisibleFrameLw().top;
2813 top += win.getGivenVisibleInsetsLw().top;
2814 if (mCurBottom > top) {
2815 mCurBottom = top;
2816 }
2817 if (DEBUG_LAYOUT) Log.v(TAG, "Input method: mDockBottom="
2818 + mDockBottom + " mContentBottom="
2819 + mContentBottom + " mCurBottom=" + mCurBottom);
2820 }
2821
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002822 /** {@inheritDoc} */
Craig Mautner61ac6bb2012-02-02 17:29:33 -08002823 @Override
2824 public void finishLayoutLw() {
2825 return;
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002826 }
2827
2828 /** {@inheritDoc} */
2829 public void beginAnimationLw(int displayWidth, int displayHeight) {
2830 mTopFullscreenOpaqueWindowState = null;
2831 mForceStatusBar = false;
2832
2833 mHideLockScreen = false;
2834 mAllowLockscreenWhenOn = false;
2835 mDismissKeyguard = false;
2836 }
2837
2838 /** {@inheritDoc} */
2839 public void animatingWindowLw(WindowState win,
2840 WindowManager.LayoutParams attrs) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002841 if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
2842 + win.isVisibleOrBehindKeyguardLw());
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002843 if (mTopFullscreenOpaqueWindowState == null &&
Dianne Hackborn01b02a72012-01-12 14:05:03 -08002844 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002845 if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
2846 mForceStatusBar = true;
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002847 }
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002848 if (attrs.type >= FIRST_APPLICATION_WINDOW
2849 && attrs.type <= LAST_APPLICATION_WINDOW
Dianne Hackborn6493e642010-10-01 13:06:30 -07002850 && attrs.x == 0 && attrs.y == 0
2851 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
2852 && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002853 if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win);
2854 mTopFullscreenOpaqueWindowState = win;
2855 if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
2856 if (localLOGV) Log.v(TAG, "Setting mHideLockScreen to true by win " + win);
2857 mHideLockScreen = true;
2858 }
2859 if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
2860 if (localLOGV) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win);
2861 mDismissKeyguard = true;
2862 }
2863 if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
2864 mAllowLockscreenWhenOn = true;
2865 }
2866 }
2867 }
2868 }
2869
2870 /** {@inheritDoc} */
2871 public int finishAnimationLw() {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002872 int changes = 0;
Joe Onorato93056472010-09-10 10:30:46 -04002873 boolean topIsFullscreen = false;
Daniel Sandlere02d8082010-10-08 15:13:22 -04002874
2875 final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null)
2876 ? mTopFullscreenOpaqueWindowState.getAttrs()
2877 : null;
2878
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002879 if (mStatusBar != null) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002880 if (DEBUG_LAYOUT) Log.i(TAG, "force=" + mForceStatusBar
Dianne Hackbornd70bc2f2009-10-06 23:25:51 -07002881 + " top=" + mTopFullscreenOpaqueWindowState);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002882 if (mForceStatusBar) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002883 if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: forced");
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002884 if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002885 } else if (mTopFullscreenOpaqueWindowState != null) {
Joe Onorato93056472010-09-10 10:30:46 -04002886 if (localLOGV) {
2887 Log.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
2888 + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw());
2889 Log.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
2890 + " lp.flags=0x" + Integer.toHexString(lp.flags));
2891 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002892 topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
2893 || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
Joe Onorato93056472010-09-10 10:30:46 -04002894 // The subtle difference between the window for mTopFullscreenOpaqueWindowState
2895 // and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
2896 // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
2897 // case though.
2898 if (topIsFullscreen) {
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002899 if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
2900 if (mStatusBar.hideLw(true)) {
2901 changes |= FINISH_LAYOUT_REDO_LAYOUT;
Daniel Sandler9c00d5b2011-09-13 14:04:26 -04002902
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002903 mHandler.post(new Runnable() { public void run() {
2904 if (mStatusBarService != null) {
2905 try {
2906 mStatusBarService.collapse();
2907 } catch (RemoteException ex) {}
2908 }
2909 }});
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07002910 } else if (DEBUG_LAYOUT) {
Daniel Sandler40427442010-07-16 11:44:52 -04002911 Log.v(TAG, "Preventing status bar from hiding by policy");
2912 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002913 } else {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08002914 if (DEBUG_LAYOUT) Log.v(TAG, "** SHOWING status bar: top is not fullscreen");
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002915 if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002916 }
2917 }
2918 }
Daniel Sandlere02d8082010-10-08 15:13:22 -04002919
Joe Onorato644f9c32011-01-25 12:06:23 -08002920 mTopIsFullscreen = topIsFullscreen;
Daniel Sandlere02d8082010-10-08 15:13:22 -04002921
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -07002922 // Hide the key guard if a visible window explicitly specifies that it wants to be displayed
2923 // when the screen is locked
2924 if (mKeyguard != null) {
Joe Onorato93056472010-09-10 10:30:46 -04002925 if (localLOGV) Log.v(TAG, "finishAnimationLw::mHideKeyguard="+mHideLockScreen);
Dianne Hackborn05726582009-09-22 17:28:24 -07002926 if (mDismissKeyguard && !mKeyguardMediator.isSecure()) {
Dianne Hackborn08743722009-12-21 12:16:51 -08002927 if (mKeyguard.hideLw(true)) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002928 changes |= FINISH_LAYOUT_REDO_LAYOUT
2929 | FINISH_LAYOUT_REDO_CONFIG
2930 | FINISH_LAYOUT_REDO_WALLPAPER;
2931 }
Dianne Hackborn05726582009-09-22 17:28:24 -07002932 if (mKeyguardMediator.isShowing()) {
Dianne Hackbornb446e972009-09-20 15:23:25 -07002933 mHandler.post(new Runnable() {
2934 public void run() {
Dianne Hackborn05726582009-09-22 17:28:24 -07002935 mKeyguardMediator.keyguardDone(false, false);
Dianne Hackbornb446e972009-09-20 15:23:25 -07002936 }
2937 });
2938 }
Dianne Hackborn05726582009-09-22 17:28:24 -07002939 } else if (mHideLockScreen) {
Dianne Hackborn08743722009-12-21 12:16:51 -08002940 if (mKeyguard.hideLw(true)) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002941 changes |= FINISH_LAYOUT_REDO_LAYOUT
2942 | FINISH_LAYOUT_REDO_CONFIG
2943 | FINISH_LAYOUT_REDO_WALLPAPER;
2944 }
Mike Lockwoodf3bfed52010-01-21 16:38:44 -05002945 mKeyguardMediator.setHidden(true);
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -07002946 } else {
Dianne Hackborn08743722009-12-21 12:16:51 -08002947 if (mKeyguard.showLw(true)) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002948 changes |= FINISH_LAYOUT_REDO_LAYOUT
2949 | FINISH_LAYOUT_REDO_CONFIG
2950 | FINISH_LAYOUT_REDO_WALLPAPER;
2951 }
Mike Lockwoodf3bfed52010-01-21 16:38:44 -05002952 mKeyguardMediator.setHidden(false);
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -07002953 }
2954 }
Joe Onorato664644d2011-01-23 17:53:23 -08002955
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002956 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07002957 // If the navigation bar has been hidden or shown, we need to do another
2958 // layout pass to update that window.
2959 changes |= FINISH_LAYOUT_REDO_LAYOUT;
2960 }
Joe Onorato664644d2011-01-23 17:53:23 -08002961
Mike Lockwood28569302010-01-28 11:54:40 -05002962 // update since mAllowLockscreenWhenOn might have changed
2963 updateLockScreenTimeout();
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002964 return changes;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002965 }
2966
Dianne Hackborn08743722009-12-21 12:16:51 -08002967 public boolean allowAppAnimationsLw() {
Craig Mautnerf03e4c52012-06-14 14:11:27 -07002968 if (mKeyguard != null && mKeyguard.isVisibleLw() && !mKeyguard.isAnimatingLw()) {
Dianne Hackborn08743722009-12-21 12:16:51 -08002969 // If keyguard is currently visible, no reason to animate
2970 // behind it.
2971 return false;
2972 }
Dianne Hackborn08743722009-12-21 12:16:51 -08002973 return true;
2974 }
2975
Dianne Hackborndf89e652011-10-06 22:35:11 -07002976 public int focusChangedLw(WindowState lastFocus, WindowState newFocus) {
Joe Onorato664644d2011-01-23 17:53:23 -08002977 mFocusedWindow = newFocus;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002978 if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07002979 // If the navigation bar has been hidden or shown, we need to do another
2980 // layout pass to update that window.
2981 return FINISH_LAYOUT_REDO_LAYOUT;
2982 }
2983 return 0;
Joe Onorato664644d2011-01-23 17:53:23 -08002984 }
2985
Dianne Hackborn0ecadf72009-03-31 18:00:37 -07002986 /** {@inheritDoc} */
Jeff Brown46b9ac02010-04-22 18:58:52 -07002987 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07002988 // do nothing if headless
Mike Lockwoodd747dc82011-09-13 16:28:22 -04002989 if (mHeadless) return;
Mike Lockwood3a74bd32011-08-12 13:55:22 -07002990
Jeff Brown46b9ac02010-04-22 18:58:52 -07002991 // lid changed state
Jeff Brownc458ce92012-04-30 14:58:40 -07002992 final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED;
2993 if (newLidState == mLidState) {
2994 return;
2995 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07002996
Jeff Brownc458ce92012-04-30 14:58:40 -07002997 mLidState = newLidState;
2998 applyLidSwitchState();
Jeff Brown01a98dd2011-09-20 15:08:29 -07002999 updateRotation(true);
Jeff Brownc458ce92012-04-30 14:58:40 -07003000
3001 if (lidOpen) {
3002 if (keyguardIsShowingTq()) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003003 mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(
Jeff Brown43150bf2011-11-08 20:22:03 -08003004 KeyEvent.KEYCODE_POWER, mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003005 } else {
3006 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
Jeff Brownc458ce92012-04-30 14:58:40 -07003007 LocalPowerManager.BUTTON_EVENT);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003008 }
Jeff Brownc458ce92012-04-30 14:58:40 -07003009 } else if (!mLidControlsSleep) {
3010 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
3011 LocalPowerManager.OTHER_EVENT);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003012 }
3013 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003014
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08003015 void setHdmiPlugged(boolean plugged) {
3016 if (mHdmiPlugged != plugged) {
3017 mHdmiPlugged = plugged;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07003018 if (plugged && mDisplay != null) {
3019 mExternalDisplayWidth = mDisplay.getRawExternalWidth();
3020 mExternalDisplayHeight = mDisplay.getRawExternalHeight();
3021 }
3022 updateRotation(true, true);
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08003023 Intent intent = new Intent(ACTION_HDMI_PLUGGED);
Joe Onoratodc100302011-01-11 17:07:41 -08003024 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08003025 intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
3026 mContext.sendStickyBroadcast(intent);
3027 }
3028 }
3029
Joe Onoratoea495d42011-04-06 11:41:11 -07003030 void initializeHdmiState() {
Joe Onorato7ba631f2011-05-04 15:28:00 -07003031 boolean plugged = false;
Joe Onoratoea495d42011-04-06 11:41:11 -07003032 // watch for HDMI plug messages if the hdmi switch exists
3033 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) {
3034 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi");
3035
Joe Onoratoea495d42011-04-06 11:41:11 -07003036 final String filename = "/sys/class/switch/hdmi/state";
3037 FileReader reader = null;
3038 try {
3039 reader = new FileReader(filename);
3040 char[] buf = new char[15];
3041 int n = reader.read(buf);
3042 if (n > 1) {
3043 plugged = 0 != Integer.parseInt(new String(buf, 0, n-1));
3044 }
3045 } catch (IOException ex) {
3046 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
3047 } catch (NumberFormatException ex) {
3048 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
3049 } finally {
3050 if (reader != null) {
3051 try {
3052 reader.close();
3053 } catch (IOException ex) {
3054 }
Joe Onoratodc100302011-01-11 17:07:41 -08003055 }
3056 }
3057 }
Joe Onorato7ba631f2011-05-04 15:28:00 -07003058 // This dance forces the code in setHdmiPlugged to run.
3059 // Always do this so the sticky intent is stuck (to false) if there is no hdmi.
3060 mHdmiPlugged = !plugged;
3061 setHdmiPlugged(!mHdmiPlugged);
Joe Onoratodc100302011-01-11 17:07:41 -08003062 }
3063
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003064 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003065 * @return Whether music is being played right now.
3066 */
3067 boolean isMusicActive() {
Eric Laurent413cb9d2009-07-17 11:52:43 -07003068 final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
3069 if (am == null) {
3070 Log.w(TAG, "isMusicActive: couldn't get AudioManager reference");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003071 return false;
3072 }
Eric Laurent413cb9d2009-07-17 11:52:43 -07003073 return am.isMusicActive();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003074 }
3075
3076 /**
3077 * Tell the audio service to adjust the volume appropriate to the event.
3078 * @param keycode
3079 */
Mike Lockwooda53e3812009-09-25 10:51:39 -04003080 void handleVolumeKey(int stream, int keycode) {
Jeff Brown4d396052010-10-29 21:50:21 -07003081 IAudioService audioService = getAudioService();
3082 if (audioService == null) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003083 return;
3084 }
3085 try {
3086 // since audio is playing, we shouldn't have to hold a wake lock
3087 // during the call, but we do it as a precaution for the rare possibility
3088 // that the music stops right before we call this
Jeff Brownb0418da2010-11-01 15:24:01 -07003089 // TODO: Actually handle MUTE.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003090 mBroadcastWakeLock.acquire();
Jeff Brown4d396052010-10-29 21:50:21 -07003091 audioService.adjustStreamVolume(stream,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003092 keycode == KeyEvent.KEYCODE_VOLUME_UP
3093 ? AudioManager.ADJUST_RAISE
3094 : AudioManager.ADJUST_LOWER,
3095 0);
3096 } catch (RemoteException e) {
3097 Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e);
3098 } finally {
3099 mBroadcastWakeLock.release();
3100 }
3101 }
Jeff Brown4d396052010-10-29 21:50:21 -07003102
Dianne Hackbornc0e3f242011-08-19 14:19:10 -07003103 final Object mScreenshotLock = new Object();
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07003104 ServiceConnection mScreenshotConnection = null;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07003105
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003106 final Runnable mScreenshotTimeout = new Runnable() {
3107 @Override public void run() {
3108 synchronized (mScreenshotLock) {
3109 if (mScreenshotConnection != null) {
3110 mContext.unbindService(mScreenshotConnection);
3111 mScreenshotConnection = null;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07003112 }
Winson Chung9112ec32011-06-27 13:15:32 -07003113 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003114 }
3115 };
3116
3117 // Assume this is called from the Handler thread.
3118 private void takeScreenshot() {
3119 synchronized (mScreenshotLock) {
3120 if (mScreenshotConnection != null) {
3121 return;
3122 }
3123 ComponentName cn = new ComponentName("com.android.systemui",
3124 "com.android.systemui.screenshot.TakeScreenshotService");
3125 Intent intent = new Intent();
3126 intent.setComponent(cn);
3127 ServiceConnection conn = new ServiceConnection() {
3128 @Override
3129 public void onServiceConnected(ComponentName name, IBinder service) {
3130 synchronized (mScreenshotLock) {
3131 if (mScreenshotConnection != this) {
3132 return;
3133 }
3134 Messenger messenger = new Messenger(service);
3135 Message msg = Message.obtain(null, 1);
3136 final ServiceConnection myConn = this;
3137 Handler h = new Handler(mHandler.getLooper()) {
3138 @Override
3139 public void handleMessage(Message msg) {
3140 synchronized (mScreenshotLock) {
3141 if (mScreenshotConnection == myConn) {
3142 mContext.unbindService(mScreenshotConnection);
3143 mScreenshotConnection = null;
3144 mHandler.removeCallbacks(mScreenshotTimeout);
3145 }
3146 }
3147 }
3148 };
3149 msg.replyTo = new Messenger(h);
Winson Chunga63bb842011-10-17 10:26:28 -07003150 msg.arg1 = msg.arg2 = 0;
3151 if (mStatusBar != null && mStatusBar.isVisibleLw())
3152 msg.arg1 = 1;
3153 if (mNavigationBar != null && mNavigationBar.isVisibleLw())
3154 msg.arg2 = 1;
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003155 try {
3156 messenger.send(msg);
3157 } catch (RemoteException e) {
3158 }
3159 }
3160 }
3161 @Override
3162 public void onServiceDisconnected(ComponentName name) {}
3163 };
3164 if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
3165 mScreenshotConnection = conn;
3166 mHandler.postDelayed(mScreenshotTimeout, 10000);
3167 }
3168 }
Winson Chung9112ec32011-06-27 13:15:32 -07003169 }
3170
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003171 /** {@inheritDoc} */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003172 @Override
Jeff Brown1f245102010-11-18 20:53:46 -08003173 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
3174 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
3175 final boolean canceled = event.isCanceled();
3176 final int keyCode = event.getKeyCode();
Jeff Browne20c9e02010-10-11 14:20:19 -07003177
Jeff Brown3122e442010-10-11 23:32:49 -07003178 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
Jeff Brown3122e442010-10-11 23:32:49 -07003179
Mike Lockwoodc72b15f2009-11-28 20:58:22 -05003180 // If screen is off then we treat the case where the keyguard is open but hidden
3181 // the same as if it were open and in front.
3182 // This will prevent any keys other than the power button from waking the screen
3183 // when the keyguard is hidden by another activity.
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003184 final boolean keyguardActive = (mKeyguardMediator == null ? false :
3185 (isScreenOn ?
3186 mKeyguardMediator.isShowingAndNotHidden() :
3187 mKeyguardMediator.isShowing()));
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003188
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07003189 if (!mSystemBooted) {
3190 // If we have not yet booted, don't let key events do anything.
3191 return 0;
3192 }
3193
Jeff Brown40013652012-05-16 21:22:36 -07003194 if (DEBUG_INPUT) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003195 Log.d(TAG, "interceptKeyTq keycode=" + keyCode
3196 + " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003197 }
3198
Jeff Brown98392ef2011-09-12 18:24:59 -07003199 if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
3200 && event.getRepeatCount() == 0) {
Jeff Brown4d396052010-10-29 21:50:21 -07003201 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
3202 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003203
Jeff Brownbc072da2011-11-15 12:56:55 -08003204 if (keyCode == KeyEvent.KEYCODE_POWER) {
3205 policyFlags |= WindowManagerPolicy.FLAG_WAKE;
3206 }
3207 final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
3208 | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
3209
Jeff Brown4d396052010-10-29 21:50:21 -07003210 // Basic policy based on screen state and keyguard.
3211 // FIXME: This policy isn't quite correct. We shouldn't care whether the screen
3212 // is on or off, really. We should care about whether the device is in an
3213 // interactive state or is in suspend pretending to be "off".
3214 // The primary screen might be turned off due to proximity sensor or
3215 // because we are presenting media on an auxiliary screen or remotely controlling
3216 // the device some other way (which is why we have an exemption here for injected
3217 // events).
3218 int result;
Mike Lockwoodd747dc82011-09-13 16:28:22 -04003219 if ((isScreenOn && !mHeadless) || (isInjected && !isWakeKey)) {
Jeff Brown4d396052010-10-29 21:50:21 -07003220 // When the screen is on or if the key is injected pass the key to the application.
3221 result = ACTION_PASS_TO_USER;
3222 } else {
3223 // When the screen is off and the key is not injected, determine whether
3224 // to wake the device but don't pass the key to the application.
3225 result = 0;
Jeff Brown4d396052010-10-29 21:50:21 -07003226 if (down && isWakeKey) {
3227 if (keyguardActive) {
3228 // If the keyguard is showing, let it decide what to do with the wake key.
Jeff Brown43150bf2011-11-08 20:22:03 -08003229 mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode,
3230 mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
Jeff Brown4d396052010-10-29 21:50:21 -07003231 } else {
3232 // Otherwise, wake the device ourselves.
3233 result |= ACTION_POKE_USER_ACTIVITY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003234 }
3235 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003236 }
3237
Jeff Brown4d396052010-10-29 21:50:21 -07003238 // Handle special keys.
3239 switch (keyCode) {
3240 case KeyEvent.KEYCODE_VOLUME_DOWN:
Jeff Brownb0418da2010-11-01 15:24:01 -07003241 case KeyEvent.KEYCODE_VOLUME_UP:
3242 case KeyEvent.KEYCODE_VOLUME_MUTE: {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003243 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
3244 if (down) {
3245 if (isScreenOn && !mVolumeDownKeyTriggered
3246 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
3247 mVolumeDownKeyTriggered = true;
3248 mVolumeDownKeyTime = event.getDownTime();
3249 mVolumeDownKeyConsumedByScreenshotChord = false;
3250 cancelPendingPowerKeyAction();
3251 interceptScreenshotChord();
3252 }
3253 } else {
3254 mVolumeDownKeyTriggered = false;
3255 cancelPendingScreenshotChordAction();
3256 }
3257 } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
3258 if (down) {
3259 if (isScreenOn && !mVolumeUpKeyTriggered
3260 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
3261 mVolumeUpKeyTriggered = true;
3262 cancelPendingPowerKeyAction();
3263 cancelPendingScreenshotChordAction();
3264 }
3265 } else {
3266 mVolumeUpKeyTriggered = false;
3267 cancelPendingScreenshotChordAction();
3268 }
3269 }
Jeff Brown4d396052010-10-29 21:50:21 -07003270 if (down) {
3271 ITelephony telephonyService = getTelephonyService();
3272 if (telephonyService != null) {
3273 try {
3274 if (telephonyService.isRinging()) {
3275 // If an incoming call is ringing, either VOLUME key means
3276 // "silence ringer". We handle these keys here, rather than
3277 // in the InCallScreen, to make sure we'll respond to them
3278 // even if the InCallScreen hasn't come to the foreground yet.
3279 // Look for the DOWN event here, to agree with the "fallback"
3280 // behavior in the InCallScreen.
3281 Log.i(TAG, "interceptKeyBeforeQueueing:"
3282 + " VOLUME key-down while ringing: Silence ringer!");
3283
3284 // Silence the ringer. (It's safe to call this
3285 // even if the ringer has already been silenced.)
3286 telephonyService.silenceRinger();
3287
3288 // And *don't* pass this key thru to the current activity
3289 // (which is probably the InCallScreen.)
3290 result &= ~ACTION_PASS_TO_USER;
3291 break;
3292 }
3293 if (telephonyService.isOffhook()
3294 && (result & ACTION_PASS_TO_USER) == 0) {
3295 // If we are in call but we decided not to pass the key to
3296 // the application, handle the volume change here.
3297 handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
3298 break;
3299 }
3300 } catch (RemoteException ex) {
3301 Log.w(TAG, "ITelephony threw RemoteException", ex);
3302 }
3303 }
3304
3305 if (isMusicActive() && (result & ACTION_PASS_TO_USER) == 0) {
3306 // If music is playing but we decided not to pass the key to the
3307 // application, handle the volume change here.
3308 handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode);
3309 break;
3310 }
3311 }
3312 break;
3313 }
3314
3315 case KeyEvent.KEYCODE_ENDCALL: {
3316 result &= ~ACTION_PASS_TO_USER;
3317 if (down) {
3318 ITelephony telephonyService = getTelephonyService();
3319 boolean hungUp = false;
3320 if (telephonyService != null) {
3321 try {
3322 hungUp = telephonyService.endCall();
3323 } catch (RemoteException ex) {
3324 Log.w(TAG, "ITelephony threw RemoteException", ex);
3325 }
3326 }
3327 interceptPowerKeyDown(!isScreenOn || hungUp);
3328 } else {
3329 if (interceptPowerKeyUp(canceled)) {
3330 if ((mEndcallBehavior
3331 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
3332 if (goHome()) {
3333 break;
Dianne Hackborn0041e972009-07-24 17:14:43 -07003334 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003335 }
Jeff Brown4d396052010-10-29 21:50:21 -07003336 if ((mEndcallBehavior
3337 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
3338 result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
3339 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003340 }
Jeff Brown4d396052010-10-29 21:50:21 -07003341 }
3342 break;
3343 }
3344
3345 case KeyEvent.KEYCODE_POWER: {
3346 result &= ~ACTION_PASS_TO_USER;
3347 if (down) {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003348 if (isScreenOn && !mPowerKeyTriggered
3349 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
3350 mPowerKeyTriggered = true;
3351 mPowerKeyTime = event.getDownTime();
3352 interceptScreenshotChord();
Winson Chung9112ec32011-06-27 13:15:32 -07003353 }
Winson Chung9112ec32011-06-27 13:15:32 -07003354
Jeff Brown4d396052010-10-29 21:50:21 -07003355 ITelephony telephonyService = getTelephonyService();
3356 boolean hungUp = false;
3357 if (telephonyService != null) {
3358 try {
3359 if (telephonyService.isRinging()) {
3360 // Pressing Power while there's a ringing incoming
3361 // call should silence the ringer.
3362 telephonyService.silenceRinger();
3363 } else if ((mIncallPowerBehavior
3364 & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
3365 && telephonyService.isOffhook()) {
3366 // Otherwise, if "Power button ends call" is enabled,
3367 // the Power button will hang up any current active call.
3368 hungUp = telephonyService.endCall();
3369 }
3370 } catch (RemoteException ex) {
3371 Log.w(TAG, "ITelephony threw RemoteException", ex);
3372 }
3373 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003374 interceptPowerKeyDown(!isScreenOn || hungUp
3375 || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003376 } else {
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003377 mPowerKeyTriggered = false;
3378 cancelPendingScreenshotChordAction();
3379 if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
Jeff Brown4d396052010-10-29 21:50:21 -07003380 result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003381 }
Jeff Brownd5bb82d2011-10-12 13:57:59 -07003382 mPendingPowerKeyUpCanceled = false;
Jeff Brown4d396052010-10-29 21:50:21 -07003383 }
3384 break;
3385 }
3386
3387 case KeyEvent.KEYCODE_MEDIA_PLAY:
3388 case KeyEvent.KEYCODE_MEDIA_PAUSE:
3389 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
3390 if (down) {
3391 ITelephony telephonyService = getTelephonyService();
3392 if (telephonyService != null) {
3393 try {
3394 if (!telephonyService.isIdle()) {
3395 // Suppress PLAY/PAUSE toggle when phone is ringing or in-call
3396 // to avoid music playback.
3397 break;
3398 }
3399 } catch (RemoteException ex) {
3400 Log.w(TAG, "ITelephony threw RemoteException", ex);
Jeff Brown3122e442010-10-11 23:32:49 -07003401 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003402 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003403 }
Jeff Brown4d396052010-10-29 21:50:21 -07003404 case KeyEvent.KEYCODE_HEADSETHOOK:
3405 case KeyEvent.KEYCODE_MUTE:
3406 case KeyEvent.KEYCODE_MEDIA_STOP:
3407 case KeyEvent.KEYCODE_MEDIA_NEXT:
3408 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
3409 case KeyEvent.KEYCODE_MEDIA_REWIND:
3410 case KeyEvent.KEYCODE_MEDIA_RECORD:
3411 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
3412 if ((result & ACTION_PASS_TO_USER) == 0) {
3413 // Only do this if we would otherwise not pass it to the user. In that
3414 // case, the PhoneWindow class will do the same thing, except it will
3415 // only do it if the showing app doesn't process the key on its own.
Jeff Brown40013652012-05-16 21:22:36 -07003416 // Note that we need to make a copy of the key event here because the
3417 // original key event will be recycled when we return.
Jeff Brown4d396052010-10-29 21:50:21 -07003418 mBroadcastWakeLock.acquire();
Jeff Brown40013652012-05-16 21:22:36 -07003419 Message msg = mHandler.obtainMessage(MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK,
3420 new KeyEvent(event));
3421 msg.setAsynchronous(true);
3422 msg.sendToTarget();
Jeff Brown4d396052010-10-29 21:50:21 -07003423 }
3424 break;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003425 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003426
Jeff Brown4d396052010-10-29 21:50:21 -07003427 case KeyEvent.KEYCODE_CALL: {
3428 if (down) {
3429 ITelephony telephonyService = getTelephonyService();
3430 if (telephonyService != null) {
3431 try {
3432 if (telephonyService.isRinging()) {
3433 Log.i(TAG, "interceptKeyBeforeQueueing:"
3434 + " CALL key-down while ringing: Answer the call!");
3435 telephonyService.answerRingingCall();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003436
Jeff Brown4d396052010-10-29 21:50:21 -07003437 // And *don't* pass this key thru to the current activity
3438 // (which is presumably the InCallScreen.)
3439 result &= ~ACTION_PASS_TO_USER;
3440 }
3441 } catch (RemoteException ex) {
3442 Log.w(TAG, "ITelephony threw RemoteException", ex);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003443 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003444 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003445 }
Jeff Brown4d396052010-10-29 21:50:21 -07003446 break;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003447 }
3448 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003449 return result;
3450 }
3451
Jeff Brown56194eb2011-03-02 19:23:13 -08003452 /** {@inheritDoc} */
3453 @Override
3454 public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
3455 int result = 0;
3456
3457 final boolean isWakeMotion = (policyFlags
3458 & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
3459 if (isWakeMotion) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003460 if (mKeyguardMediator != null && mKeyguardMediator.isShowing()) {
Jeff Brown56194eb2011-03-02 19:23:13 -08003461 // If the keyguard is showing, let it decide what to do with the wake motion.
3462 mKeyguardMediator.onWakeMotionWhenKeyguardShowingTq();
3463 } else {
3464 // Otherwise, wake the device ourselves.
3465 result |= ACTION_POKE_USER_ACTIVITY;
3466 }
3467 }
3468 return result;
3469 }
3470
Jeff Brown40013652012-05-16 21:22:36 -07003471 void dispatchMediaKeyWithWakeLock(KeyEvent event) {
3472 if (DEBUG_INPUT) {
3473 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003474 }
3475
Jeff Brown40013652012-05-16 21:22:36 -07003476 if (mHavePendingMediaKeyRepeatWithWakeLock) {
3477 if (DEBUG_INPUT) {
3478 Slog.d(TAG, "dispatchMediaKeyWithWakeLock: canceled repeat");
3479 }
3480
3481 mHandler.removeMessages(MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK);
3482 mHavePendingMediaKeyRepeatWithWakeLock = false;
3483 mBroadcastWakeLock.release(); // pending repeat was holding onto the wake lock
3484 }
3485
3486 dispatchMediaKeyWithWakeLockToAudioService(event);
3487
3488 if (event.getAction() == KeyEvent.ACTION_DOWN
3489 && event.getRepeatCount() == 0) {
3490 mHavePendingMediaKeyRepeatWithWakeLock = true;
3491
3492 Message msg = mHandler.obtainMessage(
3493 MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK, event);
3494 msg.setAsynchronous(true);
3495 mHandler.sendMessageDelayed(msg, ViewConfiguration.getKeyRepeatTimeout());
3496 } else {
3497 mBroadcastWakeLock.release();
3498 }
3499 }
3500
3501 void dispatchMediaKeyRepeatWithWakeLock(KeyEvent event) {
3502 mHavePendingMediaKeyRepeatWithWakeLock = false;
3503
3504 KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(event,
3505 SystemClock.uptimeMillis(), 1, event.getFlags() | KeyEvent.FLAG_LONG_PRESS);
3506 if (DEBUG_INPUT) {
3507 Slog.d(TAG, "dispatchMediaKeyRepeatWithWakeLock: " + repeatEvent);
3508 }
3509
3510 dispatchMediaKeyWithWakeLockToAudioService(repeatEvent);
3511 mBroadcastWakeLock.release();
3512 }
3513
3514 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
3515 if (ActivityManagerNative.isSystemReady()) {
3516 IAudioService audioService = getAudioService();
3517 if (audioService != null) {
3518 try {
3519 audioService.dispatchMediaKeyEventUnderWakelock(event);
3520 } catch (RemoteException e) {
3521 Log.e(TAG, "dispatchMediaKeyEvent threw exception " + e);
Jean-Michel Trivic6802222012-04-30 11:15:03 -07003522 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003523 }
3524 }
3525 }
3526
Mike Lockwood1753f7f2009-08-24 14:49:07 -07003527 BroadcastReceiver mDockReceiver = new BroadcastReceiver() {
3528 public void onReceive(Context context, Intent intent) {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003529 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
3530 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
3531 Intent.EXTRA_DOCK_STATE_UNDOCKED);
3532 } else {
3533 try {
3534 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
3535 ServiceManager.getService(Context.UI_MODE_SERVICE));
3536 mUiMode = uiModeService.getCurrentModeType();
3537 } catch (RemoteException e) {
3538 }
Dianne Hackborn80fa1662009-10-07 14:02:10 -07003539 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07003540 updateRotation(true);
Mike Lockwoode9867d22009-09-20 01:59:02 -04003541 updateOrientationListenerLp();
Mike Lockwood1753f7f2009-08-24 14:49:07 -07003542 }
3543 };
3544
Daniel Sandler7e37df52011-11-16 22:08:23 -08003545 BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
3546 public void onReceive(Context context, Intent intent) {
3547 if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
3548 mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
3549 if (localLOGV) Log.v(TAG, "BATTERY_CHANGED: " + intent + " plugged=" + mPluggedIn);
3550 }
3551 }
3552 };
3553
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003554 /** {@inheritDoc} */
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003555 public void screenTurnedOff(int why) {
Dianne Hackborn74489012009-03-24 20:50:09 -07003556 EventLog.writeEvent(70000, 0);
The Android Open Source Project0727d222009-03-11 12:11:58 -07003557 synchronized (mLock) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07003558 mScreenOnEarly = false;
3559 mScreenOnFully = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07003560 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003561 if (mKeyguardMediator != null) {
3562 mKeyguardMediator.onScreenTurnedOff(why);
3563 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07003564 synchronized (mLock) {
The Android Open Source Project0727d222009-03-11 12:11:58 -07003565 updateOrientationListenerLp();
Mike Lockwood28569302010-01-28 11:54:40 -05003566 updateLockScreenTimeout();
The Android Open Source Project0727d222009-03-11 12:11:58 -07003567 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003568 }
3569
3570 /** {@inheritDoc} */
Dianne Hackborn38e29a62011-09-18 14:43:08 -07003571 public void screenTurningOn(final ScreenOnListener screenOnListener) {
Dianne Hackborn74489012009-03-24 20:50:09 -07003572 EventLog.writeEvent(70000, 1);
Dianne Hackborn40011092011-09-22 13:37:48 -07003573 if (false) {
3574 RuntimeException here = new RuntimeException("here");
3575 here.fillInStackTrace();
3576 Slog.i(TAG, "Screen turning on...", here);
3577 }
3578 if (screenOnListener != null) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003579 if (mKeyguardMediator != null) {
Craig Mautner3d7b7d52012-05-24 11:28:26 -07003580 try {
3581 mWindowManager.setEventDispatching(true);
3582 } catch (RemoteException unhandled) {
3583 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003584 mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
3585 @Override public void onShown(IBinder windowToken) {
3586 if (windowToken != null) {
3587 try {
3588 mWindowManager.waitForWindowDrawn(windowToken,
3589 new IRemoteCallback.Stub() {
3590 @Override public void sendResult(Bundle data) {
3591 Slog.i(TAG, "Lock screen displayed!");
3592 screenOnListener.onScreenOn();
3593 synchronized (mLock) {
3594 mScreenOnFully = true;
3595 }
Dianne Hackborn40011092011-09-22 13:37:48 -07003596 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003597 });
3598 } catch (RemoteException e) {
3599 }
3600 } else {
3601 Slog.i(TAG, "No lock screen!");
3602 screenOnListener.onScreenOn();
3603 synchronized (mLock) {
3604 mScreenOnFully = true;
3605 }
Dianne Hackborn40011092011-09-22 13:37:48 -07003606 }
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07003607 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003608 });
3609 }
Dianne Hackborn40011092011-09-22 13:37:48 -07003610 } else {
3611 synchronized (mLock) {
3612 mScreenOnFully = true;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07003613 }
Dianne Hackborn40011092011-09-22 13:37:48 -07003614 }
The Android Open Source Project0727d222009-03-11 12:11:58 -07003615 synchronized (mLock) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07003616 mScreenOnEarly = true;
The Android Open Source Project0727d222009-03-11 12:11:58 -07003617 updateOrientationListenerLp();
Mike Lockwood28569302010-01-28 11:54:40 -05003618 updateLockScreenTimeout();
The Android Open Source Project0727d222009-03-11 12:11:58 -07003619 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003620 }
3621
3622 /** {@inheritDoc} */
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07003623 public boolean isScreenOnEarly() {
3624 return mScreenOnEarly;
3625 }
3626
3627 /** {@inheritDoc} */
3628 public boolean isScreenOnFully() {
3629 return mScreenOnFully;
Dianne Hackborn08743722009-12-21 12:16:51 -08003630 }
3631
3632 /** {@inheritDoc} */
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003633 public void enableKeyguard(boolean enabled) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003634 if (mKeyguardMediator != null) {
3635 mKeyguardMediator.setKeyguardEnabled(enabled);
3636 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003637 }
3638
3639 /** {@inheritDoc} */
3640 public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003641 if (mKeyguardMediator != null) {
3642 mKeyguardMediator.verifyUnlock(callback);
3643 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003644 }
3645
Mike Lockwoodf7913302009-11-28 22:27:10 -05003646 private boolean keyguardIsShowingTq() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003647 if (mKeyguardMediator == null) return false;
Dianne Hackborn9dc06cc2009-11-17 18:19:23 -08003648 return mKeyguardMediator.isShowingAndNotHidden();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003649 }
3650
Mike Lockwood520d8bc2011-02-18 13:23:13 -05003651
3652 /** {@inheritDoc} */
3653 public boolean isKeyguardLocked() {
3654 return keyguardOn();
3655 }
3656
3657 /** {@inheritDoc} */
3658 public boolean isKeyguardSecure() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003659 if (mKeyguardMediator == null) return false;
Mike Lockwood520d8bc2011-02-18 13:23:13 -05003660 return mKeyguardMediator.isSecure();
3661 }
3662
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003663 /** {@inheritDoc} */
3664 public boolean inKeyguardRestrictedKeyInputMode() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003665 if (mKeyguardMediator == null) return false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003666 return mKeyguardMediator.isInputRestricted();
3667 }
3668
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003669 public void dismissKeyguardLw() {
3670 if (!mKeyguardMediator.isSecure()) {
3671 if (mKeyguardMediator.isShowing()) {
3672 mHandler.post(new Runnable() {
3673 public void run() {
3674 mKeyguardMediator.keyguardDone(false, true);
3675 }
3676 });
3677 }
3678 }
3679 }
3680
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003681 void sendCloseSystemWindows() {
3682 sendCloseSystemWindows(mContext, null);
3683 }
3684
3685 void sendCloseSystemWindows(String reason) {
3686 sendCloseSystemWindows(mContext, reason);
3687 }
3688
3689 static void sendCloseSystemWindows(Context context, String reason) {
3690 if (ActivityManagerNative.isSystemReady()) {
Dianne Hackborn94a679d2009-07-28 17:51:07 -07003691 try {
3692 ActivityManagerNative.getDefault().closeSystemDialogs(reason);
3693 } catch (RemoteException e) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003694 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003695 }
3696 }
Mitsuru Oshima831d0d92009-06-16 18:27:18 -07003697
Jeff Brown01a98dd2011-09-20 15:08:29 -07003698 @Override
3699 public int rotationForOrientationLw(int orientation, int lastRotation) {
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05003700 if (false) {
3701 Slog.v(TAG, "rotationForOrientationLw(orient="
3702 + orientation + ", last=" + lastRotation
3703 + "); user=" + mUserRotation + " "
3704 + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
3705 ? "USER_ROTATION_LOCKED" : "")
3706 );
3707 }
3708
The Android Open Source Project0727d222009-03-11 12:11:58 -07003709 synchronized (mLock) {
Jeff Brownc0347aa2011-09-23 17:26:09 -07003710 int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
3711 if (sensorRotation < 0) {
3712 sensorRotation = lastRotation;
3713 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07003714
Jeff Browndec6cf42011-11-15 14:08:20 -08003715 final int preferredRotation;
Jeff Brown2e7760e2012-04-11 15:14:55 -07003716 if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07003717 // Ignore sensor when lid switch is open and rotation is forced.
3718 preferredRotation = mLidOpenRotation;
3719 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
Jeff Brownc0347aa2011-09-23 17:26:09 -07003720 && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07003721 // Ignore sensor when in car dock unless explicitly enabled.
3722 // This case can override the behavior of NOSENSOR, and can also
3723 // enable 180 degree rotation while docked.
Jeff Brownc0347aa2011-09-23 17:26:09 -07003724 preferredRotation = mCarDockEnablesAccelerometer
Jeff Brown01a98dd2011-09-20 15:08:29 -07003725 ? sensorRotation : mCarDockRotation;
Jeff Brown1a693182011-11-08 14:44:16 -08003726 } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
3727 || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
3728 || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
Jeff Brownc0347aa2011-09-23 17:26:09 -07003729 && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07003730 // Ignore sensor when in desk dock unless explicitly enabled.
3731 // This case can override the behavior of NOSENSOR, and can also
3732 // enable 180 degree rotation while docked.
Jeff Brownc0347aa2011-09-23 17:26:09 -07003733 preferredRotation = mDeskDockEnablesAccelerometer
Jeff Brown01a98dd2011-09-20 15:08:29 -07003734 ? sensorRotation : mDeskDockRotation;
Jeff Browneb3e4b92011-12-06 19:54:24 -08003735 } else if (mHdmiPlugged) {
3736 // Ignore sensor when plugged into HDMI.
3737 // Note that the dock orientation overrides the HDMI orientation.
3738 preferredRotation = mHdmiRotation;
Jeff Brown207673cd2012-06-05 17:47:11 -07003739 } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
Jeff Brown01a98dd2011-09-20 15:08:29 -07003740 && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
3741 || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED))
3742 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
3743 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
3744 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
3745 || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
3746 // Otherwise, use sensor only if requested by the application or enabled
3747 // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
Jeff Brownd3187e32011-09-21 19:26:44 -07003748 if (mAllowAllRotations < 0) {
3749 // Can't read this during init() because the context doesn't
3750 // have display metrics at that time so we cannot determine
3751 // tablet vs. phone then.
3752 mAllowAllRotations = mContext.getResources().getBoolean(
3753 com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
3754 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07003755 if (sensorRotation != Surface.ROTATION_180
Jeff Brownd3187e32011-09-21 19:26:44 -07003756 || mAllowAllRotations == 1
Jeff Brown01a98dd2011-09-20 15:08:29 -07003757 || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) {
3758 preferredRotation = sensorRotation;
3759 } else {
3760 preferredRotation = lastRotation;
3761 }
Jeff Brown207673cd2012-06-05 17:47:11 -07003762 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
3763 && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
3764 // Apply rotation lock. Does not apply to NOSENSOR.
3765 // The idea is that the user rotation expresses a weak preference for the direction
3766 // of gravity and as NOSENSOR is never affected by gravity, then neither should
3767 // NOSENSOR be affected by rotation lock (although it will be affected by docks).
Jeff Brown4dfce202011-10-05 12:00:10 -07003768 preferredRotation = mUserRotation;
Jeff Browndec6cf42011-11-15 14:08:20 -08003769 } else {
3770 // No overriding preference.
3771 // We will do exactly what the application asked us to do.
3772 preferredRotation = -1;
Jeff Brown01a98dd2011-09-20 15:08:29 -07003773 }
3774
Dianne Hackborne5439f22010-10-02 16:53:50 -07003775 switch (orientation) {
3776 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
Jeff Browndec6cf42011-11-15 14:08:20 -08003777 // Return portrait unless overridden.
3778 if (isAnyPortrait(preferredRotation)) {
3779 return preferredRotation;
3780 }
Dianne Hackborne5439f22010-10-02 16:53:50 -07003781 return mPortraitRotation;
Dianne Hackborne5439f22010-10-02 16:53:50 -07003782
Jeff Brown01a98dd2011-09-20 15:08:29 -07003783 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
Jeff Browndec6cf42011-11-15 14:08:20 -08003784 // Return landscape unless overridden.
3785 if (isLandscapeOrSeascape(preferredRotation)) {
3786 return preferredRotation;
3787 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07003788 return mLandscapeRotation;
3789
3790 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
Jeff Browndec6cf42011-11-15 14:08:20 -08003791 // Return reverse portrait unless overridden.
3792 if (isAnyPortrait(preferredRotation)) {
3793 return preferredRotation;
3794 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07003795 return mUpsideDownRotation;
3796
3797 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
Jeff Browndec6cf42011-11-15 14:08:20 -08003798 // Return seascape unless overridden.
3799 if (isLandscapeOrSeascape(preferredRotation)) {
3800 return preferredRotation;
3801 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07003802 return mSeascapeRotation;
3803
3804 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
3805 // Return either landscape rotation.
3806 if (isLandscapeOrSeascape(preferredRotation)) {
3807 return preferredRotation;
3808 }
3809 if (isLandscapeOrSeascape(lastRotation)) {
Jeff Brown4519f072011-01-23 13:16:01 -08003810 return lastRotation;
3811 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07003812 return mLandscapeRotation;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003813
Jeff Brown01a98dd2011-09-20 15:08:29 -07003814 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
3815 // Return either portrait rotation.
3816 if (isAnyPortrait(preferredRotation)) {
3817 return preferredRotation;
3818 }
3819 if (isAnyPortrait(lastRotation)) {
3820 return lastRotation;
3821 }
3822 return mPortraitRotation;
3823
3824 default:
Jeff Brown4dfce202011-10-05 12:00:10 -07003825 // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
3826 // just return the preferred orientation we already calculated.
Jeff Brown01a98dd2011-09-20 15:08:29 -07003827 if (preferredRotation >= 0) {
3828 return preferredRotation;
3829 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07003830 return Surface.ROTATION_0;
Daniel Sandlere7e5ac22011-02-22 16:10:21 -05003831 }
3832 }
Steve Howarda7bfe6a2010-09-23 16:47:49 -07003833 }
3834
Jeff Brown01a98dd2011-09-20 15:08:29 -07003835 @Override
3836 public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
3837 switch (orientation) {
3838 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
3839 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
3840 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
3841 return isAnyPortrait(rotation);
3842
3843 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
3844 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
3845 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
3846 return isLandscapeOrSeascape(rotation);
3847
3848 default:
3849 return true;
3850 }
Steve Howarda7bfe6a2010-09-23 16:47:49 -07003851 }
3852
Jeff Brownc0347aa2011-09-23 17:26:09 -07003853 @Override
3854 public void setRotationLw(int rotation) {
3855 mOrientationListener.setCurrentRotation(rotation);
3856 }
3857
Jeff Brown01a98dd2011-09-20 15:08:29 -07003858 private boolean isLandscapeOrSeascape(int rotation) {
3859 return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
Dianne Hackborne5439f22010-10-02 16:53:50 -07003860 }
3861
Jeff Brown01a98dd2011-09-20 15:08:29 -07003862 private boolean isAnyPortrait(int rotation) {
3863 return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
Dianne Hackborne5439f22010-10-02 16:53:50 -07003864 }
3865
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003866
3867 // User rotation: to be used when all else fails in assigning an orientation to the device
3868 public void setUserRotationMode(int mode, int rot) {
3869 ContentResolver res = mContext.getContentResolver();
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05003870
3871 // mUserRotationMode and mUserRotation will be assigned by the content observer
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003872 if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003873 Settings.System.putInt(res,
3874 Settings.System.USER_ROTATION,
3875 rot);
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05003876 Settings.System.putInt(res,
3877 Settings.System.ACCELEROMETER_ROTATION,
3878 0);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003879 } else {
3880 Settings.System.putInt(res,
3881 Settings.System.ACCELEROMETER_ROTATION,
3882 1);
3883 }
3884 }
3885
Jeff Brownac143512012-04-05 18:57:33 -07003886 public void setSafeMode(boolean safeMode) {
3887 mSafeMode = safeMode;
3888 performHapticFeedbackLw(null, safeMode
3889 ? HapticFeedbackConstants.SAFE_MODE_ENABLED
3890 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003891 }
3892
Dianne Hackborn181ceb52009-08-27 22:16:40 -07003893 static long[] getLongIntArray(Resources r, int resid) {
3894 int[] ar = r.getIntArray(resid);
3895 if (ar == null) {
3896 return null;
3897 }
3898 long[] out = new long[ar.length];
3899 for (int i=0; i<ar.length; i++) {
3900 out[i] = ar[i];
3901 }
3902 return out;
3903 }
3904
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003905 /** {@inheritDoc} */
3906 public void systemReady() {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07003907 if (mKeyguardMediator != null) {
3908 // tell the keyguard
3909 mKeyguardMediator.onSystemReady();
3910 }
Dianne Hackbornb1a79802009-09-29 15:18:31 -07003911 synchronized (mLock) {
3912 updateOrientationListenerLp();
Dianne Hackbornc777e072010-02-12 13:07:59 -08003913 mSystemReady = true;
3914 mHandler.post(new Runnable() {
3915 public void run() {
3916 updateSettings();
3917 }
3918 });
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003919 }
3920 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07003921
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07003922 /** {@inheritDoc} */
3923 public void systemBooted() {
3924 synchronized (mLock) {
3925 mSystemBooted = true;
3926 }
3927 }
3928
Dianne Hackborn661cd522011-08-22 00:26:20 -07003929 ProgressDialog mBootMsgDialog = null;
3930
3931 /** {@inheritDoc} */
3932 public void showBootMessage(final CharSequence msg, final boolean always) {
Mike Lockwoodaa5bf142011-09-21 13:03:40 -04003933 if (mHeadless) return;
Dianne Hackborn661cd522011-08-22 00:26:20 -07003934 mHandler.post(new Runnable() {
3935 @Override public void run() {
3936 if (mBootMsgDialog == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07003937 mBootMsgDialog = new ProgressDialog(mContext) {
3938 // This dialog will consume all events coming in to
3939 // it, to avoid it trying to do things too early in boot.
3940 @Override public boolean dispatchKeyEvent(KeyEvent event) {
3941 return true;
3942 }
3943 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) {
3944 return true;
3945 }
3946 @Override public boolean dispatchTouchEvent(MotionEvent ev) {
3947 return true;
3948 }
3949 @Override public boolean dispatchTrackballEvent(MotionEvent ev) {
3950 return true;
3951 }
3952 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) {
3953 return true;
3954 }
3955 @Override public boolean dispatchPopulateAccessibilityEvent(
3956 AccessibilityEvent event) {
3957 return true;
3958 }
3959 };
Dianne Hackborn661cd522011-08-22 00:26:20 -07003960 mBootMsgDialog.setTitle(R.string.android_upgrading_title);
3961 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
3962 mBootMsgDialog.setIndeterminate(true);
3963 mBootMsgDialog.getWindow().setType(
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07003964 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS);
Dianne Hackborn661cd522011-08-22 00:26:20 -07003965 mBootMsgDialog.getWindow().addFlags(
3966 WindowManager.LayoutParams.FLAG_DIM_BEHIND
3967 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
3968 mBootMsgDialog.getWindow().setDimAmount(1);
Dianne Hackbornd9efb952011-12-07 14:56:51 -08003969 WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes();
3970 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
3971 mBootMsgDialog.getWindow().setAttributes(lp);
Dianne Hackborn661cd522011-08-22 00:26:20 -07003972 mBootMsgDialog.setCancelable(false);
3973 mBootMsgDialog.show();
3974 }
3975 mBootMsgDialog.setMessage(msg);
3976 }
3977 });
3978 }
3979
3980 /** {@inheritDoc} */
3981 public void hideBootMessages() {
3982 mHandler.post(new Runnable() {
3983 @Override public void run() {
3984 if (mBootMsgDialog != null) {
3985 mBootMsgDialog.dismiss();
3986 mBootMsgDialog = null;
3987 }
3988 }
3989 });
3990 }
3991
Mike Lockwood28569302010-01-28 11:54:40 -05003992 /** {@inheritDoc} */
3993 public void userActivity() {
Dianne Hackborndf89e652011-10-06 22:35:11 -07003994 // ***************************************
3995 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
3996 // ***************************************
3997 // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
3998 // WITH ITS LOCKS HELD.
3999 //
4000 // This code must be VERY careful about the locks
4001 // it acquires.
4002 // In fact, the current code acquires way too many,
4003 // and probably has lurking deadlocks.
4004
Mike Lockwood28569302010-01-28 11:54:40 -05004005 synchronized (mScreenLockTimeout) {
4006 if (mLockScreenTimerActive) {
4007 // reset the timer
4008 mHandler.removeCallbacks(mScreenLockTimeout);
4009 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
4010 }
4011 }
Daniel Sandler0601eb72011-04-13 01:01:32 -04004012 }
4013
Daniel Sandler7d276c32012-01-30 14:33:52 -05004014 private IDreamManager getDreamManager() {
4015 if (!mScreenSaverFeatureAvailable) {
4016 return null;
4017 }
4018
4019 IDreamManager sandman = IDreamManager.Stub.asInterface(
4020 ServiceManager.checkService("dreams"));
4021 if (sandman == null) {
4022 Log.w(TAG, "Unable to find IDreamManager");
4023 }
4024 return sandman;
4025 }
Daniel Sandler0601eb72011-04-13 01:01:32 -04004026
Daniel Sandler7d276c32012-01-30 14:33:52 -05004027 @Override
4028 public boolean isScreenSaverEnabled() {
4029 return (mScreenSaverFeatureAvailable && mScreenSaverEnabledByUser
4030 && mScreenSaverMayRun && mScreenOnEarly && mPluggedIn);
4031 }
Daniel Sandler7e37df52011-11-16 22:08:23 -08004032
Daniel Sandler7d276c32012-01-30 14:33:52 -05004033 @Override
4034 public boolean startScreenSaver() {
4035 synchronized (mLock) {
4036 if (isScreenSaverEnabled()) {
4037 IDreamManager dm = getDreamManager();
4038 if (dm == null) return false;
4039
4040 try {
4041 if (localLOGV) Log.v(TAG, "startScreenSaver: entering dreamland...");
4042
4043 dm.dream();
4044 return true;
4045 } catch (RemoteException ex) {
4046 // too bad, so sad, oh mom, oh dad
Daniel Sandlerc224f762011-11-15 22:55:03 -08004047 }
Daniel Sandler0601eb72011-04-13 01:01:32 -04004048 }
4049 }
Daniel Sandler7d276c32012-01-30 14:33:52 -05004050 return false;
4051 }
Daniel Sandler0601eb72011-04-13 01:01:32 -04004052
Daniel Sandler7d276c32012-01-30 14:33:52 -05004053 @Override
4054 public void stopScreenSaver() {
4055 synchronized (mLock) {
4056 IDreamManager dm = getDreamManager();
4057 if (dm == null) return;
4058
4059 try {
4060 if (localLOGV) Log.v(TAG, "startScreenSaver: awakening...");
4061
4062 dm.awaken();
4063 } catch (RemoteException ex) {
Daniel Sandler0601eb72011-04-13 01:01:32 -04004064 }
4065 }
Mike Lockwood28569302010-01-28 11:54:40 -05004066 }
4067
4068 Runnable mScreenLockTimeout = new Runnable() {
4069 public void run() {
4070 synchronized (this) {
4071 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard");
Mike Lockwood3a74bd32011-08-12 13:55:22 -07004072 if (mKeyguardMediator != null) {
4073 mKeyguardMediator.doKeyguardTimeout();
4074 }
Mike Lockwood28569302010-01-28 11:54:40 -05004075 mLockScreenTimerActive = false;
4076 }
4077 }
4078 };
4079
Jim Miller93c518e2012-01-17 15:55:31 -08004080 public void lockNow() {
4081 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
4082 mHandler.removeCallbacks(mScreenLockTimeout);
4083 mHandler.post(mScreenLockTimeout);
4084 }
4085
Mike Lockwood28569302010-01-28 11:54:40 -05004086 private void updateLockScreenTimeout() {
4087 synchronized (mScreenLockTimeout) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07004088 boolean enable = (mAllowLockscreenWhenOn && mScreenOnEarly &&
4089 mKeyguardMediator != null && mKeyguardMediator.isSecure());
Mike Lockwood28569302010-01-28 11:54:40 -05004090 if (mLockScreenTimerActive != enable) {
4091 if (enable) {
4092 if (localLOGV) Log.v(TAG, "setting lockscreen timer");
4093 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
4094 } else {
4095 if (localLOGV) Log.v(TAG, "clearing lockscreen timer");
4096 mHandler.removeCallbacks(mScreenLockTimeout);
4097 }
4098 mLockScreenTimerActive = enable;
4099 }
4100 }
4101 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004102
4103 /** {@inheritDoc} */
4104 public void enableScreenAfterBoot() {
4105 readLidState();
Jeff Brownc458ce92012-04-30 14:58:40 -07004106 applyLidSwitchState();
Jeff Brown01a98dd2011-09-20 15:08:29 -07004107 updateRotation(true);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004108 }
Dianne Hackbornf54c8f92009-09-19 14:03:57 -07004109
Jeff Brownc458ce92012-04-30 14:58:40 -07004110 private void applyLidSwitchState() {
Jeff Browndaa37532012-05-01 15:54:03 -07004111 mPowerManager.setKeyboardVisibility(isBuiltInKeyboardVisible());
4112
Jeff Brownc458ce92012-04-30 14:58:40 -07004113 if (mLidState == LID_CLOSED && mLidControlsSleep) {
4114 mPowerManager.goToSleep(SystemClock.uptimeMillis());
4115 }
Jeff Brown01a98dd2011-09-20 15:08:29 -07004116 }
4117
4118 void updateRotation(boolean alwaysSendConfiguration) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004119 try {
4120 //set orientation on WindowManager
Dianne Hackbornf87d1962012-04-04 12:48:24 -07004121 mWindowManager.updateRotation(alwaysSendConfiguration, false);
4122 } catch (RemoteException e) {
4123 // Ignore
4124 }
4125 }
4126
4127 void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
4128 try {
4129 //set orientation on WindowManager
4130 mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004131 } catch (RemoteException e) {
4132 // Ignore
4133 }
4134 }
4135
4136 /**
Daniel Sandler11ddf532011-11-16 11:10:03 -08004137 * Return an Intent to launch the currently active dock app as home. Returns
4138 * null if the standard home should be launched, which is the case if any of the following is
4139 * true:
4140 * <ul>
4141 * <li>The device is not in either car mode or desk mode
4142 * <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
4143 * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
4144 * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
4145 * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
4146 * </ul>
Dianne Hackborn39c2d712009-09-22 11:41:31 -07004147 * @return
4148 */
4149 Intent createHomeDockIntent() {
Daniel Sandler11ddf532011-11-16 11:10:03 -08004150 Intent intent = null;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07004151
4152 // What home does is based on the mode, not the dock state. That
4153 // is, when in car mode you should be taken to car home regardless
4154 // of whether we are actually in a car dock.
Dianne Hackborn78968392010-03-04 20:47:56 -08004155 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
Daniel Sandler11ddf532011-11-16 11:10:03 -08004156 if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
4157 intent = mCarDockIntent;
4158 }
Dianne Hackborn78968392010-03-04 20:47:56 -08004159 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
Daniel Sandler11ddf532011-11-16 11:10:03 -08004160 if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
4161 intent = mDeskDockIntent;
4162 }
4163 }
4164
4165 if (intent == null) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07004166 return null;
4167 }
4168
4169 ActivityInfo ai = intent.resolveActivityInfo(
4170 mContext.getPackageManager(), PackageManager.GET_META_DATA);
4171 if (ai == null) {
4172 return null;
4173 }
4174
4175 if (ai.metaData != null && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) {
4176 intent = new Intent(intent);
4177 intent.setClassName(ai.packageName, ai.name);
4178 return intent;
4179 }
4180
4181 return null;
4182 }
4183
4184 void startDockOrHome() {
4185 Intent dock = createHomeDockIntent();
4186 if (dock != null) {
4187 try {
4188 mContext.startActivity(dock);
4189 return;
4190 } catch (ActivityNotFoundException e) {
4191 }
4192 }
4193 mContext.startActivity(mHomeIntent);
4194 }
4195
4196 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004197 * goes to the home screen
4198 * @return whether it did anything
4199 */
4200 boolean goHome() {
4201 if (false) {
4202 // This code always brings home to the front.
Dianne Hackborn256dd3b2009-05-19 18:51:21 -07004203 try {
4204 ActivityManagerNative.getDefault().stopAppSwitches();
4205 } catch (RemoteException e) {
4206 }
Dianne Hackborn94a679d2009-07-28 17:51:07 -07004207 sendCloseSystemWindows();
Dianne Hackborn39c2d712009-09-22 11:41:31 -07004208 startDockOrHome();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004209 } else {
4210 // This code brings home to the front or, if it is already
4211 // at the front, puts the device to sleep.
4212 try {
Wink Savilled2e6a332010-02-12 12:12:06 -08004213 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) {
4214 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry.
4215 Log.d(TAG, "UTS-TEST-MODE");
4216 } else {
4217 ActivityManagerNative.getDefault().stopAppSwitches();
4218 sendCloseSystemWindows();
4219 Intent dock = createHomeDockIntent();
4220 if (dock != null) {
4221 int result = ActivityManagerNative.getDefault()
4222 .startActivity(null, dock,
4223 dock.resolveTypeIfNeeded(mContext.getContentResolver()),
Dianne Hackborna4972e92012-03-14 10:38:05 -07004224 null, null, 0,
4225 ActivityManager.START_FLAG_ONLY_IF_NEEDED,
4226 null, null, null);
4227 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
Wink Savilled2e6a332010-02-12 12:12:06 -08004228 return false;
4229 }
Dianne Hackborn39c2d712009-09-22 11:41:31 -07004230 }
4231 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004232 int result = ActivityManagerNative.getDefault()
4233 .startActivity(null, mHomeIntent,
4234 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
Dianne Hackborna4972e92012-03-14 10:38:05 -07004235 null, null, 0,
4236 ActivityManager.START_FLAG_ONLY_IF_NEEDED,
4237 null, null, null);
4238 if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004239 return false;
4240 }
4241 } catch (RemoteException ex) {
4242 // bummer, the activity manager, which is in this process, is dead
4243 }
4244 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004245 return true;
4246 }
4247
The Android Open Source Project0727d222009-03-11 12:11:58 -07004248 public void setCurrentOrientationLw(int newOrientation) {
4249 synchronized (mLock) {
4250 if (newOrientation != mCurrentAppOrientation) {
4251 mCurrentAppOrientation = newOrientation;
4252 updateOrientationListenerLp();
4253 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004254 }
4255 }
Amith Yamasanic33cb712010-02-10 15:21:49 -08004256
The Android Open Source Project0727d222009-03-11 12:11:58 -07004257 public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {
Jim Miller89b17222009-10-27 14:54:09 -07004258 final boolean hapticsDisabled = Settings.System.getInt(mContext.getContentResolver(),
4259 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0;
Dianne Hackborn9dc06cc2009-11-17 18:19:23 -08004260 if (!always && (hapticsDisabled || mKeyguardMediator.isShowingAndNotHidden())) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004261 return false;
4262 }
Amith Yamasanic33cb712010-02-10 15:21:49 -08004263 long[] pattern = null;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004264 switch (effectId) {
4265 case HapticFeedbackConstants.LONG_PRESS:
Amith Yamasanic33cb712010-02-10 15:21:49 -08004266 pattern = mLongPressVibePattern;
4267 break;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07004268 case HapticFeedbackConstants.VIRTUAL_KEY:
Amith Yamasanic33cb712010-02-10 15:21:49 -08004269 pattern = mVirtualKeyVibePattern;
4270 break;
4271 case HapticFeedbackConstants.KEYBOARD_TAP:
4272 pattern = mKeyboardTapVibePattern;
4273 break;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07004274 case HapticFeedbackConstants.SAFE_MODE_DISABLED:
Amith Yamasanic33cb712010-02-10 15:21:49 -08004275 pattern = mSafeModeDisabledVibePattern;
4276 break;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07004277 case HapticFeedbackConstants.SAFE_MODE_ENABLED:
Amith Yamasanic33cb712010-02-10 15:21:49 -08004278 pattern = mSafeModeEnabledVibePattern;
4279 break;
Amith Yamasanic33cb712010-02-10 15:21:49 -08004280 default:
4281 return false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004282 }
Amith Yamasanic33cb712010-02-10 15:21:49 -08004283 if (pattern.length == 1) {
4284 // One-shot vibration
4285 mVibrator.vibrate(pattern[0]);
4286 } else {
4287 // Pattern vibration
4288 mVibrator.vibrate(pattern, -1);
4289 }
4290 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004291 }
4292
Daniel Sandler0601eb72011-04-13 01:01:32 -04004293 public void screenOnStartedLw() {
4294 // The window manager has just grabbed a wake lock. This is our cue to disable the screen
4295 // saver.
4296 synchronized (mLock) {
Daniel Sandler2d545362011-11-17 10:38:37 -08004297 mScreenSaverMayRun = false;
Daniel Sandler0601eb72011-04-13 01:01:32 -04004298 }
4299 }
4300
The Android Open Source Project0727d222009-03-11 12:11:58 -07004301 public void screenOnStoppedLw() {
Daniel Sandler0601eb72011-04-13 01:01:32 -04004302 if (mPowerManager.isScreenOn()) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07004303 if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) {
Daniel Sandler0601eb72011-04-13 01:01:32 -04004304 long curTime = SystemClock.uptimeMillis();
4305 mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT);
4306 }
4307
4308 synchronized (mLock) {
4309 // even if the keyguard is up, now that all the wakelocks have been released, we
4310 // should re-enable the screen saver
Daniel Sandler2d545362011-11-17 10:38:37 -08004311 mScreenSaverMayRun = true;
Daniel Sandler0601eb72011-04-13 01:01:32 -04004312 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004313 }
4314 }
Mike Lockwoodfcb39242009-10-21 23:01:07 -04004315
4316 public boolean allowKeyRepeat() {
4317 // disable key repeat when screen is off
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07004318 return mScreenOnEarly;
Mike Lockwoodfcb39242009-10-21 23:01:07 -04004319 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004320
Dianne Hackborndf89e652011-10-06 22:35:11 -07004321 private int updateSystemUiVisibilityLw() {
Joe Onorato664644d2011-01-23 17:53:23 -08004322 // If there is no window focused, there will be nobody to handle the events
4323 // anyway, so just hang on in whatever state we're in until things settle down.
Dianne Hackborndf89e652011-10-06 22:35:11 -07004324 if (mFocusedWindow == null) {
4325 return 0;
4326 }
4327 final int visibility = mFocusedWindow.getSystemUiVisibility()
Dianne Hackborne26ab702011-10-16 13:21:33 -07004328 & ~mResettingSystemUiFlags
4329 & ~mForceClearedSystemUiFlags;
4330 int diff = visibility ^ mLastSystemUiFlags;
Dianne Hackborn73ab6a42011-12-13 11:16:23 -08004331 final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
Dianne Hackborne0f085d2011-11-30 18:41:15 -08004332 if (diff == 0 && mLastFocusNeedsMenu == needsMenu
4333 && mFocusedApp == mFocusedWindow.getAppToken()) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07004334 return 0;
4335 }
Dianne Hackborne26ab702011-10-16 13:21:33 -07004336 mLastSystemUiFlags = visibility;
Dianne Hackborn4eff8d32011-11-10 19:38:40 -08004337 mLastFocusNeedsMenu = needsMenu;
Dianne Hackborne0f085d2011-11-30 18:41:15 -08004338 mFocusedApp = mFocusedWindow.getAppToken();
Dianne Hackborndf89e652011-10-06 22:35:11 -07004339 mHandler.post(new Runnable() {
4340 public void run() {
4341 if (mStatusBarService == null) {
4342 mStatusBarService = IStatusBarService.Stub.asInterface(
4343 ServiceManager.getService("statusbar"));
4344 }
4345 if (mStatusBarService != null) {
4346 try {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004347 mStatusBarService.setSystemUiVisibility(visibility, 0xffffffff);
Dianne Hackborn4eff8d32011-11-10 19:38:40 -08004348 mStatusBarService.topAppWindowChanged(needsMenu);
Dianne Hackborndf89e652011-10-06 22:35:11 -07004349 } catch (RemoteException e) {
4350 // not much to be done
4351 mStatusBarService = null;
Joe Onorato664644d2011-01-23 17:53:23 -08004352 }
4353 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07004354 }
4355 });
4356 return diff;
Joe Onorato664644d2011-01-23 17:53:23 -08004357 }
4358
Daniel Sandler0c4ccff2011-10-19 16:39:14 -04004359 // Use this instead of checking config_showNavigationBar so that it can be consistently
4360 // overridden by qemu.hw.mainkeys in the emulator.
4361 public boolean hasNavigationBar() {
4362 return mHasNavigationBar;
4363 }
4364
satok1bc0a492012-04-25 22:47:12 +09004365 @Override
4366 public void setLastInputMethodWindowLw(WindowState ime, WindowState target) {
4367 mLastInputMethodWindow = ime;
4368 mLastInputMethodTargetWindow = target;
4369 }
4370
Jeff Brownd7a04de2012-06-17 14:17:52 -07004371 public void dump(String prefix, PrintWriter pw, String[] args) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004372 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07004373 pw.print(" mSystemReady="); pw.print(mSystemReady);
4374 pw.print(" mSystemBooted="); pw.println(mSystemBooted);
Jeff Brown2e7760e2012-04-11 15:14:55 -07004375 pw.print(prefix); pw.print("mLidState="); pw.print(mLidState);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004376 pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation);
4377 pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged);
Dianne Hackborne26ab702011-10-16 13:21:33 -07004378 if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0
4379 || mForceClearedSystemUiFlags != 0) {
4380 pw.print(prefix); pw.print("mLastSystemUiFlags=0x");
4381 pw.print(Integer.toHexString(mLastSystemUiFlags));
4382 pw.print(" mResettingSystemUiFlags=0x");
4383 pw.print(Integer.toHexString(mResettingSystemUiFlags));
4384 pw.print(" mForceClearedSystemUiFlags=0x");
4385 pw.println(Integer.toHexString(mForceClearedSystemUiFlags));
Dianne Hackborndf89e652011-10-06 22:35:11 -07004386 }
Dianne Hackborn4eff8d32011-11-10 19:38:40 -08004387 if (mLastFocusNeedsMenu) {
4388 pw.print(prefix); pw.print("mLastFocusNeedsMenu=");
4389 pw.println(mLastFocusNeedsMenu);
4390 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004391 pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
4392 pw.print(" mDockMode="); pw.print(mDockMode);
4393 pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
4394 pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
4395 pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
4396 pw.print(" mUserRotation="); pw.print(mUserRotation);
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05004397 pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations);
Jeff Brown207673cd2012-06-05 17:47:11 -07004398 pw.print(prefix); pw.print(" mCurrentAppOrientation="); pw.println(mCurrentAppOrientation);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004399 pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
4400 pw.print(mCarDockEnablesAccelerometer);
4401 pw.print(" mDeskDockEnablesAccelerometer=");
4402 pw.println(mDeskDockEnablesAccelerometer);
4403 pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
4404 pw.print(mLidKeyboardAccessibility);
4405 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
Jeff Brownc458ce92012-04-30 14:58:40 -07004406 pw.print(" mLidControlsSleep="); pw.print(mLidControlsSleep);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004407 pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07004408 pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
4409 pw.print(" mScreenOnFully="); pw.print(mScreenOnFully);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004410 pw.print(" mOrientationSensorEnabled="); pw.print(mOrientationSensorEnabled);
4411 pw.print(" mHasSoftInput="); pw.println(mHasSoftInput);
4412 pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft);
4413 pw.print(","); pw.print(mUnrestrictedScreenTop);
4414 pw.print(") "); pw.print(mUnrestrictedScreenWidth);
4415 pw.print("x"); pw.println(mUnrestrictedScreenHeight);
4416 pw.print(prefix); pw.print("mRestrictedScreen=("); pw.print(mRestrictedScreenLeft);
4417 pw.print(","); pw.print(mRestrictedScreenTop);
4418 pw.print(") "); pw.print(mRestrictedScreenWidth);
4419 pw.print("x"); pw.println(mRestrictedScreenHeight);
Dianne Hackborn5b5cc4d2012-05-16 13:15:00 -07004420 pw.print(prefix); pw.print("mStableFullscreen=("); pw.print(mStableFullscreenLeft);
4421 pw.print(","); pw.print(mStableFullscreenTop);
4422 pw.print(")-("); pw.print(mStableFullscreenRight);
4423 pw.print(","); pw.print(mStableFullscreenBottom); pw.println(")");
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07004424 pw.print(prefix); pw.print("mStable=("); pw.print(mStableLeft);
4425 pw.print(","); pw.print(mStableTop);
4426 pw.print(")-("); pw.print(mStableRight);
4427 pw.print(","); pw.print(mStableBottom); pw.println(")");
Dianne Hackborn5c58de32012-04-28 19:52:37 -07004428 pw.print(prefix); pw.print("mSystem=("); pw.print(mSystemLeft);
4429 pw.print(","); pw.print(mSystemTop);
4430 pw.print(")-("); pw.print(mSystemRight);
4431 pw.print(","); pw.print(mSystemBottom); pw.println(")");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004432 pw.print(prefix); pw.print("mCur=("); pw.print(mCurLeft);
4433 pw.print(","); pw.print(mCurTop);
4434 pw.print(")-("); pw.print(mCurRight);
4435 pw.print(","); pw.print(mCurBottom); pw.println(")");
4436 pw.print(prefix); pw.print("mContent=("); pw.print(mContentLeft);
4437 pw.print(","); pw.print(mContentTop);
4438 pw.print(")-("); pw.print(mContentRight);
4439 pw.print(","); pw.print(mContentBottom); pw.println(")");
4440 pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft);
4441 pw.print(","); pw.print(mDockTop);
4442 pw.print(")-("); pw.print(mDockRight);
4443 pw.print(","); pw.print(mDockBottom); pw.println(")");
Dianne Hackborn5c58de32012-04-28 19:52:37 -07004444 pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer);
4445 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004446 pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState=");
4447 pw.println(mTopFullscreenOpaqueWindowState);
4448 pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
4449 pw.print(" mForceStatusBar="); pw.print(mForceStatusBar);
4450 pw.print(" mHideLockScreen="); pw.println(mHideLockScreen);
4451 pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard);
4452 pw.print(" mHomePressed="); pw.println(mHomePressed);
4453 pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
4454 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
4455 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
4456 pw.print(prefix); pw.print("mEndcallBehavior="); pw.print(mEndcallBehavior);
4457 pw.print(" mIncallPowerBehavior="); pw.print(mIncallPowerBehavior);
4458 pw.print(" mLongPressOnHomeBehavior="); pw.println(mLongPressOnHomeBehavior);
4459 pw.print(prefix); pw.print("mLandscapeRotation="); pw.print(mLandscapeRotation);
4460 pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation);
4461 pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation);
4462 pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation);
4463 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08004464}