blob: a598ce9ebcd6c2e56716470912906bdc5ba912c8 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080017package com.android.server.wm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
20import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
21import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -070022import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
24import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
26import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070027import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
29import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
31import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
32import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
33import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070034import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035
36import com.android.internal.app.IBatteryStats;
37import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080038import com.android.internal.policy.impl.PhoneWindowManager;
Christopher Tatea53146c2010-09-07 11:57:52 -070039import com.android.internal.view.BaseInputHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import com.android.internal.view.IInputContext;
41import com.android.internal.view.IInputMethodClient;
42import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080043import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080044import com.android.server.AttributeCache;
45import com.android.server.EventLogTags;
46import com.android.server.PowerManagerService;
47import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import com.android.server.am.BatteryStatsService;
49
50import android.Manifest;
51import android.app.ActivityManagerNative;
52import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080053import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070054import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070055import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070057import android.content.Intent;
58import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.content.pm.ActivityInfo;
60import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070061import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080063import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070064import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.graphics.Matrix;
66import android.graphics.PixelFormat;
67import android.graphics.Rect;
68import android.graphics.Region;
69import android.os.BatteryStats;
70import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070071import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.os.Debug;
73import android.os.Handler;
74import android.os.IBinder;
75import android.os.LocalPowerManager;
76import android.os.Looper;
77import android.os.Message;
78import android.os.Parcel;
79import android.os.ParcelFileDescriptor;
80import android.os.Power;
81import android.os.PowerManager;
82import android.os.Process;
83import android.os.RemoteException;
84import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070085import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.os.SystemClock;
87import android.os.SystemProperties;
88import android.os.TokenWatcher;
89import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -070090import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.util.EventLog;
Jim Millerd6b57052010-06-07 17:52:42 -070092import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080093import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070095import android.util.TypedValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import android.view.IApplicationToken;
98import android.view.IOnKeyguardExitResult;
99import android.view.IRotationWatcher;
100import android.view.IWindow;
101import android.view.IWindowManager;
102import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700103import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700104import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700105import android.view.InputEvent;
Christopher Tatea53146c2010-09-07 11:57:52 -0700106import android.view.InputHandler;
107import android.view.InputQueue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.view.KeyEvent;
109import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110import android.view.Surface;
111import android.view.SurfaceSession;
112import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.WindowManager;
114import android.view.WindowManagerImpl;
115import android.view.WindowManagerPolicy;
116import android.view.WindowManager.LayoutParams;
117import android.view.animation.Animation;
118import android.view.animation.AnimationUtils;
119import android.view.animation.Transformation;
120
121import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700122import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import java.io.File;
124import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700125import java.io.FileInputStream;
126import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.IOException;
128import java.io.OutputStream;
129import java.io.OutputStreamWriter;
130import java.io.PrintWriter;
131import java.io.StringWriter;
132import java.net.Socket;
133import java.util.ArrayList;
134import java.util.HashMap;
135import java.util.HashSet;
136import java.util.Iterator;
137import java.util.List;
138
139/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700140public class WindowManagerService extends IWindowManager.Stub
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700141 implements Watchdog.Monitor {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 static final String TAG = "WindowManager";
143 static final boolean DEBUG = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800144 static final boolean DEBUG_ADD_REMOVE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 static final boolean DEBUG_FOCUS = false;
146 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800147 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800148 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final boolean DEBUG_LAYERS = false;
150 static final boolean DEBUG_INPUT = false;
151 static final boolean DEBUG_INPUT_METHOD = false;
152 static final boolean DEBUG_VISIBILITY = false;
Dianne Hackbornbdd52b22009-09-02 21:46:19 -0700153 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800154 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700156 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 static final boolean DEBUG_APP_TRANSITIONS = false;
158 static final boolean DEBUG_STARTING_WINDOW = false;
159 static final boolean DEBUG_REORDER = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -0700160 static final boolean DEBUG_WALLPAPER = false;
Christopher Tate994ef922011-01-12 20:06:07 -0800161 static final boolean DEBUG_DRAG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700163 static final boolean HIDE_STACK_CRAWLS = true;
Michael Chan53071d62009-05-13 17:29:48 -0700164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean PROFILE_ORIENTATION = false;
166 static final boolean BLUR = true;
Dave Bortcfe65242009-04-09 14:51:04 -0700167 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 /** How much to multiply the policy's type layer, to reserve room
170 * for multiple windows of the same type and Z-ordering adjustment
171 * with TYPE_LAYER_OFFSET. */
172 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
175 * or below others in the same layer. */
176 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 /** How much to increment the layer for each window, to reserve room
179 * for effect surfaces between them.
180 */
181 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 /** The maximum length we will accept for a loaded animation duration:
184 * this is 10 seconds.
185 */
186 static final int MAX_ANIMATION_DURATION = 10*1000;
187
188 /** Amount of time (in milliseconds) to animate the dim surface from one
189 * value to another, when no window animation is driving it.
190 */
191 static final int DEFAULT_DIM_DURATION = 200;
192
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700193 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
194 * compatible windows.
195 */
196 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
197
Dianne Hackborna1111872010-11-23 20:55:11 -0800198 /**
199 * If true, the window manager will do its own custom freezing and general
200 * management of the screen during rotation.
201 */
202 static final boolean CUSTOM_SCREEN_ROTATION = true;
203
Jeff Brown7fbdc842010-06-17 20:52:56 -0700204 // Maximum number of milliseconds to wait for input event injection.
205 // FIXME is this value reasonable?
206 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brownb09abc12011-01-13 21:08:27 -0800207
208 // Maximum number of milliseconds to wait for input devices to be enumerated before
209 // proceding with safe mode detection.
210 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700211
212 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800213 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 static final int UPDATE_FOCUS_NORMAL = 0;
216 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
217 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
218 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700221 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222
223 /**
224 * Condition waited on by {@link #reenableKeyguard} to know the call to
225 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500226 * This is set to true only if mKeyguardTokenWatcher.acquired() has
227 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500229 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230
Jim Miller284b62e2010-06-08 14:27:42 -0700231 private static final int ALLOW_DISABLE_YES = 1;
232 private static final int ALLOW_DISABLE_NO = 0;
233 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
234 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
235
Mike Lockwood983ee092009-11-22 01:42:24 -0500236 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
237 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700239 if (shouldAllowDisableKeyguard()) {
240 mPolicy.enableKeyguard(false);
241 mKeyguardDisabled = true;
242 } else {
243 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 }
246 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700247 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500248 synchronized (mKeyguardTokenWatcher) {
249 mKeyguardDisabled = false;
250 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 }
252 }
253 };
254
Jim Miller284b62e2010-06-08 14:27:42 -0700255 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
256 @Override
257 public void onReceive(Context context, Intent intent) {
258 mPolicy.enableKeyguard(true);
259 synchronized(mKeyguardTokenWatcher) {
260 // lazily evaluate this next time we're asked to disable keyguard
261 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
262 mKeyguardDisabled = false;
263 }
264 }
265 };
266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 final Context mContext;
268
269 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
274
275 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700278
David 'Digit' Turner910a0682011-02-05 00:34:46 +0100279 private static final boolean mInEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 /**
282 * All currently active sessions with clients.
283 */
284 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 /**
287 * Mapping from an IWindow IBinder to the server's Window object.
288 * This is also used as the lock for all of our state.
289 */
290 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
291
292 /**
293 * Mapping from a token IBinder to a WindowToken object.
294 */
295 final HashMap<IBinder, WindowToken> mTokenMap =
296 new HashMap<IBinder, WindowToken>();
297
298 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 * Window tokens that are in the process of exiting, but still
300 * on screen for animations.
301 */
302 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
303
304 /**
305 * Z-ordered (bottom-most first) list of all application tokens, for
306 * controlling the ordering of windows in different applications. This
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800307 * contains AppWindowToken objects.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 */
309 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
310
311 /**
312 * Application tokens that are in the process of exiting, but still
313 * on screen for animations.
314 */
315 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
316
317 /**
318 * List of window tokens that have finished starting their application,
319 * and now need to have the policy remove their windows.
320 */
321 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
322
323 /**
324 * Z-ordered (bottom-most first) list of all Window objects.
325 */
Jeff Browne33348b2010-07-15 23:54:05 -0700326 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327
328 /**
329 * Windows that are being resized. Used so we can tell the client about
330 * the resize after closing the transaction in which we resized the
331 * underlying surface.
332 */
333 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
334
335 /**
336 * Windows whose animations have ended and now must be removed.
337 */
338 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
339
340 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800341 * Used when processing mPendingRemove to avoid working on the original array.
342 */
343 WindowState[] mPendingRemoveTmp = new WindowState[20];
344
345 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 * Windows whose surface should be destroyed.
347 */
348 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
349
350 /**
351 * Windows that have lost input focus and are waiting for the new
352 * focus window to be displayed before they are told about this.
353 */
354 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
355
356 /**
357 * This is set when we have run out of memory, and will either be an empty
358 * list or contain windows that need to be force removed.
359 */
360 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700361
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800362 /**
363 * Used when rebuilding window list to keep track of windows that have
364 * been removed.
365 */
366 WindowState[] mRebuildTmp = new WindowState[20];
367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700371 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 Surface mBlurSurface;
373 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700374 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800375 StrictModeFlash mStrictModeFlash;
Dianne Hackborna1111872010-11-23 20:55:11 -0800376 ScreenRotationAnimation mScreenRotationAnimation;
Romain Guy06882f82009-06-10 13:36:04 -0700377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 final float[] mTmpFloats = new float[9];
381
382 boolean mSafeMode;
383 boolean mDisplayEnabled = false;
384 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700385 int mInitialDisplayWidth = 0;
386 int mInitialDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 int mRotation = 0;
388 int mRequestedRotation = 0;
389 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700390 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 ArrayList<IRotationWatcher> mRotationWatchers
392 = new ArrayList<IRotationWatcher>();
Dianne Hackborn89ba6752011-01-23 16:51:16 -0800393 int mDeferredRotation;
394 int mDeferredRotationAnimFlags;
Romain Guy06882f82009-06-10 13:36:04 -0700395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 boolean mLayoutNeeded = true;
397 boolean mAnimationPending = false;
398 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800399 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 boolean mWindowsFreezingScreen = false;
401 long mFreezeGcPending = 0;
402 int mAppsFreezingScreen = 0;
403
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800404 int mLayoutSeq = 0;
405
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800406 // State while inside of layoutAndPlaceSurfacesLocked().
407 boolean mFocusMayChange;
408
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800409 Configuration mCurConfiguration = new Configuration();
410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 // This is held as long as we have the screen frozen, to give us time to
412 // perform a rotation animation when turning off shows the lock screen which
413 // changes the orientation.
414 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 // State management of app transitions. When we are preparing for a
417 // transition, mNextAppTransition will be the kind of transition to
418 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
419 // mOpeningApps and mClosingApps are the lists of tokens that will be
420 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700421 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700422 String mNextAppTransitionPackage;
423 int mNextAppTransitionEnter;
424 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700426 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 boolean mAppTransitionTimeout = false;
428 boolean mStartingIconInTransition = false;
429 boolean mSkipAppTransitionAnimation = false;
430 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
431 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700432 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
433 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 H mH = new H();
438
439 WindowState mCurrentFocus = null;
440 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 // This just indicates the window the input method is on top of, not
443 // necessarily the window its input is going to.
444 WindowState mInputMethodTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 boolean mInputMethodTargetWaitingAnim;
446 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 WindowState mInputMethodWindow = null;
449 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
450
Jeff Brown2992ea72011-01-28 22:04:14 -0800451 boolean mHardKeyboardAvailable;
452 boolean mHardKeyboardEnabled;
453 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
454
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700455 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800456
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700457 // If non-null, this is the currently visible window that is associated
458 // with the wallpaper.
459 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700460 // If non-null, we are in the middle of animating from one wallpaper target
461 // to another, and this is the lower one in Z-order.
462 WindowState mLowerWallpaperTarget = null;
463 // If non-null, we are in the middle of animating from one wallpaper target
464 // to another, and this is the higher one in Z-order.
465 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800466 // Window currently running an animation that has requested it be detached
467 // from the wallpaper. This means we need to ensure the wallpaper is
468 // visible behind it in case it animates in a way that would allow it to be
469 // seen.
470 WindowState mWindowDetachedWallpaper = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700471 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700472 float mLastWallpaperX = -1;
473 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800474 float mLastWallpaperXStep = -1;
475 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700476 // This is set when we are waiting for a wallpaper to tell us it is done
477 // changing its scroll position.
478 WindowState mWaitingOnWallpaper;
479 // The last time we had a timeout when waiting for a wallpaper.
480 long mLastWallpaperTimeoutTime;
481 // We give a wallpaper up to 150ms to finish scrolling.
482 static final long WALLPAPER_TIMEOUT = 150;
483 // Time we wait after a timeout before trying to wait again.
484 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 AppWindowToken mFocusedApp = null;
487
488 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 float mWindowAnimationScale = 1.0f;
491 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700492
Jeff Brown46b9ac02010-04-22 18:58:52 -0700493 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494
495 // Who is holding the screen on.
496 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700497 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700498
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700499 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800500
Christopher Tatea53146c2010-09-07 11:57:52 -0700501 DragState mDragState = null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800502 final InputHandler mDragInputHandler = new BaseInputHandler() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700503 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700504 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
505 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700506 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700507 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
508 && mDragState != null) {
509 boolean endDrag = false;
510 final float newX = event.getRawX();
511 final float newY = event.getRawY();
512
Christopher Tatea53146c2010-09-07 11:57:52 -0700513 switch (event.getAction()) {
514 case MotionEvent.ACTION_DOWN: {
515 if (DEBUG_DRAG) {
516 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
517 }
518 } break;
519
520 case MotionEvent.ACTION_MOVE: {
521 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700522 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700523 mDragState.notifyMoveLw(newX, newY);
524 }
525 } break;
526
527 case MotionEvent.ACTION_UP: {
528 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
529 + newX + "," + newY);
530 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700531 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700532 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700533 } break;
534
535 case MotionEvent.ACTION_CANCEL: {
536 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
537 endDrag = true;
538 } break;
539 }
540
541 if (endDrag) {
542 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
543 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700544 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700545 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700546 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700547 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700548
549 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700550 }
551 } catch (Exception e) {
552 Slog.e(TAG, "Exception caught by drag handleMotion", e);
553 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700554 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700555 }
556 }
557 };
558
559 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 * Whether the UI is currently running in touch mode (not showing
561 * navigational focus because the user is directly pressing the screen).
562 */
563 boolean mInTouchMode = false;
564
565 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700566 private ArrayList<WindowChangeListener> mWindowChangeListeners =
567 new ArrayList<WindowChangeListener>();
568 private boolean mWindowsChanged = false;
569
570 public interface WindowChangeListener {
571 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700572 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574
Dianne Hackbornc485a602009-03-24 22:39:49 -0700575 final Configuration mTempConfiguration = new Configuration();
Dianne Hackbornc4db95c2009-07-21 17:46:02 -0700576 int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700577
578 // The frame use to limit the size of the app running in compatibility mode.
579 Rect mCompatibleScreenFrame = new Rect();
580 // The surface used to fill the outer rim of the app running in compatibility mode.
581 Surface mBackgroundFillerSurface = null;
Dianne Hackbornac1471a2011-02-03 13:46:06 -0800582 WindowState mBackgroundFillerTarget = null;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 public static WindowManagerService main(Context context,
585 PowerManagerService pm, boolean haveInputMethods) {
586 WMThread thr = new WMThread(context, pm, haveInputMethods);
587 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 synchronized (thr) {
590 while (thr.mService == null) {
591 try {
592 thr.wait();
593 } catch (InterruptedException e) {
594 }
595 }
Jozef BABJAK06e57b52011-01-20 08:09:25 +0100596 return thr.mService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 }
Romain Guy06882f82009-06-10 13:36:04 -0700599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 static class WMThread extends Thread {
601 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 private final Context mContext;
604 private final PowerManagerService mPM;
605 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 public WMThread(Context context, PowerManagerService pm,
608 boolean haveInputMethods) {
609 super("WindowManager");
610 mContext = context;
611 mPM = pm;
612 mHaveInputMethods = haveInputMethods;
613 }
Romain Guy06882f82009-06-10 13:36:04 -0700614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 public void run() {
616 Looper.prepare();
617 WindowManagerService s = new WindowManagerService(mContext, mPM,
618 mHaveInputMethods);
619 android.os.Process.setThreadPriority(
620 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700621 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 synchronized (this) {
624 mService = s;
625 notifyAll();
626 }
Romain Guy06882f82009-06-10 13:36:04 -0700627
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700628 // For debug builds, log event loop stalls to dropbox for analysis.
629 if (StrictMode.conditionallyEnableDebugLogging()) {
630 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
631 }
632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 Looper.loop();
634 }
635 }
636
637 static class PolicyThread extends Thread {
638 private final WindowManagerPolicy mPolicy;
639 private final WindowManagerService mService;
640 private final Context mContext;
641 private final PowerManagerService mPM;
642 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 public PolicyThread(WindowManagerPolicy policy,
645 WindowManagerService service, Context context,
646 PowerManagerService pm) {
647 super("WindowManagerPolicy");
648 mPolicy = policy;
649 mService = service;
650 mContext = context;
651 mPM = pm;
652 }
Romain Guy06882f82009-06-10 13:36:04 -0700653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 public void run() {
655 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800656 WindowManagerPolicyThread.set(this, Looper.myLooper());
657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800659 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 android.os.Process.setThreadPriority(
661 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700662 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 synchronized (this) {
666 mRunning = true;
667 notifyAll();
668 }
Romain Guy06882f82009-06-10 13:36:04 -0700669
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700670 // For debug builds, log event loop stalls to dropbox for analysis.
671 if (StrictMode.conditionallyEnableDebugLogging()) {
672 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
673 }
674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 Looper.loop();
676 }
677 }
678
679 private WindowManagerService(Context context, PowerManagerService pm,
680 boolean haveInputMethods) {
681 mContext = context;
682 mHaveInputMethods = haveInputMethods;
683 mLimitedAlphaCompositing = context.getResources().getBoolean(
684 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 mPowerManager = pm;
687 mPowerManager.setPolicy(mPolicy);
688 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
689 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
690 "SCREEN_FROZEN");
691 mScreenFrozenLock.setReferenceCounted(false);
692
693 mActivityManager = ActivityManagerNative.getDefault();
694 mBatteryStats = BatteryStatsService.getService();
695
696 // Get persisted window scale setting
697 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
698 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
699 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
700 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700701
Jim Miller284b62e2010-06-08 14:27:42 -0700702 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
703 IntentFilter filter = new IntentFilter();
704 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
705 mContext.registerReceiver(mBroadcastReceiver, filter);
706
Jeff Brown46b9ac02010-04-22 18:58:52 -0700707 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
708 "KEEP_SCREEN_ON_FLAG");
709 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710
Jeff Browne33348b2010-07-15 23:54:05 -0700711 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -0700712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
714 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 synchronized (thr) {
717 while (!thr.mRunning) {
718 try {
719 thr.wait();
720 } catch (InterruptedException e) {
721 }
722 }
723 }
Romain Guy06882f82009-06-10 13:36:04 -0700724
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700725 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 // Add ourself to the Watchdog monitors.
728 Watchdog.getInstance().addMonitor(this);
729 }
730
731 @Override
732 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
733 throws RemoteException {
734 try {
735 return super.onTransact(code, data, reply, flags);
736 } catch (RuntimeException e) {
737 // The window manager only throws security exceptions, so let's
738 // log all others.
739 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800740 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 }
742 throw e;
743 }
744 }
745
Jeff Browne33348b2010-07-15 23:54:05 -0700746 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800748 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 TAG, "Adding window " + window + " at "
750 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
751 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700752 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 }
754
Jeff Browne33348b2010-07-15 23:54:05 -0700755 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800757 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 TAG, "Adding window " + window + " at "
759 + i + " of " + mWindows.size() + " (before " + pos + ")");
760 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700761 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 }
763
764 //This method finds out the index of a window that has the same app token as
765 //win. used for z ordering the windows in mWindows
766 private int findIdxBasedOnAppTokens(WindowState win) {
767 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -0700768 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769 int jmax = localmWindows.size();
770 if(jmax == 0) {
771 return -1;
772 }
773 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -0700774 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 if(wentry.mAppToken == win.mAppToken) {
776 return j;
777 }
778 }
779 return -1;
780 }
Romain Guy06882f82009-06-10 13:36:04 -0700781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
783 final IWindow client = win.mClient;
784 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -0700785 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 final int N = localmWindows.size();
788 final WindowState attached = win.mAttachedWindow;
789 int i;
790 if (attached == null) {
791 int tokenWindowsPos = token.windows.size();
792 if (token.appWindowToken != null) {
793 int index = tokenWindowsPos-1;
794 if (index >= 0) {
795 // If this application has existing windows, we
796 // simply place the new window on top of them... but
797 // keep the starting window on top.
798 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
799 // Base windows go behind everything else.
800 placeWindowBefore(token.windows.get(0), win);
801 tokenWindowsPos = 0;
802 } else {
803 AppWindowToken atoken = win.mAppToken;
804 if (atoken != null &&
805 token.windows.get(index) == atoken.startingWindow) {
806 placeWindowBefore(token.windows.get(index), win);
807 tokenWindowsPos--;
808 } else {
809 int newIdx = findIdxBasedOnAppTokens(win);
810 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700811 //there is a window above this one associated with the same
812 //apptoken note that the window could be a floating window
813 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 //windows associated with this token.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800815 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
816 Slog.v(TAG, "Adding window " + win + " at "
817 + (newIdx+1) + " of " + N);
818 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700820 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -0700821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823 }
824 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800825 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 TAG, "Figuring out where to add app window "
827 + client.asBinder() + " (token=" + token + ")");
828 // Figure out where the window should go, based on the
829 // order of applications.
830 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -0700831 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 for (i=NA-1; i>=0; i--) {
833 AppWindowToken t = mAppTokens.get(i);
834 if (t == token) {
835 i--;
836 break;
837 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800838
Dianne Hackborna8f60182009-09-01 19:01:50 -0700839 // We haven't reached the token yet; if this token
840 // is not going to the bottom and has windows, we can
841 // use it as an anchor for when we do reach the token.
842 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 pos = t.windows.get(0);
844 }
845 }
846 // We now know the index into the apps. If we found
847 // an app window above, that gives us the position; else
848 // we need to look some more.
849 if (pos != null) {
850 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -0700851 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 if (atoken != null) {
853 final int NC = atoken.windows.size();
854 if (NC > 0) {
855 WindowState bottom = atoken.windows.get(0);
856 if (bottom.mSubLayer < 0) {
857 pos = bottom;
858 }
859 }
860 }
861 placeWindowBefore(pos, win);
862 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700863 // Continue looking down until we find the first
864 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 while (i >= 0) {
866 AppWindowToken t = mAppTokens.get(i);
867 final int NW = t.windows.size();
868 if (NW > 0) {
869 pos = t.windows.get(NW-1);
870 break;
871 }
872 i--;
873 }
874 if (pos != null) {
875 // Move in front of any windows attached to this
876 // one.
Jeff Browne33348b2010-07-15 23:54:05 -0700877 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 if (atoken != null) {
879 final int NC = atoken.windows.size();
880 if (NC > 0) {
881 WindowState top = atoken.windows.get(NC-1);
882 if (top.mSubLayer >= 0) {
883 pos = top;
884 }
885 }
886 }
887 placeWindowAfter(pos, win);
888 } else {
889 // Just search for the start of this layer.
890 final int myLayer = win.mBaseLayer;
891 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -0700892 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 if (w.mBaseLayer > myLayer) {
894 break;
895 }
896 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800897 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
898 Slog.v(TAG, "Adding window " + win + " at "
899 + i + " of " + N);
900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700902 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 }
904 }
905 }
906 } else {
907 // Figure out where window should go, based on layer.
908 final int myLayer = win.mBaseLayer;
909 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -0700910 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 i++;
912 break;
913 }
914 }
915 if (i < 0) i = 0;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800916 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700917 TAG, "Adding window " + win + " at "
918 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700920 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 }
922 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800923 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 token.windows.add(tokenWindowsPos, win);
925 }
926
927 } else {
928 // Figure out this window's ordering relative to the window
929 // it is attached to.
930 final int NA = token.windows.size();
931 final int sublayer = win.mSubLayer;
932 int largestSublayer = Integer.MIN_VALUE;
933 WindowState windowWithLargestSublayer = null;
934 for (i=0; i<NA; i++) {
935 WindowState w = token.windows.get(i);
936 final int wSublayer = w.mSubLayer;
937 if (wSublayer >= largestSublayer) {
938 largestSublayer = wSublayer;
939 windowWithLargestSublayer = w;
940 }
941 if (sublayer < 0) {
942 // For negative sublayers, we go below all windows
943 // in the same sublayer.
944 if (wSublayer >= sublayer) {
945 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800946 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 token.windows.add(i, win);
948 }
949 placeWindowBefore(
950 wSublayer >= 0 ? attached : w, win);
951 break;
952 }
953 } else {
954 // For positive sublayers, we go above all windows
955 // in the same sublayer.
956 if (wSublayer > sublayer) {
957 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800958 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 token.windows.add(i, win);
960 }
961 placeWindowBefore(w, win);
962 break;
963 }
964 }
965 }
966 if (i >= NA) {
967 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800968 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 token.windows.add(win);
970 }
971 if (sublayer < 0) {
972 placeWindowBefore(attached, win);
973 } else {
974 placeWindowAfter(largestSublayer >= 0
975 ? windowWithLargestSublayer
976 : attached,
977 win);
978 }
979 }
980 }
Romain Guy06882f82009-06-10 13:36:04 -0700981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 if (win.mAppToken != null && addToToken) {
983 win.mAppToken.allAppWindows.add(win);
984 }
985 }
Romain Guy06882f82009-06-10 13:36:04 -0700986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 static boolean canBeImeTarget(WindowState w) {
988 final int fl = w.mAttrs.flags
989 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -0800990 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
991 || w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
992 if (DEBUG_INPUT_METHOD) {
993 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
994 if (!w.isVisibleOrAdding()) {
995 Slog.i(TAG, " mSurface=" + w.mSurface + " reportDestroy=" + w.mReportDestroySurface
996 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
997 + " policyVis=" + w.mPolicyVisibility + " attachHid=" + w.mAttachedHidden
998 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
999 if (w.mAppToken != null) {
1000 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1001 }
1002 }
1003 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 return w.isVisibleOrAdding();
1005 }
1006 return false;
1007 }
Romain Guy06882f82009-06-10 13:36:04 -07001008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001010 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 final int N = localmWindows.size();
1012 WindowState w = null;
1013 int i = N;
1014 while (i > 0) {
1015 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001016 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001017
Dianne Hackborne75d8722011-01-27 19:37:40 -08001018 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1019 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001021 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 // Yet more tricksyness! If this window is a "starting"
1024 // window, we do actually want to be on top of it, but
1025 // it is not -really- where input will go. So if the caller
1026 // is not actually looking to move the IME, look down below
1027 // for a real window to target...
1028 if (!willMove
1029 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1030 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001031 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001032 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1033 i--;
1034 w = wb;
1035 }
1036 }
1037 break;
1038 }
1039 }
Romain Guy06882f82009-06-10 13:36:04 -07001040
Dianne Hackborne75d8722011-01-27 19:37:40 -08001041 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
1042
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001043 // Now, a special case -- if the last target's window is in the
1044 // process of exiting, and is above the new target, keep on the
1045 // last target to avoid flicker. Consider for example a Dialog with
1046 // the IME shown: when the Dialog is dismissed, we want to keep
1047 // the IME above it until it is completely gone so it doesn't drop
1048 // behind the dialog or its full-screen scrim.
1049 if (mInputMethodTarget != null && w != null
1050 && mInputMethodTarget.isDisplayedLw()
1051 && mInputMethodTarget.mExiting) {
1052 if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
1053 w = mInputMethodTarget;
1054 i = localmWindows.indexOf(w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001055 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001056 }
1057 }
Romain Guy06882f82009-06-10 13:36:04 -07001058
Joe Onorato8a9b2202010-02-26 18:56:32 -08001059 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 if (willMove && w != null) {
1063 final WindowState curTarget = mInputMethodTarget;
1064 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 // Now some fun for dealing with window animations that
1067 // modify the Z order. We need to look at all windows below
1068 // the current target that are in this app, finding the highest
1069 // visible one in layering.
1070 AppWindowToken token = curTarget.mAppToken;
1071 WindowState highestTarget = null;
1072 int highestPos = 0;
1073 if (token.animating || token.animation != null) {
1074 int pos = 0;
1075 pos = localmWindows.indexOf(curTarget);
1076 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001077 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 if (win.mAppToken != token) {
1079 break;
1080 }
1081 if (!win.mRemoved) {
1082 if (highestTarget == null || win.mAnimLayer >
1083 highestTarget.mAnimLayer) {
1084 highestTarget = win;
1085 highestPos = pos;
1086 }
1087 }
1088 pos--;
1089 }
1090 }
Romain Guy06882f82009-06-10 13:36:04 -07001091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001093 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 + mNextAppTransition + " " + highestTarget
1095 + " animating=" + highestTarget.isAnimating()
1096 + " layer=" + highestTarget.mAnimLayer
1097 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001098
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001099 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 // If we are currently setting up for an animation,
1101 // hold everything until we can find out what will happen.
1102 mInputMethodTargetWaitingAnim = true;
1103 mInputMethodTarget = highestTarget;
1104 return highestPos + 1;
1105 } else if (highestTarget.isAnimating() &&
1106 highestTarget.mAnimLayer > w.mAnimLayer) {
1107 // If the window we are currently targeting is involved
1108 // with an animation, and it is on top of the next target
1109 // we will be over, then hold off on moving until
1110 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001111 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 mInputMethodTarget = highestTarget;
1113 return highestPos + 1;
1114 }
1115 }
1116 }
1117 }
Romain Guy06882f82009-06-10 13:36:04 -07001118
Joe Onorato8a9b2202010-02-26 18:56:32 -08001119 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 if (w != null) {
1121 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001122 if (DEBUG_INPUT_METHOD) {
1123 RuntimeException e = null;
1124 if (!HIDE_STACK_CRAWLS) {
1125 e = new RuntimeException();
1126 e.fillInStackTrace();
1127 }
1128 Slog.w(TAG, "Moving IM target from "
1129 + mInputMethodTarget + " to " + w, e);
1130 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001132 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 if (w.mAppToken != null) {
1134 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1135 } else {
1136 setInputMethodAnimLayerAdjustment(0);
1137 }
1138 }
1139 return i+1;
1140 }
1141 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001142 if (DEBUG_INPUT_METHOD) {
1143 RuntimeException e = null;
1144 if (!HIDE_STACK_CRAWLS) {
1145 e = new RuntimeException();
1146 e.fillInStackTrace();
1147 }
1148 Slog.w(TAG, "Moving IM target from "
1149 + mInputMethodTarget + " to null", e);
1150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 mInputMethodTarget = null;
1152 setInputMethodAnimLayerAdjustment(0);
1153 }
1154 return -1;
1155 }
Romain Guy06882f82009-06-10 13:36:04 -07001156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 void addInputMethodWindowToListLocked(WindowState win) {
1158 int pos = findDesiredInputMethodWindowIndexLocked(true);
1159 if (pos >= 0) {
1160 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001161 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001162 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001164 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 moveInputMethodDialogsLocked(pos+1);
1166 return;
1167 }
1168 win.mTargetAppToken = null;
1169 addWindowToListInOrderLocked(win, true);
1170 moveInputMethodDialogsLocked(pos);
1171 }
Romain Guy06882f82009-06-10 13:36:04 -07001172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001174 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 mInputMethodAnimLayerAdjustment = adj;
1176 WindowState imw = mInputMethodWindow;
1177 if (imw != null) {
1178 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001179 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 + " anim layer: " + imw.mAnimLayer);
1181 int wi = imw.mChildWindows.size();
1182 while (wi > 0) {
1183 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001184 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001186 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 + " anim layer: " + cw.mAnimLayer);
1188 }
1189 }
1190 int di = mInputMethodDialogs.size();
1191 while (di > 0) {
1192 di --;
1193 imw = mInputMethodDialogs.get(di);
1194 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001195 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 + " anim layer: " + imw.mAnimLayer);
1197 }
1198 }
Romain Guy06882f82009-06-10 13:36:04 -07001199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1201 int wpos = mWindows.indexOf(win);
1202 if (wpos >= 0) {
1203 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001204 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001206 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 int NC = win.mChildWindows.size();
1208 while (NC > 0) {
1209 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001210 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 int cpos = mWindows.indexOf(cw);
1212 if (cpos >= 0) {
1213 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001214 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001215 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 mWindows.remove(cpos);
1217 }
1218 }
1219 }
1220 return interestingPos;
1221 }
Romain Guy06882f82009-06-10 13:36:04 -07001222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 private void reAddWindowToListInOrderLocked(WindowState win) {
1224 addWindowToListInOrderLocked(win, false);
1225 // This is a hack to get all of the child windows added as well
1226 // at the right position. Child windows should be rare and
1227 // this case should be rare, so it shouldn't be that big a deal.
1228 int wpos = mWindows.indexOf(win);
1229 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001230 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001231 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001233 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 reAddWindowLocked(wpos, win);
1235 }
1236 }
Romain Guy06882f82009-06-10 13:36:04 -07001237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001238 void logWindowList(String prefix) {
1239 int N = mWindows.size();
1240 while (N > 0) {
1241 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001242 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 }
1244 }
Romain Guy06882f82009-06-10 13:36:04 -07001245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001246 void moveInputMethodDialogsLocked(int pos) {
1247 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001250 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 for (int i=0; i<N; i++) {
1252 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1253 }
1254 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001255 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 logWindowList(" ");
1257 }
Romain Guy06882f82009-06-10 13:36:04 -07001258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 if (pos >= 0) {
1260 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1261 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001262 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 if (wp == mInputMethodWindow) {
1264 pos++;
1265 }
1266 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001267 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 for (int i=0; i<N; i++) {
1269 WindowState win = dialogs.get(i);
1270 win.mTargetAppToken = targetAppToken;
1271 pos = reAddWindowLocked(pos, win);
1272 }
1273 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001274 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 logWindowList(" ");
1276 }
1277 return;
1278 }
1279 for (int i=0; i<N; i++) {
1280 WindowState win = dialogs.get(i);
1281 win.mTargetAppToken = null;
1282 reAddWindowToListInOrderLocked(win);
1283 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001284 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 logWindowList(" ");
1286 }
1287 }
1288 }
Romain Guy06882f82009-06-10 13:36:04 -07001289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1291 final WindowState imWin = mInputMethodWindow;
1292 final int DN = mInputMethodDialogs.size();
1293 if (imWin == null && DN == 0) {
1294 return false;
1295 }
Romain Guy06882f82009-06-10 13:36:04 -07001296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1298 if (imPos >= 0) {
1299 // In this case, the input method windows are to be placed
1300 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 // First check to see if the input method windows are already
1303 // located here, and contiguous.
1304 final int N = mWindows.size();
1305 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001306 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 // Figure out the actual input method window that should be
1309 // at the bottom of their stack.
1310 WindowState baseImWin = imWin != null
1311 ? imWin : mInputMethodDialogs.get(0);
1312 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001313 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 if (cw.mSubLayer < 0) baseImWin = cw;
1315 }
Romain Guy06882f82009-06-10 13:36:04 -07001316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 if (firstImWin == baseImWin) {
1318 // The windows haven't moved... but are they still contiguous?
1319 // First find the top IM window.
1320 int pos = imPos+1;
1321 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001322 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 break;
1324 }
1325 pos++;
1326 }
1327 pos++;
1328 // Now there should be no more input method windows above.
1329 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001330 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 break;
1332 }
1333 pos++;
1334 }
1335 if (pos >= N) {
1336 // All is good!
1337 return false;
1338 }
1339 }
Romain Guy06882f82009-06-10 13:36:04 -07001340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 if (imWin != null) {
1342 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001343 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 logWindowList(" ");
1345 }
1346 imPos = tmpRemoveWindowLocked(imPos, imWin);
1347 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001348 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 logWindowList(" ");
1350 }
1351 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1352 reAddWindowLocked(imPos, imWin);
1353 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001354 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 logWindowList(" ");
1356 }
1357 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1358 } else {
1359 moveInputMethodDialogsLocked(imPos);
1360 }
Romain Guy06882f82009-06-10 13:36:04 -07001361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 } else {
1363 // In this case, the input method windows go in a fixed layer,
1364 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001367 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 tmpRemoveWindowLocked(0, imWin);
1369 imWin.mTargetAppToken = null;
1370 reAddWindowToListInOrderLocked(imWin);
1371 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001372 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 logWindowList(" ");
1374 }
1375 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1376 } else {
1377 moveInputMethodDialogsLocked(-1);;
1378 }
Romain Guy06882f82009-06-10 13:36:04 -07001379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 }
Romain Guy06882f82009-06-10 13:36:04 -07001381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 if (needAssignLayers) {
1383 assignLayersLocked();
1384 }
Romain Guy06882f82009-06-10 13:36:04 -07001385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 return true;
1387 }
Romain Guy06882f82009-06-10 13:36:04 -07001388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 void adjustInputMethodDialogsLocked() {
1390 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1391 }
Romain Guy06882f82009-06-10 13:36:04 -07001392
Dianne Hackborn25994b42009-09-04 14:21:19 -07001393 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001394 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001395 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1396 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1397 ? wallpaperTarget.mAppToken.animation : null)
1398 + " upper=" + mUpperWallpaperTarget
1399 + " lower=" + mLowerWallpaperTarget);
1400 return (wallpaperTarget != null
1401 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1402 && wallpaperTarget.mAppToken.animation != null)))
1403 || mUpperWallpaperTarget != null
1404 || mLowerWallpaperTarget != null;
1405 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001406
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001407 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1408 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001409
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001410 int adjustWallpaperWindowsLocked() {
1411 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001412
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001413 final int dw = mDisplay.getWidth();
1414 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001415
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001416 // First find top-most window that has asked to be on top of the
1417 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001418 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001419 int N = localmWindows.size();
1420 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001421 WindowState foundW = null;
1422 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001423 WindowState topCurW = null;
1424 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001425 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001426 int i = N;
1427 while (i > 0) {
1428 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001429 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001430 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1431 if (topCurW == null) {
1432 topCurW = w;
1433 topCurI = i;
1434 }
1435 continue;
1436 }
1437 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001438 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001439 // If this window's app token is hidden and not animating,
1440 // it is of no interest to us.
1441 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001442 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001443 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001444 continue;
1445 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001446 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001447 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001448 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1449 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001450 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001451 && (mWallpaperTarget == w
1452 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001453 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001454 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001455 foundW = w;
1456 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001457 if (w == mWallpaperTarget && ((w.mAppToken != null
1458 && w.mAppToken.animation != null)
1459 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001460 // The current wallpaper target is animating, so we'll
1461 // look behind it for another possible target and figure
1462 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001463 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001464 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001465 continue;
1466 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001467 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001468 } else if (w == mWindowDetachedWallpaper) {
1469 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001470 }
1471 }
1472
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001473 if (foundW == null && windowDetachedI >= 0) {
1474 if (DEBUG_WALLPAPER) Slog.v(TAG,
1475 "Found animating detached wallpaper activity: #" + i + "=" + w);
1476 foundW = w;
1477 foundI = windowDetachedI;
1478 }
1479
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001480 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001481 // If we are currently waiting for an app transition, and either
1482 // the current target or the next target are involved with it,
1483 // then hold off on doing anything with the wallpaper.
1484 // Note that we are checking here for just whether the target
1485 // is part of an app token... which is potentially overly aggressive
1486 // (the app token may not be involved in the transition), but good
1487 // enough (we'll just wait until whatever transition is pending
1488 // executes).
1489 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001490 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001491 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001492 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001493 }
1494 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001495 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001496 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001497 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001498 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001499 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001500
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001501 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001502 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001503 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001504 + " oldTarget: " + mWallpaperTarget);
1505 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001506
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001507 mLowerWallpaperTarget = null;
1508 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001509
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001510 WindowState oldW = mWallpaperTarget;
1511 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001512
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001513 // Now what is happening... if the current and new targets are
1514 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001515 if (foundW != null && oldW != null) {
1516 boolean oldAnim = oldW.mAnimation != null
1517 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1518 boolean foundAnim = foundW.mAnimation != null
1519 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001520 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001521 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001522 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001523 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001524 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001525 int oldI = localmWindows.indexOf(oldW);
1526 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001527 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001528 }
1529 if (oldI >= 0) {
1530 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001531 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001532 + "=" + oldW + "; new#" + foundI
1533 + "=" + foundW);
1534 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001535
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001536 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001537 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001538 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001539 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001540 }
1541 mWallpaperTarget = oldW;
1542 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001543
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001544 // Now set the upper and lower wallpaper targets
1545 // correctly, and make sure that we are positioning
1546 // the wallpaper below the lower.
1547 if (foundI > oldI) {
1548 // The new target is on top of the old one.
1549 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001550 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001551 }
1552 mUpperWallpaperTarget = foundW;
1553 mLowerWallpaperTarget = oldW;
1554 foundW = oldW;
1555 foundI = oldI;
1556 } else {
1557 // The new target is below the old one.
1558 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001559 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001560 }
1561 mUpperWallpaperTarget = oldW;
1562 mLowerWallpaperTarget = foundW;
1563 }
1564 }
1565 }
1566 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001567
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001568 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001569 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001570 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1571 || (mLowerWallpaperTarget.mAppToken != null
1572 && mLowerWallpaperTarget.mAppToken.animation != null);
1573 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1574 || (mUpperWallpaperTarget.mAppToken != null
1575 && mUpperWallpaperTarget.mAppToken.animation != null);
1576 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001577 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001578 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001579 }
1580 mLowerWallpaperTarget = null;
1581 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001582 }
1583 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001584
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001585 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001586 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001587 // The window is visible to the compositor... but is it visible
1588 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001589 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001590 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001591
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001592 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001593 // its layer adjustment. Only do this if we are not transfering
1594 // between two wallpaper targets.
1595 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001596 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001597 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001598
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001599 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1600 * TYPE_LAYER_MULTIPLIER
1601 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001602
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001603 // Now w is the window we are supposed to be behind... but we
1604 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001605 // AND any starting window associated with it, AND below the
1606 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001607 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001608 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001609 if (wb.mBaseLayer < maxLayer &&
1610 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001611 (foundW.mAttachedWindow == null ||
1612 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001613 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001614 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001615 // This window is not related to the previous one in any
1616 // interesting way, so stop here.
1617 break;
1618 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001619 foundW = wb;
1620 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001621 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001622 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001623 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001624 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001625
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001626 if (foundW == null && topCurW != null) {
1627 // There is no wallpaper target, so it goes at the bottom.
1628 // We will assume it is the same place as last time, if known.
1629 foundW = topCurW;
1630 foundI = topCurI+1;
1631 } else {
1632 // Okay i is the position immediately above the wallpaper. Look at
1633 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001634 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001635 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001636
Dianne Hackborn284ac932009-08-28 10:34:25 -07001637 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001638 if (mWallpaperTarget.mWallpaperX >= 0) {
1639 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001640 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001641 }
1642 if (mWallpaperTarget.mWallpaperY >= 0) {
1643 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001644 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001645 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001646 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001647
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001648 // Start stepping backwards from here, ensuring that our wallpaper windows
1649 // are correctly placed.
1650 int curTokenIndex = mWallpaperTokens.size();
1651 while (curTokenIndex > 0) {
1652 curTokenIndex--;
1653 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001654 if (token.hidden == visible) {
1655 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1656 token.hidden = !visible;
1657 // Need to do a layout to ensure the wallpaper now has the
1658 // correct size.
1659 mLayoutNeeded = true;
1660 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001661
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001662 int curWallpaperIndex = token.windows.size();
1663 while (curWallpaperIndex > 0) {
1664 curWallpaperIndex--;
1665 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001666
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001667 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001668 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001669 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001670
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001671 // First, make sure the client has the current visibility
1672 // state.
1673 if (wallpaper.mWallpaperVisible != visible) {
1674 wallpaper.mWallpaperVisible = visible;
1675 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001676 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001677 "Setting visibility of wallpaper " + wallpaper
1678 + ": " + visible);
1679 wallpaper.mClient.dispatchAppVisibility(visible);
1680 } catch (RemoteException e) {
1681 }
1682 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001683
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001684 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001685 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001686 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001687
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001688 // First, if this window is at the current index, then all
1689 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001690 if (wallpaper == foundW) {
1691 foundI--;
1692 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001693 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001694 continue;
1695 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001696
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001697 // The window didn't match... the current wallpaper window,
1698 // wherever it is, is in the wrong place, so make sure it is
1699 // not in the list.
1700 int oldIndex = localmWindows.indexOf(wallpaper);
1701 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001702 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001703 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001704 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001705 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001706 if (oldIndex < foundI) {
1707 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001708 }
1709 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001710
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001711 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001712 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1713 Slog.v(TAG, "Moving wallpaper " + wallpaper
1714 + " from " + oldIndex + " to " + foundI);
1715 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001716
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001717 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001718 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001719 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001720 }
1721 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001722
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001723 return changed;
1724 }
1725
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001726 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001727 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001728 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001729 mWallpaperAnimLayerAdjustment = adj;
1730 int curTokenIndex = mWallpaperTokens.size();
1731 while (curTokenIndex > 0) {
1732 curTokenIndex--;
1733 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1734 int curWallpaperIndex = token.windows.size();
1735 while (curWallpaperIndex > 0) {
1736 curWallpaperIndex--;
1737 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1738 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001739 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001740 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001741 }
1742 }
1743 }
1744
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001745 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1746 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001747 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001748 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001749 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001750 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001751 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1752 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1753 changed = wallpaperWin.mXOffset != offset;
1754 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001755 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001756 + wallpaperWin + " x: " + offset);
1757 wallpaperWin.mXOffset = offset;
1758 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001759 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001760 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001761 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001762 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001763 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001764
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001765 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001766 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001767 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1768 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1769 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001770 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001771 + wallpaperWin + " y: " + offset);
1772 changed = true;
1773 wallpaperWin.mYOffset = offset;
1774 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001775 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001776 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001777 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001778 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001779 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001780
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001781 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001782 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001783 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001784 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1785 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001786 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001787 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001788 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001789 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001790 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1791 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001792 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001793 if (mWaitingOnWallpaper != null) {
1794 long start = SystemClock.uptimeMillis();
1795 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1796 < start) {
1797 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001798 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001799 "Waiting for offset complete...");
1800 mWindowMap.wait(WALLPAPER_TIMEOUT);
1801 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001802 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001803 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001804 if ((start+WALLPAPER_TIMEOUT)
1805 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001806 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001807 + wallpaperWin);
1808 mLastWallpaperTimeoutTime = start;
1809 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001810 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001811 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001812 }
1813 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001814 } catch (RemoteException e) {
1815 }
1816 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001817
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001818 return changed;
1819 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001820
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001821 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001822 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001823 if (mWaitingOnWallpaper != null &&
1824 mWaitingOnWallpaper.mClient.asBinder() == window) {
1825 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001826 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001827 }
1828 }
1829 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001830
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001831 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001832 final int dw = mDisplay.getWidth();
1833 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001834
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001835 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001836
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001837 WindowState target = mWallpaperTarget;
1838 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001839 if (target.mWallpaperX >= 0) {
1840 mLastWallpaperX = target.mWallpaperX;
1841 } else if (changingTarget.mWallpaperX >= 0) {
1842 mLastWallpaperX = changingTarget.mWallpaperX;
1843 }
1844 if (target.mWallpaperY >= 0) {
1845 mLastWallpaperY = target.mWallpaperY;
1846 } else if (changingTarget.mWallpaperY >= 0) {
1847 mLastWallpaperY = changingTarget.mWallpaperY;
1848 }
1849 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001850
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001851 int curTokenIndex = mWallpaperTokens.size();
1852 while (curTokenIndex > 0) {
1853 curTokenIndex--;
1854 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1855 int curWallpaperIndex = token.windows.size();
1856 while (curWallpaperIndex > 0) {
1857 curWallpaperIndex--;
1858 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1859 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1860 wallpaper.computeShownFrameLocked();
1861 changed = true;
1862 // We only want to be synchronous with one wallpaper.
1863 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001864 }
1865 }
1866 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001867
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001868 return changed;
1869 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001870
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001871 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001872 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001873 final int dw = mDisplay.getWidth();
1874 final int dh = mDisplay.getHeight();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001875
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001876 int curTokenIndex = mWallpaperTokens.size();
1877 while (curTokenIndex > 0) {
1878 curTokenIndex--;
1879 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001880 if (token.hidden == visible) {
1881 token.hidden = !visible;
1882 // Need to do a layout to ensure the wallpaper now has the
1883 // correct size.
1884 mLayoutNeeded = true;
1885 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001886
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001887 int curWallpaperIndex = token.windows.size();
1888 while (curWallpaperIndex > 0) {
1889 curWallpaperIndex--;
1890 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1891 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001892 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001893 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001894
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001895 if (wallpaper.mWallpaperVisible != visible) {
1896 wallpaper.mWallpaperVisible = visible;
1897 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001898 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001899 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001900 + ": " + visible);
1901 wallpaper.mClient.dispatchAppVisibility(visible);
1902 } catch (RemoteException e) {
1903 }
1904 }
1905 }
1906 }
1907 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 public int addWindow(Session session, IWindow client,
1910 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001911 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 int res = mPolicy.checkAddPermission(attrs);
1913 if (res != WindowManagerImpl.ADD_OKAY) {
1914 return res;
1915 }
Romain Guy06882f82009-06-10 13:36:04 -07001916
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001917 boolean reportNewConfig = false;
1918 WindowState attachedWindow = null;
1919 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07001920 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07001921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001922 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07001924 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001925 }
Romain Guy06882f82009-06-10 13:36:04 -07001926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001927 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001928 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001929 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1930 }
1931
1932 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001933 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001935 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 + attrs.token + ". Aborting.");
1937 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1938 }
1939 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1940 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001941 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001942 + attrs.token + ". Aborting.");
1943 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1944 }
1945 }
1946
1947 boolean addToken = false;
1948 WindowToken token = mTokenMap.get(attrs.token);
1949 if (token == null) {
1950 if (attrs.type >= FIRST_APPLICATION_WINDOW
1951 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001952 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 + attrs.token + ". Aborting.");
1954 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1955 }
1956 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001957 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001958 + attrs.token + ". Aborting.");
1959 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1960 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001961 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001962 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001963 + attrs.token + ". Aborting.");
1964 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1965 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001966 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001967 addToken = true;
1968 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1969 && attrs.type <= LAST_APPLICATION_WINDOW) {
1970 AppWindowToken atoken = token.appWindowToken;
1971 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001972 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001973 + token + ". Aborting.");
1974 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
1975 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001976 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 + token + ". Aborting.");
1978 return WindowManagerImpl.ADD_APP_EXITING;
1979 }
1980 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
1981 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08001982 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 TAG, "**** NO NEED TO START: " + attrs.getTitle());
1984 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
1985 }
1986 } else if (attrs.type == TYPE_INPUT_METHOD) {
1987 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001988 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 + attrs.token + ". Aborting.");
1990 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1991 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001992 } else if (attrs.type == TYPE_WALLPAPER) {
1993 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001994 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001995 + attrs.token + ". Aborting.");
1996 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001998 }
1999
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002000 win = new WindowState(this, session, client, token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002001 attachedWindow, attrs, viewVisibility);
2002 if (win.mDeathRecipient == null) {
2003 // Client has apparently died, so there is no reason to
2004 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002005 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002006 + " that is dead, aborting.");
2007 return WindowManagerImpl.ADD_APP_EXITING;
2008 }
2009
2010 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002012 res = mPolicy.prepareAddWindowLw(win, attrs);
2013 if (res != WindowManagerImpl.ADD_OKAY) {
2014 return res;
2015 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002016
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002017 if (outInputChannel != null) {
2018 String name = win.makeInputChannelName();
2019 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2020 win.mInputChannel = inputChannels[0];
2021 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2022
Jeff Brown928e0542011-01-10 11:17:36 -08002023 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002025
2026 // From now on, no exceptions or errors allowed!
2027
2028 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002029
Dianne Hackborn5132b372010-07-29 12:51:35 -07002030 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002032 if (addToken) {
2033 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 }
2035 win.attach();
2036 mWindowMap.put(client.asBinder(), win);
2037
2038 if (attrs.type == TYPE_APPLICATION_STARTING &&
2039 token.appWindowToken != null) {
2040 token.appWindowToken.startingWindow = win;
2041 }
2042
2043 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002045 if (attrs.type == TYPE_INPUT_METHOD) {
2046 mInputMethodWindow = win;
2047 addInputMethodWindowToListLocked(win);
2048 imMayMove = false;
2049 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2050 mInputMethodDialogs.add(win);
2051 addWindowToListInOrderLocked(win, true);
2052 adjustInputMethodDialogsLocked();
2053 imMayMove = false;
2054 } else {
2055 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002056 if (attrs.type == TYPE_WALLPAPER) {
2057 mLastWallpaperTimeoutTime = 0;
2058 adjustWallpaperWindowsLocked();
2059 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002060 adjustWallpaperWindowsLocked();
2061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002062 }
Romain Guy06882f82009-06-10 13:36:04 -07002063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002064 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002066 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 if (mInTouchMode) {
2069 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2070 }
2071 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2072 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2073 }
Romain Guy06882f82009-06-10 13:36:04 -07002074
Jeff Brown2e44b072011-01-24 15:21:56 -08002075 mInputMonitor.setUpdateInputWindowsNeededLw();
2076
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002077 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002078 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002079 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2080 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002081 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002082 imMayMove = false;
2083 }
2084 }
Romain Guy06882f82009-06-10 13:36:04 -07002085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002086 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002087 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002088 }
Romain Guy06882f82009-06-10 13:36:04 -07002089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002090 assignLayersLocked();
2091 // Don't do layout here, the window must call
2092 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 //dump();
2095
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002096 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002097 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002098 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002099 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002100
Joe Onorato8a9b2202010-02-26 18:56:32 -08002101 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 TAG, "New client " + client.asBinder()
2103 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002104
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002105 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002106 reportNewConfig = true;
2107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 }
2109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002110 if (reportNewConfig) {
2111 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002112 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 return res;
2117 }
Romain Guy06882f82009-06-10 13:36:04 -07002118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002119 public void removeWindow(Session session, IWindow client) {
2120 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002121 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 if (win == null) {
2123 return;
2124 }
2125 removeWindowLocked(session, win);
2126 }
2127 }
Romain Guy06882f82009-06-10 13:36:04 -07002128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 public void removeWindowLocked(Session session, WindowState win) {
2130
Joe Onorato8a9b2202010-02-26 18:56:32 -08002131 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002132 TAG, "Remove " + win + " client="
2133 + Integer.toHexString(System.identityHashCode(
2134 win.mClient.asBinder()))
2135 + ", surface=" + win.mSurface);
2136
2137 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002138
2139 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002140
Joe Onorato8a9b2202010-02-26 18:56:32 -08002141 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2143 + " mExiting=" + win.mExiting
2144 + " isAnimating=" + win.isAnimating()
2145 + " app-animation="
2146 + (win.mAppToken != null ? win.mAppToken.animation : null)
2147 + " inPendingTransaction="
2148 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2149 + " mDisplayFrozen=" + mDisplayFrozen);
2150 // Visibility of the removed window. Will be used later to update orientation later on.
2151 boolean wasVisible = false;
2152 // First, see if we need to run an animation. If we do, we have
2153 // to hold off on removing the window until the animation is done.
2154 // If the display is frozen, just remove immediately, since the
2155 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002156 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 // If we are not currently running the exit animation, we
2158 // need to see about starting one.
2159 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2162 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2163 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2164 }
2165 // Try starting an animation.
2166 if (applyAnimationLocked(win, transit, false)) {
2167 win.mExiting = true;
2168 }
2169 }
2170 if (win.mExiting || win.isAnimating()) {
2171 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002172 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 win.mExiting = true;
2174 win.mRemoveOnExit = true;
2175 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002176 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2177 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002179 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002180 if (win.mAppToken != null) {
2181 win.mAppToken.updateReportedVisibilityLocked();
2182 }
2183 //dump();
2184 Binder.restoreCallingIdentity(origId);
2185 return;
2186 }
2187 }
2188
2189 removeWindowInnerLocked(session, win);
2190 // Removing a visible window will effect the computed orientation
2191 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002192 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002193 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002194 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002195 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002197 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 Binder.restoreCallingIdentity(origId);
2199 }
Romain Guy06882f82009-06-10 13:36:04 -07002200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002202 if (win.mRemoved) {
2203 // Nothing to do.
2204 return;
2205 }
2206
2207 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2208 WindowState cwin = win.mChildWindows.get(i);
2209 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2210 + win);
2211 removeWindowInnerLocked(cwin.mSession, cwin);
2212 }
2213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002216 if (mInputMethodTarget == win) {
2217 moveInputMethodWindowsIfNeededLocked(false);
2218 }
Romain Guy06882f82009-06-10 13:36:04 -07002219
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002220 if (false) {
2221 RuntimeException e = new RuntimeException("here");
2222 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002223 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002224 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002226 mPolicy.removeWindowLw(win);
2227 win.removeLocked();
2228
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002229 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 mWindowMap.remove(win.mClient.asBinder());
2231 mWindows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002232 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002233 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002234 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002235
2236 if (mInputMethodWindow == win) {
2237 mInputMethodWindow = null;
2238 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2239 mInputMethodDialogs.remove(win);
2240 }
Romain Guy06882f82009-06-10 13:36:04 -07002241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 final WindowToken token = win.mToken;
2243 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002244 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 token.windows.remove(win);
2246 if (atoken != null) {
2247 atoken.allAppWindows.remove(win);
2248 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002249 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002250 TAG, "**** Removing window " + win + ": count="
2251 + token.windows.size());
2252 if (token.windows.size() == 0) {
2253 if (!token.explicit) {
2254 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 } else if (atoken != null) {
2256 atoken.firstWindowDrawn = false;
2257 }
2258 }
2259
2260 if (atoken != null) {
2261 if (atoken.startingWindow == win) {
2262 atoken.startingWindow = null;
2263 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2264 // If this is the last window and we had requested a starting
2265 // transition window, well there is no point now.
2266 atoken.startingData = null;
2267 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2268 // If this is the last window except for a starting transition
2269 // window, we need to get rid of the starting transition.
2270 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002271 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 + ": no more real windows");
2273 }
2274 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2275 mH.sendMessage(m);
2276 }
2277 }
Romain Guy06882f82009-06-10 13:36:04 -07002278
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002279 if (win.mAttrs.type == TYPE_WALLPAPER) {
2280 mLastWallpaperTimeoutTime = 0;
2281 adjustWallpaperWindowsLocked();
2282 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002283 adjustWallpaperWindowsLocked();
2284 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 if (!mInLayout) {
2287 assignLayersLocked();
2288 mLayoutNeeded = true;
2289 performLayoutAndPlaceSurfacesLocked();
2290 if (win.mAppToken != null) {
2291 win.mAppToken.updateReportedVisibilityLocked();
2292 }
2293 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002294
Jeff Brown2e44b072011-01-24 15:21:56 -08002295 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 }
2297
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002298 static void logSurface(WindowState w, String msg, RuntimeException where) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002299 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2300 + ": " + msg + " / " + w.mAttrs.getTitle();
2301 if (where != null) {
2302 Slog.i(TAG, str, where);
2303 } else {
2304 Slog.i(TAG, str);
2305 }
2306 }
2307
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002308 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 long origId = Binder.clearCallingIdentity();
2310 try {
2311 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002312 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 if ((w != null) && (w.mSurface != null)) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002314 if (SHOW_TRANSACTIONS) Slog.i(TAG,
2315 ">>> OPEN TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 Surface.openTransaction();
2317 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002318 if (SHOW_TRANSACTIONS) logSurface(w,
2319 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320 w.mSurface.setTransparentRegionHint(region);
2321 } finally {
2322 Surface.closeTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002323 if (SHOW_TRANSACTIONS) Slog.i(TAG,
2324 "<<< CLOSE TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 }
2326 }
2327 }
2328 } finally {
2329 Binder.restoreCallingIdentity(origId);
2330 }
2331 }
2332
2333 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002334 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002335 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 long origId = Binder.clearCallingIdentity();
2337 try {
2338 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002339 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340 if (w != null) {
2341 w.mGivenInsetsPending = false;
2342 w.mGivenContentInsets.set(contentInsets);
2343 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002344 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 w.mTouchableInsets = touchableInsets;
2346 mLayoutNeeded = true;
2347 performLayoutAndPlaceSurfacesLocked();
2348 }
2349 }
2350 } finally {
2351 Binder.restoreCallingIdentity(origId);
2352 }
2353 }
Romain Guy06882f82009-06-10 13:36:04 -07002354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002355 public void getWindowDisplayFrame(Session session, IWindow client,
2356 Rect outDisplayFrame) {
2357 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002358 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 if (win == null) {
2360 outDisplayFrame.setEmpty();
2361 return;
2362 }
2363 outDisplayFrame.set(win.mDisplayFrame);
2364 }
2365 }
2366
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002367 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2368 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002369 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2370 window.mWallpaperX = x;
2371 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002372 window.mWallpaperXStep = xStep;
2373 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002374 if (updateWallpaperOffsetLocked(window, true)) {
2375 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002376 }
2377 }
2378 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002379
Dianne Hackborn75804932009-10-20 20:15:20 -07002380 void wallpaperCommandComplete(IBinder window, Bundle result) {
2381 synchronized (mWindowMap) {
2382 if (mWaitingOnWallpaper != null &&
2383 mWaitingOnWallpaper.mClient.asBinder() == window) {
2384 mWaitingOnWallpaper = null;
2385 mWindowMap.notifyAll();
2386 }
2387 }
2388 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002389
Dianne Hackborn75804932009-10-20 20:15:20 -07002390 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2391 String action, int x, int y, int z, Bundle extras, boolean sync) {
2392 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2393 || window == mUpperWallpaperTarget) {
2394 boolean doWait = sync;
2395 int curTokenIndex = mWallpaperTokens.size();
2396 while (curTokenIndex > 0) {
2397 curTokenIndex--;
2398 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2399 int curWallpaperIndex = token.windows.size();
2400 while (curWallpaperIndex > 0) {
2401 curWallpaperIndex--;
2402 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2403 try {
2404 wallpaper.mClient.dispatchWallpaperCommand(action,
2405 x, y, z, extras, sync);
2406 // We only want to be synchronous with one wallpaper.
2407 sync = false;
2408 } catch (RemoteException e) {
2409 }
2410 }
2411 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002412
Dianne Hackborn75804932009-10-20 20:15:20 -07002413 if (doWait) {
2414 // XXX Need to wait for result.
2415 }
2416 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002417
Dianne Hackborn75804932009-10-20 20:15:20 -07002418 return null;
2419 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002421 public int relayoutWindow(Session session, IWindow client,
2422 WindowManager.LayoutParams attrs, int requestedWidth,
2423 int requestedHeight, int viewVisibility, boolean insetsPending,
2424 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002425 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 boolean displayed = false;
2427 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002428 boolean configChanged;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002429
2430 // if they don't have this permission, mask out the status bar bits
2431 if (attrs != null) {
2432 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2433 != PackageManager.PERMISSION_GRANTED) {
2434 attrs.systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
2435 attrs.subtreeSystemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
2436 }
2437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002441 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 if (win == null) {
2443 return 0;
2444 }
2445 win.mRequestedWidth = requestedWidth;
2446 win.mRequestedHeight = requestedHeight;
2447
2448 if (attrs != null) {
2449 mPolicy.adjustWindowParamsLw(attrs);
2450 }
Romain Guy06882f82009-06-10 13:36:04 -07002451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 int attrChanges = 0;
2453 int flagChanges = 0;
2454 if (attrs != null) {
2455 flagChanges = win.mAttrs.flags ^= attrs.flags;
2456 attrChanges = win.mAttrs.copyFrom(attrs);
2457 }
2458
Joe Onorato8a9b2202010-02-26 18:56:32 -08002459 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460
2461 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2462 win.mAlpha = attrs.alpha;
2463 }
2464
2465 final boolean scaledWindow =
2466 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2467
2468 if (scaledWindow) {
2469 // requested{Width|Height} Surface's physical size
2470 // attrs.{width|height} Size on screen
2471 win.mHScale = (attrs.width != requestedWidth) ?
2472 (attrs.width / (float)requestedWidth) : 1.0f;
2473 win.mVScale = (attrs.height != requestedHeight) ?
2474 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002475 } else {
2476 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 }
2478
2479 boolean imMayMove = (flagChanges&(
2480 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2481 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 boolean focusMayChange = win.mViewVisibility != viewVisibility
2484 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2485 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002486
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002487 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2488 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 win.mRelayoutCalled = true;
2491 final int oldVisibility = win.mViewVisibility;
2492 win.mViewVisibility = viewVisibility;
2493 if (viewVisibility == View.VISIBLE &&
2494 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2495 displayed = !win.isVisibleLw();
2496 if (win.mExiting) {
2497 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002498 if (win.mAnimation != null) {
2499 win.mAnimation.cancel();
2500 win.mAnimation = null;
2501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 }
2503 if (win.mDestroying) {
2504 win.mDestroying = false;
2505 mDestroySurface.remove(win);
2506 }
2507 if (oldVisibility == View.GONE) {
2508 win.mEnterAnimationPending = true;
2509 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002510 if (displayed) {
2511 if (win.mSurface != null && !win.mDrawPending
2512 && !win.mCommitDrawPending && !mDisplayFrozen
2513 && mPolicy.isScreenOn()) {
2514 applyEnterAnimationLocked(win);
2515 }
2516 if ((win.mAttrs.flags
2517 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2518 if (DEBUG_VISIBILITY) Slog.v(TAG,
2519 "Relayout window turning screen on: " + win);
2520 win.mTurnOnScreen = true;
2521 }
2522 int diff = 0;
2523 if (win.mConfiguration != mCurConfiguration
2524 && (win.mConfiguration == null
2525 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2526 win.mConfiguration = mCurConfiguration;
2527 if (DEBUG_CONFIGURATION) {
2528 Slog.i(TAG, "Window " + win + " visible with new config: "
2529 + win.mConfiguration + " / 0x"
2530 + Integer.toHexString(diff));
2531 }
2532 outConfig.setTo(mCurConfiguration);
2533 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002535 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2536 // To change the format, we need to re-build the surface.
2537 win.destroySurfaceLocked();
2538 displayed = true;
2539 }
2540 try {
2541 Surface surface = win.createSurfaceLocked();
2542 if (surface != null) {
2543 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002544 win.mReportDestroySurface = false;
2545 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002546 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002547 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002548 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002549 // For some reason there isn't a surface. Clear the
2550 // caller's object so they see the same state.
2551 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 }
2553 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002554 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browne33348b2010-07-15 23:54:05 -07002555
Joe Onorato8a9b2202010-02-26 18:56:32 -08002556 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002557 + client + " (" + win.mAttrs.getTitle() + ")",
2558 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 Binder.restoreCallingIdentity(origId);
2560 return 0;
2561 }
2562 if (displayed) {
2563 focusMayChange = true;
2564 }
2565 if (win.mAttrs.type == TYPE_INPUT_METHOD
2566 && mInputMethodWindow == null) {
2567 mInputMethodWindow = win;
2568 imMayMove = true;
2569 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002570 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2571 && win.mAppToken != null
2572 && win.mAppToken.startingWindow != null) {
2573 // Special handling of starting window over the base
2574 // window of the app: propagate lock screen flags to it,
2575 // to provide the correct semantics while starting.
2576 final int mask =
2577 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002578 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2579 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002580 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2581 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 } else {
2584 win.mEnterAnimationPending = false;
2585 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002586 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002587 + ": mExiting=" + win.mExiting
2588 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002589 // If we are not currently running the exit animation, we
2590 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002591 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 // Try starting an animation; if there isn't one, we
2593 // can destroy the surface right away.
2594 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2595 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2596 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2597 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002598 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002599 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002600 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 } else if (win.isAnimating()) {
2603 // Currently in a hide animation... turn this into
2604 // an exit.
2605 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002606 } else if (win == mWallpaperTarget) {
2607 // If the wallpaper is currently behind this
2608 // window, we need to change both of them inside
2609 // of a transaction to avoid artifacts.
2610 win.mExiting = true;
2611 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 } else {
2613 if (mInputMethodWindow == win) {
2614 mInputMethodWindow = null;
2615 }
2616 win.destroySurfaceLocked();
2617 }
2618 }
2619 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002620
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002621 if (win.mSurface == null || (win.getAttrs().flags
2622 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2623 || win.mSurfacePendingDestroy) {
2624 // We are being called from a local process, which
2625 // means outSurface holds its current surface. Ensure the
2626 // surface object is cleared, but we don't want it actually
2627 // destroyed at this point.
2628 win.mSurfacePendingDestroy = false;
2629 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002630 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002631 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002632 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002633 "Keeping surface, will report destroy: " + win);
2634 win.mReportDestroySurface = true;
2635 outSurface.copyFrom(win.mSurface);
2636 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 }
2638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 if (focusMayChange) {
2640 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002641 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2642 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643 imMayMove = false;
2644 }
2645 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2646 }
Romain Guy06882f82009-06-10 13:36:04 -07002647
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002648 // updateFocusedWindowLocked() already assigned layers so we only need to
2649 // reassign them at this point if the IM window state gets shuffled
2650 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002653 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2654 // Little hack here -- we -should- be able to rely on the
2655 // function to return true if the IME has moved and needs
2656 // its layer recomputed. However, if the IME was hidden
2657 // and isn't actually moved in the list, its layer may be
2658 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002659 assignLayers = true;
2660 }
2661 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002662 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002663 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002664 assignLayers = true;
2665 }
2666 }
Romain Guy06882f82009-06-10 13:36:04 -07002667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 mLayoutNeeded = true;
2669 win.mGivenInsetsPending = insetsPending;
2670 if (assignLayers) {
2671 assignLayersLocked();
2672 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002673 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002675 if (displayed && win.mIsWallpaper) {
2676 updateWallpaperOffsetLocked(win, mDisplay.getWidth(),
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002677 mDisplay.getHeight(), false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 if (win.mAppToken != null) {
2680 win.mAppToken.updateReportedVisibilityLocked();
2681 }
2682 outFrame.set(win.mFrame);
2683 outContentInsets.set(win.mContentInsets);
2684 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002685 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002687 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688 + ", requestedHeight=" + requestedHeight
2689 + ", viewVisibility=" + viewVisibility
2690 + "\nRelayout returning frame=" + outFrame
2691 + ", surface=" + outSurface);
2692
Joe Onorato8a9b2202010-02-26 18:56:32 -08002693 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2695
2696 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002697
Jeff Brown2e44b072011-01-24 15:21:56 -08002698 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002699 }
2700
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002701 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002702 sendNewConfiguration();
2703 }
Romain Guy06882f82009-06-10 13:36:04 -07002704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002707 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2708 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2709 }
2710
2711 public void finishDrawingWindow(Session session, IWindow client) {
2712 final long origId = Binder.clearCallingIdentity();
2713 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002714 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002716 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2717 adjustWallpaperWindowsLocked();
2718 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 mLayoutNeeded = true;
2720 performLayoutAndPlaceSurfacesLocked();
2721 }
2722 }
2723 Binder.restoreCallingIdentity(origId);
2724 }
2725
2726 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002727 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002728 + (lp != null ? lp.packageName : null)
2729 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2730 if (lp != null && lp.windowAnimations != 0) {
2731 // If this is a system resource, don't try to load it from the
2732 // application resources. It is nice to avoid loading application
2733 // resources if we can.
2734 String packageName = lp.packageName != null ? lp.packageName : "android";
2735 int resId = lp.windowAnimations;
2736 if ((resId&0xFF000000) == 0x01000000) {
2737 packageName = "android";
2738 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002739 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002740 + packageName);
2741 return AttributeCache.instance().get(packageName, resId,
2742 com.android.internal.R.styleable.WindowAnimation);
2743 }
2744 return null;
2745 }
Romain Guy06882f82009-06-10 13:36:04 -07002746
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002747 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002748 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002749 + packageName + " resId=0x" + Integer.toHexString(resId));
2750 if (packageName != null) {
2751 if ((resId&0xFF000000) == 0x01000000) {
2752 packageName = "android";
2753 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002754 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002755 + packageName);
2756 return AttributeCache.instance().get(packageName, resId,
2757 com.android.internal.R.styleable.WindowAnimation);
2758 }
2759 return null;
2760 }
2761
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002762 void applyEnterAnimationLocked(WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2764 if (win.mEnterAnimationPending) {
2765 win.mEnterAnimationPending = false;
2766 transit = WindowManagerPolicy.TRANSIT_ENTER;
2767 }
2768
2769 applyAnimationLocked(win, transit, true);
2770 }
2771
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002772 boolean applyAnimationLocked(WindowState win,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002773 int transit, boolean isEntrance) {
2774 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2775 // If we are trying to apply an animation, but already running
2776 // an animation of the same type, then just leave that one alone.
2777 return true;
2778 }
Romain Guy06882f82009-06-10 13:36:04 -07002779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002780 // Only apply an animation if the display isn't frozen. If it is
2781 // frozen, there is no reason to animate and it can cause strange
2782 // artifacts when we unfreeze the display if some different animation
2783 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002784 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 int anim = mPolicy.selectAnimationLw(win, transit);
2786 int attr = -1;
2787 Animation a = null;
2788 if (anim != 0) {
2789 a = AnimationUtils.loadAnimation(mContext, anim);
2790 } else {
2791 switch (transit) {
2792 case WindowManagerPolicy.TRANSIT_ENTER:
2793 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2794 break;
2795 case WindowManagerPolicy.TRANSIT_EXIT:
2796 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2797 break;
2798 case WindowManagerPolicy.TRANSIT_SHOW:
2799 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2800 break;
2801 case WindowManagerPolicy.TRANSIT_HIDE:
2802 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2803 break;
2804 }
2805 if (attr >= 0) {
2806 a = loadAnimation(win.mAttrs, attr);
2807 }
2808 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002809 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002810 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2811 + " mAnimation=" + win.mAnimation
2812 + " isEntrance=" + isEntrance);
2813 if (a != null) {
2814 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002815 RuntimeException e = null;
2816 if (!HIDE_STACK_CRAWLS) {
2817 e = new RuntimeException();
2818 e.fillInStackTrace();
2819 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002820 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 }
2822 win.setAnimation(a);
2823 win.mAnimationIsEntrance = isEntrance;
2824 }
2825 } else {
2826 win.clearAnimation();
2827 }
2828
2829 return win.mAnimation != null;
2830 }
2831
2832 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2833 int anim = 0;
2834 Context context = mContext;
2835 if (animAttr >= 0) {
2836 AttributeCache.Entry ent = getCachedAnimations(lp);
2837 if (ent != null) {
2838 context = ent.context;
2839 anim = ent.array.getResourceId(animAttr, 0);
2840 }
2841 }
2842 if (anim != 0) {
2843 return AnimationUtils.loadAnimation(context, anim);
2844 }
2845 return null;
2846 }
Romain Guy06882f82009-06-10 13:36:04 -07002847
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002848 private Animation loadAnimation(String packageName, int resId) {
2849 int anim = 0;
2850 Context context = mContext;
2851 if (resId >= 0) {
2852 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2853 if (ent != null) {
2854 context = ent.context;
2855 anim = resId;
2856 }
2857 }
2858 if (anim != 0) {
2859 return AnimationUtils.loadAnimation(context, anim);
2860 }
2861 return null;
2862 }
2863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002864 private boolean applyAnimationLocked(AppWindowToken wtoken,
2865 WindowManager.LayoutParams lp, int transit, boolean enter) {
2866 // Only apply an animation if the display isn't frozen. If it is
2867 // frozen, there is no reason to animate and it can cause strange
2868 // artifacts when we unfreeze the display if some different animation
2869 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002870 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002871 Animation a;
Mitsuru Oshimad2967e22009-07-20 14:01:43 -07002872 if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002873 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002874 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002875 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002876 } else if (mNextAppTransitionPackage != null) {
2877 a = loadAnimation(mNextAppTransitionPackage, enter ?
2878 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002879 } else {
2880 int animAttr = 0;
2881 switch (transit) {
2882 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2883 animAttr = enter
2884 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2885 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2886 break;
2887 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2888 animAttr = enter
2889 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2890 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2891 break;
2892 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2893 animAttr = enter
2894 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2895 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2896 break;
2897 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2898 animAttr = enter
2899 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2900 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2901 break;
2902 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2903 animAttr = enter
2904 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2905 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2906 break;
2907 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2908 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002909 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002910 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2911 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002912 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002913 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002914 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2915 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002916 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002917 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002918 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002919 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2920 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2921 break;
2922 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2923 animAttr = enter
2924 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2925 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2926 break;
2927 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2928 animAttr = enter
2929 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2930 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002931 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002932 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002933 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002934 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002935 + " anim=" + a
2936 + " animAttr=0x" + Integer.toHexString(animAttr)
2937 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002939 if (a != null) {
2940 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002941 RuntimeException e = null;
2942 if (!HIDE_STACK_CRAWLS) {
2943 e = new RuntimeException();
2944 e.fillInStackTrace();
2945 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002946 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947 }
2948 wtoken.setAnimation(a);
2949 }
2950 } else {
2951 wtoken.clearAnimation();
2952 }
2953
2954 return wtoken.animation != null;
2955 }
2956
2957 // -------------------------------------------------------------
2958 // Application Window Tokens
2959 // -------------------------------------------------------------
2960
2961 public void validateAppTokens(List tokens) {
2962 int v = tokens.size()-1;
2963 int m = mAppTokens.size()-1;
2964 while (v >= 0 && m >= 0) {
2965 AppWindowToken wtoken = mAppTokens.get(m);
2966 if (wtoken.removed) {
2967 m--;
2968 continue;
2969 }
2970 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002971 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
2973 }
2974 v--;
2975 m--;
2976 }
2977 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002978 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 v--;
2980 }
2981 while (m >= 0) {
2982 AppWindowToken wtoken = mAppTokens.get(m);
2983 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002984 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002985 }
2986 m--;
2987 }
2988 }
2989
2990 boolean checkCallingPermission(String permission, String func) {
2991 // Quick check: if the calling permission is me, it's all okay.
2992 if (Binder.getCallingPid() == Process.myPid()) {
2993 return true;
2994 }
Romain Guy06882f82009-06-10 13:36:04 -07002995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002996 if (mContext.checkCallingPermission(permission)
2997 == PackageManager.PERMISSION_GRANTED) {
2998 return true;
2999 }
3000 String msg = "Permission Denial: " + func + " from pid="
3001 + Binder.getCallingPid()
3002 + ", uid=" + Binder.getCallingUid()
3003 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003004 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 return false;
3006 }
Romain Guy06882f82009-06-10 13:36:04 -07003007
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003008 AppWindowToken findAppWindowToken(IBinder token) {
3009 WindowToken wtoken = mTokenMap.get(token);
3010 if (wtoken == null) {
3011 return null;
3012 }
3013 return wtoken.appWindowToken;
3014 }
Romain Guy06882f82009-06-10 13:36:04 -07003015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 public void addWindowToken(IBinder token, int type) {
3017 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3018 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003019 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003020 }
Romain Guy06882f82009-06-10 13:36:04 -07003021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 synchronized(mWindowMap) {
3023 WindowToken wtoken = mTokenMap.get(token);
3024 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003025 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 return;
3027 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003028 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003029 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003030 if (type == TYPE_WALLPAPER) {
3031 mWallpaperTokens.add(wtoken);
3032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 }
3034 }
Romain Guy06882f82009-06-10 13:36:04 -07003035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 public void removeWindowToken(IBinder token) {
3037 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3038 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003039 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 }
3041
3042 final long origId = Binder.clearCallingIdentity();
3043 synchronized(mWindowMap) {
3044 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003045 if (wtoken != null) {
3046 boolean delayed = false;
3047 if (!wtoken.hidden) {
3048 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003050 final int N = wtoken.windows.size();
3051 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 for (int i=0; i<N; i++) {
3054 WindowState win = wtoken.windows.get(i);
3055
3056 if (win.isAnimating()) {
3057 delayed = true;
3058 }
Romain Guy06882f82009-06-10 13:36:04 -07003059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003060 if (win.isVisibleNow()) {
3061 applyAnimationLocked(win,
3062 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003063 changed = true;
3064 }
3065 }
3066
3067 if (changed) {
3068 mLayoutNeeded = true;
3069 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003070 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3071 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 }
Romain Guy06882f82009-06-10 13:36:04 -07003073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 if (delayed) {
3075 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003076 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3077 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003078 }
3079 }
Romain Guy06882f82009-06-10 13:36:04 -07003080
Jeff Brown2e44b072011-01-24 15:21:56 -08003081 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003082 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003083 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 }
3085 }
3086 Binder.restoreCallingIdentity(origId);
3087 }
3088
3089 public void addAppToken(int addPos, IApplicationToken token,
3090 int groupId, int requestedOrientation, boolean fullscreen) {
3091 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3092 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003093 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 }
Jeff Brown349703e2010-06-22 01:27:15 -07003095
3096 // Get the dispatching timeout here while we are not holding any locks so that it
3097 // can be cached by the AppWindowToken. The timeout value is used later by the
3098 // input dispatcher in code that does hold locks. If we did not cache the value
3099 // here we would run the chance of introducing a deadlock between the window manager
3100 // (which holds locks while updating the input dispatcher state) and the activity manager
3101 // (which holds locks while querying the application token).
3102 long inputDispatchingTimeoutNanos;
3103 try {
3104 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3105 } catch (RemoteException ex) {
3106 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3107 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3108 }
Romain Guy06882f82009-06-10 13:36:04 -07003109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003110 synchronized(mWindowMap) {
3111 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3112 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003113 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003114 return;
3115 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003116 wtoken = new AppWindowToken(this, token);
Jeff Brown349703e2010-06-22 01:27:15 -07003117 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 wtoken.groupId = groupId;
3119 wtoken.appFullscreen = fullscreen;
3120 wtoken.requestedOrientation = requestedOrientation;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003121 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003122 mAppTokens.add(addPos, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123 mTokenMap.put(token.asBinder(), wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003125 // Application tokens start out hidden.
3126 wtoken.hidden = true;
3127 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003129 //dump();
3130 }
3131 }
Romain Guy06882f82009-06-10 13:36:04 -07003132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003133 public void setAppGroupId(IBinder token, int groupId) {
3134 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3135 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003136 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003137 }
3138
3139 synchronized(mWindowMap) {
3140 AppWindowToken wtoken = findAppWindowToken(token);
3141 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003142 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 return;
3144 }
3145 wtoken.groupId = groupId;
3146 }
3147 }
Romain Guy06882f82009-06-10 13:36:04 -07003148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 public int getOrientationFromWindowsLocked() {
3150 int pos = mWindows.size() - 1;
3151 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003152 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 pos--;
3154 if (wtoken.mAppToken != null) {
3155 // We hit an application window. so the orientation will be determined by the
3156 // app window. No point in continuing further.
3157 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3158 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003159 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003160 continue;
3161 }
3162 int req = wtoken.mAttrs.screenOrientation;
3163 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3164 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3165 continue;
3166 } else {
3167 return req;
3168 }
3169 }
3170 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3171 }
Romain Guy06882f82009-06-10 13:36:04 -07003172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003174 int pos = mAppTokens.size() - 1;
3175 int curGroup = 0;
3176 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3177 boolean findingBehind = false;
3178 boolean haveGroup = false;
3179 boolean lastFullscreen = false;
3180 while (pos >= 0) {
3181 AppWindowToken wtoken = mAppTokens.get(pos);
3182 pos--;
3183 // if we're about to tear down this window and not seek for
3184 // the behind activity, don't use it for orientation
3185 if (!findingBehind
3186 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3187 continue;
3188 }
3189
3190 if (!haveGroup) {
3191 // We ignore any hidden applications on the top.
3192 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003193 continue;
3194 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003195 haveGroup = true;
3196 curGroup = wtoken.groupId;
3197 lastOrientation = wtoken.requestedOrientation;
3198 } else if (curGroup != wtoken.groupId) {
3199 // If we have hit a new application group, and the bottom
3200 // of the previous group didn't explicitly say to use
3201 // the orientation behind it, and the last app was
3202 // full screen, then we'll stick with the
3203 // user's orientation.
3204 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3205 && lastFullscreen) {
3206 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003209 int or = wtoken.requestedOrientation;
3210 // If this application is fullscreen, and didn't explicitly say
3211 // to use the orientation behind it, then just take whatever
3212 // orientation it has and ignores whatever is under it.
3213 lastFullscreen = wtoken.appFullscreen;
3214 if (lastFullscreen
3215 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3216 return or;
3217 }
3218 // If this application has requested an explicit orientation,
3219 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003220 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3221 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003222 return or;
3223 }
3224 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3225 }
3226 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003227 }
Romain Guy06882f82009-06-10 13:36:04 -07003228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003230 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003231 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3232 "updateOrientationFromAppTokens()")) {
3233 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3234 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003235
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003236 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003238
3239 synchronized(mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003240 if (updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003241 if (freezeThisOneIfNeeded != null) {
3242 AppWindowToken wtoken = findAppWindowToken(
3243 freezeThisOneIfNeeded);
3244 if (wtoken != null) {
3245 startAppFreezingScreenLocked(wtoken,
3246 ActivityInfo.CONFIG_ORIENTATION);
3247 }
3248 }
3249 config = computeNewConfigurationLocked();
3250
3251 } else if (currentConfig != null) {
3252 // No obvious action we need to take, but if our current
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003253 // state mismatches the activity manager's, update it,
3254 // disregarding font scale, which should remain set to
3255 // the value of the previous configuration.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003256 mTempConfiguration.setToDefaults();
Casey Burkhardt0920ba52010-08-03 12:04:19 -07003257 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003258 if (computeNewConfigurationLocked(mTempConfiguration)) {
3259 if (currentConfig.diff(mTempConfiguration) != 0) {
3260 mWaitingForConfig = true;
3261 mLayoutNeeded = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003262 startFreezingDisplayLocked(false);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003263 config = new Configuration(mTempConfiguration);
3264 }
3265 }
3266 }
3267 }
3268
Dianne Hackborncfaef692009-06-15 14:24:44 -07003269 Binder.restoreCallingIdentity(ident);
3270 return config;
3271 }
3272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003274 * Determine the new desired orientation of the display, returning
3275 * a non-null new Configuration if it has changed from the current
3276 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3277 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3278 * SCREEN. This will typically be done for you if you call
3279 * sendNewConfiguration().
3280 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003281 * The orientation is computed from non-application windows first. If none of
3282 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003283 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3285 * android.os.IBinder)
3286 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003287 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
3288 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
Christopher Tateb696aee2010-04-02 19:08:30 -07003289 // If the display is frozen, some activities may be in the middle
3290 // of restarting, and thus have removed their old window. If the
3291 // window has the flag to hide the lock screen, then the lock screen
3292 // can re-appear and inflict its own orientation on us. Keep the
3293 // orientation stable until this all settles down.
3294 return false;
3295 }
3296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003297 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 long ident = Binder.clearCallingIdentity();
3299 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003300 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003302 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303 mForcedAppOrientation = req;
3304 //send a message to Policy indicating orientation change to take
3305 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003306 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003307 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003308 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE,
3309 inTransaction)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003310 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 }
3312 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003313
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003314 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 } finally {
3316 Binder.restoreCallingIdentity(ident);
3317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 }
Romain Guy06882f82009-06-10 13:36:04 -07003319
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003320 int computeForcedAppOrientationLocked() {
3321 int req = getOrientationFromWindowsLocked();
3322 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3323 req = getOrientationFromAppTokensLocked();
3324 }
3325 return req;
3326 }
Romain Guy06882f82009-06-10 13:36:04 -07003327
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003328 public void setNewConfiguration(Configuration config) {
3329 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3330 "setNewConfiguration()")) {
3331 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3332 }
3333
3334 synchronized(mWindowMap) {
3335 mCurConfiguration = new Configuration(config);
3336 mWaitingForConfig = false;
3337 performLayoutAndPlaceSurfacesLocked();
3338 }
3339 }
3340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003341 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3342 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3343 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003344 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003345 }
Romain Guy06882f82009-06-10 13:36:04 -07003346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003347 synchronized(mWindowMap) {
3348 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3349 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003350 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 return;
3352 }
Romain Guy06882f82009-06-10 13:36:04 -07003353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 wtoken.requestedOrientation = requestedOrientation;
3355 }
3356 }
Romain Guy06882f82009-06-10 13:36:04 -07003357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 public int getAppOrientation(IApplicationToken token) {
3359 synchronized(mWindowMap) {
3360 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3361 if (wtoken == null) {
3362 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3363 }
Romain Guy06882f82009-06-10 13:36:04 -07003364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365 return wtoken.requestedOrientation;
3366 }
3367 }
Romain Guy06882f82009-06-10 13:36:04 -07003368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3370 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3371 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003372 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 }
3374
3375 synchronized(mWindowMap) {
3376 boolean changed = false;
3377 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003378 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 changed = mFocusedApp != null;
3380 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003381 if (changed) {
3382 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003383 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 } else {
3385 AppWindowToken newFocus = findAppWindowToken(token);
3386 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003387 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 return;
3389 }
3390 changed = mFocusedApp != newFocus;
3391 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003392 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003393 if (changed) {
3394 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 }
3397
3398 if (moveFocusNow && changed) {
3399 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003400 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 Binder.restoreCallingIdentity(origId);
3402 }
3403 }
3404 }
3405
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003406 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003407 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3408 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003409 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 }
Romain Guy06882f82009-06-10 13:36:04 -07003411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003412 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003413 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003414 TAG, "Prepare app transition: transit=" + transit
3415 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003416 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003417 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3418 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003420 } else if (!alwaysKeepCurrent) {
3421 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3422 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3423 // Opening a new task always supersedes a close for the anim.
3424 mNextAppTransition = transit;
3425 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3426 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3427 // Opening a new activity always supersedes a close for the anim.
3428 mNextAppTransition = transit;
3429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 }
3431 mAppTransitionReady = false;
3432 mAppTransitionTimeout = false;
3433 mStartingIconInTransition = false;
3434 mSkipAppTransitionAnimation = false;
3435 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3436 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3437 5000);
3438 }
3439 }
3440 }
3441
3442 public int getPendingAppTransition() {
3443 return mNextAppTransition;
3444 }
Romain Guy06882f82009-06-10 13:36:04 -07003445
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003446 public void overridePendingAppTransition(String packageName,
3447 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003448 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003449 mNextAppTransitionPackage = packageName;
3450 mNextAppTransitionEnter = enterAnim;
3451 mNextAppTransitionExit = exitAnim;
3452 }
3453 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455 public void executeAppTransition() {
3456 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3457 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003458 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 }
Romain Guy06882f82009-06-10 13:36:04 -07003460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003461 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003462 if (DEBUG_APP_TRANSITIONS) {
3463 RuntimeException e = new RuntimeException("here");
3464 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003465 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003466 + mNextAppTransition, e);
3467 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003468 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003469 mAppTransitionReady = true;
3470 final long origId = Binder.clearCallingIdentity();
3471 performLayoutAndPlaceSurfacesLocked();
3472 Binder.restoreCallingIdentity(origId);
3473 }
3474 }
3475 }
3476
3477 public void setAppStartingWindow(IBinder token, String pkg,
3478 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003479 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003480 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3481 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003482 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003483 }
3484
3485 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003486 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3488 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003490 AppWindowToken wtoken = findAppWindowToken(token);
3491 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003492 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 return;
3494 }
3495
3496 // If the display is frozen, we won't do anything until the
3497 // actual window is displayed so there is no reason to put in
3498 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003499 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 return;
3501 }
Romain Guy06882f82009-06-10 13:36:04 -07003502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003503 if (wtoken.startingData != null) {
3504 return;
3505 }
Romain Guy06882f82009-06-10 13:36:04 -07003506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003507 if (transferFrom != null) {
3508 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3509 if (ttoken != null) {
3510 WindowState startingWindow = ttoken.startingWindow;
3511 if (startingWindow != null) {
3512 if (mStartingIconInTransition) {
3513 // In this case, the starting icon has already
3514 // been displayed, so start letting windows get
3515 // shown immediately without any more transitions.
3516 mSkipAppTransitionAnimation = true;
3517 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003518 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 "Moving existing starting from " + ttoken
3520 + " to " + wtoken);
3521 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 // Transfer the starting window over to the new
3524 // token.
3525 wtoken.startingData = ttoken.startingData;
3526 wtoken.startingView = ttoken.startingView;
3527 wtoken.startingWindow = startingWindow;
3528 ttoken.startingData = null;
3529 ttoken.startingView = null;
3530 ttoken.startingWindow = null;
3531 ttoken.startingMoved = true;
3532 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003533 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 startingWindow.mAppToken = wtoken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003535 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003536 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003538 mWindowsChanged = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003539 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
3540 + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 ttoken.windows.remove(startingWindow);
3542 ttoken.allAppWindows.remove(startingWindow);
3543 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003545 // Propagate other interesting state between the
3546 // tokens. If the old token is displayed, we should
3547 // immediately force the new one to be displayed. If
3548 // it is animating, we need to move that animation to
3549 // the new one.
3550 if (ttoken.allDrawn) {
3551 wtoken.allDrawn = true;
3552 }
3553 if (ttoken.firstWindowDrawn) {
3554 wtoken.firstWindowDrawn = true;
3555 }
3556 if (!ttoken.hidden) {
3557 wtoken.hidden = false;
3558 wtoken.hiddenRequested = false;
3559 wtoken.willBeHidden = false;
3560 }
3561 if (wtoken.clientHidden != ttoken.clientHidden) {
3562 wtoken.clientHidden = ttoken.clientHidden;
3563 wtoken.sendAppVisibilityToClients();
3564 }
3565 if (ttoken.animation != null) {
3566 wtoken.animation = ttoken.animation;
3567 wtoken.animating = ttoken.animating;
3568 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3569 ttoken.animation = null;
3570 ttoken.animLayerAdjustment = 0;
3571 wtoken.updateLayers();
3572 ttoken.updateLayers();
3573 }
Romain Guy06882f82009-06-10 13:36:04 -07003574
Jeff Brown3a22cd92011-01-21 13:59:04 -08003575 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3576 true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003577 mLayoutNeeded = true;
3578 performLayoutAndPlaceSurfacesLocked();
3579 Binder.restoreCallingIdentity(origId);
3580 return;
3581 } else if (ttoken.startingData != null) {
3582 // The previous app was getting ready to show a
3583 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003584 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 "Moving pending starting from " + ttoken
3586 + " to " + wtoken);
3587 wtoken.startingData = ttoken.startingData;
3588 ttoken.startingData = null;
3589 ttoken.startingMoved = true;
3590 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3591 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3592 // want to process the message ASAP, before any other queued
3593 // messages.
3594 mH.sendMessageAtFrontOfQueue(m);
3595 return;
3596 }
3597 }
3598 }
3599
3600 // There is no existing starting window, and the caller doesn't
3601 // want us to create one, so that's it!
3602 if (!createIfNeeded) {
3603 return;
3604 }
Romain Guy06882f82009-06-10 13:36:04 -07003605
Dianne Hackborn284ac932009-08-28 10:34:25 -07003606 // If this is a translucent or wallpaper window, then don't
3607 // show a starting window -- the current effect (a full-screen
3608 // opaque starting window that fades away to the real contents
3609 // when it is ready) does not work for this.
3610 if (theme != 0) {
3611 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3612 com.android.internal.R.styleable.Window);
3613 if (ent.array.getBoolean(
3614 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3615 return;
3616 }
3617 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003618 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3619 return;
3620 }
3621 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003622 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3623 return;
3624 }
3625 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003627 mStartingIconInTransition = true;
3628 wtoken.startingData = new StartingData(
3629 pkg, theme, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003630 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003631 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3632 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3633 // want to process the message ASAP, before any other queued
3634 // messages.
3635 mH.sendMessageAtFrontOfQueue(m);
3636 }
3637 }
3638
3639 public void setAppWillBeHidden(IBinder token) {
3640 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3641 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003642 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643 }
3644
3645 AppWindowToken wtoken;
3646
3647 synchronized(mWindowMap) {
3648 wtoken = findAppWindowToken(token);
3649 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003650 Slog.w(TAG, "Attempted to set will be hidden of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003651 return;
3652 }
3653 wtoken.willBeHidden = true;
3654 }
3655 }
Romain Guy06882f82009-06-10 13:36:04 -07003656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
3658 boolean visible, int transit, boolean performLayout) {
3659 boolean delayed = false;
3660
3661 if (wtoken.clientHidden == visible) {
3662 wtoken.clientHidden = !visible;
3663 wtoken.sendAppVisibilityToClients();
3664 }
Romain Guy06882f82009-06-10 13:36:04 -07003665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 wtoken.willBeHidden = false;
3667 if (wtoken.hidden == visible) {
3668 final int N = wtoken.allAppWindows.size();
3669 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003670 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3672 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003674 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003675
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003676 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 if (wtoken.animation == sDummyAnimation) {
3678 wtoken.animation = null;
3679 }
3680 applyAnimationLocked(wtoken, lp, transit, visible);
3681 changed = true;
3682 if (wtoken.animation != null) {
3683 delayed = runningAppAnimation = true;
3684 }
3685 }
Romain Guy06882f82009-06-10 13:36:04 -07003686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 for (int i=0; i<N; i++) {
3688 WindowState win = wtoken.allAppWindows.get(i);
3689 if (win == wtoken.startingWindow) {
3690 continue;
3691 }
3692
3693 if (win.isAnimating()) {
3694 delayed = true;
3695 }
Romain Guy06882f82009-06-10 13:36:04 -07003696
Joe Onorato8a9b2202010-02-26 18:56:32 -08003697 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003698 //win.dump(" ");
3699 if (visible) {
3700 if (!win.isVisibleNow()) {
3701 if (!runningAppAnimation) {
3702 applyAnimationLocked(win,
3703 WindowManagerPolicy.TRANSIT_ENTER, true);
3704 }
3705 changed = true;
3706 }
3707 } else if (win.isVisibleNow()) {
3708 if (!runningAppAnimation) {
3709 applyAnimationLocked(win,
3710 WindowManagerPolicy.TRANSIT_EXIT, false);
3711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 changed = true;
3713 }
3714 }
3715
3716 wtoken.hidden = wtoken.hiddenRequested = !visible;
3717 if (!visible) {
3718 unsetAppFreezingScreenLocked(wtoken, true, true);
3719 } else {
3720 // If we are being set visible, and the starting window is
3721 // not yet displayed, then make sure it doesn't get displayed.
3722 WindowState swin = wtoken.startingWindow;
3723 if (swin != null && (swin.mDrawPending
3724 || swin.mCommitDrawPending)) {
3725 swin.mPolicyVisibility = false;
3726 swin.mPolicyVisibilityAfterAnim = false;
3727 }
3728 }
Romain Guy06882f82009-06-10 13:36:04 -07003729
Joe Onorato8a9b2202010-02-26 18:56:32 -08003730 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003731 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3732 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003733
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003734 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08003736 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003737 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08003738 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3739 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003740 performLayoutAndPlaceSurfacesLocked();
3741 }
Jeff Brown2e44b072011-01-24 15:21:56 -08003742 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 }
3744 }
3745
3746 if (wtoken.animation != null) {
3747 delayed = true;
3748 }
Romain Guy06882f82009-06-10 13:36:04 -07003749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 return delayed;
3751 }
3752
3753 public void setAppVisibility(IBinder token, boolean visible) {
3754 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3755 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003756 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757 }
3758
3759 AppWindowToken wtoken;
3760
3761 synchronized(mWindowMap) {
3762 wtoken = findAppWindowToken(token);
3763 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003764 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 return;
3766 }
3767
3768 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003769 RuntimeException e = null;
3770 if (!HIDE_STACK_CRAWLS) {
3771 e = new RuntimeException();
3772 e.fillInStackTrace();
3773 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003774 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003775 + "): mNextAppTransition=" + mNextAppTransition
3776 + " hidden=" + wtoken.hidden
3777 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3778 }
Romain Guy06882f82009-06-10 13:36:04 -07003779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 // If we are preparing an app transition, then delay changing
3781 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003782 if (!mDisplayFrozen && mPolicy.isScreenOn()
3783 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003784 // Already in requested state, don't do anything more.
3785 if (wtoken.hiddenRequested != visible) {
3786 return;
3787 }
3788 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003789
Joe Onorato8a9b2202010-02-26 18:56:32 -08003790 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 TAG, "Setting dummy animation on: " + wtoken);
3792 wtoken.setDummyAnimation();
3793 mOpeningApps.remove(wtoken);
3794 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003795 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003796 wtoken.inPendingTransaction = true;
3797 if (visible) {
3798 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 wtoken.startingDisplayed = false;
3800 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003801
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003802 // If the token is currently hidden (should be the
3803 // common case), then we need to set up to wait for
3804 // its windows to be ready.
3805 if (wtoken.hidden) {
3806 wtoken.allDrawn = false;
3807 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003808
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003809 if (wtoken.clientHidden) {
3810 // In the case where we are making an app visible
3811 // but holding off for a transition, we still need
3812 // to tell the client to make its windows visible so
3813 // they get drawn. Otherwise, we will wait on
3814 // performing the transition until all windows have
3815 // been drawn, they never will be, and we are sad.
3816 wtoken.clientHidden = false;
3817 wtoken.sendAppVisibilityToClients();
3818 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003819 }
3820 } else {
3821 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003822
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003823 // If the token is currently visible (should be the
3824 // common case), then set up to wait for it to be hidden.
3825 if (!wtoken.hidden) {
3826 wtoken.waitingToHide = true;
3827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003828 }
3829 return;
3830 }
Romain Guy06882f82009-06-10 13:36:04 -07003831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003832 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003833 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 wtoken.updateReportedVisibilityLocked();
3835 Binder.restoreCallingIdentity(origId);
3836 }
3837 }
3838
3839 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3840 boolean unfreezeSurfaceNow, boolean force) {
3841 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003842 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 + " force=" + force);
3844 final int N = wtoken.allAppWindows.size();
3845 boolean unfrozeWindows = false;
3846 for (int i=0; i<N; i++) {
3847 WindowState w = wtoken.allAppWindows.get(i);
3848 if (w.mAppFreezing) {
3849 w.mAppFreezing = false;
3850 if (w.mSurface != null && !w.mOrientationChanging) {
3851 w.mOrientationChanging = true;
3852 }
3853 unfrozeWindows = true;
3854 }
3855 }
3856 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003857 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858 wtoken.freezingScreen = false;
3859 mAppsFreezingScreen--;
3860 }
3861 if (unfreezeSurfaceNow) {
3862 if (unfrozeWindows) {
3863 mLayoutNeeded = true;
3864 performLayoutAndPlaceSurfacesLocked();
3865 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003866 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003867 }
3868 }
3869 }
Romain Guy06882f82009-06-10 13:36:04 -07003870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003871 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3872 int configChanges) {
3873 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003874 RuntimeException e = null;
3875 if (!HIDE_STACK_CRAWLS) {
3876 e = new RuntimeException();
3877 e.fillInStackTrace();
3878 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003879 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003880 + ": hidden=" + wtoken.hidden + " freezing="
3881 + wtoken.freezingScreen, e);
3882 }
3883 if (!wtoken.hiddenRequested) {
3884 if (!wtoken.freezingScreen) {
3885 wtoken.freezingScreen = true;
3886 mAppsFreezingScreen++;
3887 if (mAppsFreezingScreen == 1) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003888 startFreezingDisplayLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3890 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3891 5000);
3892 }
3893 }
3894 final int N = wtoken.allAppWindows.size();
3895 for (int i=0; i<N; i++) {
3896 WindowState w = wtoken.allAppWindows.get(i);
3897 w.mAppFreezing = true;
3898 }
3899 }
3900 }
Romain Guy06882f82009-06-10 13:36:04 -07003901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 public void startAppFreezingScreen(IBinder token, int configChanges) {
3903 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3904 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003905 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003906 }
3907
3908 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003909 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003910 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 return;
3912 }
Romain Guy06882f82009-06-10 13:36:04 -07003913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003914 AppWindowToken wtoken = findAppWindowToken(token);
3915 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003916 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 return;
3918 }
3919 final long origId = Binder.clearCallingIdentity();
3920 startAppFreezingScreenLocked(wtoken, configChanges);
3921 Binder.restoreCallingIdentity(origId);
3922 }
3923 }
Romain Guy06882f82009-06-10 13:36:04 -07003924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 public void stopAppFreezingScreen(IBinder token, boolean force) {
3926 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3927 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003928 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 }
3930
3931 synchronized(mWindowMap) {
3932 AppWindowToken wtoken = findAppWindowToken(token);
3933 if (wtoken == null || wtoken.appToken == null) {
3934 return;
3935 }
3936 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003937 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003938 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3939 unsetAppFreezingScreenLocked(wtoken, true, force);
3940 Binder.restoreCallingIdentity(origId);
3941 }
3942 }
Romain Guy06882f82009-06-10 13:36:04 -07003943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 public void removeAppToken(IBinder token) {
3945 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3946 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003947 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 }
3949
3950 AppWindowToken wtoken = null;
3951 AppWindowToken startingToken = null;
3952 boolean delayed = false;
3953
3954 final long origId = Binder.clearCallingIdentity();
3955 synchronized(mWindowMap) {
3956 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003958 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003959 delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003960 wtoken.inPendingTransaction = false;
3961 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003962 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 if (mClosingApps.contains(wtoken)) {
3964 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003965 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003967 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 delayed = true;
3969 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003970 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 TAG, "Removing app " + wtoken + " delayed=" + delayed
3972 + " animation=" + wtoken.animation
3973 + " animating=" + wtoken.animating);
3974 if (delayed) {
3975 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003976 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
3977 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003979 } else {
3980 // Make sure there is no animation running on this token,
3981 // so any windows associated with it will be removed as
3982 // soon as their animations are complete
3983 wtoken.animation = null;
3984 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003985 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003986 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
3987 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 mAppTokens.remove(wtoken);
3989 wtoken.removed = true;
3990 if (wtoken.startingData != null) {
3991 startingToken = wtoken;
3992 }
3993 unsetAppFreezingScreenLocked(wtoken, true, true);
3994 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003995 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08003997 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003998 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003999 }
4000 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004001 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 }
Romain Guy06882f82009-06-10 13:36:04 -07004003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 if (!delayed && wtoken != null) {
4005 wtoken.updateReportedVisibilityLocked();
4006 }
4007 }
4008 Binder.restoreCallingIdentity(origId);
4009
4010 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004011 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 + startingToken + ": app token removed");
4013 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4014 mH.sendMessage(m);
4015 }
4016 }
4017
4018 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4019 final int NW = token.windows.size();
4020 for (int i=0; i<NW; i++) {
4021 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004022 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004024 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 int j = win.mChildWindows.size();
4026 while (j > 0) {
4027 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004028 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004029 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004030 "Tmp removing child window " + cwin);
4031 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 }
4033 }
4034 return NW > 0;
4035 }
4036
4037 void dumpAppTokensLocked() {
4038 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004039 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004040 }
4041 }
Romain Guy06882f82009-06-10 13:36:04 -07004042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004043 void dumpWindowsLocked() {
4044 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004045 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 }
4047 }
Romain Guy06882f82009-06-10 13:36:04 -07004048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 private int findWindowOffsetLocked(int tokenPos) {
4050 final int NW = mWindows.size();
4051
4052 if (tokenPos >= mAppTokens.size()) {
4053 int i = NW;
4054 while (i > 0) {
4055 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004056 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 if (win.getAppToken() != null) {
4058 return i+1;
4059 }
4060 }
4061 }
4062
4063 while (tokenPos > 0) {
4064 // Find the first app token below the new position that has
4065 // a window displayed.
4066 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004067 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004068 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004069 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004070 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004071 "Skipping token -- currently sending to bottom");
4072 tokenPos--;
4073 continue;
4074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004075 int i = wtoken.windows.size();
4076 while (i > 0) {
4077 i--;
4078 WindowState win = wtoken.windows.get(i);
4079 int j = win.mChildWindows.size();
4080 while (j > 0) {
4081 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004082 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004083 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 for (int pos=NW-1; pos>=0; pos--) {
4085 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004086 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087 "Found child win @" + (pos+1));
4088 return pos+1;
4089 }
4090 }
4091 }
4092 }
4093 for (int pos=NW-1; pos>=0; pos--) {
4094 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004095 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 return pos+1;
4097 }
4098 }
4099 }
4100 tokenPos--;
4101 }
4102
4103 return 0;
4104 }
4105
4106 private final int reAddWindowLocked(int index, WindowState win) {
4107 final int NCW = win.mChildWindows.size();
4108 boolean added = false;
4109 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004110 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004112 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004113 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004114 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004115 mWindows.add(index, win);
4116 index++;
4117 added = true;
4118 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004119 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004120 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004121 cwin.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 mWindows.add(index, cwin);
4123 index++;
4124 }
4125 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004126 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004127 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004128 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004129 mWindows.add(index, win);
4130 index++;
4131 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004132 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004133 return index;
4134 }
Romain Guy06882f82009-06-10 13:36:04 -07004135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004136 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4137 final int NW = token.windows.size();
4138 for (int i=0; i<NW; i++) {
4139 index = reAddWindowLocked(index, token.windows.get(i));
4140 }
4141 return index;
4142 }
4143
4144 public void moveAppToken(int index, IBinder token) {
4145 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4146 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004147 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004148 }
4149
4150 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004151 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 if (DEBUG_REORDER) dumpAppTokensLocked();
4153 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004154 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4155 "Start moving token " + wtoken + " initially at "
4156 + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004157 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004158 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004159 + token + " (" + wtoken + ")");
4160 return;
4161 }
4162 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004163 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004164 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004165 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004167 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004168 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004169 if (DEBUG_REORDER) dumpWindowsLocked();
4170 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004171 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004172 if (DEBUG_REORDER) dumpWindowsLocked();
4173 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004174 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004175 if (DEBUG_REORDER) dumpWindowsLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004176 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4177 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004178 mLayoutNeeded = true;
Jeff Brown2e44b072011-01-24 15:21:56 -08004179 mInputMonitor.setUpdateInputWindowsNeededLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004181 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004182 }
4183 Binder.restoreCallingIdentity(origId);
4184 }
4185 }
4186
4187 private void removeAppTokensLocked(List<IBinder> tokens) {
4188 // XXX This should be done more efficiently!
4189 // (take advantage of the fact that both lists should be
4190 // ordered in the same way.)
4191 int N = tokens.size();
4192 for (int i=0; i<N; i++) {
4193 IBinder token = tokens.get(i);
4194 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004195 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4196 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004198 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 + token + " (" + wtoken + ")");
4200 i--;
4201 N--;
4202 }
4203 }
4204 }
4205
Dianne Hackborna8f60182009-09-01 19:01:50 -07004206 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4207 boolean updateFocusAndLayout) {
4208 // First remove all of the windows from the list.
4209 tmpRemoveAppWindowsLocked(wtoken);
4210
4211 // Where to start adding?
4212 int pos = findWindowOffsetLocked(tokenPos);
4213
4214 // And now add them back at the correct place.
4215 pos = reAddAppWindowsLocked(pos, wtoken);
4216
4217 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08004218 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004219 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4220 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004221 assignLayersLocked();
4222 }
4223 mLayoutNeeded = true;
4224 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004225 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004226 }
4227 }
4228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004229 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4230 // First remove all of the windows from the list.
4231 final int N = tokens.size();
4232 int i;
4233 for (i=0; i<N; i++) {
4234 WindowToken token = mTokenMap.get(tokens.get(i));
4235 if (token != null) {
4236 tmpRemoveAppWindowsLocked(token);
4237 }
4238 }
4239
4240 // Where to start adding?
4241 int pos = findWindowOffsetLocked(tokenPos);
4242
4243 // And now add them back at the correct place.
4244 for (i=0; i<N; i++) {
4245 WindowToken token = mTokenMap.get(tokens.get(i));
4246 if (token != null) {
4247 pos = reAddAppWindowsLocked(pos, token);
4248 }
4249 }
4250
Jeff Brown2e44b072011-01-24 15:21:56 -08004251 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004252 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4253 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004254 assignLayersLocked();
4255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004256 mLayoutNeeded = true;
4257 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004258 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259
4260 //dump();
4261 }
4262
4263 public void moveAppTokensToTop(List<IBinder> tokens) {
4264 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4265 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004266 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004267 }
4268
4269 final long origId = Binder.clearCallingIdentity();
4270 synchronized(mWindowMap) {
4271 removeAppTokensLocked(tokens);
4272 final int N = tokens.size();
4273 for (int i=0; i<N; i++) {
4274 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4275 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004276 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4277 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004278 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004279 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004280 mToTopApps.remove(wt);
4281 mToBottomApps.remove(wt);
4282 mToTopApps.add(wt);
4283 wt.sendingToBottom = false;
4284 wt.sendingToTop = true;
4285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 }
4287 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004288
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004289 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004290 moveAppWindowsLocked(tokens, mAppTokens.size());
4291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 }
4293 Binder.restoreCallingIdentity(origId);
4294 }
4295
4296 public void moveAppTokensToBottom(List<IBinder> tokens) {
4297 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4298 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004299 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004300 }
4301
4302 final long origId = Binder.clearCallingIdentity();
4303 synchronized(mWindowMap) {
4304 removeAppTokensLocked(tokens);
4305 final int N = tokens.size();
4306 int pos = 0;
4307 for (int i=0; i<N; i++) {
4308 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4309 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004310 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4311 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004313 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004314 mToTopApps.remove(wt);
4315 mToBottomApps.remove(wt);
4316 mToBottomApps.add(i, wt);
4317 wt.sendingToTop = false;
4318 wt.sendingToBottom = true;
4319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 pos++;
4321 }
4322 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004323
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004324 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004325 moveAppWindowsLocked(tokens, 0);
4326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 }
4328 Binder.restoreCallingIdentity(origId);
4329 }
4330
4331 // -------------------------------------------------------------
4332 // Misc IWindowSession methods
4333 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004334
Jim Miller284b62e2010-06-08 14:27:42 -07004335 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004336 {
Jim Miller284b62e2010-06-08 14:27:42 -07004337 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4338 // called before DevicePolicyManagerService has started.
4339 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4340 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4341 Context.DEVICE_POLICY_SERVICE);
4342 if (dpm != null) {
4343 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4344 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4345 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4346 }
Jim Millerd6b57052010-06-07 17:52:42 -07004347 }
Jim Miller284b62e2010-06-08 14:27:42 -07004348 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004349 }
4350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004352 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 != PackageManager.PERMISSION_GRANTED) {
4354 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4355 }
Jim Millerd6b57052010-06-07 17:52:42 -07004356
Jim Miller284b62e2010-06-08 14:27:42 -07004357 synchronized (mKeyguardTokenWatcher) {
4358 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 }
4361
4362 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004363 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004364 != PackageManager.PERMISSION_GRANTED) {
4365 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367
Jim Miller284b62e2010-06-08 14:27:42 -07004368 synchronized (mKeyguardTokenWatcher) {
4369 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004370
Jim Miller284b62e2010-06-08 14:27:42 -07004371 if (!mKeyguardTokenWatcher.isAcquired()) {
4372 // If we are the last one to reenable the keyguard wait until
4373 // we have actually finished reenabling until returning.
4374 // It is possible that reenableKeyguard() can be called before
4375 // the previous disableKeyguard() is handled, in which case
4376 // neither mKeyguardTokenWatcher.acquired() or released() would
4377 // be called. In that case mKeyguardDisabled will be false here
4378 // and we have nothing to wait for.
4379 while (mKeyguardDisabled) {
4380 try {
4381 mKeyguardTokenWatcher.wait();
4382 } catch (InterruptedException e) {
4383 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 }
4385 }
4386 }
4387 }
4388 }
4389
4390 /**
4391 * @see android.app.KeyguardManager#exitKeyguardSecurely
4392 */
4393 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004394 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004395 != PackageManager.PERMISSION_GRANTED) {
4396 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4397 }
4398 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4399 public void onKeyguardExitResult(boolean success) {
4400 try {
4401 callback.onKeyguardExitResult(success);
4402 } catch (RemoteException e) {
4403 // Client has died, we don't care.
4404 }
4405 }
4406 });
4407 }
4408
4409 public boolean inKeyguardRestrictedInputMode() {
4410 return mPolicy.inKeyguardRestrictedKeyInputMode();
4411 }
Romain Guy06882f82009-06-10 13:36:04 -07004412
Dianne Hackbornffa42482009-09-23 22:20:11 -07004413 public void closeSystemDialogs(String reason) {
4414 synchronized(mWindowMap) {
4415 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004416 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004417 if (w.mSurface != null) {
4418 try {
4419 w.mClient.closeSystemDialogs(reason);
4420 } catch (RemoteException e) {
4421 }
4422 }
4423 }
4424 }
4425 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 static float fixScale(float scale) {
4428 if (scale < 0) scale = 0;
4429 else if (scale > 20) scale = 20;
4430 return Math.abs(scale);
4431 }
Romain Guy06882f82009-06-10 13:36:04 -07004432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 public void setAnimationScale(int which, float scale) {
4434 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4435 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004436 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 }
4438
4439 if (scale < 0) scale = 0;
4440 else if (scale > 20) scale = 20;
4441 scale = Math.abs(scale);
4442 switch (which) {
4443 case 0: mWindowAnimationScale = fixScale(scale); break;
4444 case 1: mTransitionAnimationScale = fixScale(scale); break;
4445 }
Romain Guy06882f82009-06-10 13:36:04 -07004446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 // Persist setting
4448 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4449 }
Romain Guy06882f82009-06-10 13:36:04 -07004450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004451 public void setAnimationScales(float[] scales) {
4452 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4453 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004454 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004455 }
4456
4457 if (scales != null) {
4458 if (scales.length >= 1) {
4459 mWindowAnimationScale = fixScale(scales[0]);
4460 }
4461 if (scales.length >= 2) {
4462 mTransitionAnimationScale = fixScale(scales[1]);
4463 }
4464 }
Romain Guy06882f82009-06-10 13:36:04 -07004465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 // Persist setting
4467 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4468 }
Romain Guy06882f82009-06-10 13:36:04 -07004469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004470 public float getAnimationScale(int which) {
4471 switch (which) {
4472 case 0: return mWindowAnimationScale;
4473 case 1: return mTransitionAnimationScale;
4474 }
4475 return 0;
4476 }
Romain Guy06882f82009-06-10 13:36:04 -07004477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004478 public float[] getAnimationScales() {
4479 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4480 }
Romain Guy06882f82009-06-10 13:36:04 -07004481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 public int getSwitchState(int sw) {
4483 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4484 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004485 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004487 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 }
Romain Guy06882f82009-06-10 13:36:04 -07004489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 public int getSwitchStateForDevice(int devid, int sw) {
4491 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4492 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004493 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004495 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004496 }
Romain Guy06882f82009-06-10 13:36:04 -07004497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 public int getScancodeState(int sw) {
4499 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4500 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004501 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004503 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 }
Romain Guy06882f82009-06-10 13:36:04 -07004505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 public int getScancodeStateForDevice(int devid, int sw) {
4507 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4508 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004509 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004511 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 }
Romain Guy06882f82009-06-10 13:36:04 -07004513
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004514 public int getTrackballScancodeState(int sw) {
4515 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4516 "getTrackballScancodeState()")) {
4517 throw new SecurityException("Requires READ_INPUT_STATE permission");
4518 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004519 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004520 }
4521
4522 public int getDPadScancodeState(int sw) {
4523 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4524 "getDPadScancodeState()")) {
4525 throw new SecurityException("Requires READ_INPUT_STATE permission");
4526 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004527 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004528 }
4529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004530 public int getKeycodeState(int sw) {
4531 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4532 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004533 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004534 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004535 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 }
Romain Guy06882f82009-06-10 13:36:04 -07004537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 public int getKeycodeStateForDevice(int devid, int sw) {
4539 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4540 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004541 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004542 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004543 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004544 }
Romain Guy06882f82009-06-10 13:36:04 -07004545
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004546 public int getTrackballKeycodeState(int sw) {
4547 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4548 "getTrackballKeycodeState()")) {
4549 throw new SecurityException("Requires READ_INPUT_STATE permission");
4550 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004551 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004552 }
4553
4554 public int getDPadKeycodeState(int sw) {
4555 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4556 "getDPadKeycodeState()")) {
4557 throw new SecurityException("Requires READ_INPUT_STATE permission");
4558 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004559 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004560 }
Jeff Browna41ca772010-08-11 14:46:32 -07004561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004563 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 }
Romain Guy06882f82009-06-10 13:36:04 -07004565
Jeff Browna41ca772010-08-11 14:46:32 -07004566 public InputChannel monitorInput(String inputChannelName) {
4567 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4568 "monitorInput()")) {
4569 throw new SecurityException("Requires READ_INPUT_STATE permission");
4570 }
4571 return mInputManager.monitorInput(inputChannelName);
4572 }
4573
Jeff Brown8d608662010-08-30 03:02:23 -07004574 public InputDevice getInputDevice(int deviceId) {
4575 return mInputManager.getInputDevice(deviceId);
4576 }
4577
4578 public int[] getInputDeviceIds() {
4579 return mInputManager.getInputDeviceIds();
4580 }
4581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 public void enableScreenAfterBoot() {
4583 synchronized(mWindowMap) {
4584 if (mSystemBooted) {
4585 return;
4586 }
4587 mSystemBooted = true;
4588 }
Romain Guy06882f82009-06-10 13:36:04 -07004589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 performEnableScreen();
4591 }
Romain Guy06882f82009-06-10 13:36:04 -07004592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 public void enableScreenIfNeededLocked() {
4594 if (mDisplayEnabled) {
4595 return;
4596 }
4597 if (!mSystemBooted) {
4598 return;
4599 }
4600 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4601 }
Romain Guy06882f82009-06-10 13:36:04 -07004602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 public void performEnableScreen() {
4604 synchronized(mWindowMap) {
4605 if (mDisplayEnabled) {
4606 return;
4607 }
4608 if (!mSystemBooted) {
4609 return;
4610 }
Romain Guy06882f82009-06-10 13:36:04 -07004611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 // Don't enable the screen until all existing windows
4613 // have been drawn.
4614 final int N = mWindows.size();
4615 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004616 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004617 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 return;
4619 }
4620 }
Romain Guy06882f82009-06-10 13:36:04 -07004621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 mDisplayEnabled = true;
4623 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004624 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 StringWriter sw = new StringWriter();
4626 PrintWriter pw = new PrintWriter(sw);
4627 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004628 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 }
4630 try {
4631 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4632 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004633 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 Parcel data = Parcel.obtain();
4635 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4636 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4637 data, null, 0);
4638 data.recycle();
4639 }
4640 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004641 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
4643 }
Romain Guy06882f82009-06-10 13:36:04 -07004644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004645 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004648 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4649 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 }
Romain Guy06882f82009-06-10 13:36:04 -07004651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 public void setInTouchMode(boolean mode) {
4653 synchronized(mWindowMap) {
4654 mInTouchMode = mode;
4655 }
4656 }
4657
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004658 // TODO: more accounting of which pid(s) turned it on, keep count,
4659 // only allow disables from pids which have count on, etc.
4660 public void showStrictModeViolation(boolean on) {
4661 int pid = Binder.getCallingPid();
4662 synchronized(mWindowMap) {
4663 // Ignoring requests to enable the red border from clients
4664 // which aren't on screen. (e.g. Broadcast Receivers in
4665 // the background..)
4666 if (on) {
4667 boolean isVisible = false;
4668 for (WindowState ws : mWindows) {
4669 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
4670 isVisible = true;
4671 break;
4672 }
4673 }
4674 if (!isVisible) {
4675 return;
4676 }
4677 }
4678
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004679 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004680 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004681 try {
4682 if (mStrictModeFlash == null) {
4683 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
4684 }
4685 mStrictModeFlash.setVisibility(on);
4686 } finally {
4687 Surface.closeTransaction();
4688 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004689 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004690 }
4691 }
4692
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08004693 public void setStrictModeVisualIndicatorPreference(String value) {
4694 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
4695 }
4696
Dianne Hackbornd2835932010-12-13 16:28:46 -08004697 public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004698 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
4699 "screenshotApplications()")) {
4700 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
4701 }
4702
4703 Bitmap rawss;
4704
Dianne Hackbornd2835932010-12-13 16:28:46 -08004705 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004706 final Rect frame = new Rect();
4707
4708 float scale;
4709 int sw, sh, dw, dh;
4710 int rot;
4711
4712 synchronized(mWindowMap) {
4713 long ident = Binder.clearCallingIdentity();
4714
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004715 dw = mDisplay.getWidth();
4716 dh = mDisplay.getHeight();
4717
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004718 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
4719 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
4720 + TYPE_LAYER_OFFSET;
4721 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
4722
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004723 boolean isImeTarget = mInputMethodTarget != null
4724 && mInputMethodTarget.mAppToken != null
4725 && mInputMethodTarget.mAppToken.appToken != null
4726 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
4727
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004728 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004729 boolean including = false;
4730 for (int i=mWindows.size()-1; i>=0; i--) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004731 WindowState ws = mWindows.get(i);
4732 if (ws.mSurface == null) {
4733 continue;
4734 }
4735 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004736 continue;
4737 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004738 // When we will skip windows: when we are not including
4739 // ones behind a window we didn't skip, and we are actually
4740 // taking a screenshot of a specific app.
4741 if (!including && appToken != null) {
4742 // Also, we can possibly skip this window if it is not
4743 // an IME target or the application for the screenshot
4744 // is not the current IME target.
4745 if (!ws.mIsImWindow || !isImeTarget) {
4746 // And finally, this window is of no interest if it
4747 // is not associated with the screenshot app.
4748 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
4749 continue;
4750 }
4751 }
4752 }
4753
4754 // We keep on including windows until we go past a full-screen
4755 // window.
4756 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
4757
Dianne Hackbornd2835932010-12-13 16:28:46 -08004758 if (maxLayer < ws.mAnimLayer) {
4759 maxLayer = ws.mAnimLayer;
4760 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004761 final Rect wf = ws.mFrame;
4762 final Rect cr = ws.mContentInsets;
4763 int left = wf.left + cr.left;
4764 int top = wf.top + cr.top;
4765 int right = wf.right - cr.right;
4766 int bottom = wf.bottom - cr.bottom;
4767 frame.union(left, top, right, bottom);
4768 }
4769 Binder.restoreCallingIdentity(ident);
4770
Dianne Hackborndd962ee2011-02-02 11:11:50 -08004771 // Constrain frame to the screen size.
4772 frame.intersect(0, 0, dw, dh);
4773
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08004774 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004775 return null;
4776 }
4777
4778 // The screenshot API does not apply the current screen rotation.
4779 rot = mDisplay.getRotation();
4780 int fw = frame.width();
4781 int fh = frame.height();
4782
4783 // First try reducing to fit in x dimension.
4784 scale = maxWidth/(float)fw;
4785 sw = maxWidth;
4786 sh = (int)(fh*scale);
4787 if (sh > maxHeight) {
4788 // y dimension became too long; constrain by that.
4789 scale = maxHeight/(float)fh;
4790 sw = (int)(fw*scale);
4791 sh = maxHeight;
4792 }
4793
4794 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004795 dw = (int)(dw*scale);
4796 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004797 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
4798 int tmp = dw;
4799 dw = dh;
4800 dh = tmp;
4801 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
4802 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08004803 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004804 }
4805
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08004806 if (rawss == null) {
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08004807 Log.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
4808 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08004809 return null;
4810 }
4811
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004812 Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
4813 Matrix matrix = new Matrix();
4814 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
4815 matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
4816 Canvas canvas = new Canvas(bm);
4817 canvas.drawBitmap(rawss, matrix, null);
4818
4819 rawss.recycle();
4820 return bm;
4821 }
4822
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004823 public void freezeRotation() {
4824 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4825 "setRotation()")) {
4826 throw new SecurityException("Requires SET_ORIENTATION permission");
4827 }
4828
4829 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
4830 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4831 }
4832
4833 public void thawRotation() {
4834 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
4835 "setRotation()")) {
4836 throw new SecurityException("Requires SET_ORIENTATION permission");
4837 }
4838
4839 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
4840 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4841 }
4842
Romain Guy06882f82009-06-10 13:36:04 -07004843 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004844 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004845 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004846 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004847 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 }
4849
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004850 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 }
Romain Guy06882f82009-06-10 13:36:04 -07004852
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004853 public void setRotationUnchecked(int rotation,
4854 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004855 if(DEBUG_ORIENTATION) Slog.v(TAG,
David 'Digit' Turner910a0682011-02-05 00:34:46 +01004856 "setRotationUnchecked(rotation=" + rotation +
4857 " alwaysSendConfiguration=" + alwaysSendConfiguration +
4858 " animFlags=" + animFlags);
Romain Guy06882f82009-06-10 13:36:04 -07004859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860 long origId = Binder.clearCallingIdentity();
4861 boolean changed;
4862 synchronized(mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004863 changed = setRotationUncheckedLocked(rotation, animFlags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864 }
Romain Guy06882f82009-06-10 13:36:04 -07004865
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004866 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 sendNewConfiguration();
4868 }
Romain Guy06882f82009-06-10 13:36:04 -07004869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 Binder.restoreCallingIdentity(origId);
4871 }
Romain Guy06882f82009-06-10 13:36:04 -07004872
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004873 /**
4874 * Apply a new rotation to the screen, respecting the requests of
4875 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4876 * re-evaluate the desired rotation.
4877 *
4878 * Returns null if the rotation has been changed. In this case YOU
4879 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4880 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004881 public boolean setRotationUncheckedLocked(int rotation, int animFlags, boolean inTransaction) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004882 if (mDragState != null || mScreenRotationAnimation != null) {
Christopher Tateccd24de2011-01-12 15:02:55 -08004883 // Potential rotation during a drag. Don't do the rotation now, but make
4884 // a note to perform the rotation later.
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004885 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation.");
4886 if (rotation != WindowManagerPolicy.USE_LAST_ROTATION) {
4887 mDeferredRotation = rotation;
4888 mDeferredRotationAnimFlags = animFlags;
4889 }
Christopher Tateccd24de2011-01-12 15:02:55 -08004890 return false;
4891 }
4892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 boolean changed;
4894 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004895 if (mDeferredRotation != WindowManagerPolicy.USE_LAST_ROTATION) {
4896 rotation = mDeferredRotation;
4897 mRequestedRotation = rotation;
4898 mLastRotationFlags = mDeferredRotationAnimFlags;
4899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 rotation = mRequestedRotation;
4901 } else {
4902 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004903 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004904 }
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004905 mDeferredRotation = WindowManagerPolicy.USE_LAST_ROTATION;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004906 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004907 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004908 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004909 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 changed = mDisplayEnabled && mRotation != rotation;
Romain Guy06882f82009-06-10 13:36:04 -07004911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004913 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 "Rotation changed to " + rotation
4915 + " from " + mRotation
4916 + " (forceApp=" + mForcedAppOrientation
4917 + ", req=" + mRequestedRotation + ")");
4918 mRotation = rotation;
4919 mWindowsFreezingScreen = true;
4920 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
4921 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
4922 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004923 mWaitingForConfig = true;
4924 mLayoutNeeded = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004925 startFreezingDisplayLocked(inTransaction);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004926 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004927 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928 if (mDisplayEnabled) {
David 'Digit' Turner910a0682011-02-05 00:34:46 +01004929 // NOTE: We disable the rotation in the emulator because
4930 // it doesn't support hardware OpenGL emulation yet.
4931 if (CUSTOM_SCREEN_ROTATION && !mInEmulator) {
Dianne Hackborna1111872010-11-23 20:55:11 -08004932 Surface.freezeDisplay(0);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004933 if (!inTransaction) {
4934 if (SHOW_TRANSACTIONS) Slog.i(TAG,
4935 ">>> OPEN TRANSACTION setRotationUnchecked");
4936 Surface.openTransaction();
Dianne Hackborna1111872010-11-23 20:55:11 -08004937 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004938 try {
4939 if (mScreenRotationAnimation != null) {
4940 mScreenRotationAnimation.setRotation(rotation);
4941 }
4942 } finally {
4943 if (!inTransaction) {
4944 Surface.closeTransaction();
4945 if (SHOW_TRANSACTIONS) Slog.i(TAG,
4946 "<<< CLOSE TRANSACTION setRotationUnchecked");
4947 }
4948 }
Dianne Hackborna1111872010-11-23 20:55:11 -08004949 Surface.setOrientation(0, rotation, animFlags);
4950 Surface.unfreezeDisplay(0);
4951 } else {
4952 Surface.setOrientation(0, rotation, animFlags);
4953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 }
4955 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004956 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004957 if (w.mSurface != null) {
4958 w.mOrientationChanging = true;
4959 }
4960 }
4961 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
4962 try {
4963 mRotationWatchers.get(i).onRotationChanged(rotation);
4964 } catch (RemoteException e) {
4965 }
4966 }
4967 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07004968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 return changed;
4970 }
Romain Guy06882f82009-06-10 13:36:04 -07004971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004972 public int getRotation() {
4973 return mRotation;
4974 }
4975
4976 public int watchRotation(IRotationWatcher watcher) {
4977 final IBinder watcherBinder = watcher.asBinder();
4978 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
4979 public void binderDied() {
4980 synchronized (mWindowMap) {
4981 for (int i=0; i<mRotationWatchers.size(); i++) {
4982 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004983 IRotationWatcher removed = mRotationWatchers.remove(i);
4984 if (removed != null) {
4985 removed.asBinder().unlinkToDeath(this, 0);
4986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004987 i--;
4988 }
4989 }
4990 }
4991 }
4992 };
Romain Guy06882f82009-06-10 13:36:04 -07004993
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994 synchronized (mWindowMap) {
4995 try {
4996 watcher.asBinder().linkToDeath(dr, 0);
4997 mRotationWatchers.add(watcher);
4998 } catch (RemoteException e) {
4999 // Client died, no cleanup needed.
5000 }
Romain Guy06882f82009-06-10 13:36:04 -07005001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 return mRotation;
5003 }
5004 }
5005
5006 /**
5007 * Starts the view server on the specified port.
5008 *
5009 * @param port The port to listener to.
5010 *
5011 * @return True if the server was successfully started, false otherwise.
5012 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005013 * @see com.android.server.wm.ViewServer
5014 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005015 */
5016 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005017 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005018 return false;
5019 }
5020
5021 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5022 return false;
5023 }
5024
5025 if (port < 1024) {
5026 return false;
5027 }
5028
5029 if (mViewServer != null) {
5030 if (!mViewServer.isRunning()) {
5031 try {
5032 return mViewServer.start();
5033 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005034 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005035 }
5036 }
5037 return false;
5038 }
5039
5040 try {
5041 mViewServer = new ViewServer(this, port);
5042 return mViewServer.start();
5043 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005044 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 }
5046 return false;
5047 }
5048
Romain Guy06882f82009-06-10 13:36:04 -07005049 private boolean isSystemSecure() {
5050 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5051 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5052 }
5053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005054 /**
5055 * Stops the view server if it exists.
5056 *
5057 * @return True if the server stopped, false if it wasn't started or
5058 * couldn't be stopped.
5059 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005060 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005061 */
5062 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005063 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005064 return false;
5065 }
5066
5067 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5068 return false;
5069 }
5070
5071 if (mViewServer != null) {
5072 return mViewServer.stop();
5073 }
5074 return false;
5075 }
5076
5077 /**
5078 * Indicates whether the view server is running.
5079 *
5080 * @return True if the server is running, false otherwise.
5081 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005082 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005083 */
5084 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005085 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005086 return false;
5087 }
5088
5089 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5090 return false;
5091 }
5092
5093 return mViewServer != null && mViewServer.isRunning();
5094 }
5095
5096 /**
5097 * Lists all availble windows in the system. The listing is written in the
5098 * specified Socket's output stream with the following syntax:
5099 * windowHashCodeInHexadecimal windowName
5100 * Each line of the ouput represents a different window.
5101 *
5102 * @param client The remote client to send the listing to.
5103 * @return False if an error occured, true otherwise.
5104 */
5105 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005106 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005107 return false;
5108 }
5109
5110 boolean result = true;
5111
Jeff Browne33348b2010-07-15 23:54:05 -07005112 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005113 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005115 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005116 }
5117
5118 BufferedWriter out = null;
5119
5120 // Any uncaught exception will crash the system process
5121 try {
5122 OutputStream clientStream = client.getOutputStream();
5123 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5124
5125 final int count = windows.length;
5126 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005127 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005128 out.write(Integer.toHexString(System.identityHashCode(w)));
5129 out.write(' ');
5130 out.append(w.mAttrs.getTitle());
5131 out.write('\n');
5132 }
5133
5134 out.write("DONE.\n");
5135 out.flush();
5136 } catch (Exception e) {
5137 result = false;
5138 } finally {
5139 if (out != null) {
5140 try {
5141 out.close();
5142 } catch (IOException e) {
5143 result = false;
5144 }
5145 }
5146 }
5147
5148 return result;
5149 }
5150
5151 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005152 * Returns the focused window in the following format:
5153 * windowHashCodeInHexadecimal windowName
5154 *
5155 * @param client The remote client to send the listing to.
5156 * @return False if an error occurred, true otherwise.
5157 */
5158 boolean viewServerGetFocusedWindow(Socket client) {
5159 if (isSystemSecure()) {
5160 return false;
5161 }
5162
5163 boolean result = true;
5164
5165 WindowState focusedWindow = getFocusedWindow();
5166
5167 BufferedWriter out = null;
5168
5169 // Any uncaught exception will crash the system process
5170 try {
5171 OutputStream clientStream = client.getOutputStream();
5172 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5173
5174 if(focusedWindow != null) {
5175 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5176 out.write(' ');
5177 out.append(focusedWindow.mAttrs.getTitle());
5178 }
5179 out.write('\n');
5180 out.flush();
5181 } catch (Exception e) {
5182 result = false;
5183 } finally {
5184 if (out != null) {
5185 try {
5186 out.close();
5187 } catch (IOException e) {
5188 result = false;
5189 }
5190 }
5191 }
5192
5193 return result;
5194 }
5195
5196 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005197 * Sends a command to a target window. The result of the command, if any, will be
5198 * written in the output stream of the specified socket.
5199 *
5200 * The parameters must follow this syntax:
5201 * windowHashcode extra
5202 *
5203 * Where XX is the length in characeters of the windowTitle.
5204 *
5205 * The first parameter is the target window. The window with the specified hashcode
5206 * will be the target. If no target can be found, nothing happens. The extra parameters
5207 * will be delivered to the target window and as parameters to the command itself.
5208 *
5209 * @param client The remote client to sent the result, if any, to.
5210 * @param command The command to execute.
5211 * @param parameters The command parameters.
5212 *
5213 * @return True if the command was successfully delivered, false otherwise. This does
5214 * not indicate whether the command itself was successful.
5215 */
5216 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005217 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 return false;
5219 }
5220
5221 boolean success = true;
5222 Parcel data = null;
5223 Parcel reply = null;
5224
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005225 BufferedWriter out = null;
5226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227 // Any uncaught exception will crash the system process
5228 try {
5229 // Find the hashcode of the window
5230 int index = parameters.indexOf(' ');
5231 if (index == -1) {
5232 index = parameters.length();
5233 }
5234 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005235 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236
5237 // Extract the command's parameter after the window description
5238 if (index < parameters.length()) {
5239 parameters = parameters.substring(index + 1);
5240 } else {
5241 parameters = "";
5242 }
5243
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005244 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005245 if (window == null) {
5246 return false;
5247 }
5248
5249 data = Parcel.obtain();
5250 data.writeInterfaceToken("android.view.IWindow");
5251 data.writeString(command);
5252 data.writeString(parameters);
5253 data.writeInt(1);
5254 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5255
5256 reply = Parcel.obtain();
5257
5258 final IBinder binder = window.mClient.asBinder();
5259 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5260 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5261
5262 reply.readException();
5263
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005264 if (!client.isOutputShutdown()) {
5265 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5266 out.write("DONE\n");
5267 out.flush();
5268 }
5269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005271 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005272 success = false;
5273 } finally {
5274 if (data != null) {
5275 data.recycle();
5276 }
5277 if (reply != null) {
5278 reply.recycle();
5279 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005280 if (out != null) {
5281 try {
5282 out.close();
5283 } catch (IOException e) {
5284
5285 }
5286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 }
5288
5289 return success;
5290 }
5291
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005292 public void addWindowChangeListener(WindowChangeListener listener) {
5293 synchronized(mWindowMap) {
5294 mWindowChangeListeners.add(listener);
5295 }
5296 }
5297
5298 public void removeWindowChangeListener(WindowChangeListener listener) {
5299 synchronized(mWindowMap) {
5300 mWindowChangeListeners.remove(listener);
5301 }
5302 }
5303
5304 private void notifyWindowsChanged() {
5305 WindowChangeListener[] windowChangeListeners;
5306 synchronized(mWindowMap) {
5307 if(mWindowChangeListeners.isEmpty()) {
5308 return;
5309 }
5310 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5311 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5312 }
5313 int N = windowChangeListeners.length;
5314 for(int i = 0; i < N; i++) {
5315 windowChangeListeners[i].windowsChanged();
5316 }
5317 }
5318
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005319 private void notifyFocusChanged() {
5320 WindowChangeListener[] windowChangeListeners;
5321 synchronized(mWindowMap) {
5322 if(mWindowChangeListeners.isEmpty()) {
5323 return;
5324 }
5325 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5326 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5327 }
5328 int N = windowChangeListeners.length;
5329 for(int i = 0; i < N; i++) {
5330 windowChangeListeners[i].focusChanged();
5331 }
5332 }
5333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 private WindowState findWindow(int hashCode) {
5335 if (hashCode == -1) {
5336 return getFocusedWindow();
5337 }
5338
5339 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005340 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341 final int count = windows.size();
5342
5343 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005344 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 if (System.identityHashCode(w) == hashCode) {
5346 return w;
5347 }
5348 }
5349 }
5350
5351 return null;
5352 }
5353
5354 /*
5355 * Instruct the Activity Manager to fetch the current configuration and broadcast
5356 * that to config-changed listeners if appropriate.
5357 */
5358 void sendNewConfiguration() {
5359 try {
5360 mActivityManager.updateConfiguration(null);
5361 } catch (RemoteException e) {
5362 }
5363 }
Romain Guy06882f82009-06-10 13:36:04 -07005364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005365 public Configuration computeNewConfiguration() {
5366 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005367 Configuration config = computeNewConfigurationLocked();
5368 if (config == null && mWaitingForConfig) {
5369 // Nothing changed but we are waiting for something... stop that!
5370 mWaitingForConfig = false;
5371 performLayoutAndPlaceSurfacesLocked();
5372 }
5373 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07005374 }
5375 }
Romain Guy06882f82009-06-10 13:36:04 -07005376
Dianne Hackbornc485a602009-03-24 22:39:49 -07005377 Configuration computeNewConfigurationLocked() {
5378 Configuration config = new Configuration();
5379 if (!computeNewConfigurationLocked(config)) {
5380 return null;
5381 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005382 return config;
5383 }
Romain Guy06882f82009-06-10 13:36:04 -07005384
Dianne Hackbornc485a602009-03-24 22:39:49 -07005385 boolean computeNewConfigurationLocked(Configuration config) {
5386 if (mDisplay == null) {
5387 return false;
5388 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005389
5390 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005391
5392 // Use the effective "visual" dimensions based on current rotation
5393 final boolean rotated = (mRotation == Surface.ROTATION_90
5394 || mRotation == Surface.ROTATION_270);
5395 final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth;
5396 final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight;
5397
Dianne Hackbornc485a602009-03-24 22:39:49 -07005398 int orientation = Configuration.ORIENTATION_SQUARE;
5399 if (dw < dh) {
5400 orientation = Configuration.ORIENTATION_PORTRAIT;
5401 } else if (dw > dh) {
5402 orientation = Configuration.ORIENTATION_LANDSCAPE;
5403 }
5404 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005405
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005406 DisplayMetrics dm = new DisplayMetrics();
5407 mDisplay.getMetrics(dm);
5408 CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
5409
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005410 if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) {
Dianne Hackborn723738c2009-06-25 19:48:04 -07005411 // Note we only do this once because at this point we don't
5412 // expect the screen to change in this way at runtime, and want
5413 // to avoid all of this computation for every config change.
Dianne Hackborn723738c2009-06-25 19:48:04 -07005414 int longSize = dw;
5415 int shortSize = dh;
5416 if (longSize < shortSize) {
5417 int tmp = longSize;
5418 longSize = shortSize;
5419 shortSize = tmp;
5420 }
5421 longSize = (int)(longSize/dm.density);
5422 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005423
Dianne Hackborn723738c2009-06-25 19:48:04 -07005424 // These semi-magic numbers define our compatibility modes for
5425 // applications with different screens. Don't change unless you
5426 // make sure to test lots and lots of apps!
5427 if (longSize < 470) {
5428 // This is shorter than an HVGA normal density screen (which
5429 // is 480 pixels on its long side).
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005430 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5431 | Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005432 } else {
Dianne Hackborn14cee9f2010-04-23 17:51:26 -07005433 // What size is this screen screen?
5434 if (longSize >= 800 && shortSize >= 600) {
5435 // SVGA or larger screens at medium density are the point
5436 // at which we consider it to be an extra large screen.
5437 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
Dianne Hackbornb51dc0f2010-10-21 15:34:47 -07005438 } else if (longSize >= 530 && shortSize >= 400) {
5439 // SVGA or larger screens at high density are the point
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005440 // at which we consider it to be a large screen.
5441 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5442 } else {
5443 mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
Dianne Hackborne97a12e2011-01-29 13:22:02 -08005444 }
5445
5446 // If this screen is wider than normal HVGA, or taller
5447 // than FWVGA, then for old apps we want to run in size
5448 // compatibility mode.
5449 if (shortSize > 321 || longSize > 570) {
5450 mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005451 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005452
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005453 // Is this a long screen?
5454 if (((longSize*3)/5) >= (shortSize-1)) {
5455 // Anything wider than WVGA (5:3) is considering to be long.
5456 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5457 } else {
5458 mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5459 }
Dianne Hackborn723738c2009-06-25 19:48:04 -07005460 }
5461 }
Dianne Hackbornc4db95c2009-07-21 17:46:02 -07005462 config.screenLayout = mScreenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005463
Jeff Brown597eec82011-01-31 17:12:25 -08005464 // Determine whether a hard keyboard is available and enabled.
Jeff Brown2992ea72011-01-28 22:04:14 -08005465 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
5466 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
5467 mHardKeyboardAvailable = hardKeyboardAvailable;
5468 mHardKeyboardEnabled = hardKeyboardAvailable;
5469
5470 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5471 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5472 }
5473 if (!mHardKeyboardEnabled) {
5474 config.keyboard = Configuration.KEYBOARD_NOKEYS;
Jeff Brown2992ea72011-01-28 22:04:14 -08005475 }
Jeff Brown597eec82011-01-31 17:12:25 -08005476
5477 // Update value of keyboardHidden, hardKeyboardHidden and navigationHidden
5478 // based on whether a hard or soft keyboard is present, whether navigation keys
5479 // are present and the lid switch state.
5480 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5481 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5482 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
5483 mPolicy.adjustConfigurationLw(config);
Dianne Hackbornc485a602009-03-24 22:39:49 -07005484 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005486
Jeff Brown2992ea72011-01-28 22:04:14 -08005487 public boolean isHardKeyboardAvailable() {
5488 synchronized (mWindowMap) {
5489 return mHardKeyboardAvailable;
5490 }
5491 }
5492
5493 public boolean isHardKeyboardEnabled() {
5494 synchronized (mWindowMap) {
5495 return mHardKeyboardEnabled;
5496 }
5497 }
5498
5499 public void setHardKeyboardEnabled(boolean enabled) {
5500 synchronized (mWindowMap) {
5501 if (mHardKeyboardEnabled != enabled) {
5502 mHardKeyboardEnabled = enabled;
5503 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5504 }
5505 }
5506 }
5507
5508 public void setOnHardKeyboardStatusChangeListener(
5509 OnHardKeyboardStatusChangeListener listener) {
5510 synchronized (mWindowMap) {
5511 mHardKeyboardStatusChangeListener = listener;
5512 }
5513 }
5514
5515 void notifyHardKeyboardStatusChange() {
5516 final boolean available, enabled;
5517 final OnHardKeyboardStatusChangeListener listener;
5518 synchronized (mWindowMap) {
5519 listener = mHardKeyboardStatusChangeListener;
5520 available = mHardKeyboardAvailable;
5521 enabled = mHardKeyboardEnabled;
5522 }
5523 if (listener != null) {
5524 listener.onHardKeyboardStatusChange(available, enabled);
5525 }
5526 }
5527
Christopher Tatea53146c2010-09-07 11:57:52 -07005528 // -------------------------------------------------------------
5529 // Drag and drop
5530 // -------------------------------------------------------------
5531
5532 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005533 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005534 if (DEBUG_DRAG) {
5535 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005536 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07005537 + " asbinder=" + window.asBinder());
5538 }
5539
5540 final int callerPid = Binder.getCallingPid();
5541 final long origId = Binder.clearCallingIdentity();
5542 IBinder token = null;
5543
5544 try {
5545 synchronized (mWindowMap) {
5546 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07005547 if (mDragState == null) {
5548 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5549 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Dianne Hackbornac1471a2011-02-03 13:46:06 -08005550 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
5551 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07005552 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005553 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005554 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005555 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005556 mDragState.mSurface = surface;
Christopher Tatea53146c2010-09-07 11:57:52 -07005557 token = mDragState.mToken = new Binder();
5558
5559 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005560 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5561 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005562 mH.sendMessageDelayed(msg, 5000);
5563 } else {
5564 Slog.w(TAG, "Drag already in progress");
5565 }
5566 } catch (Surface.OutOfResourcesException e) {
5567 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5568 if (mDragState != null) {
5569 mDragState.reset();
5570 mDragState = null;
5571 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005572 }
5573 }
5574 } finally {
5575 Binder.restoreCallingIdentity(origId);
5576 }
5577
5578 return token;
5579 }
5580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 // -------------------------------------------------------------
5582 // Input Events and Focus Management
5583 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07005584
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005585 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown349703e2010-06-22 01:27:15 -07005586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005587 public void pauseKeyDispatching(IBinder _token) {
5588 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5589 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005590 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 }
5592
5593 synchronized (mWindowMap) {
5594 WindowToken token = mTokenMap.get(_token);
5595 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005596 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005597 }
5598 }
5599 }
5600
5601 public void resumeKeyDispatching(IBinder _token) {
5602 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5603 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005604 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 }
5606
5607 synchronized (mWindowMap) {
5608 WindowToken token = mTokenMap.get(_token);
5609 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005610 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005611 }
5612 }
5613 }
5614
5615 public void setEventDispatching(boolean enabled) {
5616 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5617 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005618 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005619 }
5620
5621 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005622 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 }
5624 }
Romain Guy06882f82009-06-10 13:36:04 -07005625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005626 /**
5627 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005628 * Even when sync is false, this method may block while waiting for current
5629 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005630 *
5631 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005632 * {@link SystemClock#uptimeMillis()} as the timebase.)
5633 * @param sync If true, wait for the event to be completed before returning to the caller.
5634 * @return Returns true if event was dispatched, false if it was dropped for any reason
5635 */
5636 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5637 long downTime = ev.getDownTime();
5638 long eventTime = ev.getEventTime();
5639
5640 int action = ev.getAction();
5641 int code = ev.getKeyCode();
5642 int repeatCount = ev.getRepeatCount();
5643 int metaState = ev.getMetaState();
5644 int deviceId = ev.getDeviceId();
5645 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005646 int source = ev.getSource();
Mike Playlec6ded102010-11-29 16:01:03 +00005647 int flags = ev.getFlags();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005648
5649 if (source == InputDevice.SOURCE_UNKNOWN) {
5650 source = InputDevice.SOURCE_KEYBOARD;
5651 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005652
5653 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5654 if (downTime == 0) downTime = eventTime;
5655
5656 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jean-Baptiste Queru4a880132010-12-02 15:16:53 -08005657 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005658
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005659 final int pid = Binder.getCallingPid();
5660 final int uid = Binder.getCallingUid();
5661 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005662
Jeff Brownbbda99d2010-07-28 15:48:59 -07005663 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5664 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5665 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5666 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07005667
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005668 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005669 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 }
5671
5672 /**
5673 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005674 * Even when sync is false, this method may block while waiting for current
5675 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005676 *
5677 * @param ev A motion event describing the pointer (touch) action. (As noted in
5678 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005679 * {@link SystemClock#uptimeMillis()} as the timebase.)
5680 * @param sync If true, wait for the event to be completed before returning to the caller.
5681 * @return Returns true if event was dispatched, false if it was dropped for any reason
5682 */
5683 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005684 final int pid = Binder.getCallingPid();
5685 final int uid = Binder.getCallingUid();
5686 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005687
Jeff Brownc5ed5912010-07-14 18:48:53 -07005688 MotionEvent newEvent = MotionEvent.obtain(ev);
5689 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
5690 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
5691 }
5692
Jeff Brownbbda99d2010-07-28 15:48:59 -07005693 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5694 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5695 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5696 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07005697
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005698 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005699 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005700 }
Romain Guy06882f82009-06-10 13:36:04 -07005701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005702 /**
5703 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005704 * Even when sync is false, this method may block while waiting for current
5705 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005706 *
5707 * @param ev A motion event describing the trackball action. (As noted in
5708 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005709 * {@link SystemClock#uptimeMillis()} as the timebase.)
5710 * @param sync If true, wait for the event to be completed before returning to the caller.
5711 * @return Returns true if event was dispatched, false if it was dropped for any reason
5712 */
5713 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005714 final int pid = Binder.getCallingPid();
5715 final int uid = Binder.getCallingUid();
5716 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005717
Jeff Brownc5ed5912010-07-14 18:48:53 -07005718 MotionEvent newEvent = MotionEvent.obtain(ev);
5719 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
5720 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
5721 }
5722
Jeff Brownbbda99d2010-07-28 15:48:59 -07005723 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5724 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5725 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5726 INJECTION_TIMEOUT_MILLIS);
5727
5728 Binder.restoreCallingIdentity(ident);
5729 return reportInjectionResult(result);
5730 }
5731
5732 /**
5733 * Inject an input event into the UI without waiting for dispatch to commence.
5734 * This variant is useful for fire-and-forget input event injection. It does not
5735 * block any longer than it takes to enqueue the input event.
5736 *
5737 * @param ev An input event. (Be sure to set the input source correctly.)
5738 * @return Returns true if event was dispatched, false if it was dropped for any reason
5739 */
5740 public boolean injectInputEventNoWait(InputEvent ev) {
5741 final int pid = Binder.getCallingPid();
5742 final int uid = Binder.getCallingUid();
5743 final long ident = Binder.clearCallingIdentity();
5744
5745 final int result = mInputManager.injectInputEvent(ev, pid, uid,
5746 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
5747 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07005748
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005749 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005750 return reportInjectionResult(result);
5751 }
5752
5753 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005754 switch (result) {
5755 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
5756 Slog.w(TAG, "Input event injection permission denied.");
5757 throw new SecurityException(
5758 "Injecting to another application requires INJECT_EVENTS permission");
5759 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07005760 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005761 return true;
5762 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
5763 Slog.w(TAG, "Input event injection timed out.");
5764 return false;
5765 case InputManager.INPUT_EVENT_INJECTION_FAILED:
5766 default:
5767 Slog.w(TAG, "Input event injection failed.");
5768 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07005769 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005770 }
Romain Guy06882f82009-06-10 13:36:04 -07005771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005772 private WindowState getFocusedWindow() {
5773 synchronized (mWindowMap) {
5774 return getFocusedWindowLocked();
5775 }
5776 }
5777
5778 private WindowState getFocusedWindowLocked() {
5779 return mCurrentFocus;
5780 }
Romain Guy06882f82009-06-10 13:36:04 -07005781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005782 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08005783 if (!mInputMonitor.waitForInputDevicesReady(
5784 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
5785 Slog.w(TAG, "Devices still not ready after waiting "
5786 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
5787 + " milliseconds before attempting to detect safe mode.");
5788 }
5789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 mSafeMode = mPolicy.detectSafeMode();
5791 return mSafeMode;
5792 }
Romain Guy06882f82009-06-10 13:36:04 -07005793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07005795 synchronized(mWindowMap) {
5796 if (mDisplay != null) {
5797 throw new IllegalStateException("Display already initialized");
5798 }
5799 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
5800 mDisplay = wm.getDefaultDisplay();
5801 mInitialDisplayWidth = mDisplay.getWidth();
5802 mInitialDisplayHeight = mDisplay.getHeight();
Dianne Hackborn4c7cc342010-12-16 16:37:39 -08005803 mInputManager.setDisplaySize(0, Display.unmapDisplaySize(mInitialDisplayWidth),
5804 Display.unmapDisplaySize(mInitialDisplayHeight));
Dianne Hackborn5132b372010-07-29 12:51:35 -07005805 }
5806
5807 try {
5808 mActivityManager.updateConfiguration(null);
5809 } catch (RemoteException e) {
5810 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07005811
5812 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07005813 }
5814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005815 // This is an animation that does nothing: it just immediately finishes
5816 // itself every time it is called. It is used as a stub animation in cases
5817 // where we want to synchronize multiple things that may be animating.
5818 static final class DummyAnimation extends Animation {
5819 public boolean getTransformation(long currentTime, Transformation outTransformation) {
5820 return false;
5821 }
5822 }
5823 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07005824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 // -------------------------------------------------------------
5826 // Async Handler
5827 // -------------------------------------------------------------
5828
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005829 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 public static final int REPORT_FOCUS_CHANGE = 2;
5831 public static final int REPORT_LOSING_FOCUS = 3;
5832 public static final int ANIMATE = 4;
5833 public static final int ADD_STARTING = 5;
5834 public static final int REMOVE_STARTING = 6;
5835 public static final int FINISHED_STARTING = 7;
5836 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005837 public static final int WINDOW_FREEZE_TIMEOUT = 11;
5838 public static final int HOLD_SCREEN_CHANGED = 12;
5839 public static final int APP_TRANSITION_TIMEOUT = 13;
5840 public static final int PERSIST_ANIMATION_SCALE = 14;
5841 public static final int FORCE_GC = 15;
5842 public static final int ENABLE_SCREEN = 16;
5843 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005844 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005845 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07005846 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07005847 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08005848 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Romain Guy06882f82009-06-10 13:36:04 -07005849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005850 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07005851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005852 public H() {
5853 }
Romain Guy06882f82009-06-10 13:36:04 -07005854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005855 @Override
5856 public void handleMessage(Message msg) {
5857 switch (msg.what) {
5858 case REPORT_FOCUS_CHANGE: {
5859 WindowState lastFocus;
5860 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07005861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 synchronized(mWindowMap) {
5863 lastFocus = mLastFocus;
5864 newFocus = mCurrentFocus;
5865 if (lastFocus == newFocus) {
5866 // Focus is not changing, so nothing to do.
5867 return;
5868 }
5869 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005870 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005871 // + " to " + newFocus);
5872 if (newFocus != null && lastFocus != null
5873 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005874 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005875 mLosingFocus.add(lastFocus);
5876 lastFocus = null;
5877 }
5878 }
5879
5880 if (lastFocus != newFocus) {
5881 //System.out.println("Changing focus from " + lastFocus
5882 // + " to " + newFocus);
5883 if (newFocus != null) {
5884 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005885 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005886 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
5887 } catch (RemoteException e) {
5888 // Ignore if process has died.
5889 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07005890 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891 }
5892
5893 if (lastFocus != null) {
5894 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005895 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005896 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
5897 } catch (RemoteException e) {
5898 // Ignore if process has died.
5899 }
5900 }
Joe Onorato664644d2011-01-23 17:53:23 -08005901
5902 mPolicy.focusChanged(lastFocus, newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 }
5904 } break;
5905
5906 case REPORT_LOSING_FOCUS: {
5907 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07005908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005909 synchronized(mWindowMap) {
5910 losers = mLosingFocus;
5911 mLosingFocus = new ArrayList<WindowState>();
5912 }
5913
5914 final int N = losers.size();
5915 for (int i=0; i<N; i++) {
5916 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005917 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005918 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
5919 } catch (RemoteException e) {
5920 // Ignore if process has died.
5921 }
5922 }
5923 } break;
5924
5925 case ANIMATE: {
5926 synchronized(mWindowMap) {
5927 mAnimationPending = false;
5928 performLayoutAndPlaceSurfacesLocked();
5929 }
5930 } break;
5931
5932 case ADD_STARTING: {
5933 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
5934 final StartingData sd = wtoken.startingData;
5935
5936 if (sd == null) {
5937 // Animation has been canceled... do nothing.
5938 return;
5939 }
Romain Guy06882f82009-06-10 13:36:04 -07005940
Joe Onorato8a9b2202010-02-26 18:56:32 -08005941 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07005943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005944 View view = null;
5945 try {
5946 view = mPolicy.addStartingWindow(
5947 wtoken.token, sd.pkg,
5948 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08005949 sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005951 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 }
5953
5954 if (view != null) {
5955 boolean abort = false;
5956
5957 synchronized(mWindowMap) {
5958 if (wtoken.removed || wtoken.startingData == null) {
5959 // If the window was successfully added, then
5960 // we need to remove it.
5961 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005962 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005963 "Aborted starting " + wtoken
5964 + ": removed=" + wtoken.removed
5965 + " startingData=" + wtoken.startingData);
5966 wtoken.startingWindow = null;
5967 wtoken.startingData = null;
5968 abort = true;
5969 }
5970 } else {
5971 wtoken.startingView = view;
5972 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005973 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005974 "Added starting " + wtoken
5975 + ": startingWindow="
5976 + wtoken.startingWindow + " startingView="
5977 + wtoken.startingView);
5978 }
5979
5980 if (abort) {
5981 try {
5982 mPolicy.removeStartingWindow(wtoken.token, view);
5983 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005984 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005985 }
5986 }
5987 }
5988 } break;
5989
5990 case REMOVE_STARTING: {
5991 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
5992 IBinder token = null;
5993 View view = null;
5994 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005995 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996 + wtoken + ": startingWindow="
5997 + wtoken.startingWindow + " startingView="
5998 + wtoken.startingView);
5999 if (wtoken.startingWindow != null) {
6000 view = wtoken.startingView;
6001 token = wtoken.token;
6002 wtoken.startingData = null;
6003 wtoken.startingView = null;
6004 wtoken.startingWindow = null;
6005 }
6006 }
6007 if (view != null) {
6008 try {
6009 mPolicy.removeStartingWindow(token, view);
6010 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006011 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 }
6013 }
6014 } break;
6015
6016 case FINISHED_STARTING: {
6017 IBinder token = null;
6018 View view = null;
6019 while (true) {
6020 synchronized (mWindowMap) {
6021 final int N = mFinishedStarting.size();
6022 if (N <= 0) {
6023 break;
6024 }
6025 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
6026
Joe Onorato8a9b2202010-02-26 18:56:32 -08006027 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006028 "Finished starting " + wtoken
6029 + ": startingWindow=" + wtoken.startingWindow
6030 + " startingView=" + wtoken.startingView);
6031
6032 if (wtoken.startingWindow == null) {
6033 continue;
6034 }
6035
6036 view = wtoken.startingView;
6037 token = wtoken.token;
6038 wtoken.startingData = null;
6039 wtoken.startingView = null;
6040 wtoken.startingWindow = null;
6041 }
6042
6043 try {
6044 mPolicy.removeStartingWindow(token, view);
6045 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006046 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006047 }
6048 }
6049 } break;
6050
6051 case REPORT_APPLICATION_TOKEN_WINDOWS: {
6052 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6053
6054 boolean nowVisible = msg.arg1 != 0;
6055 boolean nowGone = msg.arg2 != 0;
6056
6057 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006058 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006059 TAG, "Reporting visible in " + wtoken
6060 + " visible=" + nowVisible
6061 + " gone=" + nowGone);
6062 if (nowVisible) {
6063 wtoken.appToken.windowsVisible();
6064 } else {
6065 wtoken.appToken.windowsGone();
6066 }
6067 } catch (RemoteException ex) {
6068 }
6069 } break;
Romain Guy06882f82009-06-10 13:36:04 -07006070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006071 case WINDOW_FREEZE_TIMEOUT: {
6072 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006073 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 int i = mWindows.size();
6075 while (i > 0) {
6076 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07006077 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006078 if (w.mOrientationChanging) {
6079 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006080 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006081 }
6082 }
6083 performLayoutAndPlaceSurfacesLocked();
6084 }
6085 break;
6086 }
Romain Guy06882f82009-06-10 13:36:04 -07006087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 case HOLD_SCREEN_CHANGED: {
6089 Session oldHold;
6090 Session newHold;
6091 synchronized (mWindowMap) {
6092 oldHold = mLastReportedHold;
6093 newHold = (Session)msg.obj;
6094 mLastReportedHold = newHold;
6095 }
Romain Guy06882f82009-06-10 13:36:04 -07006096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 if (oldHold != newHold) {
6098 try {
6099 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006100 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 "window",
6102 BatteryStats.WAKE_TYPE_WINDOW);
6103 }
6104 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006105 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 "window",
6107 BatteryStats.WAKE_TYPE_WINDOW);
6108 }
6109 } catch (RemoteException e) {
6110 }
6111 }
6112 break;
6113 }
Romain Guy06882f82009-06-10 13:36:04 -07006114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006115 case APP_TRANSITION_TIMEOUT: {
6116 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07006117 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006118 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006119 "*** APP TRANSITION TIMEOUT");
6120 mAppTransitionReady = true;
6121 mAppTransitionTimeout = true;
6122 performLayoutAndPlaceSurfacesLocked();
6123 }
6124 }
6125 break;
6126 }
Romain Guy06882f82009-06-10 13:36:04 -07006127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006128 case PERSIST_ANIMATION_SCALE: {
6129 Settings.System.putFloat(mContext.getContentResolver(),
6130 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
6131 Settings.System.putFloat(mContext.getContentResolver(),
6132 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
6133 break;
6134 }
Romain Guy06882f82009-06-10 13:36:04 -07006135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006136 case FORCE_GC: {
6137 synchronized(mWindowMap) {
6138 if (mAnimationPending) {
6139 // If we are animating, don't do the gc now but
6140 // delay a bit so we don't interrupt the animation.
6141 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
6142 2000);
6143 return;
6144 }
6145 // If we are currently rotating the display, it will
6146 // schedule a new message when done.
6147 if (mDisplayFrozen) {
6148 return;
6149 }
6150 mFreezeGcPending = 0;
6151 }
6152 Runtime.getRuntime().gc();
6153 break;
6154 }
Romain Guy06882f82009-06-10 13:36:04 -07006155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006156 case ENABLE_SCREEN: {
6157 performEnableScreen();
6158 break;
6159 }
Romain Guy06882f82009-06-10 13:36:04 -07006160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006161 case APP_FREEZE_TIMEOUT: {
6162 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006163 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006164 int i = mAppTokens.size();
6165 while (i > 0) {
6166 i--;
6167 AppWindowToken tok = mAppTokens.get(i);
6168 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006169 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006170 unsetAppFreezingScreenLocked(tok, true, true);
6171 }
6172 }
6173 }
6174 break;
6175 }
Romain Guy06882f82009-06-10 13:36:04 -07006176
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006177 case SEND_NEW_CONFIGURATION: {
6178 removeMessages(SEND_NEW_CONFIGURATION);
6179 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006180 break;
6181 }
Romain Guy06882f82009-06-10 13:36:04 -07006182
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006183 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006184 if (mWindowsChanged) {
6185 synchronized (mWindowMap) {
6186 mWindowsChanged = false;
6187 }
6188 notifyWindowsChanged();
6189 }
6190 break;
6191 }
6192
Christopher Tatea53146c2010-09-07 11:57:52 -07006193 case DRAG_START_TIMEOUT: {
6194 IBinder win = (IBinder)msg.obj;
6195 if (DEBUG_DRAG) {
6196 Slog.w(TAG, "Timeout starting drag by win " + win);
6197 }
6198 synchronized (mWindowMap) {
6199 // !!! TODO: ANR the app that has failed to start the drag in time
6200 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07006201 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08006202 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07006203 mDragState.reset();
6204 mDragState = null;
6205 }
6206 }
Chris Tated4533f12010-10-19 15:15:08 -07006207 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07006208 }
6209
Chris Tated4533f12010-10-19 15:15:08 -07006210 case DRAG_END_TIMEOUT: {
6211 IBinder win = (IBinder)msg.obj;
6212 if (DEBUG_DRAG) {
6213 Slog.w(TAG, "Timeout ending drag to win " + win);
6214 }
6215 synchronized (mWindowMap) {
6216 // !!! TODO: ANR the drag-receiving app
6217 mDragState.mDragResult = false;
6218 mDragState.endDragLw();
6219 }
6220 break;
6221 }
Jeff Brown2992ea72011-01-28 22:04:14 -08006222
6223 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
6224 notifyHardKeyboardStatusChange();
6225 break;
6226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006227 }
6228 }
6229 }
6230
6231 // -------------------------------------------------------------
6232 // IWindowManager API
6233 // -------------------------------------------------------------
6234
6235 public IWindowSession openSession(IInputMethodClient client,
6236 IInputContext inputContext) {
6237 if (client == null) throw new IllegalArgumentException("null client");
6238 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006239 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006240 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006241 }
6242
6243 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
6244 synchronized (mWindowMap) {
6245 // The focus for the client is the window immediately below
6246 // where we would place the input method window.
6247 int idx = findDesiredInputMethodWindowIndexLocked(false);
6248 WindowState imFocus;
6249 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07006250 imFocus = mWindows.get(idx-1);
Dianne Hackborne75d8722011-01-27 19:37:40 -08006251 //Log.i(TAG, "Desired input method target: " + imFocus);
6252 //Log.i(TAG, "Current focus: " + this.mCurrentFocus);
6253 //Log.i(TAG, "Last focus: " + this.mLastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006254 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08006255 // This may be a starting window, in which case we still want
6256 // to count it as okay.
6257 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
6258 && imFocus.mAppToken != null) {
6259 // The client has definitely started, so it really should
6260 // have a window in this app token. Let's look for it.
6261 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
6262 WindowState w = imFocus.mAppToken.windows.get(i);
6263 if (w != imFocus) {
6264 //Log.i(TAG, "Switching to real app window: " + w);
6265 imFocus = w;
6266 break;
6267 }
6268 }
6269 }
6270 //Log.i(TAG, "IM target client: " + imFocus.mSession.mClient);
6271 //if (imFocus.mSession.mClient != null) {
6272 // Log.i(TAG, "IM target client binder: " + imFocus.mSession.mClient.asBinder());
6273 // Log.i(TAG, "Requesting client binder: " + client.asBinder());
6274 //}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 if (imFocus.mSession.mClient != null &&
6276 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
6277 return true;
6278 }
Dianne Hackborne75d8722011-01-27 19:37:40 -08006279
6280 // Okay, how about this... what is the current focus?
6281 // It seems in some cases we may not have moved the IM
6282 // target window, such as when it was in a pop-up window,
6283 // so let's also look at the current focus. (An example:
6284 // go to Gmail, start searching so the keyboard goes up,
6285 // press home. Sometimes the IME won't go down.)
6286 // Would be nice to fix this more correctly, but it's
6287 // way at the end of a release, and this should be good enough.
6288 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null &&
6289 mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
6290 return true;
6291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006292 }
6293 }
6294 }
6295 return false;
6296 }
Romain Guy06882f82009-06-10 13:36:04 -07006297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006298 // -------------------------------------------------------------
6299 // Internals
6300 // -------------------------------------------------------------
6301
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006302 final WindowState windowForClientLocked(Session session, IWindow client,
6303 boolean throwOnError) {
6304 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006305 }
Romain Guy06882f82009-06-10 13:36:04 -07006306
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006307 final WindowState windowForClientLocked(Session session, IBinder client,
6308 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006310 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006311 TAG, "Looking up client " + client + ": " + win);
6312 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006313 RuntimeException ex = new IllegalArgumentException(
6314 "Requested window " + client + " does not exist");
6315 if (throwOnError) {
6316 throw ex;
6317 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006318 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319 return null;
6320 }
6321 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006322 RuntimeException ex = new IllegalArgumentException(
6323 "Requested window " + client + " is in session " +
6324 win.mSession + ", not " + session);
6325 if (throwOnError) {
6326 throw ex;
6327 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006328 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006329 return null;
6330 }
6331
6332 return win;
6333 }
6334
Dianne Hackborna8f60182009-09-01 19:01:50 -07006335 final void rebuildAppWindowListLocked() {
6336 int NW = mWindows.size();
6337 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006338 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006339 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006340
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006341 if (mRebuildTmp.length < NW) {
6342 mRebuildTmp = new WindowState[NW+10];
6343 }
6344
Dianne Hackborna8f60182009-09-01 19:01:50 -07006345 // First remove all existing app windows.
6346 i=0;
6347 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07006348 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006349 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07006350 WindowState win = mWindows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006351 win.mRebuilding = true;
6352 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006353 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006354 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006355 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07006356 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006357 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07006358 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006359 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
6360 && lastWallpaper == i-1) {
6361 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07006362 }
6363 i++;
6364 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006365
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006366 // The wallpaper window(s) typically live at the bottom of the stack,
6367 // so skip them before adding app tokens.
6368 lastWallpaper++;
6369 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006370
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006371 // First add all of the exiting app tokens... these are no longer
6372 // in the main app list, but still have windows shown. We put them
6373 // in the back because now that the animation is over we no longer
6374 // will care about them.
6375 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07006376 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006377 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
6378 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006379
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006380 // And add in the still active app tokens in Z order.
6381 NT = mAppTokens.size();
6382 for (int j=0; j<NT; j++) {
6383 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07006384 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006385
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006386 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006387 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006388 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006389 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006390 for (i=0; i<numRemoved; i++) {
6391 WindowState ws = mRebuildTmp[i];
6392 if (ws.mRebuilding) {
6393 StringWriter sw = new StringWriter();
6394 PrintWriter pw = new PrintWriter(sw);
6395 ws.dump(pw, "");
6396 pw.flush();
6397 Slog.w(TAG, "This window was lost: " + ws);
6398 Slog.w(TAG, sw.toString());
6399 }
6400 }
6401 Slog.w(TAG, "Current app token list:");
6402 dumpAppTokensLocked();
6403 Slog.w(TAG, "Final window list:");
6404 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006405 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07006406 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006408 private final void assignLayersLocked() {
6409 int N = mWindows.size();
6410 int curBaseLayer = 0;
6411 int curLayer = 0;
6412 int i;
Romain Guy06882f82009-06-10 13:36:04 -07006413
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006414 if (DEBUG_LAYERS) {
6415 RuntimeException here = new RuntimeException("here");
6416 here.fillInStackTrace();
6417 Log.v(TAG, "Assigning layers", here);
6418 }
6419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006420 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07006421 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006422 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
6423 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006424 curLayer += WINDOW_LAYER_MULTIPLIER;
6425 w.mLayer = curLayer;
6426 } else {
6427 curBaseLayer = curLayer = w.mBaseLayer;
6428 w.mLayer = curLayer;
6429 }
6430 if (w.mTargetAppToken != null) {
6431 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
6432 } else if (w.mAppToken != null) {
6433 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
6434 } else {
6435 w.mAnimLayer = w.mLayer;
6436 }
6437 if (w.mIsImWindow) {
6438 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006439 } else if (w.mIsWallpaper) {
6440 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006442 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006443 + w.mAnimLayer);
6444 //System.out.println(
6445 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
6446 }
6447 }
6448
6449 private boolean mInLayout = false;
6450 private final void performLayoutAndPlaceSurfacesLocked() {
6451 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07006452 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006453 throw new RuntimeException("Recursive call!");
6454 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006455 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006456 return;
6457 }
6458
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006459 if (mWaitingForConfig) {
6460 // Our configuration has changed (most likely rotation), but we
6461 // don't yet have the complete configuration to report to
6462 // applications. Don't do any window layout until we have it.
6463 return;
6464 }
6465
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006466 if (mDisplay == null) {
6467 // Not yet initialized, nothing to do.
6468 return;
6469 }
6470
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006471 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006472 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006473
6474 try {
6475 if (mForceRemoves != null) {
6476 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006477 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006478 for (int i=0; i<mForceRemoves.size(); i++) {
6479 WindowState ws = mForceRemoves.get(i);
6480 Slog.i(TAG, "Force removing: " + ws);
6481 removeWindowInnerLocked(ws.mSession, ws);
6482 }
6483 mForceRemoves = null;
6484 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
6485 Object tmp = new Object();
6486 synchronized (tmp) {
6487 try {
6488 tmp.wait(250);
6489 } catch (InterruptedException e) {
6490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006491 }
6492 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006493 } catch (RuntimeException e) {
6494 Slog.e(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006495 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 try {
6498 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07006499
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006500 int N = mPendingRemove.size();
6501 if (N > 0) {
6502 if (mPendingRemoveTmp.length < N) {
6503 mPendingRemoveTmp = new WindowState[N+10];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006504 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006505 mPendingRemove.toArray(mPendingRemoveTmp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006506 mPendingRemove.clear();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006507 for (int i=0; i<N; i++) {
6508 WindowState w = mPendingRemoveTmp[i];
6509 removeWindowInnerLocked(w.mSession, w);
6510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006511
6512 mInLayout = false;
6513 assignLayersLocked();
6514 mLayoutNeeded = true;
6515 performLayoutAndPlaceSurfacesLocked();
6516
6517 } else {
6518 mInLayout = false;
6519 if (mLayoutNeeded) {
6520 requestAnimationLocked(0);
6521 }
6522 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006523 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006524 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
6525 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006527 } catch (RuntimeException e) {
6528 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006529 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006530 }
6531 }
6532
Jeff Brown3a22cd92011-01-21 13:59:04 -08006533 private final int performLayoutLockedInner(boolean initial, boolean updateInputWindows) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006534 if (!mLayoutNeeded) {
6535 return 0;
6536 }
6537
6538 mLayoutNeeded = false;
6539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006540 final int dw = mDisplay.getWidth();
6541 final int dh = mDisplay.getHeight();
6542
6543 final int N = mWindows.size();
6544 int i;
6545
Joe Onorato8a9b2202010-02-26 18:56:32 -08006546 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08006547 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
6548
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006549 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07006550
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006551 int seq = mLayoutSeq+1;
6552 if (seq < 0) seq = 0;
6553 mLayoutSeq = seq;
6554
6555 // First perform layout of any root windows (not attached
6556 // to another window).
6557 int topAttached = -1;
6558 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07006559 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006560
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006561 // Don't do layout of a window if it is not visible, or
6562 // soon won't be visible, to avoid wasting time and funky
6563 // changes while a window is animating away.
6564 final AppWindowToken atoken = win.mAppToken;
6565 final boolean gone = win.mViewVisibility == View.GONE
6566 || !win.mRelayoutCalled
Dianne Hackbornff801ec2011-01-22 18:05:38 -08006567 || (atoken == null && win.mRootToken.hidden)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006568 || (atoken != null && atoken.hiddenRequested)
6569 || win.mAttachedHidden
6570 || win.mExiting || win.mDestroying;
6571
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006572 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
6573 Slog.v(TAG, "First pass " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006574 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
6575 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006576 if (gone) Slog.v(TAG, " (mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006577 + win.mViewVisibility + " mRelayoutCalled="
6578 + win.mRelayoutCalled + " hidden="
6579 + win.mRootToken.hidden + " hiddenRequested="
6580 + (atoken != null && atoken.hiddenRequested)
6581 + " mAttachedHidden=" + win.mAttachedHidden);
6582 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006583
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006584 // If this view is GONE, then skip it -- keep the current
6585 // frame, and let the caller know so they can ignore it
6586 // if they want. (We do the normal layout for INVISIBLE
6587 // windows, since that means "perform layout as normal,
6588 // just don't display").
6589 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006590 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006591 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08006592 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006593 win.mContentChanged = false;
6594 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006595 mPolicy.layoutWindowLw(win, win.mAttrs, null);
6596 win.mLayoutSeq = seq;
6597 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
6598 + win.mFrame + " mContainingFrame="
6599 + win.mContainingFrame + " mDisplayFrame="
6600 + win.mDisplayFrame);
6601 } else {
6602 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006603 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07006604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006605 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006606
6607 // Now perform layout of attached windows, which usually
6608 // depend on the position of the window they are attached to.
6609 // XXX does not deal with windows that are attached to windows
6610 // that are themselves attached.
6611 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07006612 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006613
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006614 if (win.mLayoutAttached) {
6615 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
6616 + " mHaveFrame=" + win.mHaveFrame
6617 + " mViewVisibility=" + win.mViewVisibility
6618 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006619 // If this view is GONE, then skip it -- keep the current
6620 // frame, and let the caller know so they can ignore it
6621 // if they want. (We do the normal layout for INVISIBLE
6622 // windows, since that means "perform layout as normal,
6623 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006624 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
6625 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006626 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08006627 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006628 win.mContentChanged = false;
6629 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006630 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
6631 win.mLayoutSeq = seq;
6632 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
6633 + win.mFrame + " mContainingFrame="
6634 + win.mContainingFrame + " mDisplayFrame="
6635 + win.mDisplayFrame);
6636 }
6637 }
6638 }
Jeff Brown349703e2010-06-22 01:27:15 -07006639
6640 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08006641 mInputMonitor.setUpdateInputWindowsNeededLw();
6642 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08006643 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08006644 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006645
6646 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 }
Romain Guy06882f82009-06-10 13:36:04 -07006648
Brad Fitzpatrick68044332010-11-22 18:19:48 -08006649 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006650 private final void performLayoutAndPlaceSurfacesLockedInner(
6651 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04006652 if (mDisplay == null) {
6653 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
6654 return;
6655 }
6656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006657 final long currentTime = SystemClock.uptimeMillis();
6658 final int dw = mDisplay.getWidth();
6659 final int dh = mDisplay.getHeight();
6660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006661 int i;
6662
Dianne Hackbornb601ce12010-03-01 23:36:02 -08006663 if (mFocusMayChange) {
6664 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08006665 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
6666 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08006667 }
6668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 // Initialize state of exiting tokens.
6670 for (i=mExitingTokens.size()-1; i>=0; i--) {
6671 mExitingTokens.get(i).hasVisible = false;
6672 }
6673
6674 // Initialize state of exiting applications.
6675 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
6676 mExitingAppTokens.get(i).hasVisible = false;
6677 }
6678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006679 boolean orientationChangeComplete = true;
6680 Session holdScreen = null;
6681 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05006682 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006683 boolean focusDisplayed = false;
6684 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006685 boolean createWatermark = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08006686 boolean updateRotation = false;
Dianne Hackborn50660e22011-02-02 17:12:25 -08006687 boolean screenRotationFinished = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006688
6689 if (mFxSession == null) {
6690 mFxSession = new SurfaceSession();
6691 createWatermark = true;
6692 }
6693
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006694 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695
6696 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006697
6698 if (createWatermark) {
6699 createWatermark();
6700 }
6701 if (mWatermark != null) {
6702 mWatermark.positionSurface(dw, dh);
6703 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08006704 if (mStrictModeFlash != null) {
6705 mStrictModeFlash.positionSurface(dw, dh);
6706 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006708 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08006709 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006710 int repeats = 0;
6711 int changes = 0;
6712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006714 repeats++;
6715 if (repeats > 6) {
6716 Slog.w(TAG, "Animation repeat aborted after too many iterations");
6717 mLayoutNeeded = false;
6718 break;
6719 }
6720
6721 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
6722 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
6723 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
6724 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
6725 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
6726 assignLayersLocked();
6727 mLayoutNeeded = true;
6728 }
6729 }
6730 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
6731 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006732 if (updateOrientationFromAppTokensLocked(true)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006733 mLayoutNeeded = true;
6734 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6735 }
6736 }
6737 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
6738 mLayoutNeeded = true;
6739 }
6740 }
6741
6742 // FIRST LOOP: Perform a layout, if needed.
6743 if (repeats < 4) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08006744 changes = performLayoutLockedInner(repeats == 0, false /*updateInputWindows*/);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006745 if (changes != 0) {
6746 continue;
6747 }
6748 } else {
6749 Slog.w(TAG, "Layout repeat skipped after too many iterations");
6750 changes = 0;
6751 }
6752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006753 final int transactionSequence = ++mTransactionSequence;
6754
6755 // Update animations of all applications, including those
6756 // associated with exiting/removed apps
6757 boolean tokensAnimating = false;
6758 final int NAT = mAppTokens.size();
6759 for (i=0; i<NAT; i++) {
6760 if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
6761 tokensAnimating = true;
6762 }
6763 }
6764 final int NEAT = mExitingAppTokens.size();
6765 for (i=0; i<NEAT; i++) {
6766 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
6767 tokensAnimating = true;
6768 }
6769 }
6770
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006771 // SECOND LOOP: Execute animations and update visibility of windows.
6772
Joe Onorato8a9b2202010-02-26 18:56:32 -08006773 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08006774 + transactionSequence + " tokensAnimating="
6775 + tokensAnimating);
6776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006778
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08006779 if (mScreenRotationAnimation != null) {
6780 if (mScreenRotationAnimation.isAnimating()) {
6781 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
6782 animating = true;
6783 } else {
Dianne Hackborn50660e22011-02-02 17:12:25 -08006784 screenRotationFinished = true;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08006785 updateRotation = true;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08006786 }
6787 }
6788 }
6789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006791 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006792 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006793 WindowState windowDetachedWallpaper = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006794
6795 mPolicy.beginAnimationLw(dw, dh);
6796
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006797 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07006800 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006801
6802 final WindowManager.LayoutParams attrs = w.mAttrs;
6803
6804 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006805 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006806 if (w.commitFinishDrawingLocked(currentTime)) {
6807 if ((w.mAttrs.flags
6808 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006809 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07006810 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07006811 wallpaperMayChange = true;
6812 }
6813 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006814
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006815 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006816
6817 int animDw = dw;
6818 int animDh = dh;
6819
6820 // If the window has moved due to its containing
6821 // content frame changing, then we'd like to animate
6822 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08006823 // likely to be true first.
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006824 if (w.shouldAnimateMove()) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006825 // Frame has moved, containing content frame
6826 // has also moved, and we're not currently animating...
6827 // let's do something.
6828 Animation a = AnimationUtils.loadAnimation(mContext,
6829 com.android.internal.R.anim.window_move_from_decor);
6830 w.setAnimation(a);
6831 animDw = w.mLastFrame.left - w.mFrame.left;
6832 animDh = w.mLastFrame.top - w.mFrame.top;
6833 }
6834
6835 // Execute animation.
6836 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
6837 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006838
6839 // If this window is animating, make a note that we have
6840 // an animating window and take care of a request to run
6841 // a detached wallpaper animation.
6842 if (nowAnimating) {
6843 if (w.mAnimation != null && w.mAnimation.getDetachWallpaper()) {
6844 windowDetachedWallpaper = w;
6845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006846 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006847 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006848
6849 // If this window's app token is running a detached wallpaper
6850 // animation, make a note so we can ensure the wallpaper is
6851 // displayed behind it.
6852 if (w.mAppToken != null && w.mAppToken.animation != null
6853 && w.mAppToken.animation.getDetachWallpaper()) {
6854 windowDetachedWallpaper = w;
6855 }
6856
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07006857 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
6858 wallpaperMayChange = true;
6859 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006860
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006861 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006862 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08006863 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006864 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08006865 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006866 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08006867 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006868 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
6869 forceHiding = true;
6870 }
6871 } else if (mPolicy.canBeForceHidden(w, attrs)) {
6872 boolean changed;
6873 if (forceHiding) {
6874 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08006875 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
6876 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006877 } else {
6878 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08006879 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
6880 "Now policy shown: " + w);
6881 if (changed) {
6882 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006883 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08006884 // Assume we will need to animate. If
6885 // we don't (because the wallpaper will
6886 // stay with the lock screen), then we will
6887 // clean up later.
6888 Animation a = mPolicy.createForceHideEnterAnimation();
6889 if (a != null) {
6890 w.setAnimation(a);
6891 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006892 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08006893 if (mCurrentFocus == null ||
6894 mCurrentFocus.mLayer < w.mLayer) {
6895 // We are showing on to of the current
6896 // focus, so re-evaluate focus to make
6897 // sure it is correct.
6898 mFocusMayChange = true;
6899 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006900 }
6901 }
6902 if (changed && (attrs.flags
6903 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
6904 wallpaperMayChange = true;
6905 }
6906 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006908 mPolicy.animatingWindowLw(w, attrs);
6909 }
6910
6911 final AppWindowToken atoken = w.mAppToken;
6912 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
6913 if (atoken.lastTransactionSequence != transactionSequence) {
6914 atoken.lastTransactionSequence = transactionSequence;
6915 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
6916 atoken.startingDisplayed = false;
6917 }
6918 if ((w.isOnScreen() || w.mAttrs.type
6919 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
6920 && !w.mExiting && !w.mDestroying) {
6921 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006922 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07006923 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006924 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07006925 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006926 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006927 + " pv=" + w.mPolicyVisibility
6928 + " dp=" + w.mDrawPending
6929 + " cdp=" + w.mCommitDrawPending
6930 + " ah=" + w.mAttachedHidden
6931 + " th=" + atoken.hiddenRequested
6932 + " a=" + w.mAnimating);
6933 }
6934 }
6935 if (w != atoken.startingWindow) {
6936 if (!atoken.freezingScreen || !w.mAppFreezing) {
6937 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07006938 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006940 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006941 "tokenMayBeDrawn: " + atoken
6942 + " freezingScreen=" + atoken.freezingScreen
6943 + " mAppFreezing=" + w.mAppFreezing);
6944 tokenMayBeDrawn = true;
6945 }
6946 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07006947 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006948 atoken.startingDisplayed = true;
6949 }
6950 }
6951 } else if (w.mReadyToShow) {
6952 w.performShowLocked();
6953 }
6954 }
6955
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006956 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957
6958 if (tokenMayBeDrawn) {
6959 // See if any windows have been drawn, so they (and others
6960 // associated with them) can now be shown.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006961 final int NT = mAppTokens.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006962 for (i=0; i<NT; i++) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006963 AppWindowToken wtoken = mAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 if (wtoken.freezingScreen) {
6965 int numInteresting = wtoken.numInterestingWindows;
6966 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006967 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 "allDrawn: " + wtoken
6969 + " interesting=" + numInteresting
6970 + " drawn=" + wtoken.numDrawnWindows);
6971 wtoken.showAllWindowsLocked();
6972 unsetAppFreezingScreenLocked(wtoken, false, true);
6973 orientationChangeComplete = true;
6974 }
6975 } else if (!wtoken.allDrawn) {
6976 int numInteresting = wtoken.numInterestingWindows;
6977 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006978 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006979 "allDrawn: " + wtoken
6980 + " interesting=" + numInteresting
6981 + " drawn=" + wtoken.numDrawnWindows);
6982 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006983 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006984
6985 // We can now show all of the drawn windows!
6986 if (!mOpeningApps.contains(wtoken)) {
6987 wtoken.showAllWindowsLocked();
6988 }
6989 }
6990 }
6991 }
6992 }
6993
6994 // If we are ready to perform an app transition, check through
6995 // all of the app tokens to be shown and see if they are ready
6996 // to go.
6997 if (mAppTransitionReady) {
6998 int NN = mOpeningApps.size();
6999 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007000 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007001 "Checking " + NN + " opening apps (frozen="
7002 + mDisplayFrozen + " timeout="
7003 + mAppTransitionTimeout + ")...");
7004 if (!mDisplayFrozen && !mAppTransitionTimeout) {
7005 // If the display isn't frozen, wait to do anything until
7006 // all of the apps are ready. Otherwise just go because
7007 // we'll unfreeze the display when everyone is ready.
7008 for (i=0; i<NN && goodToGo; i++) {
7009 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007010 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007011 "Check opening app" + wtoken + ": allDrawn="
7012 + wtoken.allDrawn + " startingDisplayed="
7013 + wtoken.startingDisplayed);
7014 if (!wtoken.allDrawn && !wtoken.startingDisplayed
7015 && !wtoken.startingMoved) {
7016 goodToGo = false;
7017 }
7018 }
7019 }
7020 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007021 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007022 int transit = mNextAppTransition;
7023 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007024 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007025 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007026 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007027 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007028 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 mAppTransitionTimeout = false;
7030 mStartingIconInTransition = false;
7031 mSkipAppTransitionAnimation = false;
7032
7033 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
7034
Dianne Hackborna8f60182009-09-01 19:01:50 -07007035 // If there are applications waiting to come to the
7036 // top of the stack, now is the time to move their windows.
7037 // (Note that we don't do apps going to the bottom
7038 // here -- we want to keep their windows in the old
7039 // Z-order until the animation completes.)
7040 if (mToTopApps.size() > 0) {
7041 NN = mAppTokens.size();
7042 for (i=0; i<NN; i++) {
7043 AppWindowToken wtoken = mAppTokens.get(i);
7044 if (wtoken.sendingToTop) {
7045 wtoken.sendingToTop = false;
7046 moveAppWindowsLocked(wtoken, NN, false);
7047 }
7048 }
7049 mToTopApps.clear();
7050 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007051
Dianne Hackborn25994b42009-09-04 14:21:19 -07007052 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007053
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007054 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007055 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007056
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007057 // The top-most window will supply the layout params,
7058 // and we will determine it below.
7059 LayoutParams animLp = null;
7060 int bestAnimLayer = -1;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007061 boolean fullscreenAnim = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007062
Joe Onorato8a9b2202010-02-26 18:56:32 -08007063 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007064 "New wallpaper target=" + mWallpaperTarget
7065 + ", lower target=" + mLowerWallpaperTarget
7066 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07007067 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007068 // Do a first pass through the tokens for two
7069 // things:
7070 // (1) Determine if both the closing and opening
7071 // app token sets are wallpaper targets, in which
7072 // case special animations are needed
7073 // (since the wallpaper needs to stay static
7074 // behind them).
7075 // (2) Find the layout params of the top-most
7076 // application window in the tokens, which is
7077 // what will control the animation theme.
7078 final int NC = mClosingApps.size();
7079 NN = NC + mOpeningApps.size();
7080 for (i=0; i<NN; i++) {
7081 AppWindowToken wtoken;
7082 int mode;
7083 if (i < NC) {
7084 wtoken = mClosingApps.get(i);
7085 mode = 1;
7086 } else {
7087 wtoken = mOpeningApps.get(i-NC);
7088 mode = 2;
7089 }
7090 if (mLowerWallpaperTarget != null) {
7091 if (mLowerWallpaperTarget.mAppToken == wtoken
7092 || mUpperWallpaperTarget.mAppToken == wtoken) {
7093 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007094 }
7095 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007096 if (wtoken.appFullscreen) {
7097 WindowState ws = wtoken.findMainWindow();
7098 if (ws != null) {
7099 // If this is a compatibility mode
7100 // window, we will always use its anim.
7101 if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
7102 animLp = ws.mAttrs;
7103 bestAnimLayer = Integer.MAX_VALUE;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007104 } else if (!fullscreenAnim || ws.mLayer > bestAnimLayer) {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007105 animLp = ws.mAttrs;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007106 bestAnimLayer = ws.mLayer;
7107 }
7108 fullscreenAnim = true;
7109 }
7110 } else if (!fullscreenAnim) {
7111 WindowState ws = wtoken.findMainWindow();
7112 if (ws != null) {
7113 if (ws.mLayer > bestAnimLayer) {
7114 animLp = ws.mAttrs;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007115 bestAnimLayer = ws.mLayer;
7116 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07007117 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007118 }
7119 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007120
Dianne Hackborn25994b42009-09-04 14:21:19 -07007121 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007122 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007123 "Wallpaper animation!");
7124 switch (transit) {
7125 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
7126 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
7127 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
7128 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
7129 break;
7130 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
7131 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
7132 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
7133 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
7134 break;
7135 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007136 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007137 "New transit: " + transit);
7138 } else if (oldWallpaper != null) {
7139 // We are transitioning from an activity with
7140 // a wallpaper to one without.
7141 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007142 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007143 "New transit away from wallpaper: " + transit);
7144 } else if (mWallpaperTarget != null) {
7145 // We are transitioning from an activity without
7146 // a wallpaper to now showing the wallpaper
7147 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007148 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007149 "New transit into wallpaper: " + transit);
7150 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007151
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007152 // If all closing windows are obscured, then there is
7153 // no need to do an animation. This is the case, for
7154 // example, when this transition is being done behind
7155 // the lock screen.
7156 if (!mPolicy.allowAppAnimationsLw()) {
7157 animLp = null;
7158 }
7159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007160 NN = mOpeningApps.size();
7161 for (i=0; i<NN; i++) {
7162 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007163 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007164 "Now opening app" + wtoken);
7165 wtoken.reportedVisible = false;
7166 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07007167 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007168 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007169 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007170 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007171 wtoken.showAllWindowsLocked();
7172 }
7173 NN = mClosingApps.size();
7174 for (i=0; i<NN; i++) {
7175 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007176 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007177 "Now closing app" + wtoken);
7178 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07007179 wtoken.animation = null;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007180 setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007181 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007182 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007183 // Force the allDrawn flag, because we want to start
7184 // this guy's animations regardless of whether it's
7185 // gotten drawn.
7186 wtoken.allDrawn = true;
7187 }
7188
Dianne Hackborn8b571a82009-09-25 16:09:43 -07007189 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007191 mOpeningApps.clear();
7192 mClosingApps.clear();
7193
7194 // This has changed the visibility of windows, so perform
7195 // a new layout to get them all up-to-date.
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007196 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT
7197 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007198 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07007199 if (!moveInputMethodWindowsIfNeededLocked(true)) {
7200 assignLayersLocked();
7201 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08007202 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
7203 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007204 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 }
7206 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007207
Dianne Hackborn16064f92010-03-25 00:47:24 -07007208 int adjResult = 0;
7209
Dianne Hackborna8f60182009-09-01 19:01:50 -07007210 if (!animating && mAppTransitionRunning) {
7211 // We have finished the animation of an app transition. To do
7212 // this, we have delayed a lot of operations like showing and
7213 // hiding apps, moving apps in Z-order, etc. The app token list
7214 // reflects the correct Z-order, but the window list may now
7215 // be out of sync with it. So here we will just rebuild the
7216 // entire app window list. Fun!
7217 mAppTransitionRunning = false;
7218 // Clear information about apps that were moving.
7219 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007220
Dianne Hackborna8f60182009-09-01 19:01:50 -07007221 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007222 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007223 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007224 moveInputMethodWindowsIfNeededLocked(false);
7225 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08007226 // Since the window list has been rebuilt, focus might
7227 // have to be recomputed since the actual order of windows
7228 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007229 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007230 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007231
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007232 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007233 // At this point, there was a window with a wallpaper that
7234 // was force hiding other windows behind it, but now it
7235 // is going away. This may be simple -- just animate
7236 // away the wallpaper and its window -- or it may be
7237 // hard -- the wallpaper now needs to be shown behind
7238 // something that was hidden.
7239 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007240 if (mLowerWallpaperTarget != null
7241 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007242 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007243 "wallpaperForceHiding changed with lower="
7244 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007245 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007246 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
7247 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
7248 if (mLowerWallpaperTarget.mAppToken.hidden) {
7249 // The lower target has become hidden before we
7250 // actually started the animation... let's completely
7251 // re-evaluate everything.
7252 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007253 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007254 }
7255 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07007256 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007257 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007258 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007259 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007260 + " NEW: " + mWallpaperTarget
7261 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007262 if (mLowerWallpaperTarget == null) {
7263 // Whoops, we don't need a special wallpaper animation.
7264 // Clear them out.
7265 forceHiding = false;
7266 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007267 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007268 if (w.mSurface != null) {
7269 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07007270 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007271 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007272 forceHiding = true;
7273 } else if (mPolicy.canBeForceHidden(w, attrs)) {
7274 if (!w.mAnimating) {
7275 // We set the animation above so it
7276 // is not yet running.
7277 w.clearAnimation();
7278 }
7279 }
7280 }
7281 }
7282 }
7283 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007284
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007285 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
7286 if (DEBUG_WALLPAPER) Slog.v(TAG,
7287 "Detached wallpaper changed from " + mWindowDetachedWallpaper
7288 + windowDetachedWallpaper);
7289 mWindowDetachedWallpaper = windowDetachedWallpaper;
7290 wallpaperMayChange = true;
7291 }
7292
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007293 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007294 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007295 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07007296 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007297 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007298
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007299 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007300 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007301 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007302 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007303 assignLayersLocked();
7304 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007305 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007306 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007307 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007308 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007309
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007310 if (mFocusMayChange) {
7311 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08007312 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
7313 false /*updateInputWindows*/)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007314 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007315 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007316 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007317 }
7318
7319 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007320 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007321 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007322
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007323 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
7324 + Integer.toHexString(changes));
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007325 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326
7327 // THIRD LOOP: Update the surfaces of all windows.
7328
7329 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
7330
7331 boolean obscured = false;
7332 boolean blurring = false;
7333 boolean dimming = false;
7334 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07007335 boolean syswin = false;
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007336 boolean backgroundFillerWasShown = mBackgroundFillerTarget != null;
7337 mBackgroundFillerTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007338
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007339 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007341 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007342 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007343
7344 boolean displayed = false;
7345 final WindowManager.LayoutParams attrs = w.mAttrs;
7346 final int attrFlags = attrs.flags;
7347
7348 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007349 // XXX NOTE: The logic here could be improved. We have
7350 // the decision about whether to resize a window separated
7351 // from whether to hide the surface. This can cause us to
7352 // resize a surface even if we are going to hide it. You
7353 // can see this by (1) holding device in landscape mode on
7354 // home screen; (2) tapping browser icon (device will rotate
7355 // to landscape; (3) tap home. The wallpaper will be resized
7356 // in step 2 but then immediately hidden, causing us to
7357 // have to resize and then redraw it again in step 3. It
7358 // would be nice to figure out how to avoid this, but it is
7359 // difficult because we do need to resize surfaces in some
7360 // cases while they are hidden such as when first showing a
7361 // window.
7362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007364 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007365 TAG, "Placing surface #" + i + " " + w.mSurface
7366 + ": new=" + w.mShownFrame + ", old="
7367 + w.mLastShownFrame);
7368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007369 int width, height;
7370 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 // for a scaled surface, we just want to use
7372 // the requested size.
7373 width = w.mRequestedWidth;
7374 height = w.mRequestedHeight;
7375 w.mLastRequestedWidth = width;
7376 w.mLastRequestedHeight = height;
7377 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007378 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007379 width = w.mShownFrame.width();
7380 height = w.mShownFrame.height();
7381 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007382 }
7383
Jeff Brownfbae7222011-01-23 13:07:25 -08007384 if (w.mSurface != null) {
7385 if (w.mSurfaceX != w.mShownFrame.left
7386 || w.mSurfaceY != w.mShownFrame.top) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007387 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007388 if (SHOW_TRANSACTIONS) logSurface(w,
Jeff Brownfbae7222011-01-23 13:07:25 -08007389 "POS " + w.mShownFrame.left
7390 + ", " + w.mShownFrame.top, null);
7391 w.mSurfaceX = w.mShownFrame.left;
7392 w.mSurfaceY = w.mShownFrame.top;
7393 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
7394 } catch (RuntimeException e) {
7395 Slog.w(TAG, "Error positioning surface of " + w
7396 + " pos=(" + w.mShownFrame.left
7397 + "," + w.mShownFrame.top + ")", e);
7398 if (!recoveringMemory) {
7399 reclaimSomeSurfaceMemoryLocked(w, "position");
7400 }
7401 }
7402 }
7403
7404 if (width < 1) {
7405 width = 1;
7406 }
7407 if (height < 1) {
7408 height = 1;
7409 }
7410
7411 if (w.mSurfaceW != width || w.mSurfaceH != height) {
7412 try {
7413 if (SHOW_TRANSACTIONS) logSurface(w,
7414 "SIZE " + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007415 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007416 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007417 w.mSurfaceW = width;
7418 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007419 w.mSurface.setSize(width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007420 } catch (RuntimeException e) {
7421 // If something goes wrong with the surface (such
7422 // as running out of memory), don't take down the
7423 // entire system.
Jeff Brownfbae7222011-01-23 13:07:25 -08007424 Slog.e(TAG, "Error resizing surface of " + w
7425 + " size=(" + width + "x" + height + ")", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007426 if (!recoveringMemory) {
7427 reclaimSomeSurfaceMemoryLocked(w, "size");
7428 }
7429 }
7430 }
7431 }
Jeff Brownfbae7222011-01-23 13:07:25 -08007432
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007433 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 w.mContentInsetsChanged =
7435 !w.mLastContentInsets.equals(w.mContentInsets);
7436 w.mVisibleInsetsChanged =
7437 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007438 boolean configChanged =
7439 w.mConfiguration != mCurConfiguration
7440 && (w.mConfiguration == null
7441 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007442 if (DEBUG_CONFIGURATION && configChanged) {
7443 Slog.v(TAG, "Win " + w + " config changed: "
7444 + mCurConfiguration);
7445 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007446 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007447 + ": configChanged=" + configChanged
7448 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Jeff Brownfbae7222011-01-23 13:07:25 -08007449 boolean frameChanged = !w.mLastFrame.equals(w.mFrame);
7450 if (frameChanged
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007451 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007452 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007453 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007454 || configChanged) {
Jeff Brownfbae7222011-01-23 13:07:25 -08007455 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
7456 Slog.v(TAG, "Resize reasons: "
7457 + "frameChanged=" + frameChanged
7458 + " contentInsetsChanged=" + w.mContentInsetsChanged
7459 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
7460 + " surfaceResized=" + w.mSurfaceResized
7461 + " configChanged=" + configChanged);
7462 }
7463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007464 w.mLastFrame.set(w.mFrame);
7465 w.mLastContentInsets.set(w.mContentInsets);
7466 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007467 // If the screen is currently frozen, then keep
7468 // it frozen until this window draws at its new
7469 // orientation.
7470 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007471 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007472 "Resizing while display frozen: " + w);
7473 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007474 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007475 mWindowsFreezingScreen = true;
7476 // XXX should probably keep timeout from
7477 // when we first froze the display.
7478 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
7479 mH.sendMessageDelayed(mH.obtainMessage(
7480 H.WINDOW_FREEZE_TIMEOUT), 2000);
7481 }
7482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007483 // If the orientation is changing, then we need to
7484 // hold off on unfreezing the display until this
7485 // window has been redrawn; to do that, we need
7486 // to go through the process of getting informed
7487 // by the application when it has finished drawing.
7488 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007489 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007490 "Orientation start waiting for draw in "
7491 + w + ", surface " + w.mSurface);
7492 w.mDrawPending = true;
7493 w.mCommitDrawPending = false;
7494 w.mReadyToShow = false;
7495 if (w.mAppToken != null) {
7496 w.mAppToken.allDrawn = false;
7497 }
7498 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007499 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007500 "Resizing window " + w + " to " + w.mFrame);
7501 mResizingWindows.add(w);
7502 } else if (w.mOrientationChanging) {
7503 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007504 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007505 "Orientation not waiting for draw in "
7506 + w + ", surface " + w.mSurface);
7507 w.mOrientationChanging = false;
7508 }
7509 }
7510 }
7511
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007512 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007513 if (!w.mLastHidden) {
7514 //dump();
7515 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007516 if (SHOW_TRANSACTIONS) logSurface(w,
7517 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007518 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007519 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007520 try {
7521 w.mSurface.hide();
7522 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007523 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 }
7525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007526 }
7527 // If we are waiting for this window to handle an
7528 // orientation change, well, it is hidden, so
7529 // doesn't really matter. Note that this does
7530 // introduce a potential glitch if the window
7531 // becomes unhidden before it has drawn for the
7532 // new orientation.
7533 if (w.mOrientationChanging) {
7534 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007535 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 "Orientation change skips hidden " + w);
7537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 } else if (w.mLastLayer != w.mAnimLayer
7539 || w.mLastAlpha != w.mShownAlpha
7540 || w.mLastDsDx != w.mDsDx
7541 || w.mLastDtDx != w.mDtDx
7542 || w.mLastDsDy != w.mDsDy
7543 || w.mLastDtDy != w.mDtDy
7544 || w.mLastHScale != w.mHScale
7545 || w.mLastVScale != w.mVScale
7546 || w.mLastHidden) {
7547 displayed = true;
7548 w.mLastAlpha = w.mShownAlpha;
7549 w.mLastLayer = w.mAnimLayer;
7550 w.mLastDsDx = w.mDsDx;
7551 w.mLastDtDx = w.mDtDx;
7552 w.mLastDsDy = w.mDsDy;
7553 w.mLastDtDy = w.mDtDy;
7554 w.mLastHScale = w.mHScale;
7555 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007556 if (SHOW_TRANSACTIONS) logSurface(w,
7557 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007558 + " matrix=[" + (w.mDsDx*w.mHScale)
7559 + "," + (w.mDtDx*w.mVScale)
7560 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007561 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007562 if (w.mSurface != null) {
7563 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007564 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007565 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007566 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007567 w.mSurface.setLayer(w.mAnimLayer);
7568 w.mSurface.setMatrix(
7569 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
7570 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
7571 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007572 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007573 if (!recoveringMemory) {
7574 reclaimSomeSurfaceMemoryLocked(w, "update");
7575 }
7576 }
7577 }
7578
7579 if (w.mLastHidden && !w.mDrawPending
7580 && !w.mCommitDrawPending
7581 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007582 if (SHOW_TRANSACTIONS) logSurface(w,
7583 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007584 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007585 + " during relayout");
7586 if (showSurfaceRobustlyLocked(w)) {
7587 w.mHasDrawn = true;
7588 w.mLastHidden = false;
7589 } else {
7590 w.mOrientationChanging = false;
7591 }
7592 }
7593 if (w.mSurface != null) {
7594 w.mToken.hasVisible = true;
7595 }
7596 } else {
7597 displayed = true;
7598 }
7599
7600 if (displayed) {
7601 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -08007602 if (attrs.width == LayoutParams.MATCH_PARENT
7603 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007604 covered = true;
7605 }
7606 }
7607 if (w.mOrientationChanging) {
7608 if (w.mDrawPending || w.mCommitDrawPending) {
7609 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007610 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007611 "Orientation continue waiting for draw in " + w);
7612 } else {
7613 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007614 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007615 "Orientation change complete in " + w);
7616 }
7617 }
7618 w.mToken.hasVisible = true;
7619 }
7620 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007621 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 "Orientation change skips hidden " + w);
7623 w.mOrientationChanging = false;
7624 }
7625
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007626 if (w.mContentChanged) {
7627 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
7628 w.mContentChanged = false;
7629 }
7630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007631 final boolean canBeSeen = w.isDisplayedLw();
7632
7633 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
7634 focusDisplayed = true;
7635 }
7636
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007637 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007638
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007639 if (mBackgroundFillerTarget != null) {
7640 if (w.isAnimating()) {
7641 // Background filler is below all other windows that
7642 // are animating.
7643 mBackgroundFillerTarget = w;
7644 } else if (w.mIsWallpaper) {
7645 mBackgroundFillerTarget = w;
7646 }
7647 }
7648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007649 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007650 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007651 if (w.mSurface != null) {
7652 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
7653 holdScreen = w.mSession;
7654 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07007655 if (!syswin && w.mAttrs.screenBrightness >= 0
7656 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007657 screenBrightness = w.mAttrs.screenBrightness;
7658 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05007659 if (!syswin && w.mAttrs.buttonBrightness >= 0
7660 && buttonBrightness < 0) {
7661 buttonBrightness = w.mAttrs.buttonBrightness;
7662 }
Mike Lockwood46af6a82010-03-09 08:28:22 -05007663 if (canBeSeen
7664 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
7665 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
7666 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07007667 syswin = true;
7668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007670
Dianne Hackborn25994b42009-09-04 14:21:19 -07007671 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
7672 if (opaqueDrawn && w.isFullscreen(dw, dh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007673 // This window completely covers everything behind it,
7674 // so we want to leave all of them as unblurred (for
7675 // performance reasons).
7676 obscured = true;
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007677 } else if (w.needsBackgroundFiller(dw, dh) && (canBeSeen || w.isAnimating())) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007678 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007679 obscured = true;
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007680 mBackgroundFillerTarget = w;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007681 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007682 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007683 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007684 + ": blurring=" + blurring
7685 + " obscured=" + obscured
7686 + " displayed=" + displayed);
7687 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
7688 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007689 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007690 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007691 if (mDimAnimator == null) {
7692 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007693 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007694 mDimAnimator.show(dw, dh);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007695 mDimAnimator.updateParameters(mContext.getResources(),
7696 w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007698 }
7699 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
7700 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007701 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007702 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007703 if (mBlurSurface == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007704 try {
Romain Guy06882f82009-06-10 13:36:04 -07007705 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08007706 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007707 -1, 16, 16,
7708 PixelFormat.OPAQUE,
7709 Surface.FX_SURFACE_BLUR);
7710 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007711 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007712 }
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007713 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
7714 + mBlurSurface + ": CREATE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007715 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007716 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007717 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
7718 + mBlurSurface + ": pos=(0,0) (" +
7719 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 mBlurSurface.setPosition(0, 0);
7721 mBlurSurface.setSize(dw, dh);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007722 mBlurSurface.setLayer(w.mAnimLayer-2);
7723 if (!mBlurShown) {
7724 try {
7725 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
7726 + mBlurSurface + ": SHOW");
7727 mBlurSurface.show();
7728 } catch (RuntimeException e) {
7729 Slog.w(TAG, "Failure showing blur surface", e);
7730 }
7731 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007732 }
7733 }
7734 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007735 }
7736 }
7737 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007738
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007739 if (obscuredChanged && mWallpaperTarget == w) {
7740 // This is the wallpaper target and its obscured state
7741 // changed... make sure the current wallaper's visibility
7742 // has been updated accordingly.
7743 updateWallpaperVisibilityLocked();
7744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007745 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007746
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007747 if (mBackgroundFillerTarget != null) {
7748 if (mBackgroundFillerSurface == null) {
7749 try {
7750 mBackgroundFillerSurface = new Surface(mFxSession, 0,
7751 "BackGroundFiller",
7752 0, dw, dh,
7753 PixelFormat.OPAQUE,
7754 Surface.FX_SURFACE_NORMAL);
7755 } catch (Exception e) {
7756 Slog.e(TAG, "Exception creating filler surface", e);
7757 }
7758 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
7759 + mBackgroundFillerSurface + ": CREATE");
7760 }
7761 try {
7762 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
7763 + mBackgroundFillerSurface + " SHOW: pos=(0,0) ("
7764 + dw + "x" + dh + ") layer="
7765 + (mBackgroundFillerTarget.mLayer - 1));
7766 mBackgroundFillerSurface.setPosition(0, 0);
7767 mBackgroundFillerSurface.setSize(dw, dh);
7768 // Using the same layer as Dim because they will never be shown at the
7769 // same time. NOTE: we do NOT use mAnimLayer, because we don't
7770 // want this surface dragged up in front of stuff that is animating.
7771 mBackgroundFillerSurface.setLayer(mBackgroundFillerTarget.mLayer - 1);
7772 mBackgroundFillerSurface.show();
7773 } catch (RuntimeException e) {
7774 Slog.e(TAG, "Exception showing filler surface");
7775 }
7776 } else if (backgroundFillerWasShown) {
7777 mBackgroundFillerTarget = null;
7778 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
7779 + mBackgroundFillerSurface + " HIDE");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007780 try {
7781 mBackgroundFillerSurface.hide();
7782 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007783 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007784 }
7785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007787 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007788 animating |= mDimAnimator.updateSurface(dimming, currentTime,
7789 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007790 }
Romain Guy06882f82009-06-10 13:36:04 -07007791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007792 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007793 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007794 + ": HIDE");
7795 try {
7796 mBlurSurface.hide();
7797 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007798 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799 }
7800 mBlurShown = false;
7801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007802 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007803 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007804 }
7805
7806 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -07007807
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007808 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
7809
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07007810 if (mWatermark != null) {
7811 mWatermark.drawIfNeeded();
7812 }
7813
Joe Onorato8a9b2202010-02-26 18:56:32 -08007814 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007815 "With display frozen, orientationChangeComplete="
7816 + orientationChangeComplete);
7817 if (orientationChangeComplete) {
7818 if (mWindowsFreezingScreen) {
7819 mWindowsFreezingScreen = false;
7820 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
7821 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007822 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007823 }
Romain Guy06882f82009-06-10 13:36:04 -07007824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007825 i = mResizingWindows.size();
7826 if (i > 0) {
7827 do {
7828 i--;
7829 WindowState win = mResizingWindows.get(i);
7830 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007831 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
7832 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007833 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007834 boolean configChanged =
7835 win.mConfiguration != mCurConfiguration
7836 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007837 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
7838 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
7839 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007840 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007841 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007842 + " / " + mCurConfiguration + " / 0x"
7843 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007844 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007845 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007846 win.mClient.resized(win.mFrame.width(),
7847 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007848 win.mLastVisibleInsets, win.mDrawPending,
7849 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007850 win.mContentInsetsChanged = false;
7851 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007852 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 } catch (RemoteException e) {
7854 win.mOrientationChanging = false;
7855 }
7856 } while (i > 0);
7857 mResizingWindows.clear();
7858 }
Romain Guy06882f82009-06-10 13:36:04 -07007859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007860 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007861 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007862 i = mDestroySurface.size();
7863 if (i > 0) {
7864 do {
7865 i--;
7866 WindowState win = mDestroySurface.get(i);
7867 win.mDestroying = false;
7868 if (mInputMethodWindow == win) {
7869 mInputMethodWindow = null;
7870 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007871 if (win == mWallpaperTarget) {
7872 wallpaperDestroyed = true;
7873 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007874 win.destroySurfaceLocked();
7875 } while (i > 0);
7876 mDestroySurface.clear();
7877 }
7878
7879 // Time to remove any exiting tokens?
7880 for (i=mExitingTokens.size()-1; i>=0; i--) {
7881 WindowToken token = mExitingTokens.get(i);
7882 if (!token.hasVisible) {
7883 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07007884 if (token.windowType == TYPE_WALLPAPER) {
7885 mWallpaperTokens.remove(token);
7886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007887 }
7888 }
7889
7890 // Time to remove any exiting applications?
7891 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
7892 AppWindowToken token = mExitingAppTokens.get(i);
7893 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07007894 // Make sure there is no animation running on this token,
7895 // so any windows associated with it will be removed as
7896 // soon as their animations are complete
7897 token.animation = null;
7898 token.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007899 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
7900 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007901 mAppTokens.remove(token);
7902 mExitingAppTokens.remove(i);
7903 }
7904 }
7905
Dianne Hackborna8f60182009-09-01 19:01:50 -07007906 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007907
Dianne Hackborna8f60182009-09-01 19:01:50 -07007908 if (!animating && mAppTransitionRunning) {
7909 // We have finished the animation of an app transition. To do
7910 // this, we have delayed a lot of operations like showing and
7911 // hiding apps, moving apps in Z-order, etc. The app token list
7912 // reflects the correct Z-order, but the window list may now
7913 // be out of sync with it. So here we will just rebuild the
7914 // entire app window list. Fun!
7915 mAppTransitionRunning = false;
7916 needRelayout = true;
7917 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -07007918 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007919 // Clear information about apps that were moving.
7920 mToBottomApps.clear();
7921 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007923 if (focusDisplayed) {
7924 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
7925 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007926 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007927 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007928 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07007929 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007930 requestAnimationLocked(0);
7931 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007932 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
7933 }
Jeff Browneb857f12010-07-16 10:06:33 -07007934
Jeff Brown3a22cd92011-01-21 13:59:04 -08007935 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08007936 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07007937
Jeff Brown8e03b752010-06-13 19:16:55 -07007938 setHoldScreenLocked(holdScreen != null);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08007939 if (!mDisplayFrozen) {
7940 if (screenBrightness < 0 || screenBrightness > 1.0f) {
7941 mPowerManager.setScreenBrightnessOverride(-1);
7942 } else {
7943 mPowerManager.setScreenBrightnessOverride((int)
7944 (screenBrightness * Power.BRIGHTNESS_ON));
7945 }
7946 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
7947 mPowerManager.setButtonBrightnessOverride(-1);
7948 } else {
7949 mPowerManager.setButtonBrightnessOverride((int)
7950 (buttonBrightness * Power.BRIGHTNESS_ON));
7951 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05007952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 if (holdScreen != mHoldingScreenOn) {
7954 mHoldingScreenOn = holdScreen;
7955 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
7956 mH.sendMessage(m);
7957 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007958
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007959 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007960 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -07007961 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
7962 LocalPowerManager.BUTTON_EVENT, true);
7963 mTurnOnScreen = false;
7964 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007965
Dianne Hackborn50660e22011-02-02 17:12:25 -08007966 if (screenRotationFinished && mScreenRotationAnimation != null) {
7967 mScreenRotationAnimation.kill();
7968 mScreenRotationAnimation = null;
7969 }
7970
Dianne Hackborn89ba6752011-01-23 16:51:16 -08007971 if (updateRotation) {
7972 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
7973 boolean changed = setRotationUncheckedLocked(
7974 WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
7975 if (changed) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08007976 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08007977 }
7978 }
7979
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08007980 // Check to see if we are now in a state where the screen should
7981 // be enabled, because the window obscured flags have changed.
7982 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007983 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07007984
7985 /**
7986 * Must be called with the main window manager lock held.
7987 */
7988 void setHoldScreenLocked(boolean holding) {
7989 boolean state = mHoldingScreenWakeLock.isHeld();
7990 if (holding != state) {
7991 if (holding) {
7992 mHoldingScreenWakeLock.acquire();
7993 } else {
7994 mPolicy.screenOnStoppedLw();
7995 mHoldingScreenWakeLock.release();
7996 }
7997 }
7998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007999
8000 void requestAnimationLocked(long delay) {
8001 if (!mAnimationPending) {
8002 mAnimationPending = true;
8003 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
8004 }
8005 }
Romain Guy06882f82009-06-10 13:36:04 -07008006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008007 /**
8008 * Have the surface flinger show a surface, robustly dealing with
8009 * error conditions. In particular, if there is not enough memory
8010 * to show the surface, then we will try to get rid of other surfaces
8011 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -07008012 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008013 * @return Returns true if the surface was successfully shown.
8014 */
8015 boolean showSurfaceRobustlyLocked(WindowState win) {
8016 try {
8017 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008018 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008019 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008020 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008021 if (DEBUG_VISIBILITY) Slog.v(TAG,
8022 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008023 win.mTurnOnScreen = false;
8024 mTurnOnScreen = true;
8025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026 }
8027 return true;
8028 } catch (RuntimeException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008029 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008030 }
Romain Guy06882f82009-06-10 13:36:04 -07008031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008032 reclaimSomeSurfaceMemoryLocked(win, "show");
Romain Guy06882f82009-06-10 13:36:04 -07008033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008034 return false;
8035 }
Romain Guy06882f82009-06-10 13:36:04 -07008036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008037 void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
8038 final Surface surface = win.mSurface;
Romain Guy06882f82009-06-10 13:36:04 -07008039
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008040 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008041 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07008042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043 if (mForceRemoves == null) {
8044 mForceRemoves = new ArrayList<WindowState>();
8045 }
Romain Guy06882f82009-06-10 13:36:04 -07008046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047 long callingIdentity = Binder.clearCallingIdentity();
8048 try {
8049 // There was some problem... first, do a sanity check of the
8050 // window list to make sure we haven't left any dangling surfaces
8051 // around.
8052 int N = mWindows.size();
8053 boolean leakedSurface = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008054 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008056 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008057 if (ws.mSurface != null) {
8058 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008059 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008060 + ws + " surface=" + ws.mSurface
8061 + " token=" + win.mToken
8062 + " pid=" + ws.mSession.mPid
8063 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008064 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008065 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008066 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008067 ws.mSurface = null;
8068 mForceRemoves.add(ws);
8069 i--;
8070 N--;
8071 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008072 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008073 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008074 + ws + " surface=" + ws.mSurface
8075 + " token=" + win.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008076 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008077 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008078 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008079 ws.mSurface = null;
8080 leakedSurface = true;
8081 }
8082 }
8083 }
Romain Guy06882f82009-06-10 13:36:04 -07008084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008085 boolean killedApps = false;
8086 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008087 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008088 SparseIntArray pidCandidates = new SparseIntArray();
8089 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008090 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008091 if (ws.mSurface != null) {
8092 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
8093 }
8094 }
8095 if (pidCandidates.size() > 0) {
8096 int[] pids = new int[pidCandidates.size()];
8097 for (int i=0; i<pids.length; i++) {
8098 pids[i] = pidCandidates.keyAt(i);
8099 }
8100 try {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07008101 if (mActivityManager.killPids(pids, "Free memory")) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008102 killedApps = true;
8103 }
8104 } catch (RemoteException e) {
8105 }
8106 }
8107 }
Romain Guy06882f82009-06-10 13:36:04 -07008108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008109 if (leakedSurface || killedApps) {
8110 // We managed to reclaim some memory, so get rid of the trouble
8111 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08008112 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008113 if (surface != null) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008114 if (SHOW_TRANSACTIONS) logSurface(win, "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008115 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008116 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 win.mSurface = null;
8118 }
Romain Guy06882f82009-06-10 13:36:04 -07008119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008120 try {
8121 win.mClient.dispatchGetNewSurface();
8122 } catch (RemoteException e) {
8123 }
8124 }
8125 } finally {
8126 Binder.restoreCallingIdentity(callingIdentity);
8127 }
8128 }
Romain Guy06882f82009-06-10 13:36:04 -07008129
Jeff Brown3a22cd92011-01-21 13:59:04 -08008130 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 WindowState newFocus = computeFocusedWindowLocked();
8132 if (mCurrentFocus != newFocus) {
8133 // This check makes sure that we don't already have the focus
8134 // change message pending.
8135 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
8136 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008137 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008138 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
8139 final WindowState oldFocus = mCurrentFocus;
8140 mCurrentFocus = newFocus;
8141 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07008142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008143 final WindowState imWindow = mInputMethodWindow;
8144 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008145 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008146 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008147 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
8148 mLayoutNeeded = true;
8149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08008151 performLayoutLockedInner(true /*initial*/, updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008152 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
8153 // Client will do the layout, but we need to assign layers
8154 // for handleNewWindowLocked() below.
8155 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008156 }
8157 }
Jeff Brown349703e2010-06-22 01:27:15 -07008158
8159 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
8160 // If we defer assigning layers, then the caller is responsible for
8161 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008162 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164 return true;
8165 }
8166 return false;
8167 }
Jeff Brown349703e2010-06-22 01:27:15 -07008168
Jeff Brown3a22cd92011-01-21 13:59:04 -08008169 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
8170 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07008171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008172
8173 private WindowState computeFocusedWindowLocked() {
8174 WindowState result = null;
8175 WindowState win;
8176
8177 int i = mWindows.size() - 1;
8178 int nextAppIndex = mAppTokens.size()-1;
8179 WindowToken nextApp = nextAppIndex >= 0
8180 ? mAppTokens.get(nextAppIndex) : null;
8181
8182 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008183 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008184
Joe Onorato8a9b2202010-02-26 18:56:32 -08008185 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008186 TAG, "Looking for focus: " + i
8187 + " = " + win
8188 + ", flags=" + win.mAttrs.flags
8189 + ", canReceive=" + win.canReceiveKeys());
8190
8191 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07008192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008193 // If this window's application has been removed, just skip it.
8194 if (thisApp != null && thisApp.removed) {
8195 i--;
8196 continue;
8197 }
Romain Guy06882f82009-06-10 13:36:04 -07008198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 // If there is a focused app, don't allow focus to go to any
8200 // windows below it. If this is an application window, step
8201 // through the app tokens until we find its app.
8202 if (thisApp != null && nextApp != null && thisApp != nextApp
8203 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
8204 int origAppIndex = nextAppIndex;
8205 while (nextAppIndex > 0) {
8206 if (nextApp == mFocusedApp) {
8207 // Whoops, we are below the focused app... no focus
8208 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008209 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008210 TAG, "Reached focused app: " + mFocusedApp);
8211 return null;
8212 }
8213 nextAppIndex--;
8214 nextApp = mAppTokens.get(nextAppIndex);
8215 if (nextApp == thisApp) {
8216 break;
8217 }
8218 }
8219 if (thisApp != nextApp) {
8220 // Uh oh, the app token doesn't exist! This shouldn't
8221 // happen, but if it does we can get totally hosed...
8222 // so restart at the original app.
8223 nextAppIndex = origAppIndex;
8224 nextApp = mAppTokens.get(nextAppIndex);
8225 }
8226 }
8227
8228 // Dispatch to this window if it is wants key events.
8229 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008230 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008231 TAG, "Found focus @ " + i + " = " + win);
8232 result = win;
8233 break;
8234 }
8235
8236 i--;
8237 }
8238
8239 return result;
8240 }
8241
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008242 private void startFreezingDisplayLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008243 if (mDisplayFrozen) {
8244 return;
8245 }
Romain Guy06882f82009-06-10 13:36:04 -07008246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008247 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07008248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008249 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008250 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008251 if (mFreezeGcPending != 0) {
8252 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008253 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008254 mH.removeMessages(H.FORCE_GC);
8255 Runtime.getRuntime().gc();
8256 mFreezeGcPending = now;
8257 }
8258 } else {
8259 mFreezeGcPending = now;
8260 }
Romain Guy06882f82009-06-10 13:36:04 -07008261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008262 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -07008263
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008264 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -07008265
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008266 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
8267 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008268 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008269 mAppTransitionReady = true;
8270 }
Romain Guy06882f82009-06-10 13:36:04 -07008271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008272 if (PROFILE_ORIENTATION) {
8273 File file = new File("/data/system/frozen");
8274 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
8275 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008276
8277 if (CUSTOM_SCREEN_ROTATION) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08008278 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
8279 mScreenRotationAnimation.kill();
8280 mScreenRotationAnimation = null;
8281 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008282 if (mScreenRotationAnimation == null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08008283 mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008284 mDisplay, mFxSession, inTransaction);
Dianne Hackborna1111872010-11-23 20:55:11 -08008285 }
8286 } else {
8287 Surface.freezeDisplay(0);
8288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008289 }
Romain Guy06882f82009-06-10 13:36:04 -07008290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008291 private void stopFreezingDisplayLocked() {
8292 if (!mDisplayFrozen) {
8293 return;
8294 }
Romain Guy06882f82009-06-10 13:36:04 -07008295
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008296 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
8297 return;
8298 }
8299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300 mDisplayFrozen = false;
8301 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
8302 if (PROFILE_ORIENTATION) {
8303 Debug.stopMethodTracing();
8304 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008305
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008306 boolean updateRotation = false;
8307
Dianne Hackborna1111872010-11-23 20:55:11 -08008308 if (CUSTOM_SCREEN_ROTATION) {
8309 if (mScreenRotationAnimation != null) {
Dianne Hackborn50660e22011-02-02 17:12:25 -08008310 if (mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08008311 mTransitionAnimationScale)) {
8312 requestAnimationLocked(0);
8313 } else {
8314 mScreenRotationAnimation = null;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008315 updateRotation = true;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08008316 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008317 }
8318 } else {
8319 Surface.unfreezeDisplay(0);
8320 }
Romain Guy06882f82009-06-10 13:36:04 -07008321
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008322 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008323
Dianne Hackborn420829e2011-01-28 11:30:35 -08008324 boolean configChanged;
8325
Christopher Tateb696aee2010-04-02 19:08:30 -07008326 // While the display is frozen we don't re-compute the orientation
8327 // to avoid inconsistent states. However, something interesting
8328 // could have actually changed during that time so re-evaluate it
8329 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08008330 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07008331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008332 // A little kludge: a lot could have happened while the
8333 // display was frozen, so now that we are coming back we
8334 // do a gc so that any remote references the system
8335 // processes holds on others can be released if they are
8336 // no longer needed.
8337 mH.removeMessages(H.FORCE_GC);
8338 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8339 2000);
Romain Guy06882f82009-06-10 13:36:04 -07008340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008341 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008342
8343 if (updateRotation) {
8344 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Dianne Hackborn420829e2011-01-28 11:30:35 -08008345 configChanged |= setRotationUncheckedLocked(
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008346 WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08008347 }
8348
8349 if (configChanged) {
8350 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008352 }
Romain Guy06882f82009-06-10 13:36:04 -07008353
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008354 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
8355 DisplayMetrics dm) {
8356 if (index < tokens.length) {
8357 String str = tokens[index];
8358 if (str != null && str.length() > 0) {
8359 try {
8360 int val = Integer.parseInt(str);
8361 return val;
8362 } catch (Exception e) {
8363 }
8364 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008365 }
8366 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
8367 return defDps;
8368 }
8369 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
8370 return val;
8371 }
8372
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008373 void createWatermark() {
8374 if (mWatermark != null) {
8375 return;
8376 }
8377
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008378 File file = new File("/system/etc/setup.conf");
8379 FileInputStream in = null;
8380 try {
8381 in = new FileInputStream(file);
8382 DataInputStream ind = new DataInputStream(in);
8383 String line = ind.readLine();
8384 if (line != null) {
8385 String[] toks = line.split("%");
8386 if (toks != null && toks.length > 0) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -07008387 mWatermark = new Watermark(mDisplay, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008388 }
8389 }
8390 } catch (FileNotFoundException e) {
8391 } catch (IOException e) {
8392 } finally {
8393 if (in != null) {
8394 try {
8395 in.close();
8396 } catch (IOException e) {
8397 }
8398 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008399 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008400 }
8401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 @Override
Joe Onorato664644d2011-01-23 17:53:23 -08008403 public void statusBarVisibilityChanged(int visibility) {
8404 synchronized (mWindowMap) {
8405 final int N = mWindows.size();
8406 for (int i = 0; i < N; i++) {
8407 WindowState ws = mWindows.get(i);
8408 try {
8409 if (ws.getAttrs().hasSystemUiListeners) {
8410 ws.mClient.dispatchSystemUiVisibilityChanged(visibility);
8411 }
8412 } catch (RemoteException e) {
8413 // so sorry
8414 }
8415 }
8416 }
8417 }
8418
8419 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008420 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8421 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
8422 != PackageManager.PERMISSION_GRANTED) {
8423 pw.println("Permission Denial: can't dump WindowManager from from pid="
8424 + Binder.getCallingPid()
8425 + ", uid=" + Binder.getCallingUid());
8426 return;
8427 }
Romain Guy06882f82009-06-10 13:36:04 -07008428
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008429 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -08008430 pw.println(" ");
8431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008432 synchronized(mWindowMap) {
8433 pw.println("Current Window Manager state:");
8434 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008435 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008436 pw.print(" Window #"); pw.print(i); pw.print(' ');
8437 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 w.dump(pw, " ");
8439 }
8440 if (mInputMethodDialogs.size() > 0) {
8441 pw.println(" ");
8442 pw.println(" Input method dialogs:");
8443 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
8444 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008445 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008446 }
8447 }
8448 if (mPendingRemove.size() > 0) {
8449 pw.println(" ");
8450 pw.println(" Remove pending for:");
8451 for (int i=mPendingRemove.size()-1; i>=0; i--) {
8452 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008453 pw.print(" Remove #"); pw.print(i); pw.print(' ');
8454 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455 w.dump(pw, " ");
8456 }
8457 }
8458 if (mForceRemoves != null && mForceRemoves.size() > 0) {
8459 pw.println(" ");
8460 pw.println(" Windows force removing:");
8461 for (int i=mForceRemoves.size()-1; i>=0; i--) {
8462 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008463 pw.print(" Removing #"); pw.print(i); pw.print(' ');
8464 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465 w.dump(pw, " ");
8466 }
8467 }
8468 if (mDestroySurface.size() > 0) {
8469 pw.println(" ");
8470 pw.println(" Windows waiting to destroy their surface:");
8471 for (int i=mDestroySurface.size()-1; i>=0; i--) {
8472 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008473 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
8474 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008475 w.dump(pw, " ");
8476 }
8477 }
8478 if (mLosingFocus.size() > 0) {
8479 pw.println(" ");
8480 pw.println(" Windows losing focus:");
8481 for (int i=mLosingFocus.size()-1; i>=0; i--) {
8482 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008483 pw.print(" Losing #"); pw.print(i); pw.print(' ');
8484 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 w.dump(pw, " ");
8486 }
8487 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008488 if (mResizingWindows.size() > 0) {
8489 pw.println(" ");
8490 pw.println(" Windows waiting to resize:");
8491 for (int i=mResizingWindows.size()-1; i>=0; i--) {
8492 WindowState w = mResizingWindows.get(i);
8493 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
8494 pw.print(w); pw.println(":");
8495 w.dump(pw, " ");
8496 }
8497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008498 if (mSessions.size() > 0) {
8499 pw.println(" ");
8500 pw.println(" All active sessions:");
8501 Iterator<Session> it = mSessions.iterator();
8502 while (it.hasNext()) {
8503 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008504 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008505 s.dump(pw, " ");
8506 }
8507 }
8508 if (mTokenMap.size() > 0) {
8509 pw.println(" ");
8510 pw.println(" All tokens:");
8511 Iterator<WindowToken> it = mTokenMap.values().iterator();
8512 while (it.hasNext()) {
8513 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008514 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008515 token.dump(pw, " ");
8516 }
8517 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008518 if (mWallpaperTokens.size() > 0) {
8519 pw.println(" ");
8520 pw.println(" Wallpaper tokens:");
8521 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
8522 WindowToken token = mWallpaperTokens.get(i);
8523 pw.print(" Wallpaper #"); pw.print(i);
8524 pw.print(' '); pw.print(token); pw.println(':');
8525 token.dump(pw, " ");
8526 }
8527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008528 if (mAppTokens.size() > 0) {
8529 pw.println(" ");
8530 pw.println(" Application tokens in Z order:");
8531 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008532 pw.print(" App #"); pw.print(i); pw.print(": ");
8533 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008534 }
8535 }
8536 if (mFinishedStarting.size() > 0) {
8537 pw.println(" ");
8538 pw.println(" Finishing start of application tokens:");
8539 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
8540 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008541 pw.print(" Finished Starting #"); pw.print(i);
8542 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008543 token.dump(pw, " ");
8544 }
8545 }
8546 if (mExitingTokens.size() > 0) {
8547 pw.println(" ");
8548 pw.println(" Exiting tokens:");
8549 for (int i=mExitingTokens.size()-1; i>=0; i--) {
8550 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008551 pw.print(" Exiting #"); pw.print(i);
8552 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008553 token.dump(pw, " ");
8554 }
8555 }
8556 if (mExitingAppTokens.size() > 0) {
8557 pw.println(" ");
8558 pw.println(" Exiting application tokens:");
8559 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
8560 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008561 pw.print(" Exiting App #"); pw.print(i);
8562 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008563 token.dump(pw, " ");
8564 }
8565 }
8566 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008567 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
8568 pw.print(" mLastFocus="); pw.println(mLastFocus);
8569 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
8570 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
8571 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -07008572 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -07008573 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
8574 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
8575 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
8576 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008577 if (mWindowDetachedWallpaper != null) {
8578 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
8579 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008580 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
8581 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
8582 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008583 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
8584 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
8585 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
8586 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008587 if (mDimAnimator != null) {
8588 mDimAnimator.printTo(pw);
8589 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -08008590 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008591 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008592 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008593 pw.print(mInputMethodAnimLayerAdjustment);
8594 pw.print(" mWallpaperAnimLayerAdjustment=");
8595 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -07008596 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
8597 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008598 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
8599 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008600 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
8601 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008602 pw.print(" mRotation="); pw.print(mRotation);
8603 pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation);
8604 pw.print(", mRequestedRotation="); pw.println(mRequestedRotation);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008605 pw.print(" mDeferredRotation="); pw.print(mDeferredRotation);
8606 pw.print(", mDeferredRotationAnimFlags="); pw.print(mDeferredRotationAnimFlags);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008607 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
8608 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
8609 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
8610 pw.print(" mNextAppTransition=0x");
8611 pw.print(Integer.toHexString(mNextAppTransition));
8612 pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008613 pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008614 pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008615 if (mNextAppTransitionPackage != null) {
8616 pw.print(" mNextAppTransitionPackage=");
8617 pw.print(mNextAppTransitionPackage);
8618 pw.print(", mNextAppTransitionEnter=0x");
8619 pw.print(Integer.toHexString(mNextAppTransitionEnter));
8620 pw.print(", mNextAppTransitionExit=0x");
8621 pw.print(Integer.toHexString(mNextAppTransitionExit));
8622 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008623 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
8624 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
8625 if (mOpeningApps.size() > 0) {
8626 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
8627 }
8628 if (mClosingApps.size() > 0) {
8629 pw.print(" mClosingApps="); pw.println(mClosingApps);
8630 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008631 if (mToTopApps.size() > 0) {
8632 pw.print(" mToTopApps="); pw.println(mToTopApps);
8633 }
8634 if (mToBottomApps.size() > 0) {
8635 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
8636 }
Dianne Hackborn87fc3082010-12-03 13:09:12 -08008637 if (mDisplay != null) {
8638 pw.print(" DisplayWidth="); pw.print(mDisplay.getWidth());
8639 pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
8640 } else {
8641 pw.println(" NO DISPLAY");
8642 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008643 pw.println(" Policy:");
8644 mPolicy.dump(" ", fd, pw, args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008645 }
8646 }
8647
Jeff Brown349703e2010-06-22 01:27:15 -07008648 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008649 public void monitor() {
8650 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -05008651 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07008652 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008653
Jeff Brown2992ea72011-01-28 22:04:14 -08008654 public interface OnHardKeyboardStatusChangeListener {
8655 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
8656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008657}