blob: dfd1b00cec904c85be6ee172ec88cc1ccc6f5585 [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.policy.impl;
18
19import android.app.Activity;
20import android.app.ActivityManagerNative;
21import android.app.IActivityManager;
Dianne Hackborn78968392010-03-04 20:47:56 -080022import android.app.IUiModeManager;
Dianne Hackborn661cd522011-08-22 00:26:20 -070023import android.app.ProgressDialog;
Dianne Hackborn78968392010-03-04 20:47:56 -080024import android.app.UiModeManager;
Dianne Hackborn39c2d712009-09-22 11:41:31 -070025import android.content.ActivityNotFoundException;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080026import android.content.BroadcastReceiver;
Daniel Sandler0601eb72011-04-13 01:01:32 -040027import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080028import android.content.ContentResolver;
29import android.content.Context;
30import android.content.Intent;
Mike Lockwood1753f7f2009-08-24 14:49:07 -070031import android.content.IntentFilter;
Winson Chung9112ec32011-06-27 13:15:32 -070032import android.content.ServiceConnection;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080033import android.content.pm.ActivityInfo;
34import android.content.pm.PackageManager;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070035import android.content.res.CompatibilityInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080036import android.content.res.Configuration;
37import android.content.res.Resources;
38import 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;
Joe Onorato664644d2011-01-23 17:53:23 -080041import android.os.Binder;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080042import android.os.Handler;
43import android.os.IBinder;
44import android.os.LocalPowerManager;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -070045import android.os.Message;
46import android.os.Messenger;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080047import android.os.PowerManager;
48import android.os.RemoteException;
49import android.os.ServiceManager;
50import android.os.SystemClock;
51import android.os.SystemProperties;
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -080052import android.os.UEventObserver;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080053import android.os.Vibrator;
54import android.provider.Settings;
55
Jim Millere6ad1a82010-08-20 19:25:39 -070056import com.android.internal.R;
Joe Onoratod208e702010-10-08 16:22:43 -040057import com.android.internal.app.ShutdownThread;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080058import com.android.internal.policy.PolicyManager;
Joe Onorato0cbda992010-05-02 16:28:15 -070059import com.android.internal.statusbar.IStatusBarService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080060import com.android.internal.telephony.ITelephony;
Jeff Browna41ca772010-08-11 14:46:32 -070061import com.android.internal.view.BaseInputHandler;
Dianne Hackborn6019c9d2010-03-01 21:43:11 -080062import com.android.internal.widget.PointerLocationView;
63
Dianne Hackborn81e56d52011-05-26 00:55:58 -070064import android.util.DisplayMetrics;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080065import android.util.EventLog;
66import android.util.Log;
Jeff Browna41ca772010-08-11 14:46:32 -070067import android.util.Slog;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080068import android.view.Gravity;
69import android.view.HapticFeedbackConstants;
70import android.view.IWindowManager;
Jeff Browna41ca772010-08-11 14:46:32 -070071import android.view.InputChannel;
Jeff Brown4d396052010-10-29 21:50:21 -070072import android.view.InputDevice;
Jeff Browna41ca772010-08-11 14:46:32 -070073import android.view.InputQueue;
74import android.view.InputHandler;
Jeff Brown6b53e8d2010-11-10 16:03:06 -080075import android.view.KeyCharacterMap;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080076import android.view.KeyEvent;
77import android.view.MotionEvent;
78import android.view.WindowOrientationListener;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080079import android.view.Surface;
80import android.view.View;
81import android.view.ViewConfiguration;
82import android.view.Window;
83import android.view.WindowManager;
84import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
85import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
86import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
87import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
88import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
89import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -070090import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Dianne Hackborn39c2d712009-09-22 11:41:31 -070091import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
Mike Lockwood28569302010-01-28 11:54:40 -050092import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080093import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
94import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
Dianne Hackborndea3ef72010-10-28 14:24:22 -070095import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080096import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
97import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
Dianne Hackborn5cb8d792009-05-21 17:34:15 -070098import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080099import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
100import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
101import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
Christopher Tatea53146c2010-09-07 11:57:52 -0700102import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800103import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;
104import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
105import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
106import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
107import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
Jeff Brown3b2b3542010-10-15 00:54:27 -0700108import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800109import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
110import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
Joe Onorato29fc2c92010-11-24 10:26:50 -0800111import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
Dianne Hackborn6a294ce2009-12-03 11:37:44 -0800112import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800113import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
114import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
115import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
116import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
117import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
118import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700119import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -0700120import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Jeff Brown83c09682010-12-23 17:50:18 -0800121import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400122import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700123import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800124import android.view.WindowManagerImpl;
125import android.view.WindowManagerPolicy;
Jeff Brown6f2fba42011-02-19 01:08:02 -0800126import android.view.KeyCharacterMap.FallbackAction;
Dianne Hackborn295e3c22011-08-25 13:19:08 -0700127import android.view.accessibility.AccessibilityEvent;
Dianne Hackborn01ad2f42009-09-24 19:24:56 -0700128import android.view.animation.Animation;
129import android.view.animation.AnimationUtils;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800130import android.media.IAudioService;
131import android.media.AudioManager;
132
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800133import java.io.File;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800134import java.io.FileDescriptor;
Joe Onoratodc100302011-01-11 17:07:41 -0800135import java.io.FileReader;
136import java.io.IOException;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800137import java.io.PrintWriter;
Dianne Hackborn08743722009-12-21 12:16:51 -0800138import java.util.ArrayList;
139
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800140/**
The Android Open Source Project0727d222009-03-11 12:11:58 -0700141 * WindowManagerPolicy implementation for the Android phone UI. This
142 * introduces a new method suffix, Lp, for an internal lock of the
143 * PhoneWindowManager. This is used to protect some internal state, and
144 * can be acquired with either thw Lw and Li lock held, so has the restrictions
145 * of both of those when held.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800146 */
147public class PhoneWindowManager implements WindowManagerPolicy {
148 static final String TAG = "WindowManager";
149 static final boolean DEBUG = false;
Joe Onorato43a17652011-04-06 19:22:23 -0700150 static final boolean localLOGV = false;
The Android Open Source Project11267662009-03-18 17:39:47 -0700151 static final boolean DEBUG_LAYOUT = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -0800152 static final boolean DEBUG_FALLBACK = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800153 static final boolean SHOW_STARTING_ANIMATIONS = true;
154 static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
Joe Onoratod208e702010-10-08 16:22:43 -0400155
156 static final int LONG_PRESS_POWER_NOTHING = 0;
157 static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
158 static final int LONG_PRESS_POWER_SHUT_OFF = 2;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700159
160 // These need to match the documentation/constant in
161 // core/res/res/values/config.xml
Joe Onorato46b0d682010-11-22 17:37:27 -0800162 static final int LONG_PRESS_HOME_NOTHING = 0;
163 static final int LONG_PRESS_HOME_RECENT_DIALOG = 1;
Michael Jurka3b1fc472011-06-13 10:54:40 -0700164 static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2;
Joe Onorato46b0d682010-11-22 17:37:27 -0800165
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -0700166 // wallpaper is at the bottom, though the window manager may move it.
Dianne Hackborn3c3bd442009-08-19 17:09:46 -0700167 static final int WALLPAPER_LAYER = 2;
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -0700168 static final int APPLICATION_LAYER = 2;
169 static final int PHONE_LAYER = 3;
170 static final int SEARCH_BAR_LAYER = 4;
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700171 static final int SYSTEM_DIALOG_LAYER = 5;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800172 // toasts and the plugged-in battery thing
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700173 static final int TOAST_LAYER = 6;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800174 // SIM errors and unlock. Not sure if this really should be in a high layer.
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700175 static final int PRIORITY_PHONE_LAYER = 7;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800176 // like the ANR / app crashed dialogs
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700177 static final int SYSTEM_ALERT_LAYER = 8;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800178 // system-level error dialogs
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700179 static final int SYSTEM_ERROR_LAYER = 9;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800180 // on-screen keyboards and other such input method user interfaces go here.
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700181 static final int INPUT_METHOD_LAYER = 10;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800182 // on-screen keyboards and other such input method user interfaces go here.
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700183 static final int INPUT_METHOD_DIALOG_LAYER = 11;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800184 // the keyguard; nothing on top of these can take focus, since they are
185 // responsible for power management when displayed.
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700186 static final int KEYGUARD_LAYER = 12;
187 static final int KEYGUARD_DIALOG_LAYER = 13;
188 static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
Dianne Hackborn71baf1d2011-07-21 18:05:11 -0700189 static final int STATUS_BAR_LAYER = 15;
190 static final int STATUS_BAR_PANEL_LAYER = 16;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400191 // the navigation bar, if available, shows atop most things
192 static final int NAVIGATION_BAR_LAYER = 17;
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700193 // the on-screen volume indicator and controller shown when the user
194 // changes the device volume
195 static final int VOLUME_OVERLAY_LAYER = 18;
Christopher Tatea53146c2010-09-07 11:57:52 -0700196 // the drag layer: input for drag-and-drop is associated with this window,
197 // which sits above all other focusable windows
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700198 static final int DRAG_LAYER = 19;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800199 // things in here CAN NOT take focus, but are shown on top of everything else.
Dianne Hackborne8ecde12011-08-03 18:55:19 -0700200 static final int SYSTEM_OVERLAY_LAYER = 20;
201 static final int SECURE_SYSTEM_OVERLAY_LAYER = 21;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700202 static final int BOOT_PROGRESS_LAYER = 22;
Jeff Brown83c09682010-12-23 17:50:18 -0800203 // the (mouse) pointer layer
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700204 static final int POINTER_LAYER = 23;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800205
Dianne Hackborn5cb8d792009-05-21 17:34:15 -0700206 static final int APPLICATION_MEDIA_SUBLAYER = -2;
207 static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800208 static final int APPLICATION_PANEL_SUBLAYER = 1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800209 static final int APPLICATION_SUB_PANEL_SUBLAYER = 2;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800210
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800211 static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
212 static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
213 static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
Joe Onoratof275f0c2009-11-24 16:11:13 -0500214 static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800215
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700216 // Useful scan codes.
217 private static final int SW_LID = 0x00;
218 private static final int BTN_MOUSE = 0x110;
219
The Android Open Source Project0727d222009-03-11 12:11:58 -0700220 final Object mLock = new Object();
221
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800222 Context mContext;
223 IWindowManager mWindowManager;
224 LocalPowerManager mPowerManager;
Joe Onorato93056472010-09-10 10:30:46 -0400225 IStatusBarService mStatusBarService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800226 Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
227
Dianne Hackborn181ceb52009-08-27 22:16:40 -0700228 // Vibrator pattern for haptic feedback of a long press.
229 long[] mLongPressVibePattern;
230
231 // Vibrator pattern for haptic feedback of virtual key press.
232 long[] mVirtualKeyVibePattern;
233
Amith Yamasanic33cb712010-02-10 15:21:49 -0800234 // Vibrator pattern for a short vibration.
235 long[] mKeyboardTapVibePattern;
236
Dianne Hackbornb1a79802009-09-29 15:18:31 -0700237 // Vibrator pattern for haptic feedback during boot when safe mode is disabled.
238 long[] mSafeModeDisabledVibePattern;
239
240 // Vibrator pattern for haptic feedback during boot when safe mode is enabled.
241 long[] mSafeModeEnabledVibePattern;
Romain Guy8154cd32010-03-29 14:41:15 -0700242
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800243 /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */
244 boolean mEnableShiftMenuBugReports = false;
245
246 boolean mSafeMode;
247 WindowState mStatusBar = null;
Daniel Sandler40427442010-07-16 11:44:52 -0400248 boolean mStatusBarCanHide;
Dianne Hackborn69cb8752011-05-19 18:13:32 -0700249 int mStatusBarHeight;
Dianne Hackborn08743722009-12-21 12:16:51 -0800250 final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400251 WindowState mNavigationBar = null;
Daniel Sandler36412a72011-08-04 09:35:13 -0400252 boolean mHasNavigationBar = false;
253 int mNavigationBarWidth = 0, mNavigationBarHeight = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400254
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800255 WindowState mKeyguard = null;
256 KeyguardViewMediator mKeyguardMediator;
257 GlobalActions mGlobalActions;
Jeff Brown4d396052010-10-29 21:50:21 -0700258 volatile boolean mPowerKeyHandled;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800259 RecentApplicationsDialog mRecentAppsDialog;
260 Handler mHandler;
Jeff Brown4aed78b2011-01-14 17:36:55 -0800261
262 private static final int LID_ABSENT = -1;
263 private static final int LID_CLOSED = 0;
264 private static final int LID_OPEN = 1;
265
266 int mLidOpen = LID_ABSENT;
267
Dianne Hackbornc777e072010-02-12 13:07:59 -0800268 boolean mSystemReady;
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800269 boolean mHdmiPlugged;
Dianne Hackborn78968392010-03-04 20:47:56 -0800270 int mUiMode = Configuration.UI_MODE_TYPE_NORMAL;
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700271 int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700272 int mLidOpenRotation;
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400273 int mCarDockRotation;
274 int mDeskDockRotation;
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400275
276 int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
277 int mUserRotation = Surface.ROTATION_0;
278
Dianne Hackborna1111872010-11-23 20:55:11 -0800279 boolean mAllowAllRotations;
Mike Lockwoode9867d22009-09-20 01:59:02 -0400280 boolean mCarDockEnablesAccelerometer;
281 boolean mDeskDockEnablesAccelerometer;
Dianne Hackborn2862fff2009-09-15 22:56:29 -0700282 int mLidKeyboardAccessibility;
283 int mLidNavigationAccessibility;
Joe Onoratod208e702010-10-08 16:22:43 -0400284 int mLongPressOnPowerBehavior = -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800285 boolean mScreenOn = false;
286 boolean mOrientationSensorEnabled = false;
287 int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
288 static final int DEFAULT_ACCELEROMETER_ROTATION = 0;
289 int mAccelerometerDefault = DEFAULT_ACCELEROMETER_ROTATION;
290 boolean mHasSoftInput = false;
291
Dianne Hackbornc777e072010-02-12 13:07:59 -0800292 int mPointerLocationMode = 0;
293 PointerLocationView mPointerLocationView = null;
Jeff Browna41ca772010-08-11 14:46:32 -0700294 InputChannel mPointerLocationInputChannel;
Joe Onorato664644d2011-01-23 17:53:23 -0800295
296 // The last window we were told about in focusChanged.
297 WindowState mFocusedWindow;
298
Jeff Browna41ca772010-08-11 14:46:32 -0700299 private final InputHandler mPointerLocationInputHandler = new BaseInputHandler() {
300 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700301 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
302 boolean handled = false;
303 try {
304 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
305 synchronized (mLock) {
306 if (mPointerLocationView != null) {
Jeff Brown33bbfd22011-02-24 20:55:35 -0800307 mPointerLocationView.addPointerEvent(event);
Jeff Brown3915bb82010-11-05 15:02:16 -0700308 handled = true;
309 }
310 }
Jeff Brown93ed4e32010-09-23 13:51:48 -0700311 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700312 } finally {
313 finishedCallback.finished(handled);
Jeff Browna41ca772010-08-11 14:46:32 -0700314 }
315 }
316 };
Dianne Hackbornc777e072010-02-12 13:07:59 -0800317
Joe Onorato29fc2c92010-11-24 10:26:50 -0800318 // The current size of the screen; really; (ir)regardless of whether the status
319 // bar can be hidden or not
320 int mUnrestrictedScreenLeft, mUnrestrictedScreenTop;
321 int mUnrestrictedScreenWidth, mUnrestrictedScreenHeight;
Dianne Hackborn82de1ae2010-10-28 11:28:39 -0700322 // The current size of the screen; these may be different than (0,0)-(dw,dh)
323 // if the status bar can't be hidden; in that case it effectively carves out
324 // that area of the display from all other windows.
Joe Onorato29fc2c92010-11-24 10:26:50 -0800325 int mRestrictedScreenLeft, mRestrictedScreenTop;
326 int mRestrictedScreenWidth, mRestrictedScreenHeight;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800327 // During layout, the current screen borders with all outer decoration
328 // (status bar, input method dock) accounted for.
329 int mCurLeft, mCurTop, mCurRight, mCurBottom;
330 // During layout, the frame in which content should be displayed
331 // to the user, accounting for all screen decoration except for any
332 // space they deem as available for other content. This is usually
333 // the same as mCur*, but may be larger if the screen decor has supplied
334 // content insets.
335 int mContentLeft, mContentTop, mContentRight, mContentBottom;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -0800336 // During layout, the current screen borders along which input method
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800337 // windows are placed.
338 int mDockLeft, mDockTop, mDockRight, mDockBottom;
339 // During layout, the layer at which the doc window is placed.
340 int mDockLayer;
341
342 static final Rect mTmpParentFrame = new Rect();
343 static final Rect mTmpDisplayFrame = new Rect();
344 static final Rect mTmpContentFrame = new Rect();
345 static final Rect mTmpVisibleFrame = new Rect();
346
347 WindowState mTopFullscreenOpaqueWindowState;
Dianne Hackborn7d049322011-06-14 15:00:32 -0700348 WindowState mTopAppWindowState;
349 WindowState mLastTopAppWindowState;
Joe Onorato93056472010-09-10 10:30:46 -0400350 boolean mTopIsFullscreen;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800351 boolean mForceStatusBar;
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700352 boolean mHideLockScreen;
353 boolean mDismissKeyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800354 boolean mHomePressed;
355 Intent mHomeIntent;
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700356 Intent mCarDockIntent;
357 Intent mDeskDockIntent;
Jeff Brown49ed71d2010-12-06 17:13:33 -0800358 int mShortcutKeyPressed = -1;
359 boolean mConsumeShortcutKeyUp;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800360
Mike Lockwood28569302010-01-28 11:54:40 -0500361 // support for activating the lock screen while the screen is on
362 boolean mAllowLockscreenWhenOn;
363 int mLockScreenTimeout;
364 boolean mLockScreenTimerActive;
365
Daniel Sandler0601eb72011-04-13 01:01:32 -0400366 // visual screen saver support
367 int mScreenSaverTimeout;
368 boolean mScreenSaverEnabled = false;
369
David Brownbaf8d092010-03-08 21:52:59 -0800370 // Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.)
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800371 int mEndcallBehavior;
David Brownbaf8d092010-03-08 21:52:59 -0800372
373 // Behavior of POWER button while in-call and screen on.
374 // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.)
375 int mIncallPowerBehavior;
376
Dianne Hackborn9d132642011-04-21 17:26:39 -0700377 int mLandscapeRotation = 0; // default landscape rotation
378 int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
379 int mPortraitRotation = 0; // default portrait rotation
380 int mUpsideDownRotation = 0; // "other" portrait rotation
Mitsuru Oshima831d0d92009-06-16 18:27:18 -0700381
Dianne Hackborn03759ed2009-03-27 16:04:08 -0700382 // Nothing to see here, move along...
383 int mFancyRotationAnimation;
Jim Milleree969aa2010-08-26 20:17:43 -0700384
Joe Onorato46b0d682010-11-22 17:37:27 -0800385 // What we do when the user long presses on home
386 private int mLongPressOnHomeBehavior = -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800387
Winson Chung9112ec32011-06-27 13:15:32 -0700388 // Screenshot trigger states
389 private boolean mVolumeDownTriggered;
390 private boolean mPowerDownTriggered;
391
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800392 ShortcutManager mShortcutManager;
393 PowerManager.WakeLock mBroadcastWakeLock;
394
Jeff Brown49ed71d2010-12-06 17:13:33 -0800395 final KeyCharacterMap.FallbackAction mFallbackAction = new KeyCharacterMap.FallbackAction();
396
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -0800397 private UEventObserver mHDMIObserver = new UEventObserver() {
398 @Override
399 public void onUEvent(UEventObserver.UEvent event) {
400 setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
401 }
402 };
403
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800404 class SettingsObserver extends ContentObserver {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800405 SettingsObserver(Handler handler) {
406 super(handler);
407 }
David Brownbaf8d092010-03-08 21:52:59 -0800408
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800409 void observe() {
410 ContentResolver resolver = mContext.getContentResolver();
411 resolver.registerContentObserver(Settings.System.getUriFor(
412 Settings.System.END_BUTTON_BEHAVIOR), false, this);
David Brownbaf8d092010-03-08 21:52:59 -0800413 resolver.registerContentObserver(Settings.Secure.getUriFor(
414 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800415 resolver.registerContentObserver(Settings.System.getUriFor(
416 Settings.System.ACCELEROMETER_ROTATION), false, this);
Mike Lockwood28569302010-01-28 11:54:40 -0500417 resolver.registerContentObserver(Settings.System.getUriFor(
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400418 Settings.System.USER_ROTATION), false, this);
419 resolver.registerContentObserver(Settings.System.getUriFor(
Mike Lockwood28569302010-01-28 11:54:40 -0500420 Settings.System.SCREEN_OFF_TIMEOUT), false, this);
Dianne Hackbornc777e072010-02-12 13:07:59 -0800421 resolver.registerContentObserver(Settings.System.getUriFor(
Jeff Brown4519f072011-01-23 13:16:01 -0800422 Settings.System.WINDOW_ORIENTATION_LISTENER_LOG), false, this);
423 resolver.registerContentObserver(Settings.System.getUriFor(
Dianne Hackbornc777e072010-02-12 13:07:59 -0800424 Settings.System.POINTER_LOCATION), false, this);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800425 resolver.registerContentObserver(Settings.Secure.getUriFor(
426 Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
Dianne Hackborn03759ed2009-03-27 16:04:08 -0700427 resolver.registerContentObserver(Settings.System.getUriFor(
428 "fancy_rotation_anim"), false, this);
Daniel Sandler0601eb72011-04-13 01:01:32 -0400429 resolver.registerContentObserver(Settings.System.getUriFor(
430 Settings.Secure.DREAM_TIMEOUT), false, this);
Dianne Hackbornc777e072010-02-12 13:07:59 -0800431 updateSettings();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800432 }
433
434 @Override public void onChange(boolean selfChange) {
Dianne Hackbornc777e072010-02-12 13:07:59 -0800435 updateSettings();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800436 try {
Dianne Hackborn32bc91d2009-03-27 16:16:03 -0700437 mWindowManager.setRotation(USE_LAST_ROTATION, false,
438 mFancyRotationAnimation);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800439 } catch (RemoteException e) {
440 // Ignore
441 }
442 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800443 }
444
445 class MyOrientationListener extends WindowOrientationListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800446 MyOrientationListener(Context context) {
447 super(context);
448 }
449
450 @Override
The Android Open Source Projectd06b0972009-03-13 13:04:23 -0700451 public void onOrientationChanged(int rotation) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800452 // Send updates based on orientation value
Dianne Hackborn05726582009-09-22 17:28:24 -0700453 if (localLOGV) Log.v(TAG, "onOrientationChanged, rotation changed to " +rotation);
Dianne Hackborn03759ed2009-03-27 16:04:08 -0700454 try {
Dianne Hackborn32bc91d2009-03-27 16:16:03 -0700455 mWindowManager.setRotation(rotation, false,
456 mFancyRotationAnimation);
Dianne Hackborn03759ed2009-03-27 16:04:08 -0700457 } catch (RemoteException e) {
458 // Ignore
Wink Saville37c124c2009-04-02 01:37:02 -0700459
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800460 }
461 }
462 }
463 MyOrientationListener mOrientationListener;
464
Dianne Hackborn03759ed2009-03-27 16:04:08 -0700465 boolean useSensorForOrientationLp(int appOrientation) {
Joe Onorato1b58b3e2009-09-22 16:44:16 -0700466 // The app says use the sensor.
Dianne Hackborne5439f22010-10-02 16:53:50 -0700467 if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
468 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
469 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
470 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800471 return true;
472 }
Joe Onorato1b58b3e2009-09-22 16:44:16 -0700473 // The user preference says we can rotate, and the app is willing to rotate.
474 if (mAccelerometerDefault != 0 &&
475 (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER
Dianne Hackborne5439f22010-10-02 16:53:50 -0700476 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800477 return true;
478 }
Dianne Hackborne5439f22010-10-02 16:53:50 -0700479 // We're in a dock that has a rotation affinity, and the app is willing to rotate.
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700480 if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR)
481 || (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) {
Joe Onorato1b58b3e2009-09-22 16:44:16 -0700482 // Note we override the nosensor flag here.
483 if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER
484 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
Dianne Hackborne5439f22010-10-02 16:53:50 -0700485 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
Joe Onorato1b58b3e2009-09-22 16:44:16 -0700486 return true;
487 }
488 }
489 // Else, don't use the sensor.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800490 return false;
491 }
492
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -0700493 /*
494 * We always let the sensor be switched on by default except when
495 * the user has explicitly disabled sensor based rotation or when the
496 * screen is switched off.
497 */
The Android Open Source Project0727d222009-03-11 12:11:58 -0700498 boolean needSensorRunningLp() {
Dianne Hackborne5439f22010-10-02 16:53:50 -0700499 if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
500 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
501 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
502 || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800503 // If the application has explicitly requested to follow the
504 // orientation, then we need to turn the sensor or.
505 return true;
506 }
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700507 if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) ||
508 (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) {
Mike Lockwoode9867d22009-09-20 01:59:02 -0400509 // enable accelerometer if we are docked in a dock that enables accelerometer
510 // orientation management,
511 return true;
512 }
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -0700513 if (mAccelerometerDefault == 0) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800514 // If the setting for using the sensor by default is enabled, then
515 // we will always leave it on. Note that the user could go to
516 // a window that forces an orientation that does not use the
517 // sensor and in theory we could turn it off... however, when next
518 // turning it on we won't have a good value for the current
519 // orientation for a little bit, which can cause orientation
520 // changes to lag, so we'd like to keep it always on. (It will
521 // still be turned off when the screen is off.)
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -0700522 return false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800523 }
Suchi Amalapurapua9e1b162009-03-24 22:24:47 -0700524 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800525 }
526
527 /*
528 * Various use cases for invoking this function
529 * screen turning off, should always disable listeners if already enabled
530 * screen turned on and current app has sensor based orientation, enable listeners
531 * if not already enabled
532 * screen turned on and current app does not have sensor orientation, disable listeners if
533 * already enabled
534 * screen turning on and current app has sensor based orientation, enable listeners if needed
535 * screen turning on and current app has nosensor based orientation, do nothing
536 */
The Android Open Source Project0727d222009-03-11 12:11:58 -0700537 void updateOrientationListenerLp() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800538 if (!mOrientationListener.canDetectOrientation()) {
539 // If sensor is turned off or nonexistent for some reason
540 return;
541 }
542 //Could have been invoked due to screen turning on or off or
543 //change of the currently visible window's orientation
Dianne Hackborn05726582009-09-22 17:28:24 -0700544 if (localLOGV) Log.v(TAG, "Screen status="+mScreenOn+
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800545 ", current orientation="+mCurrentAppOrientation+
546 ", SensorEnabled="+mOrientationSensorEnabled);
547 boolean disable = true;
The Android Open Source Project0727d222009-03-11 12:11:58 -0700548 if (mScreenOn) {
549 if (needSensorRunningLp()) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800550 disable = false;
551 //enable listener if not already enabled
The Android Open Source Project0727d222009-03-11 12:11:58 -0700552 if (!mOrientationSensorEnabled) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800553 mOrientationListener.enable();
Dianne Hackborn05726582009-09-22 17:28:24 -0700554 if(localLOGV) Log.v(TAG, "Enabling listeners");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800555 mOrientationSensorEnabled = true;
556 }
557 }
558 }
559 //check if sensors need to be disabled
The Android Open Source Project0727d222009-03-11 12:11:58 -0700560 if (disable && mOrientationSensorEnabled) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800561 mOrientationListener.disable();
Dianne Hackborn05726582009-09-22 17:28:24 -0700562 if(localLOGV) Log.v(TAG, "Disabling listeners");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800563 mOrientationSensorEnabled = false;
564 }
565 }
566
Jeff Brown4d396052010-10-29 21:50:21 -0700567 private void interceptPowerKeyDown(boolean handled) {
568 mPowerKeyHandled = handled;
569 if (!handled) {
570 mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
571 }
572 }
573
574 private boolean interceptPowerKeyUp(boolean canceled) {
575 if (!mPowerKeyHandled) {
576 mHandler.removeCallbacks(mPowerLongPress);
577 return !canceled;
578 } else {
579 mPowerKeyHandled = true;
580 return false;
581 }
582 }
583
584 private final Runnable mPowerLongPress = new Runnable() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800585 public void run() {
Jeff Brown4d396052010-10-29 21:50:21 -0700586 if (!mPowerKeyHandled) {
587 // The context isn't read
588 if (mLongPressOnPowerBehavior < 0) {
589 mLongPressOnPowerBehavior = mContext.getResources().getInteger(
590 com.android.internal.R.integer.config_longPressOnPowerBehavior);
591 }
592 switch (mLongPressOnPowerBehavior) {
593 case LONG_PRESS_POWER_NOTHING:
594 break;
595 case LONG_PRESS_POWER_GLOBAL_ACTIONS:
596 mPowerKeyHandled = true;
597 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
598 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
599 showGlobalActionsDialog();
600 break;
601 case LONG_PRESS_POWER_SHUT_OFF:
602 mPowerKeyHandled = true;
603 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
604 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
605 ShutdownThread.shutdown(mContext, true);
606 break;
607 }
Joe Onoratod208e702010-10-08 16:22:43 -0400608 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800609 }
610 };
611
612 void showGlobalActionsDialog() {
613 if (mGlobalActions == null) {
614 mGlobalActions = new GlobalActions(mContext);
615 }
Dianne Hackborn9dc06cc2009-11-17 18:19:23 -0800616 final boolean keyguardShowing = mKeyguardMediator.isShowingAndNotHidden();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800617 mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
618 if (keyguardShowing) {
619 // since it took two seconds of long press to bring this up,
620 // poke the wake lock so they have some time to see the dialog.
621 mKeyguardMediator.pokeWakelock();
622 }
623 }
624
625 boolean isDeviceProvisioned() {
626 return Settings.Secure.getInt(
627 mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
628 }
629
630 /**
631 * When a home-key longpress expires, close other system windows and launch the recent apps
632 */
633 Runnable mHomeLongPress = new Runnable() {
634 public void run() {
Patrick Dubroyece94522011-02-23 18:35:01 -0800635 handleLongPressOnHome();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800636 }
637 };
638
Patrick Dubroyece94522011-02-23 18:35:01 -0800639 private void handleLongPressOnHome() {
Jim Milleree969aa2010-08-26 20:17:43 -0700640 // We can't initialize this in init() since the configuration hasn't been loaded yet.
Joe Onorato46b0d682010-11-22 17:37:27 -0800641 if (mLongPressOnHomeBehavior < 0) {
642 mLongPressOnHomeBehavior
Joe Onorato50262e52010-11-26 14:04:54 -0800643 = mContext.getResources().getInteger(R.integer.config_longPressOnHomeBehavior);
Joe Onorato46b0d682010-11-22 17:37:27 -0800644 if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
Michael Jurka3b1fc472011-06-13 10:54:40 -0700645 mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
Joe Onorato46b0d682010-11-22 17:37:27 -0800646 mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
647 }
648 }
649
650 if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
651 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
652 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
Patrick Dubroyece94522011-02-23 18:35:01 -0800653
654 // Eat the longpress so it won't dismiss the recent apps dialog when
655 // the user lets go of the home key
656 mHomePressed = false;
Jim Milleree969aa2010-08-26 20:17:43 -0700657 }
Patrick Dubroyece94522011-02-23 18:35:01 -0800658
Joe Onorato46b0d682010-11-22 17:37:27 -0800659 if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
Jeff Brown54875002011-04-06 15:33:01 -0700660 showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
Michael Jurka3b1fc472011-06-13 10:54:40 -0700661 } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
Jim Millere6ad1a82010-08-20 19:25:39 -0700662 try {
Michael Jurka3b1fc472011-06-13 10:54:40 -0700663 mStatusBarService.toggleRecentApps();
664 } catch (RemoteException e) {
665 Slog.e(TAG, "RemoteException when showing recent apps", e);
Jim Millere6ad1a82010-08-20 19:25:39 -0700666 }
667 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800668 }
Patrick Dubroyece94522011-02-23 18:35:01 -0800669
670 /**
Jeff Brown54875002011-04-06 15:33:01 -0700671 * Create (if necessary) and launch the recent apps dialog, or hide it if it is
672 * already shown.
Patrick Dubroyece94522011-02-23 18:35:01 -0800673 */
Jeff Brown54875002011-04-06 15:33:01 -0700674 void showOrHideRecentAppsDialog(final int heldModifiers, final boolean dismissIfShown) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700675 mHandler.post(new Runnable() {
676 @Override
677 public void run() {
678 if (mRecentAppsDialog == null) {
Jeff Brown54875002011-04-06 15:33:01 -0700679 mRecentAppsDialog = new RecentApplicationsDialog(mContext);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700680 }
Jeff Brown54875002011-04-06 15:33:01 -0700681 if (mRecentAppsDialog.isShowing()) {
682 if (dismissIfShown) {
683 mRecentAppsDialog.dismiss();
684 }
685 } else {
686 mRecentAppsDialog.setHeldModifiers(heldModifiers);
687 mRecentAppsDialog.show();
688 }
Jeff Brownda3d5a92011-03-29 15:11:34 -0700689 }
690 });
Patrick Dubroyece94522011-02-23 18:35:01 -0800691 }
Jeff Brownda3d5a92011-03-29 15:11:34 -0700692
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800693 /** {@inheritDoc} */
694 public void init(Context context, IWindowManager windowManager,
695 LocalPowerManager powerManager) {
696 mContext = context;
697 mWindowManager = windowManager;
698 mPowerManager = powerManager;
699 mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
700 mHandler = new Handler();
701 mOrientationListener = new MyOrientationListener(mContext);
702 SettingsObserver settingsObserver = new SettingsObserver(mHandler);
703 settingsObserver.observe();
704 mShortcutManager = new ShortcutManager(context, mHandler);
705 mShortcutManager.observe();
706 mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
707 mHomeIntent.addCategory(Intent.CATEGORY_HOME);
708 mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
709 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Dianne Hackborn39c2d712009-09-22 11:41:31 -0700710 mCarDockIntent = new Intent(Intent.ACTION_MAIN, null);
711 mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
712 mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
713 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
714 mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null);
715 mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK);
716 mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
717 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
Jim Millere6ad1a82010-08-20 19:25:39 -0700718
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800719 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
720 mBroadcastWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
721 "PhoneWindowManager.mBroadcastWakeLock");
722 mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
Dianne Hackborn2862fff2009-09-15 22:56:29 -0700723 mLidOpenRotation = readRotation(
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400724 com.android.internal.R.integer.config_lidOpenRotation);
725 mCarDockRotation = readRotation(
726 com.android.internal.R.integer.config_carDockRotation);
727 mDeskDockRotation = readRotation(
728 com.android.internal.R.integer.config_deskDockRotation);
Dianne Hackborna1111872010-11-23 20:55:11 -0800729 mAllowAllRotations = mContext.getResources().getBoolean(
730 com.android.internal.R.bool.config_allowAllRotations);
Mike Lockwoode9867d22009-09-20 01:59:02 -0400731 mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
732 com.android.internal.R.bool.config_carDockEnablesAccelerometer);
733 mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
734 com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
Dianne Hackborn2862fff2009-09-15 22:56:29 -0700735 mLidKeyboardAccessibility = mContext.getResources().getInteger(
736 com.android.internal.R.integer.config_lidKeyboardAccessibility);
737 mLidNavigationAccessibility = mContext.getResources().getInteger(
738 com.android.internal.R.integer.config_lidNavigationAccessibility);
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700739 // register for dock events
Dianne Hackborn78968392010-03-04 20:47:56 -0800740 IntentFilter filter = new IntentFilter();
741 filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
742 filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
743 filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE);
744 filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE);
Dianne Hackborn867ab6472010-04-29 13:28:56 -0700745 filter.addAction(Intent.ACTION_DOCK_EVENT);
746 Intent intent = context.registerReceiver(mDockReceiver, filter);
747 if (intent != null) {
748 // Retrieve current sticky dock event broadcast.
749 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
750 Intent.EXTRA_DOCK_STATE_UNDOCKED);
751 }
Dianne Hackbornb1a79802009-09-29 15:18:31 -0700752 mVibrator = new Vibrator();
753 mLongPressVibePattern = getLongIntArray(mContext.getResources(),
754 com.android.internal.R.array.config_longPressVibePattern);
755 mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(),
756 com.android.internal.R.array.config_virtualKeyVibePattern);
Amith Yamasanic33cb712010-02-10 15:21:49 -0800757 mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(),
758 com.android.internal.R.array.config_keyboardTapVibePattern);
Dianne Hackbornb1a79802009-09-29 15:18:31 -0700759 mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
760 com.android.internal.R.array.config_safeModeDisabledVibePattern);
761 mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
762 com.android.internal.R.array.config_safeModeEnabledVibePattern);
Daniel Sandler40427442010-07-16 11:44:52 -0400763
Joe Onoratoea495d42011-04-06 11:41:11 -0700764 // Controls rotation and the like.
765 initializeHdmiState();
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700766 }
767
Dianne Hackborn9d132642011-04-21 17:26:39 -0700768 public void setInitialDisplaySize(int width, int height) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700769 int shortSize;
Dianne Hackborn9d132642011-04-21 17:26:39 -0700770 if (width > height) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700771 shortSize = height;
Dianne Hackborn9d132642011-04-21 17:26:39 -0700772 mLandscapeRotation = Surface.ROTATION_0;
773 mSeascapeRotation = Surface.ROTATION_180;
774 if (mContext.getResources().getBoolean(
775 com.android.internal.R.bool.config_reverseDefaultRotation)) {
776 mPortraitRotation = Surface.ROTATION_90;
777 mUpsideDownRotation = Surface.ROTATION_270;
778 } else {
779 mPortraitRotation = Surface.ROTATION_270;
780 mUpsideDownRotation = Surface.ROTATION_90;
781 }
782 } else {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700783 shortSize = width;
Dianne Hackborn9d132642011-04-21 17:26:39 -0700784 mPortraitRotation = Surface.ROTATION_0;
785 mUpsideDownRotation = Surface.ROTATION_180;
786 if (mContext.getResources().getBoolean(
787 com.android.internal.R.bool.config_reverseDefaultRotation)) {
788 mLandscapeRotation = Surface.ROTATION_270;
789 mSeascapeRotation = Surface.ROTATION_90;
790 } else {
791 mLandscapeRotation = Surface.ROTATION_90;
792 mSeascapeRotation = Surface.ROTATION_270;
793 }
794 }
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700795
796 // Determine whether the status bar can hide based on the size
797 // of the screen. We assume sizes > 600dp are tablets where we
798 // will use the system bar.
Daniel Sandler631cb3d52011-06-03 01:25:43 -0400799 int shortSizeDp = shortSize
800 * DisplayMetrics.DENSITY_DEFAULT
801 / DisplayMetrics.DENSITY_DEVICE;
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700802 mStatusBarCanHide = shortSizeDp < 600;
803 mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
804 mStatusBarCanHide
805 ? com.android.internal.R.dimen.status_bar_height
806 : com.android.internal.R.dimen.system_bar_height);
Daniel Sandler36412a72011-08-04 09:35:13 -0400807
808 mHasNavigationBar = mContext.getResources().getBoolean(
809 com.android.internal.R.bool.config_showNavigationBar);
810 mNavigationBarHeight = mHasNavigationBar
811 ? mContext.getResources().getDimensionPixelSize(
812 com.android.internal.R.dimen.navigation_bar_height)
813 : 0;
814 mNavigationBarWidth = mHasNavigationBar
815 ? mContext.getResources().getDimensionPixelSize(
816 com.android.internal.R.dimen.navigation_bar_width)
817 : 0;
Dianne Hackborn9d132642011-04-21 17:26:39 -0700818 }
819
Dianne Hackbornc777e072010-02-12 13:07:59 -0800820 public void updateSettings() {
821 ContentResolver resolver = mContext.getContentResolver();
822 boolean updateRotation = false;
823 View addView = null;
824 View removeView = null;
825 synchronized (mLock) {
826 mEndcallBehavior = Settings.System.getInt(resolver,
David Brownbaf8d092010-03-08 21:52:59 -0800827 Settings.System.END_BUTTON_BEHAVIOR,
828 Settings.System.END_BUTTON_BEHAVIOR_DEFAULT);
829 mIncallPowerBehavior = Settings.Secure.getInt(resolver,
830 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
831 Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
Dianne Hackbornc777e072010-02-12 13:07:59 -0800832 mFancyRotationAnimation = Settings.System.getInt(resolver,
833 "fancy_rotation_anim", 0) != 0 ? 0x80 : 0;
834 int accelerometerDefault = Settings.System.getInt(resolver,
835 Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION);
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400836
837 // set up rotation lock state
Daniel Sandler1b815d62010-11-05 10:24:27 -0400838 mUserRotationMode = (accelerometerDefault == 0)
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400839 ? WindowManagerPolicy.USER_ROTATION_LOCKED
840 : WindowManagerPolicy.USER_ROTATION_FREE;
841 mUserRotation = Settings.System.getInt(resolver,
842 Settings.System.USER_ROTATION,
843 Surface.ROTATION_0);
844
Dianne Hackbornc777e072010-02-12 13:07:59 -0800845 if (mAccelerometerDefault != accelerometerDefault) {
846 mAccelerometerDefault = accelerometerDefault;
847 updateOrientationListenerLp();
848 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -0400849
Jeff Brown4519f072011-01-23 13:16:01 -0800850 mOrientationListener.setLogEnabled(
851 Settings.System.getInt(resolver,
852 Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, 0) != 0);
853
Dianne Hackbornc777e072010-02-12 13:07:59 -0800854 if (mSystemReady) {
855 int pointerLocation = Settings.System.getInt(resolver,
856 Settings.System.POINTER_LOCATION, 0);
857 if (mPointerLocationMode != pointerLocation) {
858 mPointerLocationMode = pointerLocation;
859 if (pointerLocation != 0) {
860 if (mPointerLocationView == null) {
861 mPointerLocationView = new PointerLocationView(mContext);
862 mPointerLocationView.setPrintCoords(false);
863 addView = mPointerLocationView;
864 }
865 } else {
866 removeView = mPointerLocationView;
867 mPointerLocationView = null;
868 }
869 }
870 }
871 // use screen off timeout setting as the timeout for the lockscreen
872 mLockScreenTimeout = Settings.System.getInt(resolver,
873 Settings.System.SCREEN_OFF_TIMEOUT, 0);
874 String imId = Settings.Secure.getString(resolver,
875 Settings.Secure.DEFAULT_INPUT_METHOD);
876 boolean hasSoftInput = imId != null && imId.length() > 0;
877 if (mHasSoftInput != hasSoftInput) {
878 mHasSoftInput = hasSoftInput;
879 updateRotation = true;
880 }
Daniel Sandler0601eb72011-04-13 01:01:32 -0400881
882 mScreenSaverTimeout = Settings.System.getInt(resolver,
883 Settings.Secure.DREAM_TIMEOUT, 0);
884 mScreenSaverEnabled = true;
885 updateScreenSaverTimeoutLocked();
Dianne Hackbornc777e072010-02-12 13:07:59 -0800886 }
887 if (updateRotation) {
888 updateRotation(0);
889 }
890 if (addView != null) {
891 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
892 WindowManager.LayoutParams.MATCH_PARENT,
893 WindowManager.LayoutParams.MATCH_PARENT);
Jeff Brown3b2b3542010-10-15 00:54:27 -0700894 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
Dianne Hackbornc777e072010-02-12 13:07:59 -0800895 lp.flags =
896 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
897 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
898 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
899 lp.format = PixelFormat.TRANSLUCENT;
900 lp.setTitle("PointerLocation");
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700901 WindowManager wm = (WindowManager)
Dianne Hackbornc777e072010-02-12 13:07:59 -0800902 mContext.getSystemService(Context.WINDOW_SERVICE);
903 wm.addView(addView, lp);
Jeff Browna41ca772010-08-11 14:46:32 -0700904
905 if (mPointerLocationInputChannel == null) {
906 try {
907 mPointerLocationInputChannel =
908 mWindowManager.monitorInput("PointerLocationView");
909 InputQueue.registerInputChannel(mPointerLocationInputChannel,
910 mPointerLocationInputHandler, mHandler.getLooper().getQueue());
911 } catch (RemoteException ex) {
912 Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
913 ex);
914 }
915 }
Dianne Hackbornc777e072010-02-12 13:07:59 -0800916 }
917 if (removeView != null) {
Jeff Browna41ca772010-08-11 14:46:32 -0700918 if (mPointerLocationInputChannel != null) {
919 InputQueue.unregisterInputChannel(mPointerLocationInputChannel);
920 mPointerLocationInputChannel.dispose();
921 mPointerLocationInputChannel = null;
922 }
923
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700924 WindowManager wm = (WindowManager)
Dianne Hackbornc777e072010-02-12 13:07:59 -0800925 mContext.getSystemService(Context.WINDOW_SERVICE);
926 wm.removeView(removeView);
927 }
928 }
929
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400930 private int readRotation(int resID) {
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700931 try {
932 int rotation = mContext.getResources().getInteger(resID);
933 switch (rotation) {
934 case 0:
935 return Surface.ROTATION_0;
936 case 90:
937 return Surface.ROTATION_90;
938 case 180:
939 return Surface.ROTATION_180;
940 case 270:
941 return Surface.ROTATION_270;
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700942 }
943 } catch (Resources.NotFoundException e) {
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400944 // fall through
Mike Lockwood1753f7f2009-08-24 14:49:07 -0700945 }
Mike Lockwood2d1efbd2009-09-16 12:15:53 -0400946 return -1;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800947 }
948
949 /** {@inheritDoc} */
950 public int checkAddPermission(WindowManager.LayoutParams attrs) {
951 int type = attrs.type;
Mitsuru Oshima831d0d92009-06-16 18:27:18 -0700952
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800953 if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
954 || type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
955 return WindowManagerImpl.ADD_OKAY;
956 }
957 String permission = null;
958 switch (type) {
959 case TYPE_TOAST:
960 // XXX right now the app process has complete control over
961 // this... should introduce a token to let the system
962 // monitor/control what they are doing.
963 break;
964 case TYPE_INPUT_METHOD:
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -0700965 case TYPE_WALLPAPER:
966 // The window manager will check these.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800967 break;
968 case TYPE_PHONE:
969 case TYPE_PRIORITY_PHONE:
970 case TYPE_SYSTEM_ALERT:
971 case TYPE_SYSTEM_ERROR:
972 case TYPE_SYSTEM_OVERLAY:
973 permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW;
974 break;
975 default:
976 permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
977 }
978 if (permission != null) {
979 if (mContext.checkCallingOrSelfPermission(permission)
980 != PackageManager.PERMISSION_GRANTED) {
981 return WindowManagerImpl.ADD_PERMISSION_DENIED;
982 }
983 }
984 return WindowManagerImpl.ADD_OKAY;
985 }
986
987 public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) {
988 switch (attrs.type) {
989 case TYPE_SYSTEM_OVERLAY:
Jeff Brown3b2b3542010-10-15 00:54:27 -0700990 case TYPE_SECURE_SYSTEM_OVERLAY:
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800991 case TYPE_TOAST:
992 // These types of windows can't receive input events.
993 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
994 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
995 break;
996 }
997 }
998
999 void readLidState() {
1000 try {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001001 int sw = mWindowManager.getSwitchState(SW_LID);
Jeff Brown4aed78b2011-01-14 17:36:55 -08001002 if (sw > 0) {
1003 mLidOpen = LID_OPEN;
1004 } else if (sw == 0) {
1005 mLidOpen = LID_CLOSED;
1006 } else {
1007 mLidOpen = LID_ABSENT;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001008 }
1009 } catch (RemoteException e) {
1010 // Ignore
1011 }
1012 }
1013
Jeff Brown4aed78b2011-01-14 17:36:55 -08001014 private int determineHiddenState(int mode, int hiddenValue, int visibleValue) {
Jeff Brownd04a88c2011-01-16 14:05:47 -08001015 if (mLidOpen != LID_ABSENT) {
1016 switch (mode) {
1017 case 1:
1018 return mLidOpen == LID_OPEN ? visibleValue : hiddenValue;
1019 case 2:
1020 return mLidOpen == LID_OPEN ? hiddenValue : visibleValue;
1021 }
Dianne Hackborn2862fff2009-09-15 22:56:29 -07001022 }
1023 return visibleValue;
1024 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08001025
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001026 /** {@inheritDoc} */
1027 public void adjustConfigurationLw(Configuration config) {
1028 readLidState();
Jeff Brownd04a88c2011-01-16 14:05:47 -08001029
Jeff Brown4aed78b2011-01-14 17:36:55 -08001030 mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN);
Jeff Brownd04a88c2011-01-16 14:05:47 -08001031
1032 if (config.keyboard == Configuration.KEYBOARD_NOKEYS) {
1033 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
1034 } else {
1035 config.hardKeyboardHidden = determineHiddenState(mLidKeyboardAccessibility,
1036 Configuration.HARDKEYBOARDHIDDEN_YES, Configuration.HARDKEYBOARDHIDDEN_NO);
1037 }
1038
1039 if (config.navigation == Configuration.NAVIGATION_NONAV) {
1040 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES;
1041 } else {
1042 config.navigationHidden = determineHiddenState(mLidNavigationAccessibility,
1043 Configuration.NAVIGATIONHIDDEN_YES, Configuration.NAVIGATIONHIDDEN_NO);
1044 }
1045
1046 if (mHasSoftInput || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
1047 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
1048 } else {
1049 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
1050 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001051 }
Jeff Brownd04a88c2011-01-16 14:05:47 -08001052
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001053 /** {@inheritDoc} */
1054 public int windowTypeToLayerLw(int type) {
1055 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
1056 return APPLICATION_LAYER;
1057 }
1058 switch (type) {
1059 case TYPE_STATUS_BAR:
1060 return STATUS_BAR_LAYER;
1061 case TYPE_STATUS_BAR_PANEL:
1062 return STATUS_BAR_PANEL_LAYER;
Joe Onorato29fc2c92010-11-24 10:26:50 -08001063 case TYPE_STATUS_BAR_SUB_PANEL:
1064 return STATUS_BAR_SUB_PANEL_LAYER;
Dianne Hackborn6a294ce2009-12-03 11:37:44 -08001065 case TYPE_SYSTEM_DIALOG:
1066 return SYSTEM_DIALOG_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001067 case TYPE_SEARCH_BAR:
1068 return SEARCH_BAR_LAYER;
1069 case TYPE_PHONE:
1070 return PHONE_LAYER;
1071 case TYPE_KEYGUARD:
1072 return KEYGUARD_LAYER;
1073 case TYPE_KEYGUARD_DIALOG:
1074 return KEYGUARD_DIALOG_LAYER;
1075 case TYPE_SYSTEM_ALERT:
1076 return SYSTEM_ALERT_LAYER;
1077 case TYPE_SYSTEM_ERROR:
1078 return SYSTEM_ERROR_LAYER;
1079 case TYPE_INPUT_METHOD:
1080 return INPUT_METHOD_LAYER;
1081 case TYPE_INPUT_METHOD_DIALOG:
1082 return INPUT_METHOD_DIALOG_LAYER;
Dianne Hackborne8ecde12011-08-03 18:55:19 -07001083 case TYPE_VOLUME_OVERLAY:
1084 return VOLUME_OVERLAY_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001085 case TYPE_SYSTEM_OVERLAY:
1086 return SYSTEM_OVERLAY_LAYER;
Jeff Brown3b2b3542010-10-15 00:54:27 -07001087 case TYPE_SECURE_SYSTEM_OVERLAY:
1088 return SECURE_SYSTEM_OVERLAY_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001089 case TYPE_PRIORITY_PHONE:
1090 return PRIORITY_PHONE_LAYER;
1091 case TYPE_TOAST:
1092 return TOAST_LAYER;
Dianne Hackbornb7cd8b92009-08-08 20:53:03 -07001093 case TYPE_WALLPAPER:
1094 return WALLPAPER_LAYER;
Christopher Tatea53146c2010-09-07 11:57:52 -07001095 case TYPE_DRAG:
1096 return DRAG_LAYER;
Jeff Brown83c09682010-12-23 17:50:18 -08001097 case TYPE_POINTER:
1098 return POINTER_LAYER;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001099 case TYPE_NAVIGATION_BAR:
1100 return NAVIGATION_BAR_LAYER;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07001101 case TYPE_BOOT_PROGRESS:
1102 return BOOT_PROGRESS_LAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001103 }
1104 Log.e(TAG, "Unknown window type: " + type);
1105 return APPLICATION_LAYER;
1106 }
1107
1108 /** {@inheritDoc} */
1109 public int subWindowTypeToLayerLw(int type) {
1110 switch (type) {
1111 case TYPE_APPLICATION_PANEL:
1112 case TYPE_APPLICATION_ATTACHED_DIALOG:
1113 return APPLICATION_PANEL_SUBLAYER;
1114 case TYPE_APPLICATION_MEDIA:
1115 return APPLICATION_MEDIA_SUBLAYER;
Dianne Hackborn5cb8d792009-05-21 17:34:15 -07001116 case TYPE_APPLICATION_MEDIA_OVERLAY:
1117 return APPLICATION_MEDIA_OVERLAY_SUBLAYER;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001118 case TYPE_APPLICATION_SUB_PANEL:
1119 return APPLICATION_SUB_PANEL_SUBLAYER;
1120 }
1121 Log.e(TAG, "Unknown sub-window type: " + type);
1122 return 0;
1123 }
1124
Dianne Hackbornabe0da02009-09-18 01:55:39 -07001125 public int getMaxWallpaperLayer() {
1126 return STATUS_BAR_LAYER;
1127 }
1128
Dianne Hackborn81e56d52011-05-26 00:55:58 -07001129 public boolean canStatusBarHide() {
1130 return mStatusBarCanHide;
1131 }
1132
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001133 public int getNonDecorDisplayWidth(int rotation, int fullWidth) {
Daniel Sandler36412a72011-08-04 09:35:13 -04001134 // Assumes that the navigation bar appears on the side of the display in landscape.
1135 final boolean horizontal
1136 = (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90);
1137 return fullWidth - (horizontal ? mNavigationBarWidth : 0);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001138 }
1139
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001140 public int getNonDecorDisplayHeight(int rotation, int fullHeight) {
Daniel Sandler36412a72011-08-04 09:35:13 -04001141 final boolean horizontal
1142 = (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90);
1143 return fullHeight
1144 - (mStatusBarCanHide ? 0 : mStatusBarHeight)
1145 - (horizontal ? 0 : mNavigationBarHeight);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001146 }
1147
1148 public int getConfigDisplayWidth(int rotation, int fullWidth) {
Daniel Sandler36412a72011-08-04 09:35:13 -04001149 return getNonDecorDisplayWidth(rotation, fullWidth);
Dianne Hackborn69cb8752011-05-19 18:13:32 -07001150 }
1151
1152 public int getConfigDisplayHeight(int rotation, int fullHeight) {
Daniel Sandler36412a72011-08-04 09:35:13 -04001153 return getNonDecorDisplayHeight(rotation, fullHeight);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001154 }
1155
Dianne Hackborn01ad2f42009-09-24 19:24:56 -07001156 public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
1157 return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD;
1158 }
1159
1160 public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
1161 return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
1162 && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER;
1163 }
1164
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001165 /** {@inheritDoc} */
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001166 public View addStartingWindow(IBinder appToken, String packageName, int theme,
1167 CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
1168 int icon, int windowFlags) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001169 if (!SHOW_STARTING_ANIMATIONS) {
1170 return null;
1171 }
1172 if (packageName == null) {
1173 return null;
1174 }
1175
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001176 try {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001177 Context context = mContext;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001178 //Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel="
1179 // + nonLocalizedLabel + " theme=" + Integer.toHexString(theme));
Dianne Hackborn247fe742011-01-08 17:25:57 -08001180 if (theme != context.getThemeResId() || labelRes != 0) {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001181 try {
1182 context = context.createPackageContext(packageName, 0);
Dianne Hackborn247fe742011-01-08 17:25:57 -08001183 context.setTheme(theme);
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001184 } catch (PackageManager.NameNotFoundException e) {
1185 // Ignore
1186 }
1187 }
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001188
1189 Window win = PolicyManager.makeNewWindow(context);
1190 if (win.getWindowStyle().getBoolean(
1191 com.android.internal.R.styleable.Window_windowDisablePreview, false)) {
1192 return null;
1193 }
1194
1195 Resources r = context.getResources();
1196 win.setTitle(r.getText(labelRes, nonLocalizedLabel));
1197
1198 win.setType(
1199 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
1200 // Force the window flags: this is a fake window, so it is not really
1201 // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM
1202 // flag because we do know that the next window will take input
1203 // focus, so we want to get the IME window up on top of us right away.
1204 win.setFlags(
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08001205 windowFlags|
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001206 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
1207 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
1208 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08001209 windowFlags|
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001210 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
1211 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
1212 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
1213
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001214 if (!compatInfo.supportsScreen()) {
1215 win.addFlags(WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW);
1216 }
1217
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001218 win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001219 WindowManager.LayoutParams.MATCH_PARENT);
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001220
1221 final WindowManager.LayoutParams params = win.getAttributes();
1222 params.token = appToken;
1223 params.packageName = packageName;
1224 params.windowAnimations = win.getWindowStyle().getResourceId(
1225 com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
1226 params.setTitle("Starting " + packageName);
1227
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001228 WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001229 View view = win.getDecorView();
1230
1231 if (win.isFloating()) {
1232 // Whoops, there is no way to display an animation/preview
1233 // of such a thing! After all that work... let's skip it.
1234 // (Note that we must do this here because it is in
1235 // getDecorView() where the theme is evaluated... maybe
1236 // we should peek the floating attribute from the theme
1237 // earlier.)
1238 return null;
1239 }
1240
1241 if (localLOGV) Log.v(
1242 TAG, "Adding starting window for " + packageName
1243 + " / " + appToken + ": "
1244 + (view.getParent() != null ? view : null));
1245
1246 wm.addView(view, params);
1247
1248 // Only return the view if it was successfully added to the
1249 // window manager... which we can tell by it having a parent.
1250 return view.getParent() != null ? view : null;
1251 } catch (WindowManagerImpl.BadTokenException e) {
1252 // ignore
1253 Log.w(TAG, appToken + " already running, starting window not displayed");
Dianne Hackborn867ab6472010-04-29 13:28:56 -07001254 } catch (RuntimeException e) {
1255 // don't crash if something else bad happens, for example a
1256 // failure loading resources because we are loading from an app
1257 // on external storage that has been unmounted.
1258 Log.w(TAG, appToken + " failed creating starting window", e);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001259 }
1260
1261 return null;
1262 }
1263
1264 /** {@inheritDoc} */
1265 public void removeStartingWindow(IBinder appToken, View window) {
1266 // RuntimeException e = new RuntimeException();
1267 // Log.i(TAG, "remove " + appToken + " " + window, e);
1268
1269 if (localLOGV) Log.v(
1270 TAG, "Removing starting window for " + appToken + ": " + window);
1271
1272 if (window != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001273 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001274 wm.removeView(window);
1275 }
1276 }
1277
1278 /**
1279 * Preflight adding a window to the system.
1280 *
1281 * Currently enforces that three window types are singletons:
1282 * <ul>
1283 * <li>STATUS_BAR_TYPE</li>
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001284 * <li>KEYGUARD_TYPE</li>
1285 * </ul>
1286 *
1287 * @param win The window to be added
1288 * @param attrs Information about the window to be added
1289 *
1290 * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons, WindowManagerImpl.ADD_MULTIPLE_SINGLETON
1291 */
1292 public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
1293 switch (attrs.type) {
1294 case TYPE_STATUS_BAR:
Joe Onorato8bc6c512010-06-04 16:21:12 -04001295 mContext.enforceCallingOrSelfPermission(
1296 android.Manifest.permission.STATUS_BAR_SERVICE,
1297 "PhoneWindowManager");
1298 // TODO: Need to handle the race condition of the status bar proc
1299 // dying and coming back before the removeWindowLw cleanup has happened.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001300 if (mStatusBar != null) {
1301 return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
1302 }
1303 mStatusBar = win;
1304 break;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001305 case TYPE_NAVIGATION_BAR:
1306 mContext.enforceCallingOrSelfPermission(
1307 android.Manifest.permission.STATUS_BAR_SERVICE,
1308 "PhoneWindowManager");
1309 mNavigationBar = win;
1310 if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
1311 break;
Dianne Hackborn08743722009-12-21 12:16:51 -08001312 case TYPE_STATUS_BAR_PANEL:
Joe Onorato8bc6c512010-06-04 16:21:12 -04001313 mContext.enforceCallingOrSelfPermission(
1314 android.Manifest.permission.STATUS_BAR_SERVICE,
1315 "PhoneWindowManager");
Dianne Hackborn08743722009-12-21 12:16:51 -08001316 mStatusBarPanels.add(win);
1317 break;
Joe Onorato29fc2c92010-11-24 10:26:50 -08001318 case TYPE_STATUS_BAR_SUB_PANEL:
1319 mContext.enforceCallingOrSelfPermission(
1320 android.Manifest.permission.STATUS_BAR_SERVICE,
1321 "PhoneWindowManager");
1322 mStatusBarPanels.add(win);
1323 break;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001324 case TYPE_KEYGUARD:
1325 if (mKeyguard != null) {
1326 return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
1327 }
1328 mKeyguard = win;
1329 break;
1330 }
1331 return WindowManagerImpl.ADD_OKAY;
1332 }
1333
1334 /** {@inheritDoc} */
1335 public void removeWindowLw(WindowState win) {
1336 if (mStatusBar == win) {
1337 mStatusBar = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001338 } else if (mKeyguard == win) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001339 mKeyguard = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001340 } else if (mNavigationBar == win) {
1341 mNavigationBar = null;
Dianne Hackborn08743722009-12-21 12:16:51 -08001342 } else {
1343 mStatusBarPanels.remove(win);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001344 }
1345 }
1346
1347 static final boolean PRINT_ANIM = false;
1348
1349 /** {@inheritDoc} */
1350 public int selectAnimationLw(WindowState win, int transit) {
1351 if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
1352 + ": transit=" + transit);
1353 if (transit == TRANSIT_PREVIEW_DONE) {
1354 if (win.hasAppShownWindows()) {
1355 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");
1356 return com.android.internal.R.anim.app_starting_exit;
1357 }
1358 }
1359
1360 return 0;
1361 }
1362
Dianne Hackborn01ad2f42009-09-24 19:24:56 -07001363 public Animation createForceHideEnterAnimation() {
1364 return AnimationUtils.loadAnimation(mContext,
1365 com.android.internal.R.anim.lock_screen_behind_enter);
1366 }
1367
Jeff Brown4d396052010-10-29 21:50:21 -07001368 static ITelephony getTelephonyService() {
1369 ITelephony telephonyService = ITelephony.Stub.asInterface(
1370 ServiceManager.checkService(Context.TELEPHONY_SERVICE));
1371 if (telephonyService == null) {
1372 Log.w(TAG, "Unable to find ITelephony interface.");
1373 }
1374 return telephonyService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001375 }
1376
Jeff Brown4d396052010-10-29 21:50:21 -07001377 static IAudioService getAudioService() {
1378 IAudioService audioService = IAudioService.Stub.asInterface(
1379 ServiceManager.checkService(Context.AUDIO_SERVICE));
1380 if (audioService == null) {
1381 Log.w(TAG, "Unable to find IAudioService interface.");
1382 }
1383 return audioService;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001384 }
1385
1386 boolean keyguardOn() {
1387 return keyguardIsShowingTq() || inKeyguardRestrictedKeyInputMode();
1388 }
1389
1390 private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
1391 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
1392 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
1393 };
1394
1395 /** {@inheritDoc} */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001396 @Override
Jeff Brown1f245102010-11-18 20:53:46 -08001397 public boolean interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001398 final boolean keyguardOn = keyguardOn();
Jeff Brown1f245102010-11-18 20:53:46 -08001399 final int keyCode = event.getKeyCode();
1400 final int repeatCount = event.getRepeatCount();
1401 final int metaState = event.getMetaState();
1402 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
1403 final boolean canceled = event.isCanceled();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001404
1405 if (false) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001406 Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001407 + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
1408 }
1409
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001410 // First we always handle the home key here, so applications
1411 // can never break it, although if keyguard is on, we do let
1412 // it handle it, because that gives us the correct 5 second
1413 // timeout.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001414 if (keyCode == KeyEvent.KEYCODE_HOME) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08001415 // Clear a pending HOME longpress if the user releases Home
1416 if (!down) {
1417 mHandler.removeCallbacks(mHomeLongPress);
1418 }
1419
1420 // If we have released the home key, and didn't do anything else
1421 // while it was pressed, then it is time to go home!
1422 if (mHomePressed && !down) {
1423 mHomePressed = false;
1424 if (!canceled) {
1425 // If an incoming call is ringing, HOME is totally disabled.
1426 // (The user is already on the InCallScreen at this point,
1427 // and his ONLY options are to answer or reject the call.)
1428 boolean incomingRinging = false;
1429 try {
1430 ITelephony telephonyService = getTelephonyService();
1431 if (telephonyService != null) {
1432 incomingRinging = telephonyService.isRinging();
1433 }
1434 } catch (RemoteException ex) {
1435 Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
1436 }
1437
1438 if (incomingRinging) {
1439 Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
1440 } else {
1441 launchHomeFromHotKey();
1442 }
1443 } else {
1444 Log.i(TAG, "Ignoring HOME; event canceled.");
1445 }
1446 return true;
1447 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001448
1449 // If a system window has focus, then it doesn't make sense
1450 // right now to interact with applications.
1451 WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
1452 if (attrs != null) {
1453 final int type = attrs.type;
1454 if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
1455 || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
1456 // the "app" is keyguard, so give it the key
1457 return false;
1458 }
1459 final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
1460 for (int i=0; i<typeCount; i++) {
1461 if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
1462 // don't do anything, but also don't pass it to the app
1463 return true;
1464 }
1465 }
1466 }
1467
1468 if (down && repeatCount == 0) {
1469 if (!keyguardOn) {
1470 mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
1471 }
1472 mHomePressed = true;
1473 }
1474 return true;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001475 } else if (keyCode == KeyEvent.KEYCODE_MENU) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001476 // Hijack modified menu keys for debugging features
1477 final int chordBug = KeyEvent.META_SHIFT_ON;
1478
1479 if (down && repeatCount == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001480 if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001481 Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
1482 mContext.sendOrderedBroadcast(intent, null);
1483 return true;
1484 } else if (SHOW_PROCESSES_ON_ALT_MENU &&
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001485 (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001486 Intent service = new Intent();
1487 service.setClassName(mContext, "com.android.server.LoadAverageService");
1488 ContentResolver res = mContext.getContentResolver();
1489 boolean shown = Settings.System.getInt(
1490 res, Settings.System.SHOW_PROCESSES, 0) != 0;
1491 if (!shown) {
1492 mContext.startService(service);
1493 } else {
1494 mContext.stopService(service);
1495 }
1496 Settings.System.putInt(
1497 res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1);
1498 return true;
1499 }
1500 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001501 } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001502 if (down) {
1503 if (repeatCount == 0) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08001504 mShortcutKeyPressed = keyCode;
1505 mConsumeShortcutKeyUp = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001506 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08001507 } else if (keyCode == mShortcutKeyPressed) {
1508 mShortcutKeyPressed = -1;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001509 if (mConsumeShortcutKeyUp) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08001510 mConsumeShortcutKeyUp = false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001511 return true;
1512 }
1513 }
Jeff Browncaab4d02010-12-09 22:13:41 -08001514 return false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001515 } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
Jeff Brownda3d5a92011-03-29 15:11:34 -07001516 if (down && repeatCount == 0) {
Jeff Brown54875002011-04-06 15:33:01 -07001517 showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
Jeff Brown49ed71d2010-12-06 17:13:33 -08001518 }
1519 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001520 }
Jeff Browncaab4d02010-12-09 22:13:41 -08001521
Jeff Brownc1fb48d2010-12-08 16:52:09 -08001522 // Shortcuts are invoked through Search+key, so intercept those here
Jeff Browncaab4d02010-12-09 22:13:41 -08001523 // Any printing key that is chorded with Search should be consumed
1524 // even if no shortcut was invoked. This prevents text from being
1525 // inadvertently inserted when using a keyboard that has built-in macro
1526 // shortcut keys (that emit Search+x) and some of them are not registered.
1527 if (mShortcutKeyPressed != -1) {
1528 final KeyCharacterMap kcm = event.getKeyCharacterMap();
1529 if (kcm.isPrintingKey(keyCode)) {
1530 mConsumeShortcutKeyUp = true;
1531 if (down && repeatCount == 0 && !keyguardOn) {
1532 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode, metaState);
1533 if (shortcutIntent != null) {
1534 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Jeff Brownf0a3cc52011-01-26 18:42:46 -08001535 try {
1536 mContext.startActivity(shortcutIntent);
1537 } catch (ActivityNotFoundException ex) {
1538 Slog.w(TAG, "Dropping shortcut key combination because "
1539 + "the activity to which it is registered was not found: "
1540 + KeyEvent.keyCodeToString(mShortcutKeyPressed)
1541 + "+" + KeyEvent.keyCodeToString(keyCode), ex);
1542 }
Jeff Browncaab4d02010-12-09 22:13:41 -08001543 } else {
1544 Slog.i(TAG, "Dropping unregistered shortcut key combination: "
1545 + KeyEvent.keyCodeToString(mShortcutKeyPressed)
1546 + "+" + KeyEvent.keyCodeToString(keyCode));
Jeff Brown49ed71d2010-12-06 17:13:33 -08001547 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001548 }
Jeff Browncaab4d02010-12-09 22:13:41 -08001549 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001550 }
1551 }
1552
1553 return false;
1554 }
1555
Jeff Brown3915bb82010-11-05 15:02:16 -07001556 /** {@inheritDoc} */
1557 @Override
Jeff Brown49ed71d2010-12-06 17:13:33 -08001558 public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
Jeff Brown54875002011-04-06 15:33:01 -07001559 // Note: This method is only called if the initial down was unhandled.
Jeff Brown49ed71d2010-12-06 17:13:33 -08001560 if (DEBUG_FALLBACK) {
Jeff Brown1f245102010-11-18 20:53:46 -08001561 Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction()
1562 + ", flags=" + event.getFlags()
1563 + ", keyCode=" + event.getKeyCode()
1564 + ", scanCode=" + event.getScanCode()
1565 + ", metaState=" + event.getMetaState()
1566 + ", repeatCount=" + event.getRepeatCount()
1567 + ", policyFlags=" + policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -07001568 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08001569
1570 if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
1571 final KeyCharacterMap kcm = event.getKeyCharacterMap();
Jeff Brownc1fb48d2010-12-08 16:52:09 -08001572 final int keyCode = event.getKeyCode();
1573 final int metaState = event.getMetaState();
Jeff Brown54875002011-04-06 15:33:01 -07001574 final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
1575 && event.getRepeatCount() == 0;
1576
1577 if (initialDown) {
1578 // Invoke shortcuts using Meta as a fallback.
1579 if ((metaState & KeyEvent.META_META_ON) != 0) {
1580 Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
1581 metaState & ~(KeyEvent.META_META_ON
1582 | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
1583 if (shortcutIntent != null) {
1584 shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1585 try {
1586 mContext.startActivity(shortcutIntent);
1587 } catch (ActivityNotFoundException ex) {
1588 Slog.w(TAG, "Dropping shortcut key combination because "
1589 + "the activity to which it is registered was not found: "
1590 + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
1591 }
1592 return null;
Jeff Brownbfaf3b92011-02-22 15:00:50 -08001593 }
Jeff Brown54875002011-04-06 15:33:01 -07001594 }
1595
1596 // Display task switcher for ALT-TAB or Meta-TAB.
1597 if (keyCode == KeyEvent.KEYCODE_TAB) {
1598 final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
1599 if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
1600 || KeyEvent.metaStateHasModifiers(
1601 shiftlessModifiers, KeyEvent.META_META_ON)) {
1602 showOrHideRecentAppsDialog(shiftlessModifiers, false /*dismissIfShown*/);
1603 return null;
1604 }
Jeff Brownc1fb48d2010-12-08 16:52:09 -08001605 }
1606 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08001607
Jeff Brown54875002011-04-06 15:33:01 -07001608 // Check for fallback actions specified by the key character map.
Jeff Brown6f2fba42011-02-19 01:08:02 -08001609 if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08001610 if (DEBUG_FALLBACK) {
1611 Slog.d(TAG, "Fallback: keyCode=" + mFallbackAction.keyCode
1612 + " metaState=" + Integer.toHexString(mFallbackAction.metaState));
1613 }
1614
1615 int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK;
1616 KeyEvent fallbackEvent = KeyEvent.obtain(
1617 event.getDownTime(), event.getEventTime(),
1618 event.getAction(), mFallbackAction.keyCode,
1619 event.getRepeatCount(), mFallbackAction.metaState,
1620 event.getDeviceId(), event.getScanCode(),
1621 flags, event.getSource(), null);
1622 int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true);
1623 if ((actions & ACTION_PASS_TO_USER) != 0) {
1624 if (!interceptKeyBeforeDispatching(win, fallbackEvent, policyFlags)) {
1625 if (DEBUG_FALLBACK) {
1626 Slog.d(TAG, "Performing fallback.");
1627 }
1628 return fallbackEvent;
1629 }
1630 }
1631 fallbackEvent.recycle();
1632 }
1633 }
1634
1635 if (DEBUG_FALLBACK) {
1636 Slog.d(TAG, "No fallback.");
1637 }
1638 return null;
Jeff Brown3915bb82010-11-05 15:02:16 -07001639 }
1640
Jeff Brown6f2fba42011-02-19 01:08:02 -08001641 private boolean getFallbackAction(KeyCharacterMap kcm, int keyCode, int metaState,
1642 FallbackAction outFallbackAction) {
1643 // Consult the key character map for specific fallback actions.
1644 // For example, map NUMPAD_1 to MOVE_HOME when NUMLOCK is not pressed.
Jeff Browncc0c1592011-02-19 05:07:28 -08001645 return kcm.getFallbackAction(keyCode, metaState, outFallbackAction);
Jeff Brown6f2fba42011-02-19 01:08:02 -08001646 }
1647
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001648 /**
1649 * A home key -> launch home action was detected. Take the appropriate action
1650 * given the situation with the keyguard.
1651 */
1652 void launchHomeFromHotKey() {
Dianne Hackborn9dc06cc2009-11-17 18:19:23 -08001653 if (mKeyguardMediator.isShowingAndNotHidden()) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001654 // don't launch home if keyguard showing
Dianne Hackborn39c2d712009-09-22 11:41:31 -07001655 } else if (!mHideLockScreen && mKeyguardMediator.isInputRestricted()) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001656 // when in keyguard restricted mode, must first verify unlock
1657 // before launching home
1658 mKeyguardMediator.verifyUnlock(new OnKeyguardExitResult() {
1659 public void onKeyguardExitResult(boolean success) {
1660 if (success) {
Dianne Hackborn256dd3b2009-05-19 18:51:21 -07001661 try {
1662 ActivityManagerNative.getDefault().stopAppSwitches();
1663 } catch (RemoteException e) {
1664 }
Joe Onoratof275f0c2009-11-24 16:11:13 -05001665 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
Dianne Hackborn39c2d712009-09-22 11:41:31 -07001666 startDockOrHome();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001667 }
1668 }
1669 });
1670 } else {
1671 // no keyguard stuff to worry about, just launch home!
Dianne Hackborn256dd3b2009-05-19 18:51:21 -07001672 try {
1673 ActivityManagerNative.getDefault().stopAppSwitches();
1674 } catch (RemoteException e) {
1675 }
Joe Onoratof275f0c2009-11-24 16:11:13 -05001676 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
Dianne Hackborn39c2d712009-09-22 11:41:31 -07001677 startDockOrHome();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001678 }
1679 }
1680
1681 public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) {
1682 final int fl = attrs.flags;
1683
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001684 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001685 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001686 contentInset.set(mCurLeft, mCurTop,
Joe Onorato29fc2c92010-11-24 10:26:50 -08001687 (mRestrictedScreenLeft+mRestrictedScreenWidth) - mCurRight,
1688 (mRestrictedScreenTop+mRestrictedScreenHeight) - mCurBottom);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001689 } else {
1690 contentInset.setEmpty();
1691 }
1692 }
1693
1694 /** {@inheritDoc} */
1695 public void beginLayoutLw(int displayWidth, int displayHeight) {
Joe Onorato29fc2c92010-11-24 10:26:50 -08001696 mUnrestrictedScreenLeft = mUnrestrictedScreenTop = 0;
1697 mUnrestrictedScreenWidth = displayWidth;
1698 mUnrestrictedScreenHeight = displayHeight;
1699 mRestrictedScreenLeft = mRestrictedScreenTop = 0;
1700 mRestrictedScreenWidth = displayWidth;
1701 mRestrictedScreenHeight = displayHeight;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001702 mDockLeft = mContentLeft = mCurLeft = 0;
1703 mDockTop = mContentTop = mCurTop = 0;
1704 mDockRight = mContentRight = mCurRight = displayWidth;
1705 mDockBottom = mContentBottom = mCurBottom = displayHeight;
1706 mDockLayer = 0x10000000;
1707
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001708 // start with the current dock rect, which will be (0,0,displayWidth,displayHeight)
1709 final Rect pf = mTmpParentFrame;
1710 final Rect df = mTmpDisplayFrame;
1711 final Rect vf = mTmpVisibleFrame;
1712 pf.left = df.left = vf.left = mDockLeft;
1713 pf.top = df.top = vf.top = mDockTop;
1714 pf.right = df.right = vf.right = mDockRight;
1715 pf.bottom = df.bottom = vf.bottom = mDockBottom;
1716
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001717 // decide where the status bar goes ahead of time
1718 if (mStatusBar != null) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001719 Rect navr = null;
1720 if (mNavigationBar != null) {
1721 mNavigationBar.computeFrameLw(pf, df, vf, vf);
1722 if (mNavigationBar.isVisibleLw()) {
1723 navr = mNavigationBar.getFrameLw();
1724
1725 if (navr.top == 0) {
1726 // Navigation bar is vertical
1727 if (mDockLeft == navr.left) {
1728 mDockLeft = navr.right;
1729 } else if (mDockRight == navr.right) {
1730 mDockRight = navr.left;
1731 }
1732 } else {
1733 // Navigation bar horizontal, at bottom
1734 if (mDockBottom == navr.bottom) {
1735 mDockBottom = navr.top;
1736 }
1737 }
1738 }
1739 }
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001740 if (DEBUG_LAYOUT) {
1741 Log.i(TAG, "mNavigationBar frame: " + navr);
1742 Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
1743 mDockLeft, mDockTop, mDockRight, mDockBottom));
1744 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001745
1746 // apply navigation bar insets
1747 pf.left = df.left = vf.left = mDockLeft;
1748 pf.top = df.top = vf.top = mDockTop;
1749 pf.right = df.right = vf.right = mDockRight;
1750 pf.bottom = df.bottom = vf.bottom = mDockBottom;
1751
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001752 mStatusBar.computeFrameLw(pf, df, vf, vf);
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001753
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001754 // now, let's consider the navigation bar; if it exists, it must be removed from the
1755 // available screen real estate (like an un-hideable status bar)
1756 if (navr != null) {
1757 if (navr.top == 0) {
1758 // Navigation bar is vertical
1759 if (mRestrictedScreenLeft == navr.left) {
1760 mRestrictedScreenLeft = navr.right;
1761 mRestrictedScreenWidth -= (navr.right - navr.left);
1762 } else if ((mRestrictedScreenLeft+mRestrictedScreenWidth) == navr.right) {
1763 mRestrictedScreenWidth -= (navr.right - navr.left);
1764 }
1765 } else {
1766 // Navigation bar horizontal, at bottom
1767 if ((mRestrictedScreenHeight+mRestrictedScreenTop) == navr.bottom) {
1768 mRestrictedScreenHeight -= (navr.bottom-navr.top);
1769 }
1770 }
1771 }
1772
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001773 if (mStatusBar.isVisibleLw()) {
1774 // If the status bar is hidden, we don't want to cause
1775 // windows behind it to scroll.
Joe Onorato34bcebc2010-07-07 18:05:01 -04001776 final Rect r = mStatusBar.getFrameLw();
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001777 if (mStatusBarCanHide) {
1778 // Status bar may go away, so the screen area it occupies
1779 // is available to apps but just covering them when the
1780 // status bar is visible.
1781 if (mDockTop == r.top) mDockTop = r.bottom;
1782 else if (mDockBottom == r.bottom) mDockBottom = r.top;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001783
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001784 mContentTop = mCurTop = mDockTop;
1785 mContentBottom = mCurBottom = mDockBottom;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001786 mContentLeft = mCurLeft = mDockLeft;
1787 mContentRight = mCurRight = mDockRight;
1788
1789 if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
1790 String.format(
1791 "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
1792 mDockLeft, mDockTop, mDockRight, mDockBottom,
1793 mContentLeft, mContentTop, mContentRight, mContentBottom,
1794 mCurLeft, mCurTop, mCurRight, mCurBottom));
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001795 } else {
1796 // Status bar can't go away; the part of the screen it
1797 // covers does not exist for anything behind it.
Joe Onorato29fc2c92010-11-24 10:26:50 -08001798 if (mRestrictedScreenTop == r.top) {
1799 mRestrictedScreenTop = r.bottom;
1800 mRestrictedScreenHeight -= (r.bottom-r.top);
1801 } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
1802 mRestrictedScreenHeight -= (r.bottom-r.top);
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001803 }
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001804
Joe Onorato29fc2c92010-11-24 10:26:50 -08001805 mContentTop = mCurTop = mDockTop = mRestrictedScreenTop;
1806 mContentBottom = mCurBottom = mDockBottom
1807 = mRestrictedScreenTop + mRestrictedScreenHeight;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001808 if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: restricted screen area: ("
1809 + mRestrictedScreenLeft + ","
1810 + mRestrictedScreenTop + ","
1811 + (mRestrictedScreenLeft + mRestrictedScreenWidth) + ","
1812 + (mRestrictedScreenTop + mRestrictedScreenHeight) + ")");
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001813 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001814 }
1815 }
1816 }
1817
Dianne Hackborndea3ef72010-10-28 14:24:22 -07001818 void setAttachedWindowFrames(WindowState win, int fl, int adjust,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001819 WindowState attached, boolean insetDecors, Rect pf, Rect df, Rect cf, Rect vf) {
1820 if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) {
1821 // Here's a special case: if this attached window is a panel that is
1822 // above the dock window, and the window it is attached to is below
1823 // the dock window, then the frames we computed for the window it is
1824 // attached to can not be used because the dock is effectively part
1825 // of the underlying window and the attached window is floating on top
1826 // of the whole thing. So, we ignore the attached window and explicitly
1827 // compute the frames that would be appropriate without the dock.
1828 df.left = cf.left = vf.left = mDockLeft;
1829 df.top = cf.top = vf.top = mDockTop;
1830 df.right = cf.right = vf.right = mDockRight;
1831 df.bottom = cf.bottom = vf.bottom = mDockBottom;
1832 } else {
1833 // The effective display frame of the attached window depends on
1834 // whether it is taking care of insetting its content. If not,
1835 // we need to use the parent's content frame so that the entire
1836 // window is positioned within that content. Otherwise we can use
1837 // the display frame and let the attached window take care of
1838 // positioning its content appropriately.
Dianne Hackborndea3ef72010-10-28 14:24:22 -07001839 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001840 cf.set(attached.getDisplayFrameLw());
1841 } else {
1842 // If the window is resizing, then we want to base the content
1843 // frame on our attached content frame to resize... however,
1844 // things can be tricky if the attached window is NOT in resize
1845 // mode, in which case its content frame will be larger.
1846 // Ungh. So to deal with that, make sure the content frame
1847 // we end up using is not covering the IM dock.
1848 cf.set(attached.getContentFrameLw());
1849 if (attached.getSurfaceLayer() < mDockLayer) {
1850 if (cf.left < mContentLeft) cf.left = mContentLeft;
1851 if (cf.top < mContentTop) cf.top = mContentTop;
1852 if (cf.right > mContentRight) cf.right = mContentRight;
1853 if (cf.bottom > mContentBottom) cf.bottom = mContentBottom;
1854 }
1855 }
1856 df.set(insetDecors ? attached.getDisplayFrameLw() : cf);
1857 vf.set(attached.getVisibleFrameLw());
1858 }
1859 // The LAYOUT_IN_SCREEN flag is used to determine whether the attached
1860 // window should be positioned relative to its parent or the entire
1861 // screen.
1862 pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0
1863 ? attached.getFrameLw() : df);
1864 }
1865
1866 /** {@inheritDoc} */
Dianne Hackborn0ecadf72009-03-31 18:00:37 -07001867 public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
1868 WindowState attached) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001869 // we've already done the status bar
1870 if (win == mStatusBar) {
1871 return;
1872 }
1873
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001874 final int fl = attrs.flags;
1875 final int sim = attrs.softInputMode;
1876
1877 final Rect pf = mTmpParentFrame;
1878 final Rect df = mTmpDisplayFrame;
1879 final Rect cf = mTmpContentFrame;
1880 final Rect vf = mTmpVisibleFrame;
1881
Daniel Sandler36412a72011-08-04 09:35:13 -04001882 final boolean hasNavBar = (mHasNavigationBar
1883 && mNavigationBar != null && mNavigationBar.isVisibleLw());
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001884
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001885 if (attrs.type == TYPE_INPUT_METHOD) {
1886 pf.left = df.left = cf.left = vf.left = mDockLeft;
1887 pf.top = df.top = cf.top = vf.top = mDockTop;
1888 pf.right = df.right = cf.right = vf.right = mDockRight;
1889 pf.bottom = df.bottom = cf.bottom = vf.bottom = mDockBottom;
1890 // IM dock windows always go to the bottom of the screen.
1891 attrs.gravity = Gravity.BOTTOM;
1892 mDockLayer = win.getSurfaceLayer();
1893 } else {
Dianne Hackborndea3ef72010-10-28 14:24:22 -07001894 final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
1895
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001896 if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001897 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001898 if (DEBUG_LAYOUT)
1899 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle()
1900 + "): IN_SCREEN, INSET_DECOR, !FULLSCREEN");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001901 // This is the case for a normal activity window: we want it
1902 // to cover all of the screen space, and it can take care of
1903 // moving its contents to account for screen decorations that
1904 // intrude into that space.
1905 if (attached != null) {
1906 // If this window is attached to another, our display
1907 // frame is the same as the one we are attached to.
1908 setAttachedWindowFrames(win, fl, sim, attached, true, pf, df, cf, vf);
1909 } else {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001910 if (attrs.type == TYPE_STATUS_BAR_PANEL
1911 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
Joe Onorato29fc2c92010-11-24 10:26:50 -08001912 // Status bar panels are the only windows who can go on top of
1913 // the status bar. They are protected by the STATUS_BAR_SERVICE
1914 // permission, so they have the same privileges as the status
1915 // bar itself.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001916 //
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001917 // However, they should still dodge the navigation bar if it exists.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001918
1919 pf.left = df.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
Joe Onorato29fc2c92010-11-24 10:26:50 -08001920 pf.top = df.top = mUnrestrictedScreenTop;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001921 pf.right = df.right = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001922 ? mRestrictedScreenLeft+mRestrictedScreenWidth
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001923 : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
1924 pf.bottom = df.bottom = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001925 ? mRestrictedScreenTop+mRestrictedScreenHeight
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001926 : mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
1927
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001928 if (DEBUG_LAYOUT) {
1929 Log.v(TAG, String.format(
1930 "Laying out status bar window: (%d,%d - %d,%d)",
1931 pf.left, pf.top, pf.right, pf.bottom));
1932 }
Joe Onorato29fc2c92010-11-24 10:26:50 -08001933 } else {
1934 pf.left = df.left = mRestrictedScreenLeft;
1935 pf.top = df.top = mRestrictedScreenTop;
1936 pf.right = df.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
1937 pf.bottom = df.bottom = mRestrictedScreenTop+mRestrictedScreenHeight;
1938 }
Dianne Hackborndea3ef72010-10-28 14:24:22 -07001939 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001940 cf.left = mDockLeft;
1941 cf.top = mDockTop;
1942 cf.right = mDockRight;
1943 cf.bottom = mDockBottom;
1944 } else {
1945 cf.left = mContentLeft;
1946 cf.top = mContentTop;
1947 cf.right = mContentRight;
1948 cf.bottom = mContentBottom;
1949 }
Dianne Hackborndea3ef72010-10-28 14:24:22 -07001950 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
1951 vf.left = mCurLeft;
1952 vf.top = mCurTop;
1953 vf.right = mCurRight;
1954 vf.bottom = mCurBottom;
1955 } else {
1956 vf.set(cf);
1957 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001958 }
Dianne Hackborn82de1ae2010-10-28 11:28:39 -07001959 } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001960 if (DEBUG_LAYOUT)
1961 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001962 // A window that has requested to fill the entire screen just
1963 // gets everything, period.
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001964 if (attrs.type == TYPE_STATUS_BAR_PANEL
1965 || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
1966 pf.left = df.left = cf.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
Joe Onorato29fc2c92010-11-24 10:26:50 -08001967 pf.top = df.top = cf.top = mUnrestrictedScreenTop;
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001968 pf.right = df.right = cf.right = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001969 ? mRestrictedScreenLeft+mRestrictedScreenWidth
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001970 : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
1971 pf.bottom = df.bottom = cf.bottom = hasNavBar
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001972 ? mRestrictedScreenTop+mRestrictedScreenHeight
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001973 : mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
1974
Daniel Sandler36412a72011-08-04 09:35:13 -04001975 if (DEBUG_LAYOUT) {
1976 Log.v(TAG, String.format(
1977 "Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
1978 pf.left, pf.top, pf.right, pf.bottom));
1979 }
Daniel Sandler8e8b4152011-07-21 01:16:43 -04001980 } else if (attrs.type == TYPE_NAVIGATION_BAR) {
1981 // The navigation bar has Real Ultimate Power.
1982 pf.left = df.left = mUnrestrictedScreenLeft;
1983 pf.top = df.top = mUnrestrictedScreenTop;
1984 pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
1985 pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
1986 if (DEBUG_LAYOUT) {
1987 Log.v(TAG, String.format(
1988 "Laying out navigation bar window: (%d,%d - %d,%d)",
1989 pf.left, pf.top, pf.right, pf.bottom));
1990 }
Joe Onorato29fc2c92010-11-24 10:26:50 -08001991 } else {
1992 pf.left = df.left = cf.left = mRestrictedScreenLeft;
1993 pf.top = df.top = cf.top = mRestrictedScreenTop;
1994 pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
1995 pf.bottom = df.bottom = cf.bottom
1996 = mRestrictedScreenTop+mRestrictedScreenHeight;
1997 }
Dianne Hackborndea3ef72010-10-28 14:24:22 -07001998 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
1999 vf.left = mCurLeft;
2000 vf.top = mCurTop;
2001 vf.right = mCurRight;
2002 vf.bottom = mCurBottom;
2003 } else {
2004 vf.set(cf);
2005 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002006 } else if (attached != null) {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002007 if (DEBUG_LAYOUT)
2008 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): attached to " + attached);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002009 // A child window should be placed inside of the same visible
2010 // frame that its parent had.
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002011 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002012 } else {
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002013 if (DEBUG_LAYOUT)
2014 Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): normal window");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002015 // Otherwise, a normal window must be placed inside the content
2016 // of all screen decorations.
Dianne Hackborna239c842011-06-01 12:28:20 -07002017 if (attrs.type == TYPE_STATUS_BAR_PANEL) {
2018 // Status bar panels are the only windows who can go on top of
2019 // the status bar. They are protected by the STATUS_BAR_SERVICE
2020 // permission, so they have the same privileges as the status
2021 // bar itself.
Dianne Hackborn7d049322011-06-14 15:00:32 -07002022 pf.left = df.left = cf.left = mRestrictedScreenLeft;
2023 pf.top = df.top = cf.top = mRestrictedScreenTop;
2024 pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
2025 pf.bottom = df.bottom = cf.bottom
2026 = mRestrictedScreenTop+mRestrictedScreenHeight;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002027 } else {
Dianne Hackborna239c842011-06-01 12:28:20 -07002028 pf.left = mContentLeft;
2029 pf.top = mContentTop;
2030 pf.right = mContentRight;
2031 pf.bottom = mContentBottom;
2032 if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
2033 df.left = cf.left = mDockLeft;
2034 df.top = cf.top = mDockTop;
2035 df.right = cf.right = mDockRight;
2036 df.bottom = cf.bottom = mDockBottom;
2037 } else {
2038 df.left = cf.left = mContentLeft;
2039 df.top = cf.top = mContentTop;
2040 df.right = cf.right = mContentRight;
2041 df.bottom = cf.bottom = mContentBottom;
2042 }
2043 if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
2044 vf.left = mCurLeft;
2045 vf.top = mCurTop;
2046 vf.right = mCurRight;
2047 vf.bottom = mCurBottom;
2048 } else {
2049 vf.set(cf);
2050 }
Dianne Hackborndea3ef72010-10-28 14:24:22 -07002051 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002052 }
2053 }
2054
2055 if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0) {
2056 df.left = df.top = cf.left = cf.top = vf.left = vf.top = -10000;
2057 df.right = df.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000;
2058 }
2059
The Android Open Source Project11267662009-03-18 17:39:47 -07002060 if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle()
2061 + ": sim=#" + Integer.toHexString(sim)
Daniel Sandler8956dbb2011-04-22 07:55:02 -04002062 + " attach=" + attached + " type=" + attrs.type
2063 + String.format(" flags=0x%08x", fl)
The Android Open Source Project11267662009-03-18 17:39:47 -07002064 + " pf=" + pf.toShortString() + " df=" + df.toShortString()
2065 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString());
2066
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002067 win.computeFrameLw(pf, df, cf, vf);
2068
2069 // Dock windows carve out the bottom of the screen, so normal windows
2070 // can't appear underneath them.
2071 if (attrs.type == TYPE_INPUT_METHOD && !win.getGivenInsetsPendingLw()) {
2072 int top = win.getContentFrameLw().top;
2073 top += win.getGivenContentInsetsLw().top;
2074 if (mContentBottom > top) {
2075 mContentBottom = top;
2076 }
2077 top = win.getVisibleFrameLw().top;
2078 top += win.getGivenVisibleInsetsLw().top;
2079 if (mCurBottom > top) {
2080 mCurBottom = top;
2081 }
The Android Open Source Project11267662009-03-18 17:39:47 -07002082 if (DEBUG_LAYOUT) Log.v(TAG, "Input method: mDockBottom="
2083 + mDockBottom + " mContentBottom="
2084 + mContentBottom + " mCurBottom=" + mCurBottom);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002085 }
2086 }
2087
2088 /** {@inheritDoc} */
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002089 public int finishLayoutLw() {
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002090 return 0;
2091 }
2092
2093 /** {@inheritDoc} */
2094 public void beginAnimationLw(int displayWidth, int displayHeight) {
2095 mTopFullscreenOpaqueWindowState = null;
Dianne Hackborn7d049322011-06-14 15:00:32 -07002096 mTopAppWindowState = null;
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002097 mForceStatusBar = false;
2098
2099 mHideLockScreen = false;
2100 mAllowLockscreenWhenOn = false;
2101 mDismissKeyguard = false;
2102 }
2103
2104 /** {@inheritDoc} */
2105 public void animatingWindowLw(WindowState win,
2106 WindowManager.LayoutParams attrs) {
2107 if (mTopFullscreenOpaqueWindowState == null &&
2108 win.isVisibleOrBehindKeyguardLw()) {
2109 if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
2110 mForceStatusBar = true;
2111 }
2112 if (attrs.type >= FIRST_APPLICATION_WINDOW
2113 && attrs.type <= LAST_APPLICATION_WINDOW
Dianne Hackborn6493e642010-10-01 13:06:30 -07002114 && attrs.x == 0 && attrs.y == 0
2115 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
2116 && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002117 if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win);
2118 mTopFullscreenOpaqueWindowState = win;
2119 if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
2120 if (localLOGV) Log.v(TAG, "Setting mHideLockScreen to true by win " + win);
2121 mHideLockScreen = true;
2122 }
2123 if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
2124 if (localLOGV) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win);
2125 mDismissKeyguard = true;
2126 }
2127 if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
2128 mAllowLockscreenWhenOn = true;
2129 }
2130 }
2131 }
Dianne Hackborn7d049322011-06-14 15:00:32 -07002132 if (mTopAppWindowState == null && win.isVisibleOrBehindKeyguardLw()) {
2133 if (attrs.type >= FIRST_APPLICATION_WINDOW
2134 && attrs.type <= LAST_APPLICATION_WINDOW) {
2135 mTopAppWindowState = win;
2136 }
2137 }
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002138 }
2139
2140 /** {@inheritDoc} */
2141 public int finishAnimationLw() {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002142 int changes = 0;
Joe Onorato93056472010-09-10 10:30:46 -04002143 boolean topIsFullscreen = false;
Daniel Sandlere02d8082010-10-08 15:13:22 -04002144
2145 final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null)
2146 ? mTopFullscreenOpaqueWindowState.getAttrs()
2147 : null;
2148
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002149 if (mStatusBar != null) {
Dianne Hackbornd70bc2f2009-10-06 23:25:51 -07002150 if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar
2151 + " top=" + mTopFullscreenOpaqueWindowState);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002152 if (mForceStatusBar) {
Dianne Hackborn0ecadf72009-03-31 18:00:37 -07002153 if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar");
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002154 if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002155 } else if (mTopFullscreenOpaqueWindowState != null) {
Joe Onorato93056472010-09-10 10:30:46 -04002156 if (localLOGV) {
2157 Log.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
2158 + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw());
2159 Log.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
2160 + " lp.flags=0x" + Integer.toHexString(lp.flags));
2161 }
2162 topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
2163 // The subtle difference between the window for mTopFullscreenOpaqueWindowState
2164 // and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
2165 // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the
2166 // case though.
2167 if (topIsFullscreen) {
Daniel Sandler40427442010-07-16 11:44:52 -04002168 if (mStatusBarCanHide) {
2169 if (DEBUG_LAYOUT) Log.v(TAG, "Hiding status bar");
2170 if (mStatusBar.hideLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
Daniel Sandler40427442010-07-16 11:44:52 -04002171 } else if (localLOGV) {
2172 Log.v(TAG, "Preventing status bar from hiding by policy");
2173 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002174 } else {
Dianne Hackborn0ecadf72009-03-31 18:00:37 -07002175 if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar");
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002176 if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002177 }
2178 }
2179 }
Daniel Sandlere02d8082010-10-08 15:13:22 -04002180
Joe Onorato644f9c32011-01-25 12:06:23 -08002181 mTopIsFullscreen = topIsFullscreen;
Daniel Sandlere02d8082010-10-08 15:13:22 -04002182
Dianne Hackborn7d049322011-06-14 15:00:32 -07002183 if (mTopAppWindowState != null && mTopAppWindowState != mLastTopAppWindowState) {
2184 mLastTopAppWindowState = mTopAppWindowState;
Daniel Sandlere02d8082010-10-08 15:13:22 -04002185
Dianne Hackborn7d049322011-06-14 15:00:32 -07002186 final boolean topNeedsMenu = (mTopAppWindowState.getAttrs().flags
2187 & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
Daniel Sandlere02d8082010-10-08 15:13:22 -04002188
Joe Onorato93056472010-09-10 10:30:46 -04002189 mHandler.post(new Runnable() {
2190 public void run() {
2191 if (mStatusBarService == null) {
2192 // This is the one that can not go away, but it doesn't come up
2193 // before the window manager does, so don't fail if it doesn't
2194 // exist. This works as long as no fullscreen windows come up
2195 // before the status bar service does.
2196 mStatusBarService = IStatusBarService.Stub.asInterface(
2197 ServiceManager.getService("statusbar"));
2198 }
2199 final IStatusBarService sbs = mStatusBarService;
2200 if (mStatusBarService != null) {
2201 try {
Dianne Hackborn7d049322011-06-14 15:00:32 -07002202 sbs.topAppWindowChanged(topNeedsMenu);
Joe Onorato93056472010-09-10 10:30:46 -04002203 } catch (RemoteException e) {
2204 // This should be impossible because we're in the same process.
2205 mStatusBarService = null;
2206 }
2207 }
2208 }
2209 });
Dianne Hackborn5f3063e2010-03-10 16:01:58 -08002210 }
2211
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -07002212 // Hide the key guard if a visible window explicitly specifies that it wants to be displayed
2213 // when the screen is locked
2214 if (mKeyguard != null) {
Joe Onorato93056472010-09-10 10:30:46 -04002215 if (localLOGV) Log.v(TAG, "finishAnimationLw::mHideKeyguard="+mHideLockScreen);
Dianne Hackborn05726582009-09-22 17:28:24 -07002216 if (mDismissKeyguard && !mKeyguardMediator.isSecure()) {
Dianne Hackborn08743722009-12-21 12:16:51 -08002217 if (mKeyguard.hideLw(true)) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002218 changes |= FINISH_LAYOUT_REDO_LAYOUT
2219 | FINISH_LAYOUT_REDO_CONFIG
2220 | FINISH_LAYOUT_REDO_WALLPAPER;
2221 }
Dianne Hackborn05726582009-09-22 17:28:24 -07002222 if (mKeyguardMediator.isShowing()) {
Dianne Hackbornb446e972009-09-20 15:23:25 -07002223 mHandler.post(new Runnable() {
2224 public void run() {
Dianne Hackborn05726582009-09-22 17:28:24 -07002225 mKeyguardMediator.keyguardDone(false, false);
Dianne Hackbornb446e972009-09-20 15:23:25 -07002226 }
2227 });
2228 }
Dianne Hackborn05726582009-09-22 17:28:24 -07002229 } else if (mHideLockScreen) {
Dianne Hackborn08743722009-12-21 12:16:51 -08002230 if (mKeyguard.hideLw(true)) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002231 changes |= FINISH_LAYOUT_REDO_LAYOUT
2232 | FINISH_LAYOUT_REDO_CONFIG
2233 | FINISH_LAYOUT_REDO_WALLPAPER;
2234 }
Mike Lockwoodf3bfed52010-01-21 16:38:44 -05002235 mKeyguardMediator.setHidden(true);
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -07002236 } else {
Dianne Hackborn08743722009-12-21 12:16:51 -08002237 if (mKeyguard.showLw(true)) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002238 changes |= FINISH_LAYOUT_REDO_LAYOUT
2239 | FINISH_LAYOUT_REDO_CONFIG
2240 | FINISH_LAYOUT_REDO_WALLPAPER;
2241 }
Mike Lockwoodf3bfed52010-01-21 16:38:44 -05002242 mKeyguardMediator.setHidden(false);
Suchi Amalapurapu9cdc9032009-05-14 18:01:07 -07002243 }
2244 }
Joe Onorato664644d2011-01-23 17:53:23 -08002245
2246 updateSystemUiVisibility();
2247
Mike Lockwood28569302010-01-28 11:54:40 -05002248 // update since mAllowLockscreenWhenOn might have changed
2249 updateLockScreenTimeout();
Dianne Hackborn39c2d712009-09-22 11:41:31 -07002250 return changes;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002251 }
2252
Dianne Hackborn08743722009-12-21 12:16:51 -08002253 public boolean allowAppAnimationsLw() {
2254 if (mKeyguard != null && mKeyguard.isVisibleLw()) {
2255 // If keyguard is currently visible, no reason to animate
2256 // behind it.
2257 return false;
2258 }
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002259 if (false) {
2260 // Don't do this on the tablet, since the system bar never completely
2261 // covers the screen, and with all its transparency this will
2262 // incorrectly think it does cover it when it doesn't. We'll revisit
2263 // this later when we re-do the phone status bar.
2264 if (mStatusBar != null && mStatusBar.isVisibleLw()) {
2265 Rect rect = new Rect(mStatusBar.getShownFrameLw());
2266 for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
2267 WindowState w = mStatusBarPanels.get(i);
2268 if (w.isVisibleLw()) {
2269 rect.union(w.getShownFrameLw());
2270 }
Dianne Hackborn08743722009-12-21 12:16:51 -08002271 }
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002272 final int insetw = mRestrictedScreenWidth/10;
2273 final int inseth = mRestrictedScreenHeight/10;
2274 if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
2275 mRestrictedScreenHeight-inseth)) {
2276 // All of the status bar windows put together cover the
2277 // screen, so the app can't be seen. (Note this test doesn't
2278 // work if the rects of these windows are at off offsets or
2279 // sizes, causing gaps in the rect union we have computed.)
2280 return false;
2281 }
Dianne Hackborn08743722009-12-21 12:16:51 -08002282 }
2283 }
2284 return true;
2285 }
2286
Joe Onorato664644d2011-01-23 17:53:23 -08002287 public void focusChanged(WindowState lastFocus, WindowState newFocus) {
2288 mFocusedWindow = newFocus;
2289 updateSystemUiVisibility();
2290 }
2291
Dianne Hackborn0ecadf72009-03-31 18:00:37 -07002292 /** {@inheritDoc} */
Jeff Brown46b9ac02010-04-22 18:58:52 -07002293 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
2294 // lid changed state
Jeff Brown4aed78b2011-01-14 17:36:55 -08002295 mLidOpen = lidOpen ? LID_OPEN : LID_CLOSED;
2296 boolean awakeNow = mKeyguardMediator.doLidChangeTq(lidOpen);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002297 updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
2298 if (awakeNow) {
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08002299 // If the lid is opening and we don't have to keep the
Jeff Brown46b9ac02010-04-22 18:58:52 -07002300 // keyguard up, then we can turn on the screen
2301 // immediately.
2302 mKeyguardMediator.pokeWakelock();
2303 } else if (keyguardIsShowingTq()) {
Jeff Brown4aed78b2011-01-14 17:36:55 -08002304 if (lidOpen) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002305 // If we are opening the lid and not hiding the
2306 // keyguard, then we need to have it turn on the
2307 // screen once it is shown.
2308 mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(
2309 KeyEvent.KEYCODE_POWER);
2310 }
2311 } else {
2312 // Light up the keyboard if we are sliding up.
Jeff Brown4aed78b2011-01-14 17:36:55 -08002313 if (lidOpen) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002314 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
2315 LocalPowerManager.BUTTON_EVENT);
2316 } else {
2317 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
2318 LocalPowerManager.OTHER_EVENT);
2319 }
2320 }
2321 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002322
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08002323 void setHdmiPlugged(boolean plugged) {
2324 if (mHdmiPlugged != plugged) {
2325 mHdmiPlugged = plugged;
2326 updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
2327 Intent intent = new Intent(ACTION_HDMI_PLUGGED);
Joe Onoratodc100302011-01-11 17:07:41 -08002328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08002329 intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
2330 mContext.sendStickyBroadcast(intent);
2331 }
2332 }
2333
Joe Onoratoea495d42011-04-06 11:41:11 -07002334 void initializeHdmiState() {
Joe Onorato7ba631f2011-05-04 15:28:00 -07002335 boolean plugged = false;
Joe Onoratoea495d42011-04-06 11:41:11 -07002336 // watch for HDMI plug messages if the hdmi switch exists
2337 if (new File("/sys/devices/virtual/switch/hdmi/state").exists()) {
2338 mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi");
2339
Joe Onoratoea495d42011-04-06 11:41:11 -07002340 final String filename = "/sys/class/switch/hdmi/state";
2341 FileReader reader = null;
2342 try {
2343 reader = new FileReader(filename);
2344 char[] buf = new char[15];
2345 int n = reader.read(buf);
2346 if (n > 1) {
2347 plugged = 0 != Integer.parseInt(new String(buf, 0, n-1));
2348 }
2349 } catch (IOException ex) {
2350 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
2351 } catch (NumberFormatException ex) {
2352 Slog.w(TAG, "Couldn't read hdmi state from " + filename + ": " + ex);
2353 } finally {
2354 if (reader != null) {
2355 try {
2356 reader.close();
2357 } catch (IOException ex) {
2358 }
Joe Onoratodc100302011-01-11 17:07:41 -08002359 }
2360 }
2361 }
Joe Onorato7ba631f2011-05-04 15:28:00 -07002362 // This dance forces the code in setHdmiPlugged to run.
2363 // Always do this so the sticky intent is stuck (to false) if there is no hdmi.
2364 mHdmiPlugged = !plugged;
2365 setHdmiPlugged(!mHdmiPlugged);
Joe Onoratodc100302011-01-11 17:07:41 -08002366 }
2367
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002368 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002369 * @return Whether music is being played right now.
2370 */
2371 boolean isMusicActive() {
Eric Laurent413cb9d2009-07-17 11:52:43 -07002372 final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
2373 if (am == null) {
2374 Log.w(TAG, "isMusicActive: couldn't get AudioManager reference");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002375 return false;
2376 }
Eric Laurent413cb9d2009-07-17 11:52:43 -07002377 return am.isMusicActive();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002378 }
2379
2380 /**
2381 * Tell the audio service to adjust the volume appropriate to the event.
2382 * @param keycode
2383 */
Mike Lockwooda53e3812009-09-25 10:51:39 -04002384 void handleVolumeKey(int stream, int keycode) {
Jeff Brown4d396052010-10-29 21:50:21 -07002385 IAudioService audioService = getAudioService();
2386 if (audioService == null) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002387 return;
2388 }
2389 try {
2390 // since audio is playing, we shouldn't have to hold a wake lock
2391 // during the call, but we do it as a precaution for the rare possibility
2392 // that the music stops right before we call this
Jeff Brownb0418da2010-11-01 15:24:01 -07002393 // TODO: Actually handle MUTE.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002394 mBroadcastWakeLock.acquire();
Jeff Brown4d396052010-10-29 21:50:21 -07002395 audioService.adjustStreamVolume(stream,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002396 keycode == KeyEvent.KEYCODE_VOLUME_UP
2397 ? AudioManager.ADJUST_RAISE
2398 : AudioManager.ADJUST_LOWER,
2399 0);
2400 } catch (RemoteException e) {
2401 Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e);
2402 } finally {
2403 mBroadcastWakeLock.release();
2404 }
2405 }
Jeff Brown4d396052010-10-29 21:50:21 -07002406
Dianne Hackbornc0e3f242011-08-19 14:19:10 -07002407 final Object mScreenshotLock = new Object();
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07002408 ServiceConnection mScreenshotConnection = null;
2409 Runnable mScreenshotTimeout = null;
2410
Dianne Hackbornc0e3f242011-08-19 14:19:10 -07002411 void finishScreenshotLSS(ServiceConnection conn) {
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07002412 if (mScreenshotConnection == conn) {
2413 mContext.unbindService(conn);
2414 mScreenshotConnection = null;
2415 if (mScreenshotTimeout != null) {
2416 mHandler.removeCallbacks(mScreenshotTimeout);
2417 mScreenshotTimeout = null;
2418 }
2419 }
2420 }
2421
Winson Chung9112ec32011-06-27 13:15:32 -07002422 private void takeScreenshot() {
2423 mHandler.post(new Runnable() {
2424 @Override
2425 public void run() {
Dianne Hackbornc0e3f242011-08-19 14:19:10 -07002426 synchronized (mScreenshotLock) {
2427 if (mScreenshotConnection != null) {
2428 return;
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07002429 }
Dianne Hackbornc0e3f242011-08-19 14:19:10 -07002430 ComponentName cn = new ComponentName("com.android.systemui",
2431 "com.android.systemui.screenshot.TakeScreenshotService");
2432 Intent intent = new Intent();
2433 intent.setComponent(cn);
2434 ServiceConnection conn = new ServiceConnection() {
2435 @Override
2436 public void onServiceConnected(ComponentName name, IBinder service) {
2437 synchronized (mScreenshotLock) {
2438 if (mScreenshotConnection != this) {
2439 return;
2440 }
2441 Messenger messenger = new Messenger(service);
2442 Message msg = Message.obtain(null, 1);
2443 final ServiceConnection myConn = this;
2444 Handler h = new Handler(mHandler.getLooper()) {
2445 @Override
2446 public void handleMessage(Message msg) {
2447 synchronized (mScreenshotLock) {
2448 finishScreenshotLSS(myConn);
2449 }
2450 }
2451 };
2452 msg.replyTo = new Messenger(h);
2453 try {
2454 messenger.send(msg);
2455 } catch (RemoteException e) {
2456 }
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07002457 }
2458 }
Dianne Hackbornc0e3f242011-08-19 14:19:10 -07002459 @Override
2460 public void onServiceDisconnected(ComponentName name) {}
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07002461 };
Dianne Hackbornc0e3f242011-08-19 14:19:10 -07002462 if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
2463 mScreenshotConnection = conn;
2464 mScreenshotTimeout = new Runnable() {
2465 @Override public void run() {
2466 synchronized (mScreenshotLock) {
2467 if (mScreenshotConnection != null) {
2468 finishScreenshotLSS(mScreenshotConnection);
2469 }
2470 }
2471 }
2472
2473 };
2474 mHandler.postDelayed(mScreenshotTimeout, 10000);
2475 }
Dianne Hackbornfc8fa632011-08-17 16:20:47 -07002476 }
Winson Chung9112ec32011-06-27 13:15:32 -07002477 }
2478 });
2479 }
2480
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002481 /** {@inheritDoc} */
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002482 @Override
Jeff Brown1f245102010-11-18 20:53:46 -08002483 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
2484 final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
2485 final boolean canceled = event.isCanceled();
2486 final int keyCode = event.getKeyCode();
Jeff Browne20c9e02010-10-11 14:20:19 -07002487
Jeff Brown3122e442010-10-11 23:32:49 -07002488 final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
Jeff Brown3122e442010-10-11 23:32:49 -07002489
Mike Lockwoodc72b15f2009-11-28 20:58:22 -05002490 // If screen is off then we treat the case where the keyguard is open but hidden
2491 // the same as if it were open and in front.
2492 // This will prevent any keys other than the power button from waking the screen
2493 // when the keyguard is hidden by another activity.
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002494 final boolean keyguardActive = (isScreenOn ?
Mike Lockwoodc72b15f2009-11-28 20:58:22 -05002495 mKeyguardMediator.isShowingAndNotHidden() :
2496 mKeyguardMediator.isShowing());
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002497
2498 if (false) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002499 Log.d(TAG, "interceptKeyTq keycode=" + keyCode
2500 + " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002501 }
2502
Jeff Brown4d396052010-10-29 21:50:21 -07002503 if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
2504 performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
2505 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002506
Jeff Brown4d396052010-10-29 21:50:21 -07002507 // Basic policy based on screen state and keyguard.
2508 // FIXME: This policy isn't quite correct. We shouldn't care whether the screen
2509 // is on or off, really. We should care about whether the device is in an
2510 // interactive state or is in suspend pretending to be "off".
2511 // The primary screen might be turned off due to proximity sensor or
2512 // because we are presenting media on an auxiliary screen or remotely controlling
2513 // the device some other way (which is why we have an exemption here for injected
2514 // events).
2515 int result;
2516 if (isScreenOn || isInjected) {
2517 // When the screen is on or if the key is injected pass the key to the application.
2518 result = ACTION_PASS_TO_USER;
2519 } else {
2520 // When the screen is off and the key is not injected, determine whether
2521 // to wake the device but don't pass the key to the application.
2522 result = 0;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002523
Jeff Brown4d396052010-10-29 21:50:21 -07002524 final boolean isWakeKey = (policyFlags
2525 & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
2526 if (down && isWakeKey) {
2527 if (keyguardActive) {
2528 // If the keyguard is showing, let it decide what to do with the wake key.
2529 mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode);
2530 } else {
2531 // Otherwise, wake the device ourselves.
2532 result |= ACTION_POKE_USER_ACTIVITY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002533 }
2534 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002535 }
2536
Jeff Brown4d396052010-10-29 21:50:21 -07002537 // Handle special keys.
2538 switch (keyCode) {
2539 case KeyEvent.KEYCODE_VOLUME_DOWN:
Winson Chung9112ec32011-06-27 13:15:32 -07002540 if (down) {
Winson Chungd859fa32011-07-22 12:19:52 -07002541 if (isScreenOn) {
2542 // If the power key down was already triggered, take the screenshot
2543 if (mPowerDownTriggered) {
2544 // Dismiss the power-key longpress
2545 mHandler.removeCallbacks(mPowerLongPress);
2546 mPowerKeyHandled = true;
Winson Chung9112ec32011-06-27 13:15:32 -07002547
Winson Chungd859fa32011-07-22 12:19:52 -07002548 // Take the screenshot
2549 takeScreenshot();
Winson Chung9112ec32011-06-27 13:15:32 -07002550
Winson Chungd859fa32011-07-22 12:19:52 -07002551 // Prevent the event from being passed through to the current activity
2552 result &= ~ACTION_PASS_TO_USER;
2553 break;
2554 }
2555 mVolumeDownTriggered = true;
Winson Chung9112ec32011-06-27 13:15:32 -07002556 }
Winson Chung9112ec32011-06-27 13:15:32 -07002557 } else {
2558 mVolumeDownTriggered = false;
2559 }
Jeff Brownb0418da2010-11-01 15:24:01 -07002560 case KeyEvent.KEYCODE_VOLUME_UP:
2561 case KeyEvent.KEYCODE_VOLUME_MUTE: {
Jeff Brown4d396052010-10-29 21:50:21 -07002562 if (down) {
2563 ITelephony telephonyService = getTelephonyService();
2564 if (telephonyService != null) {
2565 try {
2566 if (telephonyService.isRinging()) {
2567 // If an incoming call is ringing, either VOLUME key means
2568 // "silence ringer". We handle these keys here, rather than
2569 // in the InCallScreen, to make sure we'll respond to them
2570 // even if the InCallScreen hasn't come to the foreground yet.
2571 // Look for the DOWN event here, to agree with the "fallback"
2572 // behavior in the InCallScreen.
2573 Log.i(TAG, "interceptKeyBeforeQueueing:"
2574 + " VOLUME key-down while ringing: Silence ringer!");
2575
2576 // Silence the ringer. (It's safe to call this
2577 // even if the ringer has already been silenced.)
2578 telephonyService.silenceRinger();
2579
2580 // And *don't* pass this key thru to the current activity
2581 // (which is probably the InCallScreen.)
2582 result &= ~ACTION_PASS_TO_USER;
2583 break;
2584 }
2585 if (telephonyService.isOffhook()
2586 && (result & ACTION_PASS_TO_USER) == 0) {
2587 // If we are in call but we decided not to pass the key to
2588 // the application, handle the volume change here.
2589 handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
2590 break;
2591 }
2592 } catch (RemoteException ex) {
2593 Log.w(TAG, "ITelephony threw RemoteException", ex);
2594 }
2595 }
2596
2597 if (isMusicActive() && (result & ACTION_PASS_TO_USER) == 0) {
2598 // If music is playing but we decided not to pass the key to the
2599 // application, handle the volume change here.
2600 handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode);
2601 break;
2602 }
2603 }
2604 break;
2605 }
2606
2607 case KeyEvent.KEYCODE_ENDCALL: {
2608 result &= ~ACTION_PASS_TO_USER;
2609 if (down) {
2610 ITelephony telephonyService = getTelephonyService();
2611 boolean hungUp = false;
2612 if (telephonyService != null) {
2613 try {
2614 hungUp = telephonyService.endCall();
2615 } catch (RemoteException ex) {
2616 Log.w(TAG, "ITelephony threw RemoteException", ex);
2617 }
2618 }
2619 interceptPowerKeyDown(!isScreenOn || hungUp);
2620 } else {
2621 if (interceptPowerKeyUp(canceled)) {
2622 if ((mEndcallBehavior
2623 & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
2624 if (goHome()) {
2625 break;
Dianne Hackborn0041e972009-07-24 17:14:43 -07002626 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002627 }
Jeff Brown4d396052010-10-29 21:50:21 -07002628 if ((mEndcallBehavior
2629 & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
2630 result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
2631 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002632 }
Jeff Brown4d396052010-10-29 21:50:21 -07002633 }
2634 break;
2635 }
2636
2637 case KeyEvent.KEYCODE_POWER: {
2638 result &= ~ACTION_PASS_TO_USER;
2639 if (down) {
Winson Chungd859fa32011-07-22 12:19:52 -07002640 if (isScreenOn) {
2641 // If the volume down key has been triggered, then just take the screenshot
2642 if (mVolumeDownTriggered) {
2643 // Take the screenshot
2644 takeScreenshot();
2645 mPowerKeyHandled = true;
Winson Chung9112ec32011-06-27 13:15:32 -07002646
Winson Chungd859fa32011-07-22 12:19:52 -07002647 // Prevent the event from being passed through to the current activity
2648 break;
2649 }
2650 mPowerDownTriggered = true;
Winson Chung9112ec32011-06-27 13:15:32 -07002651 }
Winson Chung9112ec32011-06-27 13:15:32 -07002652
Jeff Brown4d396052010-10-29 21:50:21 -07002653 ITelephony telephonyService = getTelephonyService();
2654 boolean hungUp = false;
2655 if (telephonyService != null) {
2656 try {
2657 if (telephonyService.isRinging()) {
2658 // Pressing Power while there's a ringing incoming
2659 // call should silence the ringer.
2660 telephonyService.silenceRinger();
2661 } else if ((mIncallPowerBehavior
2662 & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
2663 && telephonyService.isOffhook()) {
2664 // Otherwise, if "Power button ends call" is enabled,
2665 // the Power button will hang up any current active call.
2666 hungUp = telephonyService.endCall();
2667 }
2668 } catch (RemoteException ex) {
2669 Log.w(TAG, "ITelephony threw RemoteException", ex);
2670 }
2671 }
2672 interceptPowerKeyDown(!isScreenOn || hungUp);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002673 } else {
Winson Chung9112ec32011-06-27 13:15:32 -07002674 mPowerDownTriggered = false;
Jeff Brown4d396052010-10-29 21:50:21 -07002675 if (interceptPowerKeyUp(canceled)) {
2676 result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002677 }
Jeff Brown4d396052010-10-29 21:50:21 -07002678 }
2679 break;
2680 }
2681
2682 case KeyEvent.KEYCODE_MEDIA_PLAY:
2683 case KeyEvent.KEYCODE_MEDIA_PAUSE:
2684 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
2685 if (down) {
2686 ITelephony telephonyService = getTelephonyService();
2687 if (telephonyService != null) {
2688 try {
2689 if (!telephonyService.isIdle()) {
2690 // Suppress PLAY/PAUSE toggle when phone is ringing or in-call
2691 // to avoid music playback.
2692 break;
2693 }
2694 } catch (RemoteException ex) {
2695 Log.w(TAG, "ITelephony threw RemoteException", ex);
Jeff Brown3122e442010-10-11 23:32:49 -07002696 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002697 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002698 }
Jeff Brown4d396052010-10-29 21:50:21 -07002699 case KeyEvent.KEYCODE_HEADSETHOOK:
2700 case KeyEvent.KEYCODE_MUTE:
2701 case KeyEvent.KEYCODE_MEDIA_STOP:
2702 case KeyEvent.KEYCODE_MEDIA_NEXT:
2703 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
2704 case KeyEvent.KEYCODE_MEDIA_REWIND:
2705 case KeyEvent.KEYCODE_MEDIA_RECORD:
2706 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
2707 if ((result & ACTION_PASS_TO_USER) == 0) {
2708 // Only do this if we would otherwise not pass it to the user. In that
2709 // case, the PhoneWindow class will do the same thing, except it will
2710 // only do it if the showing app doesn't process the key on its own.
Jeff Brown4d396052010-10-29 21:50:21 -07002711 mBroadcastWakeLock.acquire();
Jeff Brown1f245102010-11-18 20:53:46 -08002712 mHandler.post(new PassHeadsetKey(new KeyEvent(event)));
Jeff Brown4d396052010-10-29 21:50:21 -07002713 }
2714 break;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002715 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002716
Jeff Brown4d396052010-10-29 21:50:21 -07002717 case KeyEvent.KEYCODE_CALL: {
2718 if (down) {
2719 ITelephony telephonyService = getTelephonyService();
2720 if (telephonyService != null) {
2721 try {
2722 if (telephonyService.isRinging()) {
2723 Log.i(TAG, "interceptKeyBeforeQueueing:"
2724 + " CALL key-down while ringing: Answer the call!");
2725 telephonyService.answerRingingCall();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002726
Jeff Brown4d396052010-10-29 21:50:21 -07002727 // And *don't* pass this key thru to the current activity
2728 // (which is presumably the InCallScreen.)
2729 result &= ~ACTION_PASS_TO_USER;
2730 }
2731 } catch (RemoteException ex) {
2732 Log.w(TAG, "ITelephony threw RemoteException", ex);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002733 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002734 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002735 }
Jeff Brown4d396052010-10-29 21:50:21 -07002736 break;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002737 }
2738 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002739 return result;
2740 }
2741
Jeff Brown56194eb2011-03-02 19:23:13 -08002742 /** {@inheritDoc} */
2743 @Override
2744 public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
2745 int result = 0;
2746
2747 final boolean isWakeMotion = (policyFlags
2748 & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
2749 if (isWakeMotion) {
2750 if (mKeyguardMediator.isShowing()) {
2751 // If the keyguard is showing, let it decide what to do with the wake motion.
2752 mKeyguardMediator.onWakeMotionWhenKeyguardShowingTq();
2753 } else {
2754 // Otherwise, wake the device ourselves.
2755 result |= ACTION_POKE_USER_ACTIVITY;
2756 }
2757 }
2758 return result;
2759 }
2760
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002761 class PassHeadsetKey implements Runnable {
2762 KeyEvent mKeyEvent;
2763
2764 PassHeadsetKey(KeyEvent keyEvent) {
2765 mKeyEvent = keyEvent;
2766 }
2767
2768 public void run() {
2769 if (ActivityManagerNative.isSystemReady()) {
2770 Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
2771 intent.putExtra(Intent.EXTRA_KEY_EVENT, mKeyEvent);
2772 mContext.sendOrderedBroadcast(intent, null, mBroadcastDone,
2773 mHandler, Activity.RESULT_OK, null, null);
2774 }
2775 }
2776 }
2777
2778 BroadcastReceiver mBroadcastDone = new BroadcastReceiver() {
2779 public void onReceive(Context context, Intent intent) {
2780 mBroadcastWakeLock.release();
2781 }
2782 };
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002783
2784 BroadcastReceiver mDockReceiver = new BroadcastReceiver() {
2785 public void onReceive(Context context, Intent intent) {
Dianne Hackborn867ab6472010-04-29 13:28:56 -07002786 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
2787 mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
2788 Intent.EXTRA_DOCK_STATE_UNDOCKED);
2789 } else {
2790 try {
2791 IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
2792 ServiceManager.getService(Context.UI_MODE_SERVICE));
2793 mUiMode = uiModeService.getCurrentModeType();
2794 } catch (RemoteException e) {
2795 }
Dianne Hackborn80fa1662009-10-07 14:02:10 -07002796 }
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002797 updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
Mike Lockwoode9867d22009-09-20 01:59:02 -04002798 updateOrientationListenerLp();
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002799 }
2800 };
2801
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002802 /** {@inheritDoc} */
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002803 public void screenTurnedOff(int why) {
Dianne Hackborn74489012009-03-24 20:50:09 -07002804 EventLog.writeEvent(70000, 0);
The Android Open Source Project0727d222009-03-11 12:11:58 -07002805 synchronized (mLock) {
The Android Open Source Project0727d222009-03-11 12:11:58 -07002806 mScreenOn = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002807 }
2808 mKeyguardMediator.onScreenTurnedOff(why);
2809 synchronized (mLock) {
The Android Open Source Project0727d222009-03-11 12:11:58 -07002810 updateOrientationListenerLp();
Mike Lockwood28569302010-01-28 11:54:40 -05002811 updateLockScreenTimeout();
Daniel Sandler0601eb72011-04-13 01:01:32 -04002812 updateScreenSaverTimeoutLocked();
The Android Open Source Project0727d222009-03-11 12:11:58 -07002813 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002814 try {
2815 mWindowManager.waitForAllDrawn();
2816 } catch (RemoteException e) {
2817 }
2818 // Wait for one frame to give surface flinger time to do its
2819 // compositing. Yes this is a hack, but I am really not up right now for
2820 // implementing some mechanism to block until SF is done. :p
2821 try {
2822 Thread.sleep(20);
2823 } catch (InterruptedException e) {
2824 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002825 }
2826
2827 /** {@inheritDoc} */
2828 public void screenTurnedOn() {
Dianne Hackborn74489012009-03-24 20:50:09 -07002829 EventLog.writeEvent(70000, 1);
2830 mKeyguardMediator.onScreenTurnedOn();
The Android Open Source Project0727d222009-03-11 12:11:58 -07002831 synchronized (mLock) {
The Android Open Source Project0727d222009-03-11 12:11:58 -07002832 mScreenOn = true;
2833 updateOrientationListenerLp();
Mike Lockwood28569302010-01-28 11:54:40 -05002834 updateLockScreenTimeout();
Daniel Sandler0601eb72011-04-13 01:01:32 -04002835 updateScreenSaverTimeoutLocked();
The Android Open Source Project0727d222009-03-11 12:11:58 -07002836 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002837 }
2838
2839 /** {@inheritDoc} */
Dianne Hackborn08743722009-12-21 12:16:51 -08002840 public boolean isScreenOn() {
2841 return mScreenOn;
2842 }
2843
2844 /** {@inheritDoc} */
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002845 public void enableKeyguard(boolean enabled) {
2846 mKeyguardMediator.setKeyguardEnabled(enabled);
2847 }
2848
2849 /** {@inheritDoc} */
2850 public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
2851 mKeyguardMediator.verifyUnlock(callback);
2852 }
2853
Mike Lockwoodf7913302009-11-28 22:27:10 -05002854 private boolean keyguardIsShowingTq() {
Dianne Hackborn9dc06cc2009-11-17 18:19:23 -08002855 return mKeyguardMediator.isShowingAndNotHidden();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002856 }
2857
Mike Lockwood520d8bc2011-02-18 13:23:13 -05002858
2859 /** {@inheritDoc} */
2860 public boolean isKeyguardLocked() {
2861 return keyguardOn();
2862 }
2863
2864 /** {@inheritDoc} */
2865 public boolean isKeyguardSecure() {
2866 return mKeyguardMediator.isSecure();
2867 }
2868
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002869 /** {@inheritDoc} */
2870 public boolean inKeyguardRestrictedKeyInputMode() {
2871 return mKeyguardMediator.isInputRestricted();
2872 }
2873
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002874 void sendCloseSystemWindows() {
2875 sendCloseSystemWindows(mContext, null);
2876 }
2877
2878 void sendCloseSystemWindows(String reason) {
2879 sendCloseSystemWindows(mContext, reason);
2880 }
2881
2882 static void sendCloseSystemWindows(Context context, String reason) {
2883 if (ActivityManagerNative.isSystemReady()) {
Dianne Hackborn94a679d2009-07-28 17:51:07 -07002884 try {
2885 ActivityManagerNative.getDefault().closeSystemDialogs(reason);
2886 } catch (RemoteException e) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002887 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002888 }
2889 }
Dianne Hackborn9d132642011-04-21 17:26:39 -07002890
The Android Open Source Project0727d222009-03-11 12:11:58 -07002891 public int rotationForOrientationLw(int orientation, int lastRotation,
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002892 boolean displayEnabled) {
Mitsuru Oshima831d0d92009-06-16 18:27:18 -07002893
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05002894 if (false) {
2895 Slog.v(TAG, "rotationForOrientationLw(orient="
2896 + orientation + ", last=" + lastRotation
2897 + "); user=" + mUserRotation + " "
2898 + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
2899 ? "USER_ROTATION_LOCKED" : "")
2900 );
2901 }
2902
The Android Open Source Project0727d222009-03-11 12:11:58 -07002903 synchronized (mLock) {
Dianne Hackborne5439f22010-10-02 16:53:50 -07002904 switch (orientation) {
2905 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
2906 //always return portrait if orientation set to portrait
2907 return mPortraitRotation;
2908 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
2909 //always return landscape if orientation set to landscape
2910 return mLandscapeRotation;
2911 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
2912 //always return portrait if orientation set to portrait
2913 return mUpsideDownRotation;
2914 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
2915 //always return seascape if orientation set to reverse landscape
2916 return mSeascapeRotation;
2917 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
2918 //return either landscape rotation based on the sensor
Dianne Hackborne5439f22010-10-02 16:53:50 -07002919 return getCurrentLandscapeRotation(lastRotation);
2920 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
Dianne Hackborne5439f22010-10-02 16:53:50 -07002921 return getCurrentPortraitRotation(lastRotation);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002922 }
Dianne Hackborne5439f22010-10-02 16:53:50 -07002923
The Android Open Source Project0727d222009-03-11 12:11:58 -07002924 // case for nosensor meaning ignore sensor and consider only lid
2925 // or orientation sensor disabled
2926 //or case.unspecified
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08002927 if (mHdmiPlugged) {
Erik Gilling10a058c2011-08-16 15:45:34 -07002928 return mLandscapeRotation;
Jeff Brown4aed78b2011-01-14 17:36:55 -08002929 } else if (mLidOpen == LID_OPEN) {
Mike Lockwood1753f7f2009-08-24 14:49:07 -07002930 return mLidOpenRotation;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07002931 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04002932 return mCarDockRotation;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07002933 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04002934 return mDeskDockRotation;
Daniel Sandlerb73617d2010-08-17 00:41:00 -04002935 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
2936 return mUserRotation;
The Android Open Source Project0727d222009-03-11 12:11:58 -07002937 } else {
Dianne Hackborn03759ed2009-03-27 16:04:08 -07002938 if (useSensorForOrientationLp(orientation)) {
Jeff Brown4519f072011-01-23 13:16:01 -08002939 // Disable 180 degree rotation unless allowed by default for the device
2940 // or explicitly requested by the application.
2941 int rotation = mOrientationListener.getCurrentRotation(lastRotation);
2942 if (rotation == Surface.ROTATION_180
2943 && !mAllowAllRotations
2944 && orientation != ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) {
2945 return lastRotation;
2946 }
2947 return rotation;
The Android Open Source Project0727d222009-03-11 12:11:58 -07002948 }
2949 return Surface.ROTATION_0;
2950 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002951 }
2952 }
2953
Dianne Hackborndacea8c2011-04-21 17:26:39 -07002954 public int getLockedRotationLw() {
2955 synchronized (mLock) {
2956 if (false) {
2957 // Not yet working.
2958 if (mHdmiPlugged) {
2959 return Surface.ROTATION_0;
2960 } else if (mLidOpen == LID_OPEN) {
2961 return mLidOpenRotation;
2962 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {
2963 return mCarDockRotation;
2964 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
2965 return mDeskDockRotation;
2966 } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
2967 return mUserRotation;
2968 }
2969 }
2970 return -1;
2971 }
2972 }
2973
Steve Howarda7bfe6a2010-09-23 16:47:49 -07002974 private int getCurrentLandscapeRotation(int lastRotation) {
Daniel Sandlere7e5ac22011-02-22 16:10:21 -05002975 // if the user has locked rotation, we ignore the sensor
2976 if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
2977 if (isLandscapeOrSeascape(mUserRotation)) {
2978 return mUserRotation;
2979 } else {
2980 // it seems odd to obey the sensor at all if rotation lock is enabled
2981 return mLandscapeRotation;
2982 }
2983 }
2984
Dianne Hackborne5439f22010-10-02 16:53:50 -07002985 int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation);
2986 if (isLandscapeOrSeascape(sensorRotation)) {
2987 return sensorRotation;
Steve Howarda7bfe6a2010-09-23 16:47:49 -07002988 }
2989 // try to preserve the old rotation if it was landscape
2990 if (isLandscapeOrSeascape(lastRotation)) {
2991 return lastRotation;
2992 }
Dianne Hackborne5439f22010-10-02 16:53:50 -07002993 // default to one of the primary landscape rotation
Steve Howarda7bfe6a2010-09-23 16:47:49 -07002994 return mLandscapeRotation;
2995 }
2996
2997 private boolean isLandscapeOrSeascape(int sensorRotation) {
2998 return sensorRotation == mLandscapeRotation || sensorRotation == mSeascapeRotation;
2999 }
3000
Dianne Hackborne5439f22010-10-02 16:53:50 -07003001 private int getCurrentPortraitRotation(int lastRotation) {
Daniel Sandlere7e5ac22011-02-22 16:10:21 -05003002 // if the user has locked rotation, we ignore the sensor
3003 if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
3004 if (isAnyPortrait(mUserRotation)) {
3005 return mUserRotation;
3006 } else {
3007 // it seems odd to obey the sensor at all if rotation lock is enabled
3008 return mPortraitRotation;
3009 }
3010 }
3011
Dianne Hackborne5439f22010-10-02 16:53:50 -07003012 int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation);
3013 if (isAnyPortrait(sensorRotation)) {
3014 return sensorRotation;
3015 }
3016 // try to preserve the old rotation if it was portrait
3017 if (isAnyPortrait(lastRotation)) {
3018 return lastRotation;
3019 }
3020 // default to one of the primary portrait rotations
3021 return mPortraitRotation;
3022 }
3023
3024 private boolean isAnyPortrait(int sensorRotation) {
3025 return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation;
3026 }
3027
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003028
3029 // User rotation: to be used when all else fails in assigning an orientation to the device
3030 public void setUserRotationMode(int mode, int rot) {
3031 ContentResolver res = mContext.getContentResolver();
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05003032
3033 // mUserRotationMode and mUserRotation will be assigned by the content observer
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003034 if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003035 Settings.System.putInt(res,
3036 Settings.System.USER_ROTATION,
3037 rot);
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05003038 Settings.System.putInt(res,
3039 Settings.System.ACCELEROMETER_ROTATION,
3040 0);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04003041 } else {
3042 Settings.System.putInt(res,
3043 Settings.System.ACCELEROMETER_ROTATION,
3044 1);
3045 }
3046 }
3047
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003048 public boolean detectSafeMode() {
3049 try {
3050 int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
Dianne Hackbornb1a79802009-09-29 15:18:31 -07003051 int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
Dianne Hackborna8730f92009-11-17 15:53:36 -08003052 int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003053 int trackballState = mWindowManager.getTrackballScancodeState(BTN_MOUSE);
Jeff Brownb09abc12011-01-13 21:08:27 -08003054 int volumeDownState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_VOLUME_DOWN);
3055 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
3056 || volumeDownState > 0;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07003057 performHapticFeedbackLw(null, mSafeMode
3058 ? HapticFeedbackConstants.SAFE_MODE_ENABLED
3059 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
Dianne Hackborn73b1ec82009-10-04 13:33:00 -07003060 if (mSafeMode) {
3061 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
3062 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
3063 } else {
3064 Log.i(TAG, "SAFE MODE not enabled");
3065 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003066 return mSafeMode;
3067 } catch (RemoteException e) {
3068 // Doom! (it's also local)
3069 throw new RuntimeException("window manager dead");
3070 }
3071 }
3072
Dianne Hackborn181ceb52009-08-27 22:16:40 -07003073 static long[] getLongIntArray(Resources r, int resid) {
3074 int[] ar = r.getIntArray(resid);
3075 if (ar == null) {
3076 return null;
3077 }
3078 long[] out = new long[ar.length];
3079 for (int i=0; i<ar.length; i++) {
3080 out[i] = ar[i];
3081 }
3082 return out;
3083 }
3084
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003085 /** {@inheritDoc} */
3086 public void systemReady() {
Dianne Hackbornb1a79802009-09-29 15:18:31 -07003087 // tell the keyguard
3088 mKeyguardMediator.onSystemReady();
3089 android.os.SystemProperties.set("dev.bootcomplete", "1");
3090 synchronized (mLock) {
3091 updateOrientationListenerLp();
Dianne Hackbornc777e072010-02-12 13:07:59 -08003092 mSystemReady = true;
3093 mHandler.post(new Runnable() {
3094 public void run() {
3095 updateSettings();
3096 }
3097 });
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003098 }
3099 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07003100
3101 ProgressDialog mBootMsgDialog = null;
3102
3103 /** {@inheritDoc} */
3104 public void showBootMessage(final CharSequence msg, final boolean always) {
3105 mHandler.post(new Runnable() {
3106 @Override public void run() {
3107 if (mBootMsgDialog == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07003108 mBootMsgDialog = new ProgressDialog(mContext) {
3109 // This dialog will consume all events coming in to
3110 // it, to avoid it trying to do things too early in boot.
3111 @Override public boolean dispatchKeyEvent(KeyEvent event) {
3112 return true;
3113 }
3114 @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) {
3115 return true;
3116 }
3117 @Override public boolean dispatchTouchEvent(MotionEvent ev) {
3118 return true;
3119 }
3120 @Override public boolean dispatchTrackballEvent(MotionEvent ev) {
3121 return true;
3122 }
3123 @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) {
3124 return true;
3125 }
3126 @Override public boolean dispatchPopulateAccessibilityEvent(
3127 AccessibilityEvent event) {
3128 return true;
3129 }
3130 };
Dianne Hackborn661cd522011-08-22 00:26:20 -07003131 mBootMsgDialog.setTitle(R.string.android_upgrading_title);
3132 mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
3133 mBootMsgDialog.setIndeterminate(true);
3134 mBootMsgDialog.getWindow().setType(
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07003135 WindowManager.LayoutParams.TYPE_BOOT_PROGRESS);
Dianne Hackborn661cd522011-08-22 00:26:20 -07003136 mBootMsgDialog.getWindow().addFlags(
3137 WindowManager.LayoutParams.FLAG_DIM_BEHIND
3138 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
3139 mBootMsgDialog.getWindow().setDimAmount(1);
3140 mBootMsgDialog.setCancelable(false);
3141 mBootMsgDialog.show();
3142 }
3143 mBootMsgDialog.setMessage(msg);
3144 }
3145 });
3146 }
3147
3148 /** {@inheritDoc} */
3149 public void hideBootMessages() {
3150 mHandler.post(new Runnable() {
3151 @Override public void run() {
3152 if (mBootMsgDialog != null) {
3153 mBootMsgDialog.dismiss();
3154 mBootMsgDialog = null;
3155 }
3156 }
3157 });
3158 }
3159
Mike Lockwood28569302010-01-28 11:54:40 -05003160 /** {@inheritDoc} */
3161 public void userActivity() {
3162 synchronized (mScreenLockTimeout) {
3163 if (mLockScreenTimerActive) {
3164 // reset the timer
3165 mHandler.removeCallbacks(mScreenLockTimeout);
3166 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
3167 }
3168 }
Daniel Sandler1d4d30a2011-04-28 12:35:29 -04003169
Daniel Sandler0129b312011-05-11 11:54:11 -04003170 if (mStatusBarService != null) {
3171 try {
3172 mStatusBarService.userActivity();
3173 } catch (RemoteException ex) {}
3174 }
Daniel Sandler0601eb72011-04-13 01:01:32 -04003175
3176 synchronized (mLock) {
3177 updateScreenSaverTimeoutLocked();
3178 }
3179 }
3180
Daniel Sandleree91d942011-08-03 14:13:36 -04003181 Runnable mScreenSaverActivator = null;
3182 /*new Runnable() {
Daniel Sandler0601eb72011-04-13 01:01:32 -04003183 public void run() {
3184 synchronized (this) {
3185 if (!(mScreenSaverEnabled && mScreenOn)) {
3186 Log.w(TAG, "mScreenSaverActivator ran, but the screensaver should not be showing. Who's driving this thing?");
3187 return;
3188 }
3189
3190 if (localLOGV) Log.v(TAG, "mScreenSaverActivator entering dreamland");
3191 try {
3192 String component = Settings.System.getString(
3193 mContext.getContentResolver(), Settings.Secure.DREAM_COMPONENT);
3194 if (component != null) {
3195 ComponentName cn = ComponentName.unflattenFromString(component);
3196 Intent intent = new Intent(Intent.ACTION_MAIN)
3197 .setComponent(cn)
3198 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
3199 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
3200 | Intent.FLAG_ACTIVITY_NO_USER_ACTION
3201 | Intent.FLAG_ACTIVITY_SINGLE_TOP);
3202 mContext.startActivity(intent);
3203 } else {
3204 Log.e(TAG, "Couldn't start screen saver: none selected");
3205 }
3206 } catch (android.content.ActivityNotFoundException exc) {
3207 // no screensaver? give up
3208 Log.e(TAG, "Couldn't start screen saver: none installed");
3209 }
3210 }
3211 }
3212 };
Daniel Sandleree91d942011-08-03 14:13:36 -04003213 */
Daniel Sandler0601eb72011-04-13 01:01:32 -04003214
3215 // Must call while holding mLock
3216 private void updateScreenSaverTimeoutLocked() {
Daniel Sandleree91d942011-08-03 14:13:36 -04003217 if (mScreenSaverActivator == null) return;
3218
Daniel Sandler0601eb72011-04-13 01:01:32 -04003219 synchronized (mScreenSaverActivator) {
3220 mHandler.removeCallbacks(mScreenSaverActivator);
3221 if (mScreenSaverEnabled && mScreenOn && mScreenSaverTimeout > 0) {
3222 if (localLOGV)
3223 Log.v(TAG, "scheduling screensaver for " + mScreenSaverTimeout + "ms from now");
3224 mHandler.postDelayed(mScreenSaverActivator, mScreenSaverTimeout);
3225 } else {
3226 if (localLOGV) {
3227 if (mScreenSaverTimeout == 0)
3228 Log.v(TAG, "screen saver disabled by user");
3229 else if (!mScreenOn)
3230 Log.v(TAG, "screen saver disabled while screen off");
3231 else
3232 Log.v(TAG, "screen saver disabled by wakelock");
3233 }
3234 }
3235 }
Mike Lockwood28569302010-01-28 11:54:40 -05003236 }
3237
3238 Runnable mScreenLockTimeout = new Runnable() {
3239 public void run() {
3240 synchronized (this) {
3241 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard");
3242 mKeyguardMediator.doKeyguardTimeout();
3243 mLockScreenTimerActive = false;
3244 }
3245 }
3246 };
3247
3248 private void updateLockScreenTimeout() {
3249 synchronized (mScreenLockTimeout) {
3250 boolean enable = (mAllowLockscreenWhenOn && mScreenOn && mKeyguardMediator.isSecure());
3251 if (mLockScreenTimerActive != enable) {
3252 if (enable) {
3253 if (localLOGV) Log.v(TAG, "setting lockscreen timer");
3254 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
3255 } else {
3256 if (localLOGV) Log.v(TAG, "clearing lockscreen timer");
3257 mHandler.removeCallbacks(mScreenLockTimeout);
3258 }
3259 mLockScreenTimerActive = enable;
3260 }
3261 }
3262 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003263
3264 /** {@inheritDoc} */
3265 public void enableScreenAfterBoot() {
3266 readLidState();
Dianne Hackborn32bc91d2009-03-27 16:16:03 -07003267 updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003268 }
Dianne Hackbornf54c8f92009-09-19 14:03:57 -07003269
Dianne Hackborn03759ed2009-03-27 16:04:08 -07003270 void updateRotation(int animFlags) {
Jeff Brown4aed78b2011-01-14 17:36:55 -08003271 mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN);
Mike Lockwood1753f7f2009-08-24 14:49:07 -07003272 int rotation = Surface.ROTATION_0;
Dianne Hackbornad7fa7f2011-01-07 14:06:50 -08003273 if (mHdmiPlugged) {
3274 rotation = Surface.ROTATION_0;
Jeff Brown4aed78b2011-01-14 17:36:55 -08003275 } else if (mLidOpen == LID_OPEN) {
Mike Lockwood1753f7f2009-08-24 14:49:07 -07003276 rotation = mLidOpenRotation;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003277 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04003278 rotation = mCarDockRotation;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003279 } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
Mike Lockwood2d1efbd2009-09-16 12:15:53 -04003280 rotation = mDeskDockRotation;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003281 }
3282 //if lid is closed orientation will be portrait
3283 try {
3284 //set orientation on WindowManager
Dianne Hackborn32bc91d2009-03-27 16:16:03 -07003285 mWindowManager.setRotation(rotation, true,
3286 mFancyRotationAnimation | animFlags);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003287 } catch (RemoteException e) {
3288 // Ignore
3289 }
3290 }
3291
3292 /**
Dianne Hackborn39c2d712009-09-22 11:41:31 -07003293 * Return an Intent to launch the currently active dock as home. Returns
3294 * null if the standard home should be launched.
3295 * @return
3296 */
3297 Intent createHomeDockIntent() {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07003298 Intent intent;
Dianne Hackborn867ab6472010-04-29 13:28:56 -07003299
3300 // What home does is based on the mode, not the dock state. That
3301 // is, when in car mode you should be taken to car home regardless
3302 // of whether we are actually in a car dock.
Dianne Hackborn78968392010-03-04 20:47:56 -08003303 if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07003304 intent = mCarDockIntent;
Dianne Hackborn78968392010-03-04 20:47:56 -08003305 } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07003306 intent = mDeskDockIntent;
3307 } else {
Dianne Hackborn39c2d712009-09-22 11:41:31 -07003308 return null;
3309 }
3310
3311 ActivityInfo ai = intent.resolveActivityInfo(
3312 mContext.getPackageManager(), PackageManager.GET_META_DATA);
3313 if (ai == null) {
3314 return null;
3315 }
3316
3317 if (ai.metaData != null && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) {
3318 intent = new Intent(intent);
3319 intent.setClassName(ai.packageName, ai.name);
3320 return intent;
3321 }
3322
3323 return null;
3324 }
3325
3326 void startDockOrHome() {
3327 Intent dock = createHomeDockIntent();
3328 if (dock != null) {
3329 try {
3330 mContext.startActivity(dock);
3331 return;
3332 } catch (ActivityNotFoundException e) {
3333 }
3334 }
3335 mContext.startActivity(mHomeIntent);
3336 }
3337
3338 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003339 * goes to the home screen
3340 * @return whether it did anything
3341 */
3342 boolean goHome() {
3343 if (false) {
3344 // This code always brings home to the front.
Dianne Hackborn256dd3b2009-05-19 18:51:21 -07003345 try {
3346 ActivityManagerNative.getDefault().stopAppSwitches();
3347 } catch (RemoteException e) {
3348 }
Dianne Hackborn94a679d2009-07-28 17:51:07 -07003349 sendCloseSystemWindows();
Dianne Hackborn39c2d712009-09-22 11:41:31 -07003350 startDockOrHome();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003351 } else {
3352 // This code brings home to the front or, if it is already
3353 // at the front, puts the device to sleep.
3354 try {
Wink Savilled2e6a332010-02-12 12:12:06 -08003355 if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) {
3356 /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry.
3357 Log.d(TAG, "UTS-TEST-MODE");
3358 } else {
3359 ActivityManagerNative.getDefault().stopAppSwitches();
3360 sendCloseSystemWindows();
3361 Intent dock = createHomeDockIntent();
3362 if (dock != null) {
3363 int result = ActivityManagerNative.getDefault()
3364 .startActivity(null, dock,
3365 dock.resolveTypeIfNeeded(mContext.getContentResolver()),
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003366 null, 0, null, null, 0, true /* onlyIfNeeded*/, false,
3367 null, null, false);
Wink Savilled2e6a332010-02-12 12:12:06 -08003368 if (result == IActivityManager.START_RETURN_INTENT_TO_CALLER) {
3369 return false;
3370 }
Dianne Hackborn39c2d712009-09-22 11:41:31 -07003371 }
3372 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003373 int result = ActivityManagerNative.getDefault()
3374 .startActivity(null, mHomeIntent,
3375 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003376 null, 0, null, null, 0, true /* onlyIfNeeded*/, false,
3377 null, null, false);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003378 if (result == IActivityManager.START_RETURN_INTENT_TO_CALLER) {
3379 return false;
3380 }
3381 } catch (RemoteException ex) {
3382 // bummer, the activity manager, which is in this process, is dead
3383 }
3384 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003385 return true;
3386 }
3387
The Android Open Source Project0727d222009-03-11 12:11:58 -07003388 public void setCurrentOrientationLw(int newOrientation) {
3389 synchronized (mLock) {
3390 if (newOrientation != mCurrentAppOrientation) {
3391 mCurrentAppOrientation = newOrientation;
3392 updateOrientationListenerLp();
3393 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003394 }
3395 }
Amith Yamasanic33cb712010-02-10 15:21:49 -08003396
The Android Open Source Project0727d222009-03-11 12:11:58 -07003397 public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {
Jim Miller89b17222009-10-27 14:54:09 -07003398 final boolean hapticsDisabled = Settings.System.getInt(mContext.getContentResolver(),
3399 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0;
Dianne Hackborn9dc06cc2009-11-17 18:19:23 -08003400 if (!always && (hapticsDisabled || mKeyguardMediator.isShowingAndNotHidden())) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003401 return false;
3402 }
Amith Yamasanic33cb712010-02-10 15:21:49 -08003403 long[] pattern = null;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003404 switch (effectId) {
3405 case HapticFeedbackConstants.LONG_PRESS:
Amith Yamasanic33cb712010-02-10 15:21:49 -08003406 pattern = mLongPressVibePattern;
3407 break;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07003408 case HapticFeedbackConstants.VIRTUAL_KEY:
Amith Yamasanic33cb712010-02-10 15:21:49 -08003409 pattern = mVirtualKeyVibePattern;
3410 break;
3411 case HapticFeedbackConstants.KEYBOARD_TAP:
3412 pattern = mKeyboardTapVibePattern;
3413 break;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07003414 case HapticFeedbackConstants.SAFE_MODE_DISABLED:
Amith Yamasanic33cb712010-02-10 15:21:49 -08003415 pattern = mSafeModeDisabledVibePattern;
3416 break;
Dianne Hackbornb1a79802009-09-29 15:18:31 -07003417 case HapticFeedbackConstants.SAFE_MODE_ENABLED:
Amith Yamasanic33cb712010-02-10 15:21:49 -08003418 pattern = mSafeModeEnabledVibePattern;
3419 break;
Amith Yamasanic33cb712010-02-10 15:21:49 -08003420 default:
3421 return false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003422 }
Amith Yamasanic33cb712010-02-10 15:21:49 -08003423 if (pattern.length == 1) {
3424 // One-shot vibration
3425 mVibrator.vibrate(pattern[0]);
3426 } else {
3427 // Pattern vibration
3428 mVibrator.vibrate(pattern, -1);
3429 }
3430 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003431 }
3432
Daniel Sandler0601eb72011-04-13 01:01:32 -04003433 public void screenOnStartedLw() {
3434 // The window manager has just grabbed a wake lock. This is our cue to disable the screen
3435 // saver.
3436 synchronized (mLock) {
3437 mScreenSaverEnabled = false;
3438 }
3439 }
3440
The Android Open Source Project0727d222009-03-11 12:11:58 -07003441 public void screenOnStoppedLw() {
Daniel Sandler0601eb72011-04-13 01:01:32 -04003442 if (mPowerManager.isScreenOn()) {
3443 if (!mKeyguardMediator.isShowingAndNotHidden()) {
3444 long curTime = SystemClock.uptimeMillis();
3445 mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT);
3446 }
3447
3448 synchronized (mLock) {
3449 // even if the keyguard is up, now that all the wakelocks have been released, we
3450 // should re-enable the screen saver
3451 mScreenSaverEnabled = true;
3452 updateScreenSaverTimeoutLocked();
3453 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003454 }
3455 }
Mike Lockwoodfcb39242009-10-21 23:01:07 -04003456
3457 public boolean allowKeyRepeat() {
3458 // disable key repeat when screen is off
3459 return mScreenOn;
3460 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003461
Joe Onorato664644d2011-01-23 17:53:23 -08003462 private void updateSystemUiVisibility() {
3463 // If there is no window focused, there will be nobody to handle the events
3464 // anyway, so just hang on in whatever state we're in until things settle down.
3465 if (mFocusedWindow != null) {
Joe Onorato14782f72011-01-25 19:53:17 -08003466 final WindowManager.LayoutParams params = mFocusedWindow.getAttrs();
3467 final int visibility = params.systemUiVisibility | params.subtreeSystemUiVisibility;
Joe Onorato664644d2011-01-23 17:53:23 -08003468 mHandler.post(new Runnable() {
3469 public void run() {
3470 if (mStatusBarService == null) {
3471 mStatusBarService = IStatusBarService.Stub.asInterface(
3472 ServiceManager.getService("statusbar"));
3473 }
3474 if (mStatusBarService != null) {
3475 // need to assume status bar privileges to invoke lights on
3476 long origId = Binder.clearCallingIdentity();
3477 try {
3478 mStatusBarService.setSystemUiVisibility(visibility);
3479 } catch (RemoteException e) {
3480 // not much to be done
3481 mStatusBarService = null;
3482 } finally {
3483 Binder.restoreCallingIdentity(origId);
3484 }
3485 }
3486 }
3487 });
3488 }
3489 }
3490
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003491 public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
3492 pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
3493 pw.print(" mSystemRead="); pw.println(mSystemReady);
3494 pw.print(prefix); pw.print("mLidOpen="); pw.print(mLidOpen);
3495 pw.print(" mLidOpenRotation="); pw.print(mLidOpenRotation);
3496 pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged);
3497 pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
3498 pw.print(" mDockMode="); pw.print(mDockMode);
3499 pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
3500 pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
3501 pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
3502 pw.print(" mUserRotation="); pw.print(mUserRotation);
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05003503 pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003504 pw.print(prefix); pw.print("mAccelerometerDefault="); pw.print(mAccelerometerDefault);
3505 pw.print(" mCurrentAppOrientation="); pw.println(mCurrentAppOrientation);
3506 pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
3507 pw.print(mCarDockEnablesAccelerometer);
3508 pw.print(" mDeskDockEnablesAccelerometer=");
3509 pw.println(mDeskDockEnablesAccelerometer);
3510 pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
3511 pw.print(mLidKeyboardAccessibility);
3512 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
3513 pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior);
3514 pw.print(prefix); pw.print("mScreenOn="); pw.print(mScreenOn);
3515 pw.print(" mOrientationSensorEnabled="); pw.print(mOrientationSensorEnabled);
3516 pw.print(" mHasSoftInput="); pw.println(mHasSoftInput);
3517 pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft);
3518 pw.print(","); pw.print(mUnrestrictedScreenTop);
3519 pw.print(") "); pw.print(mUnrestrictedScreenWidth);
3520 pw.print("x"); pw.println(mUnrestrictedScreenHeight);
3521 pw.print(prefix); pw.print("mRestrictedScreen=("); pw.print(mRestrictedScreenLeft);
3522 pw.print(","); pw.print(mRestrictedScreenTop);
3523 pw.print(") "); pw.print(mRestrictedScreenWidth);
3524 pw.print("x"); pw.println(mRestrictedScreenHeight);
3525 pw.print(prefix); pw.print("mCur=("); pw.print(mCurLeft);
3526 pw.print(","); pw.print(mCurTop);
3527 pw.print(")-("); pw.print(mCurRight);
3528 pw.print(","); pw.print(mCurBottom); pw.println(")");
3529 pw.print(prefix); pw.print("mContent=("); pw.print(mContentLeft);
3530 pw.print(","); pw.print(mContentTop);
3531 pw.print(")-("); pw.print(mContentRight);
3532 pw.print(","); pw.print(mContentBottom); pw.println(")");
3533 pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft);
3534 pw.print(","); pw.print(mDockTop);
3535 pw.print(")-("); pw.print(mDockRight);
3536 pw.print(","); pw.print(mDockBottom); pw.println(")");
3537 pw.print(prefix); pw.print("mDockLayer="); pw.println(mDockLayer);
3538 pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState=");
3539 pw.println(mTopFullscreenOpaqueWindowState);
3540 pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
3541 pw.print(" mForceStatusBar="); pw.print(mForceStatusBar);
3542 pw.print(" mHideLockScreen="); pw.println(mHideLockScreen);
3543 pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard);
3544 pw.print(" mHomePressed="); pw.println(mHomePressed);
3545 pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
3546 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
3547 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
3548 pw.print(prefix); pw.print("mEndcallBehavior="); pw.print(mEndcallBehavior);
3549 pw.print(" mIncallPowerBehavior="); pw.print(mIncallPowerBehavior);
3550 pw.print(" mLongPressOnHomeBehavior="); pw.println(mLongPressOnHomeBehavior);
3551 pw.print(prefix); pw.print("mLandscapeRotation="); pw.print(mLandscapeRotation);
3552 pw.print(" mSeascapeRotation="); pw.println(mSeascapeRotation);
3553 pw.print(prefix); pw.print("mPortraitRotation="); pw.print(mPortraitRotation);
3554 pw.print(" mUpsideDownRotation="); pw.println(mUpsideDownRotation);
3555 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08003556}