blob: 642d52cabedf0ba7c1a1edc09625c92c2fffc637 [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;
22import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
23import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
25import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070026import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
28import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
30import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
31import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
32import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070033import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
35import com.android.internal.app.IBatteryStats;
36import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080037import com.android.internal.policy.impl.PhoneWindowManager;
Christopher Tatea53146c2010-09-07 11:57:52 -070038import com.android.internal.view.BaseInputHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import com.android.internal.view.IInputContext;
40import com.android.internal.view.IInputMethodClient;
41import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080042import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080043import com.android.server.AttributeCache;
44import com.android.server.EventLogTags;
45import com.android.server.PowerManagerService;
46import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import com.android.server.am.BatteryStatsService;
48
49import android.Manifest;
50import android.app.ActivityManagerNative;
51import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080052import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070053import android.app.admin.DevicePolicyManager;
Jim Miller284b62e2010-06-08 14:27:42 -070054import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070056import android.content.Intent;
57import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.pm.ActivityInfo;
59import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070060import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080062import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070063import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.graphics.Matrix;
65import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070066import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import 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
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800183 /**
184 * Dim surface layer is immediately below target window.
185 */
186 static final int LAYER_OFFSET_DIM = 1;
187
188 /**
189 * Blur surface layer is immediately below dim layer.
190 */
191 static final int LAYER_OFFSET_BLUR = 2;
192
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700193 /**
194 * Layer at which to put the rotation freeze snapshot.
195 */
196 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
197
198 /**
199 * Layer at which to put the mask for emulated screen sizes.
200 */
201 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 /** The maximum length we will accept for a loaded animation duration:
204 * this is 10 seconds.
205 */
206 static final int MAX_ANIMATION_DURATION = 10*1000;
207
208 /** Amount of time (in milliseconds) to animate the dim surface from one
209 * value to another, when no window animation is driving it.
210 */
211 static final int DEFAULT_DIM_DURATION = 200;
212
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700213 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
214 * compatible windows.
215 */
216 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
217
Dianne Hackborna1111872010-11-23 20:55:11 -0800218 /**
219 * If true, the window manager will do its own custom freezing and general
220 * management of the screen during rotation.
221 */
222 static final boolean CUSTOM_SCREEN_ROTATION = true;
223
Jeff Brown7fbdc842010-06-17 20:52:56 -0700224 // Maximum number of milliseconds to wait for input event injection.
225 // FIXME is this value reasonable?
226 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
Jeff Brownb09abc12011-01-13 21:08:27 -0800227
228 // Maximum number of milliseconds to wait for input devices to be enumerated before
229 // proceding with safe mode detection.
230 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jeff Brown349703e2010-06-22 01:27:15 -0700231
232 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800233 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 static final int UPDATE_FOCUS_NORMAL = 0;
236 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
237 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
238 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700241 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242
243 /**
244 * Condition waited on by {@link #reenableKeyguard} to know the call to
245 * the window policy has finished.
Mike Lockwood983ee092009-11-22 01:42:24 -0500246 * This is set to true only if mKeyguardTokenWatcher.acquired() has
247 * actually disabled the keyguard.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 */
Mike Lockwood983ee092009-11-22 01:42:24 -0500249 private boolean mKeyguardDisabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
Jim Miller284b62e2010-06-08 14:27:42 -0700251 private static final int ALLOW_DISABLE_YES = 1;
252 private static final int ALLOW_DISABLE_NO = 0;
253 private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
254 private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
255
Mike Lockwood983ee092009-11-22 01:42:24 -0500256 final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
257 new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 public void acquired() {
Jim Miller284b62e2010-06-08 14:27:42 -0700259 if (shouldAllowDisableKeyguard()) {
260 mPolicy.enableKeyguard(false);
261 mKeyguardDisabled = true;
262 } else {
263 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 }
266 public void released() {
Dianne Hackborna33e3f72009-09-29 17:28:24 -0700267 mPolicy.enableKeyguard(true);
Mike Lockwood983ee092009-11-22 01:42:24 -0500268 synchronized (mKeyguardTokenWatcher) {
269 mKeyguardDisabled = false;
270 mKeyguardTokenWatcher.notifyAll();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 }
272 }
273 };
274
Jim Miller284b62e2010-06-08 14:27:42 -0700275 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
276 @Override
277 public void onReceive(Context context, Intent intent) {
278 mPolicy.enableKeyguard(true);
279 synchronized(mKeyguardTokenWatcher) {
280 // lazily evaluate this next time we're asked to disable keyguard
281 mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
282 mKeyguardDisabled = false;
283 }
284 }
285 };
286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 final Context mContext;
288
289 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
294
295 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 /**
300 * All currently active sessions with clients.
301 */
302 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 /**
305 * Mapping from an IWindow IBinder to the server's Window object.
306 * This is also used as the lock for all of our state.
307 */
308 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
309
310 /**
311 * Mapping from a token IBinder to a WindowToken object.
312 */
313 final HashMap<IBinder, WindowToken> mTokenMap =
314 new HashMap<IBinder, WindowToken>();
315
316 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 * Window tokens that are in the process of exiting, but still
318 * on screen for animations.
319 */
320 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
321
322 /**
323 * Z-ordered (bottom-most first) list of all application tokens, for
324 * controlling the ordering of windows in different applications. This
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800325 * contains AppWindowToken objects.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 */
327 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
328
329 /**
330 * Application tokens that are in the process of exiting, but still
331 * on screen for animations.
332 */
333 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
334
335 /**
336 * List of window tokens that have finished starting their application,
337 * and now need to have the policy remove their windows.
338 */
339 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
340
341 /**
342 * Z-ordered (bottom-most first) list of all Window objects.
343 */
Jeff Browne33348b2010-07-15 23:54:05 -0700344 final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345
346 /**
347 * Windows that are being resized. Used so we can tell the client about
348 * the resize after closing the transaction in which we resized the
349 * underlying surface.
350 */
351 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
352
353 /**
354 * Windows whose animations have ended and now must be removed.
355 */
356 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
357
358 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800359 * Used when processing mPendingRemove to avoid working on the original array.
360 */
361 WindowState[] mPendingRemoveTmp = new WindowState[20];
362
363 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 * Windows whose surface should be destroyed.
365 */
366 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
367
368 /**
369 * Windows that have lost input focus and are waiting for the new
370 * focus window to be displayed before they are told about this.
371 */
372 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
373
374 /**
375 * This is set when we have run out of memory, and will either be an empty
376 * list or contain windows that need to be force removed.
377 */
378 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700379
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800380 /**
381 * Used when rebuilding window list to keep track of windows that have
382 * been removed.
383 */
384 WindowState[] mRebuildTmp = new WindowState[20];
385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 SurfaceSession mFxSession;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700389 private DimAnimator mDimAnimator = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 Surface mBlurSurface;
391 boolean mBlurShown;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700392 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800393 StrictModeFlash mStrictModeFlash;
Dianne Hackborna1111872010-11-23 20:55:11 -0800394 ScreenRotationAnimation mScreenRotationAnimation;
Romain Guy06882f82009-06-10 13:36:04 -0700395
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700396 BlackFrame mBlackFrame;
397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 int mTransactionSequence = 0;
Romain Guy06882f82009-06-10 13:36:04 -0700399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 final float[] mTmpFloats = new float[9];
401
402 boolean mSafeMode;
403 boolean mDisplayEnabled = false;
404 boolean mSystemBooted = false;
Christopher Tateb696aee2010-04-02 19:08:30 -0700405 int mInitialDisplayWidth = 0;
406 int mInitialDisplayHeight = 0;
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700407 int mBaseDisplayWidth = 0;
408 int mBaseDisplayHeight = 0;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -0700409 int mCurDisplayWidth = 0;
410 int mCurDisplayHeight = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 int mRotation = 0;
412 int mRequestedRotation = 0;
413 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700414 boolean mAltOrientation = false;
Dianne Hackborn321ae682009-03-27 16:16:03 -0700415 int mLastRotationFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 ArrayList<IRotationWatcher> mRotationWatchers
417 = new ArrayList<IRotationWatcher>();
Dianne Hackborn89ba6752011-01-23 16:51:16 -0800418 int mDeferredRotation;
419 int mDeferredRotationAnimFlags;
Romain Guy06882f82009-06-10 13:36:04 -0700420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 boolean mLayoutNeeded = true;
422 boolean mAnimationPending = false;
423 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800424 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 boolean mWindowsFreezingScreen = false;
426 long mFreezeGcPending = 0;
427 int mAppsFreezingScreen = 0;
428
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800429 int mLayoutSeq = 0;
430
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800431 // State while inside of layoutAndPlaceSurfacesLocked().
432 boolean mFocusMayChange;
433
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800434 Configuration mCurConfiguration = new Configuration();
435
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 // This is held as long as we have the screen frozen, to give us time to
437 // perform a rotation animation when turning off shows the lock screen which
438 // changes the orientation.
439 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 // State management of app transitions. When we are preparing for a
442 // transition, mNextAppTransition will be the kind of transition to
443 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
444 // mOpeningApps and mClosingApps are the lists of tokens that will be
445 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700446 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700447 String mNextAppTransitionPackage;
448 int mNextAppTransitionEnter;
449 int mNextAppTransitionExit;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700451 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 boolean mAppTransitionTimeout = false;
453 boolean mStartingIconInTransition = false;
454 boolean mSkipAppTransitionAnimation = false;
455 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
456 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Dianne Hackborna8f60182009-09-01 19:01:50 -0700457 final ArrayList<AppWindowToken> mToTopApps = new ArrayList<AppWindowToken>();
458 final ArrayList<AppWindowToken> mToBottomApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 Display mDisplay;
Romain Guy06882f82009-06-10 13:36:04 -0700461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 H mH = new H();
463
464 WindowState mCurrentFocus = null;
465 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 // This just indicates the window the input method is on top of, not
468 // necessarily the window its input is going to.
469 WindowState mInputMethodTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 boolean mInputMethodTargetWaitingAnim;
471 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 WindowState mInputMethodWindow = null;
474 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
475
Jeff Brown2992ea72011-01-28 22:04:14 -0800476 boolean mHardKeyboardAvailable;
477 boolean mHardKeyboardEnabled;
478 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
479
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700480 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800481
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700482 // If non-null, this is the currently visible window that is associated
483 // with the wallpaper.
484 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700485 // If non-null, we are in the middle of animating from one wallpaper target
486 // to another, and this is the lower one in Z-order.
487 WindowState mLowerWallpaperTarget = null;
488 // If non-null, we are in the middle of animating from one wallpaper target
489 // to another, and this is the higher one in Z-order.
490 WindowState mUpperWallpaperTarget = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -0800491 // Window currently running an animation that has requested it be detached
492 // from the wallpaper. This means we need to ensure the wallpaper is
493 // visible behind it in case it animates in a way that would allow it to be
494 // seen.
495 WindowState mWindowDetachedWallpaper = null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800496 DimSurface mWindowAnimationBackgroundSurface = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700497 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700498 float mLastWallpaperX = -1;
499 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800500 float mLastWallpaperXStep = -1;
501 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700502 // This is set when we are waiting for a wallpaper to tell us it is done
503 // changing its scroll position.
504 WindowState mWaitingOnWallpaper;
505 // The last time we had a timeout when waiting for a wallpaper.
506 long mLastWallpaperTimeoutTime;
507 // We give a wallpaper up to 150ms to finish scrolling.
508 static final long WALLPAPER_TIMEOUT = 150;
509 // Time we wait after a timeout before trying to wait again.
510 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 AppWindowToken mFocusedApp = null;
513
514 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 float mWindowAnimationScale = 1.0f;
517 float mTransitionAnimationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700518
Jeff Brown46b9ac02010-04-22 18:58:52 -0700519 final InputManager mInputManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520
521 // Who is holding the screen on.
522 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700523 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700524
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700525 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800526
Christopher Tatea53146c2010-09-07 11:57:52 -0700527 DragState mDragState = null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800528 final InputHandler mDragInputHandler = new BaseInputHandler() {
Christopher Tatea53146c2010-09-07 11:57:52 -0700529 @Override
Jeff Brown3915bb82010-11-05 15:02:16 -0700530 public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
531 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700532 try {
Jeff Brown3915bb82010-11-05 15:02:16 -0700533 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
534 && mDragState != null) {
535 boolean endDrag = false;
536 final float newX = event.getRawX();
537 final float newY = event.getRawY();
538
Christopher Tatea53146c2010-09-07 11:57:52 -0700539 switch (event.getAction()) {
540 case MotionEvent.ACTION_DOWN: {
541 if (DEBUG_DRAG) {
542 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
543 }
544 } break;
545
546 case MotionEvent.ACTION_MOVE: {
547 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700548 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700549 mDragState.notifyMoveLw(newX, newY);
550 }
551 } break;
552
553 case MotionEvent.ACTION_UP: {
554 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
555 + newX + "," + newY);
556 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700557 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700558 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700559 } break;
560
561 case MotionEvent.ACTION_CANCEL: {
562 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
563 endDrag = true;
564 } break;
565 }
566
567 if (endDrag) {
568 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
569 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700570 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700571 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700572 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700573 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700574
575 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700576 }
577 } catch (Exception e) {
578 Slog.e(TAG, "Exception caught by drag handleMotion", e);
579 } finally {
Jeff Brown3915bb82010-11-05 15:02:16 -0700580 finishedCallback.finished(handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700581 }
582 }
583 };
584
585 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 * Whether the UI is currently running in touch mode (not showing
587 * navigational focus because the user is directly pressing the screen).
588 */
589 boolean mInTouchMode = false;
590
591 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700592 private ArrayList<WindowChangeListener> mWindowChangeListeners =
593 new ArrayList<WindowChangeListener>();
594 private boolean mWindowsChanged = false;
595
596 public interface WindowChangeListener {
597 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700598 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600
Dianne Hackbornc485a602009-03-24 22:39:49 -0700601 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700602
603 // The frame use to limit the size of the app running in compatibility mode.
604 Rect mCompatibleScreenFrame = new Rect();
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400605 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700606 // The surface used to fill the outer rim of the app running in compatibility mode.
607 Surface mBackgroundFillerSurface = null;
Dianne Hackbornac1471a2011-02-03 13:46:06 -0800608 WindowState mBackgroundFillerTarget = null;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 public static WindowManagerService main(Context context,
611 PowerManagerService pm, boolean haveInputMethods) {
612 WMThread thr = new WMThread(context, pm, haveInputMethods);
613 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 synchronized (thr) {
616 while (thr.mService == null) {
617 try {
618 thr.wait();
619 } catch (InterruptedException e) {
620 }
621 }
Jozef BABJAK06e57b52011-01-20 08:09:25 +0100622 return thr.mService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 }
Romain Guy06882f82009-06-10 13:36:04 -0700625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 static class WMThread extends Thread {
627 WindowManagerService mService;
Romain Guy06882f82009-06-10 13:36:04 -0700628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 private final Context mContext;
630 private final PowerManagerService mPM;
631 private final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 public WMThread(Context context, PowerManagerService pm,
634 boolean haveInputMethods) {
635 super("WindowManager");
636 mContext = context;
637 mPM = pm;
638 mHaveInputMethods = haveInputMethods;
639 }
Romain Guy06882f82009-06-10 13:36:04 -0700640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 public void run() {
642 Looper.prepare();
643 WindowManagerService s = new WindowManagerService(mContext, mPM,
644 mHaveInputMethods);
645 android.os.Process.setThreadPriority(
646 android.os.Process.THREAD_PRIORITY_DISPLAY);
Christopher Tate160edb32010-06-30 17:46:30 -0700647 android.os.Process.setCanSelfBackground(false);
Romain Guy06882f82009-06-10 13:36:04 -0700648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 synchronized (this) {
650 mService = s;
651 notifyAll();
652 }
Romain Guy06882f82009-06-10 13:36:04 -0700653
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700654 // For debug builds, log event loop stalls to dropbox for analysis.
655 if (StrictMode.conditionallyEnableDebugLogging()) {
656 Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
657 }
658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 Looper.loop();
660 }
661 }
662
663 static class PolicyThread extends Thread {
664 private final WindowManagerPolicy mPolicy;
665 private final WindowManagerService mService;
666 private final Context mContext;
667 private final PowerManagerService mPM;
668 boolean mRunning = false;
Romain Guy06882f82009-06-10 13:36:04 -0700669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 public PolicyThread(WindowManagerPolicy policy,
671 WindowManagerService service, Context context,
672 PowerManagerService pm) {
673 super("WindowManagerPolicy");
674 mPolicy = policy;
675 mService = service;
676 mContext = context;
677 mPM = pm;
678 }
Romain Guy06882f82009-06-10 13:36:04 -0700679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 public void run() {
681 Looper.prepare();
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800682 WindowManagerPolicyThread.set(this, Looper.myLooper());
683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 //Looper.myLooper().setMessageLogging(new LogPrinter(
Joe Onorato8a9b2202010-02-26 18:56:32 -0800685 // Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 android.os.Process.setThreadPriority(
687 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -0700688 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 mPolicy.init(mContext, mService, mPM);
Romain Guy06882f82009-06-10 13:36:04 -0700690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 synchronized (this) {
692 mRunning = true;
693 notifyAll();
694 }
Romain Guy06882f82009-06-10 13:36:04 -0700695
Brad Fitzpatrickec062f62010-11-03 09:56:54 -0700696 // For debug builds, log event loop stalls to dropbox for analysis.
697 if (StrictMode.conditionallyEnableDebugLogging()) {
698 Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
699 }
700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 Looper.loop();
702 }
703 }
704
705 private WindowManagerService(Context context, PowerManagerService pm,
706 boolean haveInputMethods) {
707 mContext = context;
708 mHaveInputMethods = haveInputMethods;
709 mLimitedAlphaCompositing = context.getResources().getBoolean(
710 com.android.internal.R.bool.config_sf_limitedAlpha);
Romain Guy06882f82009-06-10 13:36:04 -0700711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 mPowerManager = pm;
713 mPowerManager.setPolicy(mPolicy);
714 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
715 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
716 "SCREEN_FROZEN");
717 mScreenFrozenLock.setReferenceCounted(false);
718
719 mActivityManager = ActivityManagerNative.getDefault();
720 mBatteryStats = BatteryStatsService.getService();
721
722 // Get persisted window scale setting
723 mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
724 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
725 mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
726 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
Romain Guy06882f82009-06-10 13:36:04 -0700727
Jim Miller284b62e2010-06-08 14:27:42 -0700728 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
729 IntentFilter filter = new IntentFilter();
730 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
731 mContext.registerReceiver(mBroadcastReceiver, filter);
732
Jeff Brown46b9ac02010-04-22 18:58:52 -0700733 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
734 "KEEP_SCREEN_ON_FLAG");
735 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736
Jeff Browne33348b2010-07-15 23:54:05 -0700737 mInputManager = new InputManager(context, this);
Romain Guy06882f82009-06-10 13:36:04 -0700738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
740 thr.start();
Romain Guy06882f82009-06-10 13:36:04 -0700741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 synchronized (thr) {
743 while (!thr.mRunning) {
744 try {
745 thr.wait();
746 } catch (InterruptedException e) {
747 }
748 }
749 }
Romain Guy06882f82009-06-10 13:36:04 -0700750
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700751 mInputManager.start();
Romain Guy06882f82009-06-10 13:36:04 -0700752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 // Add ourself to the Watchdog monitors.
754 Watchdog.getInstance().addMonitor(this);
755 }
756
757 @Override
758 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
759 throws RemoteException {
760 try {
761 return super.onTransact(code, data, reply, flags);
762 } catch (RuntimeException e) {
763 // The window manager only throws security exceptions, so let's
764 // log all others.
765 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800766 Slog.e(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 }
768 throw e;
769 }
770 }
771
Jeff Browne33348b2010-07-15 23:54:05 -0700772 private void placeWindowAfter(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800774 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 TAG, "Adding window " + window + " at "
776 + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
777 mWindows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700778 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 }
780
Jeff Browne33348b2010-07-15 23:54:05 -0700781 private void placeWindowBefore(WindowState pos, WindowState window) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 final int i = mWindows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800783 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 TAG, "Adding window " + window + " at "
785 + i + " of " + mWindows.size() + " (before " + pos + ")");
786 mWindows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700787 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 }
789
790 //This method finds out the index of a window that has the same app token as
791 //win. used for z ordering the windows in mWindows
792 private int findIdxBasedOnAppTokens(WindowState win) {
793 //use a local variable to cache mWindows
Jeff Browne33348b2010-07-15 23:54:05 -0700794 ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 int jmax = localmWindows.size();
796 if(jmax == 0) {
797 return -1;
798 }
799 for(int j = (jmax-1); j >= 0; j--) {
Jeff Browne33348b2010-07-15 23:54:05 -0700800 WindowState wentry = localmWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 if(wentry.mAppToken == win.mAppToken) {
802 return j;
803 }
804 }
805 return -1;
806 }
Romain Guy06882f82009-06-10 13:36:04 -0700807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
809 final IWindow client = win.mClient;
810 final WindowToken token = win.mToken;
Jeff Browne33348b2010-07-15 23:54:05 -0700811 final ArrayList<WindowState> localmWindows = mWindows;
Romain Guy06882f82009-06-10 13:36:04 -0700812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 final int N = localmWindows.size();
814 final WindowState attached = win.mAttachedWindow;
815 int i;
816 if (attached == null) {
817 int tokenWindowsPos = token.windows.size();
818 if (token.appWindowToken != null) {
819 int index = tokenWindowsPos-1;
820 if (index >= 0) {
821 // If this application has existing windows, we
822 // simply place the new window on top of them... but
823 // keep the starting window on top.
824 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
825 // Base windows go behind everything else.
826 placeWindowBefore(token.windows.get(0), win);
827 tokenWindowsPos = 0;
828 } else {
829 AppWindowToken atoken = win.mAppToken;
830 if (atoken != null &&
831 token.windows.get(index) == atoken.startingWindow) {
832 placeWindowBefore(token.windows.get(index), win);
833 tokenWindowsPos--;
834 } else {
835 int newIdx = findIdxBasedOnAppTokens(win);
836 if(newIdx != -1) {
Romain Guy06882f82009-06-10 13:36:04 -0700837 //there is a window above this one associated with the same
838 //apptoken note that the window could be a floating window
839 //that was created later or a window at the top of the list of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 //windows associated with this token.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800841 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
842 Slog.v(TAG, "Adding window " + win + " at "
843 + (newIdx+1) + " of " + N);
844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 localmWindows.add(newIdx+1, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700846 mWindowsChanged = true;
Romain Guy06882f82009-06-10 13:36:04 -0700847 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 }
849 }
850 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800851 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 TAG, "Figuring out where to add app window "
853 + client.asBinder() + " (token=" + token + ")");
854 // Figure out where the window should go, based on the
855 // order of applications.
856 final int NA = mAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -0700857 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 for (i=NA-1; i>=0; i--) {
859 AppWindowToken t = mAppTokens.get(i);
860 if (t == token) {
861 i--;
862 break;
863 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800864
Dianne Hackborna8f60182009-09-01 19:01:50 -0700865 // We haven't reached the token yet; if this token
866 // is not going to the bottom and has windows, we can
867 // use it as an anchor for when we do reach the token.
868 if (!t.sendingToBottom && t.windows.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 pos = t.windows.get(0);
870 }
871 }
872 // We now know the index into the apps. If we found
873 // an app window above, that gives us the position; else
874 // we need to look some more.
875 if (pos != null) {
876 // Move behind any windows attached to this 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 bottom = atoken.windows.get(0);
882 if (bottom.mSubLayer < 0) {
883 pos = bottom;
884 }
885 }
886 }
887 placeWindowBefore(pos, win);
888 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -0700889 // Continue looking down until we find the first
890 // token that has windows.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 while (i >= 0) {
892 AppWindowToken t = mAppTokens.get(i);
893 final int NW = t.windows.size();
894 if (NW > 0) {
895 pos = t.windows.get(NW-1);
896 break;
897 }
898 i--;
899 }
900 if (pos != null) {
901 // Move in front of any windows attached to this
902 // one.
Jeff Browne33348b2010-07-15 23:54:05 -0700903 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 if (atoken != null) {
905 final int NC = atoken.windows.size();
906 if (NC > 0) {
907 WindowState top = atoken.windows.get(NC-1);
908 if (top.mSubLayer >= 0) {
909 pos = top;
910 }
911 }
912 }
913 placeWindowAfter(pos, win);
914 } else {
915 // Just search for the start of this layer.
916 final int myLayer = win.mBaseLayer;
917 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -0700918 WindowState w = localmWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 if (w.mBaseLayer > myLayer) {
920 break;
921 }
922 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800923 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
924 Slog.v(TAG, "Adding window " + win + " at "
925 + i + " of " + N);
926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700928 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 }
930 }
931 }
932 } else {
933 // Figure out where window should go, based on layer.
934 final int myLayer = win.mBaseLayer;
935 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -0700936 if (localmWindows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 i++;
938 break;
939 }
940 }
941 if (i < 0) i = 0;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800942 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700943 TAG, "Adding window " + win + " at "
944 + i + " of " + N);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 localmWindows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700946 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 }
948 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800949 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 token.windows.add(tokenWindowsPos, win);
951 }
952
953 } else {
954 // Figure out this window's ordering relative to the window
955 // it is attached to.
956 final int NA = token.windows.size();
957 final int sublayer = win.mSubLayer;
958 int largestSublayer = Integer.MIN_VALUE;
959 WindowState windowWithLargestSublayer = null;
960 for (i=0; i<NA; i++) {
961 WindowState w = token.windows.get(i);
962 final int wSublayer = w.mSubLayer;
963 if (wSublayer >= largestSublayer) {
964 largestSublayer = wSublayer;
965 windowWithLargestSublayer = w;
966 }
967 if (sublayer < 0) {
968 // For negative sublayers, we go below all windows
969 // in the same sublayer.
970 if (wSublayer >= sublayer) {
971 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800972 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 token.windows.add(i, win);
974 }
975 placeWindowBefore(
976 wSublayer >= 0 ? attached : w, win);
977 break;
978 }
979 } else {
980 // For positive sublayers, we go above all windows
981 // in the same sublayer.
982 if (wSublayer > sublayer) {
983 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800984 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 token.windows.add(i, win);
986 }
987 placeWindowBefore(w, win);
988 break;
989 }
990 }
991 }
992 if (i >= NA) {
993 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800994 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 token.windows.add(win);
996 }
997 if (sublayer < 0) {
998 placeWindowBefore(attached, win);
999 } else {
1000 placeWindowAfter(largestSublayer >= 0
1001 ? windowWithLargestSublayer
1002 : attached,
1003 win);
1004 }
1005 }
1006 }
Romain Guy06882f82009-06-10 13:36:04 -07001007
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 if (win.mAppToken != null && addToToken) {
1009 win.mAppToken.allAppWindows.add(win);
1010 }
1011 }
Romain Guy06882f82009-06-10 13:36:04 -07001012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 static boolean canBeImeTarget(WindowState w) {
1014 final int fl = w.mAttrs.flags
1015 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001016 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
1017 || w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
1018 if (DEBUG_INPUT_METHOD) {
1019 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1020 if (!w.isVisibleOrAdding()) {
1021 Slog.i(TAG, " mSurface=" + w.mSurface + " reportDestroy=" + w.mReportDestroySurface
1022 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
1023 + " policyVis=" + w.mPolicyVisibility + " attachHid=" + w.mAttachedHidden
1024 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1025 if (w.mAppToken != null) {
1026 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1027 }
1028 }
1029 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 return w.isVisibleOrAdding();
1031 }
1032 return false;
1033 }
Romain Guy06882f82009-06-10 13:36:04 -07001034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Jeff Browne33348b2010-07-15 23:54:05 -07001036 final ArrayList<WindowState> localmWindows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 final int N = localmWindows.size();
1038 WindowState w = null;
1039 int i = N;
1040 while (i > 0) {
1041 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001042 w = localmWindows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001043
Dianne Hackborne75d8722011-01-27 19:37:40 -08001044 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1045 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001047 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 // Yet more tricksyness! If this window is a "starting"
1050 // window, we do actually want to be on top of it, but
1051 // it is not -really- where input will go. So if the caller
1052 // is not actually looking to move the IME, look down below
1053 // for a real window to target...
1054 if (!willMove
1055 && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1056 && i > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001057 WindowState wb = localmWindows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1059 i--;
1060 w = wb;
1061 }
1062 }
1063 break;
1064 }
1065 }
Romain Guy06882f82009-06-10 13:36:04 -07001066
Dianne Hackborne75d8722011-01-27 19:37:40 -08001067 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
1068
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001069 // Now, a special case -- if the last target's window is in the
1070 // process of exiting, and is above the new target, keep on the
1071 // last target to avoid flicker. Consider for example a Dialog with
1072 // the IME shown: when the Dialog is dismissed, we want to keep
1073 // the IME above it until it is completely gone so it doesn't drop
1074 // behind the dialog or its full-screen scrim.
1075 if (mInputMethodTarget != null && w != null
1076 && mInputMethodTarget.isDisplayedLw()
1077 && mInputMethodTarget.mExiting) {
1078 if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
1079 w = mInputMethodTarget;
1080 i = localmWindows.indexOf(w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001081 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001082 }
1083 }
Romain Guy06882f82009-06-10 13:36:04 -07001084
Joe Onorato8a9b2202010-02-26 18:56:32 -08001085 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 if (willMove && w != null) {
1089 final WindowState curTarget = mInputMethodTarget;
1090 if (curTarget != null && curTarget.mAppToken != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 // Now some fun for dealing with window animations that
1093 // modify the Z order. We need to look at all windows below
1094 // the current target that are in this app, finding the highest
1095 // visible one in layering.
1096 AppWindowToken token = curTarget.mAppToken;
1097 WindowState highestTarget = null;
1098 int highestPos = 0;
1099 if (token.animating || token.animation != null) {
1100 int pos = 0;
1101 pos = localmWindows.indexOf(curTarget);
1102 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001103 WindowState win = localmWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 if (win.mAppToken != token) {
1105 break;
1106 }
1107 if (!win.mRemoved) {
1108 if (highestTarget == null || win.mAnimLayer >
1109 highestTarget.mAnimLayer) {
1110 highestTarget = win;
1111 highestPos = pos;
1112 }
1113 }
1114 pos--;
1115 }
1116 }
Romain Guy06882f82009-06-10 13:36:04 -07001117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001119 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 + mNextAppTransition + " " + highestTarget
1121 + " animating=" + highestTarget.isAnimating()
1122 + " layer=" + highestTarget.mAnimLayer
1123 + " new layer=" + w.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001124
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001125 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 // If we are currently setting up for an animation,
1127 // hold everything until we can find out what will happen.
1128 mInputMethodTargetWaitingAnim = true;
1129 mInputMethodTarget = highestTarget;
1130 return highestPos + 1;
1131 } else if (highestTarget.isAnimating() &&
1132 highestTarget.mAnimLayer > w.mAnimLayer) {
1133 // If the window we are currently targeting is involved
1134 // with an animation, and it is on top of the next target
1135 // we will be over, then hold off on moving until
1136 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001137 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 mInputMethodTarget = highestTarget;
1139 return highestPos + 1;
1140 }
1141 }
1142 }
1143 }
Romain Guy06882f82009-06-10 13:36:04 -07001144
Joe Onorato8a9b2202010-02-26 18:56:32 -08001145 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 if (w != null) {
1147 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001148 if (DEBUG_INPUT_METHOD) {
1149 RuntimeException e = null;
1150 if (!HIDE_STACK_CRAWLS) {
1151 e = new RuntimeException();
1152 e.fillInStackTrace();
1153 }
1154 Slog.w(TAG, "Moving IM target from "
1155 + mInputMethodTarget + " to " + w, e);
1156 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001158 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001159 if (w.mAppToken != null) {
1160 setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
1161 } else {
1162 setInputMethodAnimLayerAdjustment(0);
1163 }
1164 }
1165 return i+1;
1166 }
1167 if (willMove) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08001168 if (DEBUG_INPUT_METHOD) {
1169 RuntimeException e = null;
1170 if (!HIDE_STACK_CRAWLS) {
1171 e = new RuntimeException();
1172 e.fillInStackTrace();
1173 }
1174 Slog.w(TAG, "Moving IM target from "
1175 + mInputMethodTarget + " to null", e);
1176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 mInputMethodTarget = null;
1178 setInputMethodAnimLayerAdjustment(0);
1179 }
1180 return -1;
1181 }
Romain Guy06882f82009-06-10 13:36:04 -07001182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 void addInputMethodWindowToListLocked(WindowState win) {
1184 int pos = findDesiredInputMethodWindowIndexLocked(true);
1185 if (pos >= 0) {
1186 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001187 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001188 TAG, "Adding input method window " + win + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 mWindows.add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001190 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 moveInputMethodDialogsLocked(pos+1);
1192 return;
1193 }
1194 win.mTargetAppToken = null;
1195 addWindowToListInOrderLocked(win, true);
1196 moveInputMethodDialogsLocked(pos);
1197 }
Romain Guy06882f82009-06-10 13:36:04 -07001198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001200 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 mInputMethodAnimLayerAdjustment = adj;
1202 WindowState imw = mInputMethodWindow;
1203 if (imw != null) {
1204 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001205 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001206 + " anim layer: " + imw.mAnimLayer);
1207 int wi = imw.mChildWindows.size();
1208 while (wi > 0) {
1209 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001210 WindowState cw = imw.mChildWindows.get(wi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 cw.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001212 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 + " anim layer: " + cw.mAnimLayer);
1214 }
1215 }
1216 int di = mInputMethodDialogs.size();
1217 while (di > 0) {
1218 di --;
1219 imw = mInputMethodDialogs.get(di);
1220 imw.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001221 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 + " anim layer: " + imw.mAnimLayer);
1223 }
1224 }
Romain Guy06882f82009-06-10 13:36:04 -07001225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1227 int wpos = mWindows.indexOf(win);
1228 if (wpos >= 0) {
1229 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001230 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001232 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 int NC = win.mChildWindows.size();
1234 while (NC > 0) {
1235 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001236 WindowState cw = win.mChildWindows.get(NC);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 int cpos = mWindows.indexOf(cw);
1238 if (cpos >= 0) {
1239 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001240 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001241 + cpos + ": " + cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001242 mWindows.remove(cpos);
1243 }
1244 }
1245 }
1246 return interestingPos;
1247 }
Romain Guy06882f82009-06-10 13:36:04 -07001248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 private void reAddWindowToListInOrderLocked(WindowState win) {
1250 addWindowToListInOrderLocked(win, false);
1251 // This is a hack to get all of the child windows added as well
1252 // at the right position. Child windows should be rare and
1253 // this case should be rare, so it shouldn't be that big a deal.
1254 int wpos = mWindows.indexOf(win);
1255 if (wpos >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001256 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001257 + ": " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 mWindows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001259 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 reAddWindowLocked(wpos, win);
1261 }
1262 }
Romain Guy06882f82009-06-10 13:36:04 -07001263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 void logWindowList(String prefix) {
1265 int N = mWindows.size();
1266 while (N > 0) {
1267 N--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001268 Slog.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 }
1270 }
Romain Guy06882f82009-06-10 13:36:04 -07001271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 void moveInputMethodDialogsLocked(int pos) {
1273 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001276 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 for (int i=0; i<N; i++) {
1278 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1279 }
1280 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001281 Slog.v(TAG, "Window list w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 logWindowList(" ");
1283 }
Romain Guy06882f82009-06-10 13:36:04 -07001284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 if (pos >= 0) {
1286 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1287 if (pos < mWindows.size()) {
Jeff Browne33348b2010-07-15 23:54:05 -07001288 WindowState wp = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 if (wp == mInputMethodWindow) {
1290 pos++;
1291 }
1292 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001293 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 for (int i=0; i<N; i++) {
1295 WindowState win = dialogs.get(i);
1296 win.mTargetAppToken = targetAppToken;
1297 pos = reAddWindowLocked(pos, win);
1298 }
1299 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001300 Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 logWindowList(" ");
1302 }
1303 return;
1304 }
1305 for (int i=0; i<N; i++) {
1306 WindowState win = dialogs.get(i);
1307 win.mTargetAppToken = null;
1308 reAddWindowToListInOrderLocked(win);
1309 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001310 Slog.v(TAG, "No IM target, final list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 logWindowList(" ");
1312 }
1313 }
1314 }
Romain Guy06882f82009-06-10 13:36:04 -07001315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1317 final WindowState imWin = mInputMethodWindow;
1318 final int DN = mInputMethodDialogs.size();
1319 if (imWin == null && DN == 0) {
1320 return false;
1321 }
Romain Guy06882f82009-06-10 13:36:04 -07001322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1324 if (imPos >= 0) {
1325 // In this case, the input method windows are to be placed
1326 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 // First check to see if the input method windows are already
1329 // located here, and contiguous.
1330 final int N = mWindows.size();
1331 WindowState firstImWin = imPos < N
Jeff Browne33348b2010-07-15 23:54:05 -07001332 ? mWindows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 // Figure out the actual input method window that should be
1335 // at the bottom of their stack.
1336 WindowState baseImWin = imWin != null
1337 ? imWin : mInputMethodDialogs.get(0);
1338 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001339 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 if (cw.mSubLayer < 0) baseImWin = cw;
1341 }
Romain Guy06882f82009-06-10 13:36:04 -07001342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 if (firstImWin == baseImWin) {
1344 // The windows haven't moved... but are they still contiguous?
1345 // First find the top IM window.
1346 int pos = imPos+1;
1347 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001348 if (!(mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 break;
1350 }
1351 pos++;
1352 }
1353 pos++;
1354 // Now there should be no more input method windows above.
1355 while (pos < N) {
Jeff Browne33348b2010-07-15 23:54:05 -07001356 if ((mWindows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 break;
1358 }
1359 pos++;
1360 }
1361 if (pos >= N) {
1362 // All is good!
1363 return false;
1364 }
1365 }
Romain Guy06882f82009-06-10 13:36:04 -07001366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 if (imWin != null) {
1368 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001369 Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 logWindowList(" ");
1371 }
1372 imPos = tmpRemoveWindowLocked(imPos, imWin);
1373 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001374 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 logWindowList(" ");
1376 }
1377 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1378 reAddWindowLocked(imPos, imWin);
1379 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001380 Slog.v(TAG, "List after moving IM to " + imPos + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 logWindowList(" ");
1382 }
1383 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1384 } else {
1385 moveInputMethodDialogsLocked(imPos);
1386 }
Romain Guy06882f82009-06-10 13:36:04 -07001387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 } else {
1389 // In this case, the input method windows go in a fixed layer,
1390 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001393 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 tmpRemoveWindowLocked(0, imWin);
1395 imWin.mTargetAppToken = null;
1396 reAddWindowToListInOrderLocked(imWin);
1397 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001398 Slog.v(TAG, "List with no IM target:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 logWindowList(" ");
1400 }
1401 if (DN > 0) moveInputMethodDialogsLocked(-1);;
1402 } else {
1403 moveInputMethodDialogsLocked(-1);;
1404 }
Romain Guy06882f82009-06-10 13:36:04 -07001405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
Romain Guy06882f82009-06-10 13:36:04 -07001407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 if (needAssignLayers) {
1409 assignLayersLocked();
1410 }
Romain Guy06882f82009-06-10 13:36:04 -07001411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 return true;
1413 }
Romain Guy06882f82009-06-10 13:36:04 -07001414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 void adjustInputMethodDialogsLocked() {
1416 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1417 }
Romain Guy06882f82009-06-10 13:36:04 -07001418
Dianne Hackborn25994b42009-09-04 14:21:19 -07001419 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001420 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001421 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1422 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1423 ? wallpaperTarget.mAppToken.animation : null)
1424 + " upper=" + mUpperWallpaperTarget
1425 + " lower=" + mLowerWallpaperTarget);
1426 return (wallpaperTarget != null
1427 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1428 && wallpaperTarget.mAppToken.animation != null)))
1429 || mUpperWallpaperTarget != null
1430 || mLowerWallpaperTarget != null;
1431 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001432
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001433 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1434 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001435
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001436 int adjustWallpaperWindowsLocked() {
1437 int changed = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001438
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001439 final int dw = mCurDisplayWidth;
1440 final int dh = mCurDisplayHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001441
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001442 // First find top-most window that has asked to be on top of the
1443 // wallpaper; all wallpapers go behind it.
Jeff Browne33348b2010-07-15 23:54:05 -07001444 final ArrayList<WindowState> localmWindows = mWindows;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001445 int N = localmWindows.size();
1446 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001447 WindowState foundW = null;
1448 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001449 WindowState topCurW = null;
1450 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001451 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001452 int i = N;
1453 while (i > 0) {
1454 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07001455 w = localmWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001456 if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
1457 if (topCurW == null) {
1458 topCurW = w;
1459 topCurI = i;
1460 }
1461 continue;
1462 }
1463 topCurW = null;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001464 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001465 // If this window's app token is hidden and not animating,
1466 // it is of no interest to us.
1467 if (w.mAppToken.hidden && w.mAppToken.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001468 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001469 "Skipping not hidden or animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001470 continue;
1471 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001472 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001473 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": readyfordisplay="
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001474 + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
1475 + " commitdrawpending=" + w.mCommitDrawPending);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001476 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07001477 && (mWallpaperTarget == w
1478 || (!w.mDrawPending && !w.mCommitDrawPending))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001479 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001480 "Found wallpaper activity: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001481 foundW = w;
1482 foundI = i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001483 if (w == mWallpaperTarget && ((w.mAppToken != null
1484 && w.mAppToken.animation != null)
1485 || w.mAnimation != null)) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001486 // The current wallpaper target is animating, so we'll
1487 // look behind it for another possible target and figure
1488 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001489 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001490 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001491 continue;
1492 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001493 break;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001494 } else if (w == mWindowDetachedWallpaper) {
1495 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001496 }
1497 }
1498
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001499 if (foundW == null && windowDetachedI >= 0) {
1500 if (DEBUG_WALLPAPER) Slog.v(TAG,
1501 "Found animating detached wallpaper activity: #" + i + "=" + w);
1502 foundW = w;
1503 foundI = windowDetachedI;
1504 }
1505
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001506 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001507 // If we are currently waiting for an app transition, and either
1508 // the current target or the next target are involved with it,
1509 // then hold off on doing anything with the wallpaper.
1510 // Note that we are checking here for just whether the target
1511 // is part of an app token... which is potentially overly aggressive
1512 // (the app token may not be involved in the transition), but good
1513 // enough (we'll just wait until whatever transition is pending
1514 // executes).
1515 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001516 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001517 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001518 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001519 }
1520 if (foundW != null && foundW.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001521 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001522 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001523 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001524 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001525 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001526
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001527 if (mWallpaperTarget != foundW) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001528 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001529 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001530 + " oldTarget: " + mWallpaperTarget);
1531 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001532
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001533 mLowerWallpaperTarget = null;
1534 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001535
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001536 WindowState oldW = mWallpaperTarget;
1537 mWallpaperTarget = foundW;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001538
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001539 // Now what is happening... if the current and new targets are
1540 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001541 if (foundW != null && oldW != null) {
1542 boolean oldAnim = oldW.mAnimation != null
1543 || (oldW.mAppToken != null && oldW.mAppToken.animation != null);
1544 boolean foundAnim = foundW.mAnimation != null
1545 || (foundW.mAppToken != null && foundW.mAppToken.animation != null);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001546 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001547 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001548 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001549 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001550 if (foundAnim && oldAnim) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001551 int oldI = localmWindows.indexOf(oldW);
1552 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001553 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001554 }
1555 if (oldI >= 0) {
1556 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001557 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001558 + "=" + oldW + "; new#" + foundI
1559 + "=" + foundW);
1560 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001561
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001562 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001563 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001564 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001565 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001566 }
1567 mWallpaperTarget = oldW;
1568 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001569
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001570 // Now set the upper and lower wallpaper targets
1571 // correctly, and make sure that we are positioning
1572 // the wallpaper below the lower.
1573 if (foundI > oldI) {
1574 // The new target is on top of the old one.
1575 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001576 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001577 }
1578 mUpperWallpaperTarget = foundW;
1579 mLowerWallpaperTarget = oldW;
1580 foundW = oldW;
1581 foundI = oldI;
1582 } else {
1583 // The new target is below the old one.
1584 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001585 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001586 }
1587 mUpperWallpaperTarget = oldW;
1588 mLowerWallpaperTarget = foundW;
1589 }
1590 }
1591 }
1592 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001593
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001594 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001595 // Is it time to stop animating?
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001596 boolean lowerAnimating = mLowerWallpaperTarget.mAnimation != null
1597 || (mLowerWallpaperTarget.mAppToken != null
1598 && mLowerWallpaperTarget.mAppToken.animation != null);
1599 boolean upperAnimating = mUpperWallpaperTarget.mAnimation != null
1600 || (mUpperWallpaperTarget.mAppToken != null
1601 && mUpperWallpaperTarget.mAppToken.animation != null);
1602 if (!lowerAnimating || !upperAnimating) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001603 if (DEBUG_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001604 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001605 }
1606 mLowerWallpaperTarget = null;
1607 mUpperWallpaperTarget = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001608 }
1609 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001610
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001611 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001612 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001613 // The window is visible to the compositor... but is it visible
1614 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001615 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001616 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001617
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001618 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001619 // its layer adjustment. Only do this if we are not transfering
1620 // between two wallpaper targets.
1621 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001622 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001623 ? foundW.mAppToken.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001624
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001625 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1626 * TYPE_LAYER_MULTIPLIER
1627 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001628
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001629 // Now w is the window we are supposed to be behind... but we
1630 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001631 // AND any starting window associated with it, AND below the
1632 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001633 while (foundI > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001634 WindowState wb = localmWindows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001635 if (wb.mBaseLayer < maxLayer &&
1636 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001637 (foundW.mAttachedWindow == null ||
1638 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001639 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001640 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001641 // This window is not related to the previous one in any
1642 // interesting way, so stop here.
1643 break;
1644 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001645 foundW = wb;
1646 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001647 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001648 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001649 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001650 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001651
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001652 if (foundW == null && topCurW != null) {
1653 // There is no wallpaper target, so it goes at the bottom.
1654 // We will assume it is the same place as last time, if known.
1655 foundW = topCurW;
1656 foundI = topCurI+1;
1657 } else {
1658 // Okay i is the position immediately above the wallpaper. Look at
1659 // what is below it for later.
Jeff Browne33348b2010-07-15 23:54:05 -07001660 foundW = foundI > 0 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001661 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001662
Dianne Hackborn284ac932009-08-28 10:34:25 -07001663 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001664 if (mWallpaperTarget.mWallpaperX >= 0) {
1665 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001666 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001667 }
1668 if (mWallpaperTarget.mWallpaperY >= 0) {
1669 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001670 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001671 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001672 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001673
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001674 // Start stepping backwards from here, ensuring that our wallpaper windows
1675 // are correctly placed.
1676 int curTokenIndex = mWallpaperTokens.size();
1677 while (curTokenIndex > 0) {
1678 curTokenIndex--;
1679 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001680 if (token.hidden == visible) {
1681 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1682 token.hidden = !visible;
1683 // Need to do a layout to ensure the wallpaper now has the
1684 // correct size.
1685 mLayoutNeeded = true;
1686 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001687
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001688 int curWallpaperIndex = token.windows.size();
1689 while (curWallpaperIndex > 0) {
1690 curWallpaperIndex--;
1691 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001692
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001693 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001694 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001695 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001696
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001697 // First, make sure the client has the current visibility
1698 // state.
1699 if (wallpaper.mWallpaperVisible != visible) {
1700 wallpaper.mWallpaperVisible = visible;
1701 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001702 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001703 "Setting visibility of wallpaper " + wallpaper
1704 + ": " + visible);
1705 wallpaper.mClient.dispatchAppVisibility(visible);
1706 } catch (RemoteException e) {
1707 }
1708 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001709
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001710 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001711 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001712 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001713
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001714 // First, if this window is at the current index, then all
1715 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001716 if (wallpaper == foundW) {
1717 foundI--;
1718 foundW = foundI > 0
Jeff Browne33348b2010-07-15 23:54:05 -07001719 ? localmWindows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001720 continue;
1721 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001722
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001723 // The window didn't match... the current wallpaper window,
1724 // wherever it is, is in the wrong place, so make sure it is
1725 // not in the list.
1726 int oldIndex = localmWindows.indexOf(wallpaper);
1727 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001728 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001729 + oldIndex + ": " + wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001730 localmWindows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001731 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001732 if (oldIndex < foundI) {
1733 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001734 }
1735 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001736
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001737 // Now stick it in.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001738 if (DEBUG_WALLPAPER || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1739 Slog.v(TAG, "Moving wallpaper " + wallpaper
1740 + " from " + oldIndex + " to " + foundI);
1741 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001742
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001743 localmWindows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001744 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001745 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001746 }
1747 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001748
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001749 return changed;
1750 }
1751
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001752 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001753 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001754 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001755 mWallpaperAnimLayerAdjustment = adj;
1756 int curTokenIndex = mWallpaperTokens.size();
1757 while (curTokenIndex > 0) {
1758 curTokenIndex--;
1759 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1760 int curWallpaperIndex = token.windows.size();
1761 while (curWallpaperIndex > 0) {
1762 curWallpaperIndex--;
1763 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1764 wallpaper.mAnimLayer = wallpaper.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001765 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001766 + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001767 }
1768 }
1769 }
1770
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001771 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1772 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001773 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001774 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001775 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001776 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001777 int availw = wallpaperWin.mScaledFrame.right-wallpaperWin.mScaledFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001778 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1779 changed = wallpaperWin.mXOffset != offset;
1780 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001781 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001782 + wallpaperWin + " x: " + offset);
1783 wallpaperWin.mXOffset = offset;
1784 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001785 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001786 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001787 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001788 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001789 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001790
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001791 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001792 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001793 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1794 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1795 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001796 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001797 + wallpaperWin + " y: " + offset);
1798 changed = true;
1799 wallpaperWin.mYOffset = offset;
1800 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001801 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001802 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001803 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001804 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001805 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001806
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001807 if (rawChanged) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001808 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001809 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001810 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1811 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001812 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001813 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001814 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001815 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001816 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1817 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001818 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001819 if (mWaitingOnWallpaper != null) {
1820 long start = SystemClock.uptimeMillis();
1821 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1822 < start) {
1823 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001824 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001825 "Waiting for offset complete...");
1826 mWindowMap.wait(WALLPAPER_TIMEOUT);
1827 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001828 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001829 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001830 if ((start+WALLPAPER_TIMEOUT)
1831 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001832 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001833 + wallpaperWin);
1834 mLastWallpaperTimeoutTime = start;
1835 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001836 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001837 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001838 }
1839 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001840 } catch (RemoteException e) {
1841 }
1842 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001843
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001844 return changed;
1845 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001846
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001847 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001848 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001849 if (mWaitingOnWallpaper != null &&
1850 mWaitingOnWallpaper.mClient.asBinder() == window) {
1851 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001852 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001853 }
1854 }
1855 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001856
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001857 boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001858 final int dw = mCurDisplayWidth;
1859 final int dh = mCurDisplayHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001860
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001861 boolean changed = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001862
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001863 WindowState target = mWallpaperTarget;
1864 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001865 if (target.mWallpaperX >= 0) {
1866 mLastWallpaperX = target.mWallpaperX;
1867 } else if (changingTarget.mWallpaperX >= 0) {
1868 mLastWallpaperX = changingTarget.mWallpaperX;
1869 }
1870 if (target.mWallpaperY >= 0) {
1871 mLastWallpaperY = target.mWallpaperY;
1872 } else if (changingTarget.mWallpaperY >= 0) {
1873 mLastWallpaperY = changingTarget.mWallpaperY;
1874 }
1875 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001876
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001877 int curTokenIndex = mWallpaperTokens.size();
1878 while (curTokenIndex > 0) {
1879 curTokenIndex--;
1880 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1881 int curWallpaperIndex = token.windows.size();
1882 while (curWallpaperIndex > 0) {
1883 curWallpaperIndex--;
1884 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1885 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
1886 wallpaper.computeShownFrameLocked();
1887 changed = true;
1888 // We only want to be synchronous with one wallpaper.
1889 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001890 }
1891 }
1892 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001893
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001894 return changed;
1895 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001896
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001897 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07001898 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001899 final int dw = mCurDisplayWidth;
1900 final int dh = mCurDisplayHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001901
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001902 int curTokenIndex = mWallpaperTokens.size();
1903 while (curTokenIndex > 0) {
1904 curTokenIndex--;
1905 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001906 if (token.hidden == visible) {
1907 token.hidden = !visible;
1908 // Need to do a layout to ensure the wallpaper now has the
1909 // correct size.
1910 mLayoutNeeded = true;
1911 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001912
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001913 int curWallpaperIndex = token.windows.size();
1914 while (curWallpaperIndex > 0) {
1915 curWallpaperIndex--;
1916 WindowState wallpaper = token.windows.get(curWallpaperIndex);
1917 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001918 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001919 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001920
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001921 if (wallpaper.mWallpaperVisible != visible) {
1922 wallpaper.mWallpaperVisible = visible;
1923 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001924 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07001925 "Updating visibility of wallpaper " + wallpaper
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001926 + ": " + visible);
1927 wallpaper.mClient.dispatchAppVisibility(visible);
1928 } catch (RemoteException e) {
1929 }
1930 }
1931 }
1932 }
1933 }
Dianne Hackborn90d2db32010-02-11 22:19:06 -08001934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001935 public int addWindow(Session session, IWindow client,
1936 WindowManager.LayoutParams attrs, int viewVisibility,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001937 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001938 int res = mPolicy.checkAddPermission(attrs);
1939 if (res != WindowManagerImpl.ADD_OKAY) {
1940 return res;
1941 }
Romain Guy06882f82009-06-10 13:36:04 -07001942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001943 boolean reportNewConfig = false;
1944 WindowState attachedWindow = null;
1945 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07001946 long origId;
Romain Guy06882f82009-06-10 13:36:04 -07001947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 if (mDisplay == null) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07001950 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001951 }
Romain Guy06882f82009-06-10 13:36:04 -07001952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001954 Slog.w(TAG, "Window " + client + " is already added");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 return WindowManagerImpl.ADD_DUPLICATE_ADD;
1956 }
1957
1958 if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08001959 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001960 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001961 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 + attrs.token + ". Aborting.");
1963 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1964 }
1965 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
1966 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001967 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 + attrs.token + ". Aborting.");
1969 return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
1970 }
1971 }
1972
1973 boolean addToken = false;
1974 WindowToken token = mTokenMap.get(attrs.token);
1975 if (token == null) {
1976 if (attrs.type >= FIRST_APPLICATION_WINDOW
1977 && attrs.type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001978 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 + attrs.token + ". Aborting.");
1980 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1981 }
1982 if (attrs.type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001983 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001984 + attrs.token + ". Aborting.");
1985 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1986 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001987 if (attrs.type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001988 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001989 + attrs.token + ". Aborting.");
1990 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
1991 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001992 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001993 addToken = true;
1994 } else if (attrs.type >= FIRST_APPLICATION_WINDOW
1995 && attrs.type <= LAST_APPLICATION_WINDOW) {
1996 AppWindowToken atoken = token.appWindowToken;
1997 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001998 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 + token + ". Aborting.");
2000 return WindowManagerImpl.ADD_NOT_APP_TOKEN;
2001 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002002 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 + token + ". Aborting.");
2004 return WindowManagerImpl.ADD_APP_EXITING;
2005 }
2006 if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
2007 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002008 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002009 TAG, "**** NO NEED TO START: " + attrs.getTitle());
2010 return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
2011 }
2012 } else if (attrs.type == TYPE_INPUT_METHOD) {
2013 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002014 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 + attrs.token + ". Aborting.");
2016 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2017 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002018 } else if (attrs.type == TYPE_WALLPAPER) {
2019 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002020 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002021 + attrs.token + ". Aborting.");
2022 return WindowManagerImpl.ADD_BAD_APP_TOKEN;
2023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002024 }
2025
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002026 win = new WindowState(this, session, client, token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002027 attachedWindow, attrs, viewVisibility);
2028 if (win.mDeathRecipient == null) {
2029 // Client has apparently died, so there is no reason to
2030 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002031 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002032 + " that is dead, aborting.");
2033 return WindowManagerImpl.ADD_APP_EXITING;
2034 }
2035
2036 mPolicy.adjustWindowParamsLw(win.mAttrs);
Romain Guy06882f82009-06-10 13:36:04 -07002037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 res = mPolicy.prepareAddWindowLw(win, attrs);
2039 if (res != WindowManagerImpl.ADD_OKAY) {
2040 return res;
2041 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002042
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002043 if (outInputChannel != null) {
2044 String name = win.makeInputChannelName();
2045 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2046 win.mInputChannel = inputChannels[0];
2047 inputChannels[1].transferToBinderOutParameter(outInputChannel);
2048
Jeff Brown928e0542011-01-10 11:17:36 -08002049 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051
2052 // From now on, no exceptions or errors allowed!
2053
2054 res = WindowManagerImpl.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002055
Dianne Hackborn5132b372010-07-29 12:51:35 -07002056 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002058 if (addToken) {
2059 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002060 }
2061 win.attach();
2062 mWindowMap.put(client.asBinder(), win);
2063
2064 if (attrs.type == TYPE_APPLICATION_STARTING &&
2065 token.appWindowToken != null) {
2066 token.appWindowToken.startingWindow = win;
2067 }
2068
2069 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002071 if (attrs.type == TYPE_INPUT_METHOD) {
2072 mInputMethodWindow = win;
2073 addInputMethodWindowToListLocked(win);
2074 imMayMove = false;
2075 } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
2076 mInputMethodDialogs.add(win);
2077 addWindowToListInOrderLocked(win, true);
2078 adjustInputMethodDialogsLocked();
2079 imMayMove = false;
2080 } else {
2081 addWindowToListInOrderLocked(win, true);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002082 if (attrs.type == TYPE_WALLPAPER) {
2083 mLastWallpaperTimeoutTime = 0;
2084 adjustWallpaperWindowsLocked();
2085 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002086 adjustWallpaperWindowsLocked();
2087 }
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 win.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002092 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
Romain Guy06882f82009-06-10 13:36:04 -07002093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 if (mInTouchMode) {
2095 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
2096 }
2097 if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
2098 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
2099 }
Romain Guy06882f82009-06-10 13:36:04 -07002100
Jeff Brown2e44b072011-01-24 15:21:56 -08002101 mInputMonitor.setUpdateInputWindowsNeededLw();
2102
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002103 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002104 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002105 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2106 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002107 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108 imMayMove = false;
2109 }
2110 }
Romain Guy06882f82009-06-10 13:36:04 -07002111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002112 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002113 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 }
Romain Guy06882f82009-06-10 13:36:04 -07002115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 assignLayersLocked();
2117 // Don't do layout here, the window must call
2118 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 //dump();
2121
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002122 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002123 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002124 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002125 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002126
Joe Onorato8a9b2202010-02-26 18:56:32 -08002127 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002128 TAG, "New client " + client.asBinder()
2129 + ": window=" + win);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002130
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002131 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002132 reportNewConfig = true;
2133 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002134 }
2135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136 if (reportNewConfig) {
2137 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 return res;
2143 }
Romain Guy06882f82009-06-10 13:36:04 -07002144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 public void removeWindow(Session session, IWindow client) {
2146 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002147 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 if (win == null) {
2149 return;
2150 }
2151 removeWindowLocked(session, win);
2152 }
2153 }
Romain Guy06882f82009-06-10 13:36:04 -07002154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 public void removeWindowLocked(Session session, WindowState win) {
2156
Joe Onorato8a9b2202010-02-26 18:56:32 -08002157 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 TAG, "Remove " + win + " client="
2159 + Integer.toHexString(System.identityHashCode(
2160 win.mClient.asBinder()))
2161 + ", surface=" + win.mSurface);
2162
2163 final long origId = Binder.clearCallingIdentity();
Jeff Brownc5ed5912010-07-14 18:48:53 -07002164
2165 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002166
Joe Onorato8a9b2202010-02-26 18:56:32 -08002167 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002168 TAG, "Remove " + win + ": mSurface=" + win.mSurface
2169 + " mExiting=" + win.mExiting
2170 + " isAnimating=" + win.isAnimating()
2171 + " app-animation="
2172 + (win.mAppToken != null ? win.mAppToken.animation : null)
2173 + " inPendingTransaction="
2174 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2175 + " mDisplayFrozen=" + mDisplayFrozen);
2176 // Visibility of the removed window. Will be used later to update orientation later on.
2177 boolean wasVisible = false;
2178 // First, see if we need to run an animation. If we do, we have
2179 // to hold off on removing the window until the animation is done.
2180 // If the display is frozen, just remove immediately, since the
2181 // animation wouldn't be seen.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002182 if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 // If we are not currently running the exit animation, we
2184 // need to see about starting one.
2185 if (wasVisible=win.isWinVisibleLw()) {
Romain Guy06882f82009-06-10 13:36:04 -07002186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2188 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2189 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2190 }
2191 // Try starting an animation.
2192 if (applyAnimationLocked(win, transit, false)) {
2193 win.mExiting = true;
2194 }
2195 }
2196 if (win.mExiting || win.isAnimating()) {
2197 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002198 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002199 win.mExiting = true;
2200 win.mRemoveOnExit = true;
2201 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002202 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2203 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002204 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002205 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002206 if (win.mAppToken != null) {
2207 win.mAppToken.updateReportedVisibilityLocked();
2208 }
2209 //dump();
2210 Binder.restoreCallingIdentity(origId);
2211 return;
2212 }
2213 }
2214
2215 removeWindowInnerLocked(session, win);
2216 // Removing a visible window will effect the computed orientation
2217 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002218 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002219 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002220 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002221 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002222 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002223 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002224 Binder.restoreCallingIdentity(origId);
2225 }
Romain Guy06882f82009-06-10 13:36:04 -07002226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002227 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002228 if (win.mRemoved) {
2229 // Nothing to do.
2230 return;
2231 }
2232
2233 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2234 WindowState cwin = win.mChildWindows.get(i);
2235 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2236 + win);
2237 removeWindowInnerLocked(cwin.mSession, cwin);
2238 }
2239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 if (mInputMethodTarget == win) {
2243 moveInputMethodWindowsIfNeededLocked(false);
2244 }
Romain Guy06882f82009-06-10 13:36:04 -07002245
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002246 if (false) {
2247 RuntimeException e = new RuntimeException("here");
2248 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002249 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002250 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 mPolicy.removeWindowLw(win);
2253 win.removeLocked();
2254
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002255 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256 mWindowMap.remove(win.mClient.asBinder());
2257 mWindows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002258 mPendingRemove.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002259 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002260 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261
2262 if (mInputMethodWindow == win) {
2263 mInputMethodWindow = null;
2264 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2265 mInputMethodDialogs.remove(win);
2266 }
Romain Guy06882f82009-06-10 13:36:04 -07002267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 final WindowToken token = win.mToken;
2269 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002270 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 token.windows.remove(win);
2272 if (atoken != null) {
2273 atoken.allAppWindows.remove(win);
2274 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002275 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 TAG, "**** Removing window " + win + ": count="
2277 + token.windows.size());
2278 if (token.windows.size() == 0) {
2279 if (!token.explicit) {
2280 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 } else if (atoken != null) {
2282 atoken.firstWindowDrawn = false;
2283 }
2284 }
2285
2286 if (atoken != null) {
2287 if (atoken.startingWindow == win) {
2288 atoken.startingWindow = null;
2289 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2290 // If this is the last window and we had requested a starting
2291 // transition window, well there is no point now.
2292 atoken.startingData = null;
2293 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2294 // If this is the last window except for a starting transition
2295 // window, we need to get rid of the starting transition.
2296 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002297 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 + ": no more real windows");
2299 }
2300 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2301 mH.sendMessage(m);
2302 }
2303 }
Romain Guy06882f82009-06-10 13:36:04 -07002304
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002305 if (win.mAttrs.type == TYPE_WALLPAPER) {
2306 mLastWallpaperTimeoutTime = 0;
2307 adjustWallpaperWindowsLocked();
2308 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002309 adjustWallpaperWindowsLocked();
2310 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 if (!mInLayout) {
2313 assignLayersLocked();
2314 mLayoutNeeded = true;
2315 performLayoutAndPlaceSurfacesLocked();
2316 if (win.mAppToken != null) {
2317 win.mAppToken.updateReportedVisibilityLocked();
2318 }
2319 }
Jeff Brownc5ed5912010-07-14 18:48:53 -07002320
Jeff Brown2e44b072011-01-24 15:21:56 -08002321 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 }
2323
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002324 static void logSurface(WindowState w, String msg, RuntimeException where) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002325 String str = " SURFACE " + Integer.toHexString(w.hashCode())
2326 + ": " + msg + " / " + w.mAttrs.getTitle();
2327 if (where != null) {
2328 Slog.i(TAG, str, where);
2329 } else {
2330 Slog.i(TAG, str);
2331 }
2332 }
2333
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002334 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 long origId = Binder.clearCallingIdentity();
2336 try {
2337 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002338 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002339 if ((w != null) && (w.mSurface != null)) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002340 if (SHOW_TRANSACTIONS) Slog.i(TAG,
2341 ">>> OPEN TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 Surface.openTransaction();
2343 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002344 if (SHOW_TRANSACTIONS) logSurface(w,
2345 "transparentRegionHint=" + region, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 w.mSurface.setTransparentRegionHint(region);
2347 } finally {
2348 Surface.closeTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002349 if (SHOW_TRANSACTIONS) Slog.i(TAG,
2350 "<<< CLOSE TRANSACTION setTransparentRegion");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 }
2352 }
2353 }
2354 } finally {
2355 Binder.restoreCallingIdentity(origId);
2356 }
2357 }
2358
2359 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002360 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002361 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002362 long origId = Binder.clearCallingIdentity();
2363 try {
2364 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002365 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 if (w != null) {
2367 w.mGivenInsetsPending = false;
2368 w.mGivenContentInsets.set(contentInsets);
2369 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002370 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 w.mTouchableInsets = touchableInsets;
2372 mLayoutNeeded = true;
2373 performLayoutAndPlaceSurfacesLocked();
2374 }
2375 }
2376 } finally {
2377 Binder.restoreCallingIdentity(origId);
2378 }
2379 }
Romain Guy06882f82009-06-10 13:36:04 -07002380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 public void getWindowDisplayFrame(Session session, IWindow client,
2382 Rect outDisplayFrame) {
2383 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002384 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 if (win == null) {
2386 outDisplayFrame.setEmpty();
2387 return;
2388 }
2389 outDisplayFrame.set(win.mDisplayFrame);
2390 }
2391 }
2392
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002393 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2394 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002395 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2396 window.mWallpaperX = x;
2397 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002398 window.mWallpaperXStep = xStep;
2399 window.mWallpaperYStep = yStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002400 if (updateWallpaperOffsetLocked(window, true)) {
2401 performLayoutAndPlaceSurfacesLocked();
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002402 }
2403 }
2404 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002405
Dianne Hackborn75804932009-10-20 20:15:20 -07002406 void wallpaperCommandComplete(IBinder window, Bundle result) {
2407 synchronized (mWindowMap) {
2408 if (mWaitingOnWallpaper != null &&
2409 mWaitingOnWallpaper.mClient.asBinder() == window) {
2410 mWaitingOnWallpaper = null;
2411 mWindowMap.notifyAll();
2412 }
2413 }
2414 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002415
Dianne Hackborn75804932009-10-20 20:15:20 -07002416 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2417 String action, int x, int y, int z, Bundle extras, boolean sync) {
2418 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2419 || window == mUpperWallpaperTarget) {
2420 boolean doWait = sync;
2421 int curTokenIndex = mWallpaperTokens.size();
2422 while (curTokenIndex > 0) {
2423 curTokenIndex--;
2424 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2425 int curWallpaperIndex = token.windows.size();
2426 while (curWallpaperIndex > 0) {
2427 curWallpaperIndex--;
2428 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2429 try {
2430 wallpaper.mClient.dispatchWallpaperCommand(action,
2431 x, y, z, extras, sync);
2432 // We only want to be synchronous with one wallpaper.
2433 sync = false;
2434 } catch (RemoteException e) {
2435 }
2436 }
2437 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002438
Dianne Hackborn75804932009-10-20 20:15:20 -07002439 if (doWait) {
2440 // XXX Need to wait for result.
2441 }
2442 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002443
Dianne Hackborn75804932009-10-20 20:15:20 -07002444 return null;
2445 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 public int relayoutWindow(Session session, IWindow client,
2448 WindowManager.LayoutParams attrs, int requestedWidth,
2449 int requestedHeight, int viewVisibility, boolean insetsPending,
2450 Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002451 Configuration outConfig, Surface outSurface) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 boolean displayed = false;
2453 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002454 boolean configChanged;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002455
2456 // if they don't have this permission, mask out the status bar bits
2457 if (attrs != null) {
2458 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2459 != PackageManager.PERMISSION_GRANTED) {
2460 attrs.systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
2461 attrs.subtreeSystemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
2462 }
2463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002464 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002466 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002467 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 if (win == null) {
2469 return 0;
2470 }
2471 win.mRequestedWidth = requestedWidth;
2472 win.mRequestedHeight = requestedHeight;
2473
2474 if (attrs != null) {
2475 mPolicy.adjustWindowParamsLw(attrs);
2476 }
Romain Guy06882f82009-06-10 13:36:04 -07002477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 int attrChanges = 0;
2479 int flagChanges = 0;
2480 if (attrs != null) {
2481 flagChanges = win.mAttrs.flags ^= attrs.flags;
2482 attrChanges = win.mAttrs.copyFrom(attrs);
2483 }
2484
Joe Onorato8a9b2202010-02-26 18:56:32 -08002485 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486
2487 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2488 win.mAlpha = attrs.alpha;
2489 }
2490
2491 final boolean scaledWindow =
2492 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2493
2494 if (scaledWindow) {
2495 // requested{Width|Height} Surface's physical size
2496 // attrs.{width|height} Size on screen
2497 win.mHScale = (attrs.width != requestedWidth) ?
2498 (attrs.width / (float)requestedWidth) : 1.0f;
2499 win.mVScale = (attrs.height != requestedHeight) ?
2500 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002501 } else {
2502 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 }
2504
2505 boolean imMayMove = (flagChanges&(
2506 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
2507 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 boolean focusMayChange = win.mViewVisibility != viewVisibility
2510 || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
2511 || (!win.mRelayoutCalled);
Romain Guy06882f82009-06-10 13:36:04 -07002512
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002513 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2514 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002516 win.mRelayoutCalled = true;
2517 final int oldVisibility = win.mViewVisibility;
2518 win.mViewVisibility = viewVisibility;
2519 if (viewVisibility == View.VISIBLE &&
2520 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2521 displayed = !win.isVisibleLw();
2522 if (win.mExiting) {
2523 win.mExiting = false;
Brad Fitzpatrick3fe38512010-11-03 11:46:54 -07002524 if (win.mAnimation != null) {
2525 win.mAnimation.cancel();
2526 win.mAnimation = null;
2527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002528 }
2529 if (win.mDestroying) {
2530 win.mDestroying = false;
2531 mDestroySurface.remove(win);
2532 }
2533 if (oldVisibility == View.GONE) {
2534 win.mEnterAnimationPending = true;
2535 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002536 if (displayed) {
2537 if (win.mSurface != null && !win.mDrawPending
2538 && !win.mCommitDrawPending && !mDisplayFrozen
2539 && mPolicy.isScreenOn()) {
2540 applyEnterAnimationLocked(win);
2541 }
2542 if ((win.mAttrs.flags
2543 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2544 if (DEBUG_VISIBILITY) Slog.v(TAG,
2545 "Relayout window turning screen on: " + win);
2546 win.mTurnOnScreen = true;
2547 }
2548 int diff = 0;
2549 if (win.mConfiguration != mCurConfiguration
2550 && (win.mConfiguration == null
2551 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
2552 win.mConfiguration = mCurConfiguration;
2553 if (DEBUG_CONFIGURATION) {
2554 Slog.i(TAG, "Window " + win + " visible with new config: "
2555 + win.mConfiguration + " / 0x"
2556 + Integer.toHexString(diff));
2557 }
2558 outConfig.setTo(mCurConfiguration);
2559 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2562 // To change the format, we need to re-build the surface.
2563 win.destroySurfaceLocked();
2564 displayed = true;
2565 }
2566 try {
2567 Surface surface = win.createSurfaceLocked();
2568 if (surface != null) {
2569 outSurface.copyFrom(surface);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002570 win.mReportDestroySurface = false;
2571 win.mSurfacePendingDestroy = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002572 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002573 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002574 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002575 // For some reason there isn't a surface. Clear the
2576 // caller's object so they see the same state.
2577 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 }
2579 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002580 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browne33348b2010-07-15 23:54:05 -07002581
Joe Onorato8a9b2202010-02-26 18:56:32 -08002582 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002583 + client + " (" + win.mAttrs.getTitle() + ")",
2584 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 Binder.restoreCallingIdentity(origId);
2586 return 0;
2587 }
2588 if (displayed) {
2589 focusMayChange = true;
2590 }
2591 if (win.mAttrs.type == TYPE_INPUT_METHOD
2592 && mInputMethodWindow == null) {
2593 mInputMethodWindow = win;
2594 imMayMove = true;
2595 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002596 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2597 && win.mAppToken != null
2598 && win.mAppToken.startingWindow != null) {
2599 // Special handling of starting window over the base
2600 // window of the app: propagate lock screen flags to it,
2601 // to provide the correct semantics while starting.
2602 final int mask =
2603 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002604 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2605 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002606 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2607 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2608 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002609 } else {
2610 win.mEnterAnimationPending = false;
2611 if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002612 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002613 + ": mExiting=" + win.mExiting
2614 + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 // If we are not currently running the exit animation, we
2616 // need to see about starting one.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002617 if (!win.mExiting || win.mSurfacePendingDestroy) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 // Try starting an animation; if there isn't one, we
2619 // can destroy the surface right away.
2620 int transit = WindowManagerPolicy.TRANSIT_EXIT;
2621 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
2622 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2623 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002624 if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 applyAnimationLocked(win, transit, false)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002626 focusMayChange = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 win.mExiting = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 } else if (win.isAnimating()) {
2629 // Currently in a hide animation... turn this into
2630 // an exit.
2631 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002632 } else if (win == mWallpaperTarget) {
2633 // If the wallpaper is currently behind this
2634 // window, we need to change both of them inside
2635 // of a transaction to avoid artifacts.
2636 win.mExiting = true;
2637 win.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 } else {
2639 if (mInputMethodWindow == win) {
2640 mInputMethodWindow = null;
2641 }
2642 win.destroySurfaceLocked();
2643 }
2644 }
2645 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002646
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002647 if (win.mSurface == null || (win.getAttrs().flags
2648 & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
2649 || win.mSurfacePendingDestroy) {
2650 // We are being called from a local process, which
2651 // means outSurface holds its current surface. Ensure the
2652 // surface object is cleared, but we don't want it actually
2653 // destroyed at this point.
2654 win.mSurfacePendingDestroy = false;
2655 outSurface.release();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002656 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002657 } else if (win.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002658 if (DEBUG_VISIBILITY) Slog.i(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002659 "Keeping surface, will report destroy: " + win);
2660 win.mReportDestroySurface = true;
2661 outSurface.copyFrom(win.mSurface);
2662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 }
2664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 if (focusMayChange) {
2666 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002667 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2668 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002669 imMayMove = false;
2670 }
2671 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2672 }
Romain Guy06882f82009-06-10 13:36:04 -07002673
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002674 // updateFocusedWindowLocked() already assigned layers so we only need to
2675 // reassign them at this point if the IM window state gets shuffled
2676 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 if (imMayMove) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002679 if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
2680 // Little hack here -- we -should- be able to rely on the
2681 // function to return true if the IME has moved and needs
2682 // its layer recomputed. However, if the IME was hidden
2683 // and isn't actually moved in the list, its layer may be
2684 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 assignLayers = true;
2686 }
2687 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002688 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002689 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002690 assignLayers = true;
2691 }
2692 }
Romain Guy06882f82009-06-10 13:36:04 -07002693
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 mLayoutNeeded = true;
2695 win.mGivenInsetsPending = insetsPending;
2696 if (assignLayers) {
2697 assignLayersLocked();
2698 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002699 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002700 performLayoutAndPlaceSurfacesLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -07002701 if (displayed && win.mIsWallpaper) {
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07002702 updateWallpaperOffsetLocked(win, mCurDisplayWidth, mCurDisplayHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 if (win.mAppToken != null) {
2705 win.mAppToken.updateReportedVisibilityLocked();
2706 }
2707 outFrame.set(win.mFrame);
2708 outContentInsets.set(win.mContentInsets);
2709 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002710 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002712 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 + ", requestedHeight=" + requestedHeight
2714 + ", viewVisibility=" + viewVisibility
2715 + "\nRelayout returning frame=" + outFrame
2716 + ", surface=" + outSurface);
2717
Joe Onorato8a9b2202010-02-26 18:56:32 -08002718 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
2720
2721 inTouchMode = mInTouchMode;
Jeff Browne33348b2010-07-15 23:54:05 -07002722
Jeff Brown2e44b072011-01-24 15:21:56 -08002723 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 }
2725
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002726 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 sendNewConfiguration();
2728 }
Romain Guy06882f82009-06-10 13:36:04 -07002729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002730 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
2733 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
2734 }
2735
Dianne Hackborn64825172011-03-02 21:32:58 -08002736 public boolean outOfMemoryWindow(Session session, IWindow client) {
2737 long origId = Binder.clearCallingIdentity();
2738
2739 try {
2740 synchronized(mWindowMap) {
2741 WindowState win = windowForClientLocked(session, client, false);
2742 if (win == null) {
2743 return false;
2744 }
2745 return reclaimSomeSurfaceMemoryLocked(win, "from-client", false);
2746 }
2747 } finally {
2748 Binder.restoreCallingIdentity(origId);
2749 }
2750 }
2751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 public void finishDrawingWindow(Session session, IWindow client) {
2753 final long origId = Binder.clearCallingIdentity();
2754 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002755 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 if (win != null && win.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07002757 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2758 adjustWallpaperWindowsLocked();
2759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002760 mLayoutNeeded = true;
2761 performLayoutAndPlaceSurfacesLocked();
2762 }
2763 }
2764 Binder.restoreCallingIdentity(origId);
2765 }
2766
2767 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002768 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 + (lp != null ? lp.packageName : null)
2770 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
2771 if (lp != null && lp.windowAnimations != 0) {
2772 // If this is a system resource, don't try to load it from the
2773 // application resources. It is nice to avoid loading application
2774 // resources if we can.
2775 String packageName = lp.packageName != null ? lp.packageName : "android";
2776 int resId = lp.windowAnimations;
2777 if ((resId&0xFF000000) == 0x01000000) {
2778 packageName = "android";
2779 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002780 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002781 + packageName);
2782 return AttributeCache.instance().get(packageName, resId,
2783 com.android.internal.R.styleable.WindowAnimation);
2784 }
2785 return null;
2786 }
Romain Guy06882f82009-06-10 13:36:04 -07002787
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002788 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08002789 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002790 + packageName + " resId=0x" + Integer.toHexString(resId));
2791 if (packageName != null) {
2792 if ((resId&0xFF000000) == 0x01000000) {
2793 packageName = "android";
2794 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002795 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002796 + packageName);
2797 return AttributeCache.instance().get(packageName, resId,
2798 com.android.internal.R.styleable.WindowAnimation);
2799 }
2800 return null;
2801 }
2802
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002803 void applyEnterAnimationLocked(WindowState win) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 int transit = WindowManagerPolicy.TRANSIT_SHOW;
2805 if (win.mEnterAnimationPending) {
2806 win.mEnterAnimationPending = false;
2807 transit = WindowManagerPolicy.TRANSIT_ENTER;
2808 }
2809
2810 applyAnimationLocked(win, transit, true);
2811 }
2812
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002813 boolean applyAnimationLocked(WindowState win,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 int transit, boolean isEntrance) {
2815 if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
2816 // If we are trying to apply an animation, but already running
2817 // an animation of the same type, then just leave that one alone.
2818 return true;
2819 }
Romain Guy06882f82009-06-10 13:36:04 -07002820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 // Only apply an animation if the display isn't frozen. If it is
2822 // frozen, there is no reason to animate and it can cause strange
2823 // artifacts when we unfreeze the display if some different animation
2824 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002825 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 int anim = mPolicy.selectAnimationLw(win, transit);
2827 int attr = -1;
2828 Animation a = null;
2829 if (anim != 0) {
2830 a = AnimationUtils.loadAnimation(mContext, anim);
2831 } else {
2832 switch (transit) {
2833 case WindowManagerPolicy.TRANSIT_ENTER:
2834 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
2835 break;
2836 case WindowManagerPolicy.TRANSIT_EXIT:
2837 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
2838 break;
2839 case WindowManagerPolicy.TRANSIT_SHOW:
2840 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
2841 break;
2842 case WindowManagerPolicy.TRANSIT_HIDE:
2843 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
2844 break;
2845 }
2846 if (attr >= 0) {
2847 a = loadAnimation(win.mAttrs, attr);
2848 }
2849 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002850 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: win=" + win
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
2852 + " mAnimation=" + win.mAnimation
2853 + " isEntrance=" + isEntrance);
2854 if (a != null) {
2855 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002856 RuntimeException e = null;
2857 if (!HIDE_STACK_CRAWLS) {
2858 e = new RuntimeException();
2859 e.fillInStackTrace();
2860 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002861 Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 }
2863 win.setAnimation(a);
2864 win.mAnimationIsEntrance = isEntrance;
2865 }
2866 } else {
2867 win.clearAnimation();
2868 }
2869
2870 return win.mAnimation != null;
2871 }
2872
2873 private Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
2874 int anim = 0;
2875 Context context = mContext;
2876 if (animAttr >= 0) {
2877 AttributeCache.Entry ent = getCachedAnimations(lp);
2878 if (ent != null) {
2879 context = ent.context;
2880 anim = ent.array.getResourceId(animAttr, 0);
2881 }
2882 }
2883 if (anim != 0) {
2884 return AnimationUtils.loadAnimation(context, anim);
2885 }
2886 return null;
2887 }
Romain Guy06882f82009-06-10 13:36:04 -07002888
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002889 private Animation loadAnimation(String packageName, int resId) {
2890 int anim = 0;
2891 Context context = mContext;
2892 if (resId >= 0) {
2893 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
2894 if (ent != null) {
2895 context = ent.context;
2896 anim = resId;
2897 }
2898 }
2899 if (anim != 0) {
2900 return AnimationUtils.loadAnimation(context, anim);
2901 }
2902 return null;
2903 }
2904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 private boolean applyAnimationLocked(AppWindowToken wtoken,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002906 WindowManager.LayoutParams lp, int transit, boolean enter, boolean bgFiller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002907 // Only apply an animation if the display isn't frozen. If it is
2908 // frozen, there is no reason to animate and it can cause strange
2909 // artifacts when we unfreeze the display if some different animation
2910 // is running.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08002911 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002912 Animation a;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002913 if (bgFiller) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002914 a = new FadeInOutAnimation(enter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002915 if (DEBUG_ANIM) Slog.v(TAG,
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002916 "applying FadeInOutAnimation for a window in compatibility mode");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002917 } else if (mNextAppTransitionPackage != null) {
2918 a = loadAnimation(mNextAppTransitionPackage, enter ?
2919 mNextAppTransitionEnter : mNextAppTransitionExit);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002920 } else {
2921 int animAttr = 0;
2922 switch (transit) {
2923 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
2924 animAttr = enter
2925 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
2926 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
2927 break;
2928 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
2929 animAttr = enter
2930 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
2931 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
2932 break;
2933 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
2934 animAttr = enter
2935 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
2936 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
2937 break;
2938 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
2939 animAttr = enter
2940 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
2941 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
2942 break;
2943 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
2944 animAttr = enter
2945 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
2946 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
2947 break;
2948 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
2949 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07002950 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002951 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
2952 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002953 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002954 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002955 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
2956 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002957 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07002958 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002959 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07002960 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
2961 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
2962 break;
2963 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
2964 animAttr = enter
2965 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
2966 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
2967 break;
2968 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
2969 animAttr = enter
2970 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
2971 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07002972 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002973 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07002974 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002975 if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07002976 + " anim=" + a
2977 + " animAttr=0x" + Integer.toHexString(animAttr)
2978 + " transit=" + transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002980 if (a != null) {
2981 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002982 RuntimeException e = null;
2983 if (!HIDE_STACK_CRAWLS) {
2984 e = new RuntimeException();
2985 e.fillInStackTrace();
2986 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002987 Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 }
2989 wtoken.setAnimation(a);
2990 }
2991 } else {
2992 wtoken.clearAnimation();
2993 }
2994
2995 return wtoken.animation != null;
2996 }
2997
2998 // -------------------------------------------------------------
2999 // Application Window Tokens
3000 // -------------------------------------------------------------
3001
3002 public void validateAppTokens(List tokens) {
3003 int v = tokens.size()-1;
3004 int m = mAppTokens.size()-1;
3005 while (v >= 0 && m >= 0) {
3006 AppWindowToken wtoken = mAppTokens.get(m);
3007 if (wtoken.removed) {
3008 m--;
3009 continue;
3010 }
3011 if (tokens.get(v) != wtoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003012 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013 + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
3014 }
3015 v--;
3016 m--;
3017 }
3018 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003019 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003020 v--;
3021 }
3022 while (m >= 0) {
3023 AppWindowToken wtoken = mAppTokens.get(m);
3024 if (!wtoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003025 Slog.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 }
3027 m--;
3028 }
3029 }
3030
3031 boolean checkCallingPermission(String permission, String func) {
3032 // Quick check: if the calling permission is me, it's all okay.
3033 if (Binder.getCallingPid() == Process.myPid()) {
3034 return true;
3035 }
Romain Guy06882f82009-06-10 13:36:04 -07003036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037 if (mContext.checkCallingPermission(permission)
3038 == PackageManager.PERMISSION_GRANTED) {
3039 return true;
3040 }
3041 String msg = "Permission Denial: " + func + " from pid="
3042 + Binder.getCallingPid()
3043 + ", uid=" + Binder.getCallingUid()
3044 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003045 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003046 return false;
3047 }
Romain Guy06882f82009-06-10 13:36:04 -07003048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 AppWindowToken findAppWindowToken(IBinder token) {
3050 WindowToken wtoken = mTokenMap.get(token);
3051 if (wtoken == null) {
3052 return null;
3053 }
3054 return wtoken.appWindowToken;
3055 }
Romain Guy06882f82009-06-10 13:36:04 -07003056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 public void addWindowToken(IBinder token, int type) {
3058 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3059 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003060 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 }
Romain Guy06882f82009-06-10 13:36:04 -07003062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003063 synchronized(mWindowMap) {
3064 WindowToken wtoken = mTokenMap.get(token);
3065 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003066 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003067 return;
3068 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003069 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003070 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003071 if (type == TYPE_WALLPAPER) {
3072 mWallpaperTokens.add(wtoken);
3073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 }
3075 }
Romain Guy06882f82009-06-10 13:36:04 -07003076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003077 public void removeWindowToken(IBinder token) {
3078 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3079 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003080 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003081 }
3082
3083 final long origId = Binder.clearCallingIdentity();
3084 synchronized(mWindowMap) {
3085 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003086 if (wtoken != null) {
3087 boolean delayed = false;
3088 if (!wtoken.hidden) {
3089 wtoken.hidden = true;
Romain Guy06882f82009-06-10 13:36:04 -07003090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 final int N = wtoken.windows.size();
3092 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 for (int i=0; i<N; i++) {
3095 WindowState win = wtoken.windows.get(i);
3096
3097 if (win.isAnimating()) {
3098 delayed = true;
3099 }
Romain Guy06882f82009-06-10 13:36:04 -07003100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003101 if (win.isVisibleNow()) {
3102 applyAnimationLocked(win,
3103 WindowManagerPolicy.TRANSIT_EXIT, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 changed = true;
3105 }
3106 }
3107
3108 if (changed) {
3109 mLayoutNeeded = true;
3110 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003111 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3112 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 }
Romain Guy06882f82009-06-10 13:36:04 -07003114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003115 if (delayed) {
3116 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003117 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3118 mWallpaperTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003119 }
3120 }
Romain Guy06882f82009-06-10 13:36:04 -07003121
Jeff Brown2e44b072011-01-24 15:21:56 -08003122 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003124 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003125 }
3126 }
3127 Binder.restoreCallingIdentity(origId);
3128 }
3129
3130 public void addAppToken(int addPos, IApplicationToken token,
3131 int groupId, int requestedOrientation, boolean fullscreen) {
3132 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3133 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003134 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 }
Jeff Brown349703e2010-06-22 01:27:15 -07003136
3137 // Get the dispatching timeout here while we are not holding any locks so that it
3138 // can be cached by the AppWindowToken. The timeout value is used later by the
3139 // input dispatcher in code that does hold locks. If we did not cache the value
3140 // here we would run the chance of introducing a deadlock between the window manager
3141 // (which holds locks while updating the input dispatcher state) and the activity manager
3142 // (which holds locks while querying the application token).
3143 long inputDispatchingTimeoutNanos;
3144 try {
3145 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3146 } catch (RemoteException ex) {
3147 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3148 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3149 }
Romain Guy06882f82009-06-10 13:36:04 -07003150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003151 synchronized(mWindowMap) {
3152 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3153 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003154 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003155 return;
3156 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003157 wtoken = new AppWindowToken(this, token);
Jeff Brown349703e2010-06-22 01:27:15 -07003158 wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 wtoken.groupId = groupId;
3160 wtoken.appFullscreen = fullscreen;
3161 wtoken.requestedOrientation = requestedOrientation;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003162 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003163 mAppTokens.add(addPos, wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164 mTokenMap.put(token.asBinder(), wtoken);
Romain Guy06882f82009-06-10 13:36:04 -07003165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003166 // Application tokens start out hidden.
3167 wtoken.hidden = true;
3168 wtoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003170 //dump();
3171 }
3172 }
Romain Guy06882f82009-06-10 13:36:04 -07003173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003174 public void setAppGroupId(IBinder token, int groupId) {
3175 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3176 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003177 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 }
3179
3180 synchronized(mWindowMap) {
3181 AppWindowToken wtoken = findAppWindowToken(token);
3182 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003183 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003184 return;
3185 }
3186 wtoken.groupId = groupId;
3187 }
3188 }
Romain Guy06882f82009-06-10 13:36:04 -07003189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 public int getOrientationFromWindowsLocked() {
3191 int pos = mWindows.size() - 1;
3192 while (pos >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07003193 WindowState wtoken = mWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 pos--;
3195 if (wtoken.mAppToken != null) {
3196 // We hit an application window. so the orientation will be determined by the
3197 // app window. No point in continuing further.
3198 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3199 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003200 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003201 continue;
3202 }
3203 int req = wtoken.mAttrs.screenOrientation;
3204 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3205 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3206 continue;
3207 } else {
3208 return req;
3209 }
3210 }
3211 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3212 }
Romain Guy06882f82009-06-10 13:36:04 -07003213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003214 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003215 int pos = mAppTokens.size() - 1;
3216 int curGroup = 0;
3217 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3218 boolean findingBehind = false;
3219 boolean haveGroup = false;
3220 boolean lastFullscreen = false;
3221 while (pos >= 0) {
3222 AppWindowToken wtoken = mAppTokens.get(pos);
3223 pos--;
3224 // if we're about to tear down this window and not seek for
3225 // the behind activity, don't use it for orientation
3226 if (!findingBehind
3227 && (!wtoken.hidden && wtoken.hiddenRequested)) {
3228 continue;
3229 }
3230
3231 if (!haveGroup) {
3232 // We ignore any hidden applications on the top.
3233 if (wtoken.hiddenRequested || wtoken.willBeHidden) {
The Android Open Source Project10592532009-03-18 17:39:46 -07003234 continue;
3235 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003236 haveGroup = true;
3237 curGroup = wtoken.groupId;
3238 lastOrientation = wtoken.requestedOrientation;
3239 } else if (curGroup != wtoken.groupId) {
3240 // If we have hit a new application group, and the bottom
3241 // of the previous group didn't explicitly say to use
3242 // the orientation behind it, and the last app was
3243 // full screen, then we'll stick with the
3244 // user's orientation.
3245 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3246 && lastFullscreen) {
3247 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003250 int or = wtoken.requestedOrientation;
3251 // If this application is fullscreen, and didn't explicitly say
3252 // to use the orientation behind it, then just take whatever
3253 // orientation it has and ignores whatever is under it.
3254 lastFullscreen = wtoken.appFullscreen;
3255 if (lastFullscreen
3256 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3257 return or;
3258 }
3259 // If this application has requested an explicit orientation,
3260 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003261 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3262 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003263 return or;
3264 }
3265 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3266 }
3267 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 }
Romain Guy06882f82009-06-10 13:36:04 -07003269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003270 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003271 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003272 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3273 "updateOrientationFromAppTokens()")) {
3274 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3275 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003276
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003277 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003278 long ident = Binder.clearCallingIdentity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003279
3280 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003281 config = updateOrientationFromAppTokensLocked(currentConfig,
3282 freezeThisOneIfNeeded);
3283 }
3284
3285 Binder.restoreCallingIdentity(ident);
3286 return config;
3287 }
3288
3289 private Configuration updateOrientationFromAppTokensLocked(
3290 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3291 Configuration config = null;
3292
3293 if (updateOrientationFromAppTokensLocked(false)) {
3294 if (freezeThisOneIfNeeded != null) {
3295 AppWindowToken wtoken = findAppWindowToken(
3296 freezeThisOneIfNeeded);
3297 if (wtoken != null) {
3298 startAppFreezingScreenLocked(wtoken,
3299 ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003300 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003301 }
3302 config = computeNewConfigurationLocked();
3303
3304 } else if (currentConfig != null) {
3305 // No obvious action we need to take, but if our current
3306 // state mismatches the activity manager's, update it,
3307 // disregarding font scale, which should remain set to
3308 // the value of the previous configuration.
3309 mTempConfiguration.setToDefaults();
3310 mTempConfiguration.fontScale = currentConfig.fontScale;
3311 if (computeNewConfigurationLocked(mTempConfiguration)) {
3312 if (currentConfig.diff(mTempConfiguration) != 0) {
3313 mWaitingForConfig = true;
3314 mLayoutNeeded = true;
3315 startFreezingDisplayLocked(false);
3316 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003317 }
3318 }
3319 }
3320
Dianne Hackborncfaef692009-06-15 14:24:44 -07003321 return config;
3322 }
3323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003325 * Determine the new desired orientation of the display, returning
3326 * a non-null new Configuration if it has changed from the current
3327 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3328 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3329 * SCREEN. This will typically be done for you if you call
3330 * sendNewConfiguration().
3331 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003332 * The orientation is computed from non-application windows first. If none of
3333 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003334 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3336 * android.os.IBinder)
3337 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003338 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
3339 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
Christopher Tateb696aee2010-04-02 19:08:30 -07003340 // If the display is frozen, some activities may be in the middle
3341 // of restarting, and thus have removed their old window. If the
3342 // window has the flag to hide the lock screen, then the lock screen
3343 // can re-appear and inflict its own orientation on us. Keep the
3344 // orientation stable until this all settles down.
3345 return false;
3346 }
3347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 boolean changed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 long ident = Binder.clearCallingIdentity();
3350 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003351 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 mForcedAppOrientation = req;
3355 //send a message to Policy indicating orientation change to take
3356 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003357 mPolicy.setCurrentOrientationLw(req);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003358 if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003359 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE,
3360 inTransaction)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003361 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 }
3363 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003364
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003365 return changed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 } finally {
3367 Binder.restoreCallingIdentity(ident);
3368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 }
Romain Guy06882f82009-06-10 13:36:04 -07003370
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003371 int computeForcedAppOrientationLocked() {
3372 int req = getOrientationFromWindowsLocked();
3373 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3374 req = getOrientationFromAppTokensLocked();
3375 }
3376 return req;
3377 }
Romain Guy06882f82009-06-10 13:36:04 -07003378
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003379 public void setNewConfiguration(Configuration config) {
3380 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3381 "setNewConfiguration()")) {
3382 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3383 }
3384
3385 synchronized(mWindowMap) {
3386 mCurConfiguration = new Configuration(config);
3387 mWaitingForConfig = false;
3388 performLayoutAndPlaceSurfacesLocked();
3389 }
3390 }
3391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003392 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3393 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3394 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003395 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 }
Romain Guy06882f82009-06-10 13:36:04 -07003397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003398 synchronized(mWindowMap) {
3399 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3400 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003401 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 return;
3403 }
Romain Guy06882f82009-06-10 13:36:04 -07003404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 wtoken.requestedOrientation = requestedOrientation;
3406 }
3407 }
Romain Guy06882f82009-06-10 13:36:04 -07003408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003409 public int getAppOrientation(IApplicationToken token) {
3410 synchronized(mWindowMap) {
3411 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3412 if (wtoken == null) {
3413 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3414 }
Romain Guy06882f82009-06-10 13:36:04 -07003415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 return wtoken.requestedOrientation;
3417 }
3418 }
Romain Guy06882f82009-06-10 13:36:04 -07003419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3421 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3422 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003423 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003424 }
3425
3426 synchronized(mWindowMap) {
3427 boolean changed = false;
3428 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003429 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 changed = mFocusedApp != null;
3431 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003432 if (changed) {
3433 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07003434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 } else {
3436 AppWindowToken newFocus = findAppWindowToken(token);
3437 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003438 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 return;
3440 }
3441 changed = mFocusedApp != newFocus;
3442 mFocusedApp = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003443 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07003444 if (changed) {
3445 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07003446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003447 }
3448
3449 if (moveFocusNow && changed) {
3450 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003451 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 Binder.restoreCallingIdentity(origId);
3453 }
3454 }
3455 }
3456
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003457 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003458 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3459 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003460 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003461 }
Romain Guy06882f82009-06-10 13:36:04 -07003462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003464 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 TAG, "Prepare app transition: transit=" + transit
3466 + " mNextAppTransition=" + mNextAppTransition);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003467 if (!mDisplayFrozen && mPolicy.isScreenOn()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003468 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
3469 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08003471 } else if (!alwaysKeepCurrent) {
3472 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
3473 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
3474 // Opening a new task always supersedes a close for the anim.
3475 mNextAppTransition = transit;
3476 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
3477 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
3478 // Opening a new activity always supersedes a close for the anim.
3479 mNextAppTransition = transit;
3480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003481 }
3482 mAppTransitionReady = false;
3483 mAppTransitionTimeout = false;
3484 mStartingIconInTransition = false;
3485 mSkipAppTransitionAnimation = false;
3486 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3487 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
3488 5000);
3489 }
3490 }
3491 }
3492
3493 public int getPendingAppTransition() {
3494 return mNextAppTransition;
3495 }
Romain Guy06882f82009-06-10 13:36:04 -07003496
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003497 public void overridePendingAppTransition(String packageName,
3498 int enterAnim, int exitAnim) {
Dianne Hackborn8b571a82009-09-25 16:09:43 -07003499 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003500 mNextAppTransitionPackage = packageName;
3501 mNextAppTransitionEnter = enterAnim;
3502 mNextAppTransitionExit = exitAnim;
3503 }
3504 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506 public void executeAppTransition() {
3507 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3508 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003509 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510 }
Romain Guy06882f82009-06-10 13:36:04 -07003511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003512 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003513 if (DEBUG_APP_TRANSITIONS) {
3514 RuntimeException e = new RuntimeException("here");
3515 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003516 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003517 + mNextAppTransition, e);
3518 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003519 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 mAppTransitionReady = true;
3521 final long origId = Binder.clearCallingIdentity();
3522 performLayoutAndPlaceSurfacesLocked();
3523 Binder.restoreCallingIdentity(origId);
3524 }
3525 }
3526 }
3527
3528 public void setAppStartingWindow(IBinder token, String pkg,
3529 int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003530 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3532 "setAppStartingIcon()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003533 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 }
3535
3536 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003537 if (DEBUG_STARTING_WINDOW) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
3539 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07003540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 AppWindowToken wtoken = findAppWindowToken(token);
3542 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003543 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 return;
3545 }
3546
3547 // If the display is frozen, we won't do anything until the
3548 // actual window is displayed so there is no reason to put in
3549 // the starting window.
Dianne Hackbornde2606d2009-12-18 16:53:55 -08003550 if (mDisplayFrozen || !mPolicy.isScreenOn()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 return;
3552 }
Romain Guy06882f82009-06-10 13:36:04 -07003553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 if (wtoken.startingData != null) {
3555 return;
3556 }
Romain Guy06882f82009-06-10 13:36:04 -07003557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 if (transferFrom != null) {
3559 AppWindowToken ttoken = findAppWindowToken(transferFrom);
3560 if (ttoken != null) {
3561 WindowState startingWindow = ttoken.startingWindow;
3562 if (startingWindow != null) {
3563 if (mStartingIconInTransition) {
3564 // In this case, the starting icon has already
3565 // been displayed, so start letting windows get
3566 // shown immediately without any more transitions.
3567 mSkipAppTransitionAnimation = true;
3568 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003569 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003570 "Moving existing starting from " + ttoken
3571 + " to " + wtoken);
3572 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07003573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003574 // Transfer the starting window over to the new
3575 // token.
3576 wtoken.startingData = ttoken.startingData;
3577 wtoken.startingView = ttoken.startingView;
3578 wtoken.startingWindow = startingWindow;
3579 ttoken.startingData = null;
3580 ttoken.startingView = null;
3581 ttoken.startingWindow = null;
3582 ttoken.startingMoved = true;
3583 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07003584 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 startingWindow.mAppToken = wtoken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003586 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003587 "Removing starting window: " + startingWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003588 mWindows.remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07003589 mWindowsChanged = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08003590 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
3591 + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003592 ttoken.windows.remove(startingWindow);
3593 ttoken.allAppWindows.remove(startingWindow);
3594 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07003595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003596 // Propagate other interesting state between the
3597 // tokens. If the old token is displayed, we should
3598 // immediately force the new one to be displayed. If
3599 // it is animating, we need to move that animation to
3600 // the new one.
3601 if (ttoken.allDrawn) {
3602 wtoken.allDrawn = true;
3603 }
3604 if (ttoken.firstWindowDrawn) {
3605 wtoken.firstWindowDrawn = true;
3606 }
3607 if (!ttoken.hidden) {
3608 wtoken.hidden = false;
3609 wtoken.hiddenRequested = false;
3610 wtoken.willBeHidden = false;
3611 }
3612 if (wtoken.clientHidden != ttoken.clientHidden) {
3613 wtoken.clientHidden = ttoken.clientHidden;
3614 wtoken.sendAppVisibilityToClients();
3615 }
3616 if (ttoken.animation != null) {
3617 wtoken.animation = ttoken.animation;
3618 wtoken.animating = ttoken.animating;
3619 wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
3620 ttoken.animation = null;
3621 ttoken.animLayerAdjustment = 0;
3622 wtoken.updateLayers();
3623 ttoken.updateLayers();
3624 }
Romain Guy06882f82009-06-10 13:36:04 -07003625
Jeff Brown3a22cd92011-01-21 13:59:04 -08003626 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3627 true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 mLayoutNeeded = true;
3629 performLayoutAndPlaceSurfacesLocked();
3630 Binder.restoreCallingIdentity(origId);
3631 return;
3632 } else if (ttoken.startingData != null) {
3633 // The previous app was getting ready to show a
3634 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003635 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003636 "Moving pending starting from " + ttoken
3637 + " to " + wtoken);
3638 wtoken.startingData = ttoken.startingData;
3639 ttoken.startingData = null;
3640 ttoken.startingMoved = true;
3641 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3642 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3643 // want to process the message ASAP, before any other queued
3644 // messages.
3645 mH.sendMessageAtFrontOfQueue(m);
3646 return;
3647 }
3648 }
3649 }
3650
3651 // There is no existing starting window, and the caller doesn't
3652 // want us to create one, so that's it!
3653 if (!createIfNeeded) {
3654 return;
3655 }
Romain Guy06882f82009-06-10 13:36:04 -07003656
Dianne Hackborn284ac932009-08-28 10:34:25 -07003657 // If this is a translucent or wallpaper window, then don't
3658 // show a starting window -- the current effect (a full-screen
3659 // opaque starting window that fades away to the real contents
3660 // when it is ready) does not work for this.
3661 if (theme != 0) {
3662 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
3663 com.android.internal.R.styleable.Window);
3664 if (ent.array.getBoolean(
3665 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
3666 return;
3667 }
3668 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07003669 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
3670 return;
3671 }
3672 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07003673 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
3674 return;
3675 }
3676 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003678 mStartingIconInTransition = true;
3679 wtoken.startingData = new StartingData(
3680 pkg, theme, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08003681 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003682 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
3683 // Note: we really want to do sendMessageAtFrontOfQueue() because we
3684 // want to process the message ASAP, before any other queued
3685 // messages.
3686 mH.sendMessageAtFrontOfQueue(m);
3687 }
3688 }
3689
3690 public void setAppWillBeHidden(IBinder token) {
3691 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3692 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003693 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 }
3695
3696 AppWindowToken wtoken;
3697
3698 synchronized(mWindowMap) {
3699 wtoken = findAppWindowToken(token);
3700 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003701 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 -08003702 return;
3703 }
3704 wtoken.willBeHidden = true;
3705 }
3706 }
Romain Guy06882f82009-06-10 13:36:04 -07003707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003709 boolean visible, int transit, boolean performLayout, boolean bgFiller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 boolean delayed = false;
3711
3712 if (wtoken.clientHidden == visible) {
3713 wtoken.clientHidden = !visible;
3714 wtoken.sendAppVisibilityToClients();
3715 }
Romain Guy06882f82009-06-10 13:36:04 -07003716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 wtoken.willBeHidden = false;
3718 if (wtoken.hidden == visible) {
3719 final int N = wtoken.allAppWindows.size();
3720 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003721 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
3723 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07003724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07003726
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003727 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 if (wtoken.animation == sDummyAnimation) {
3729 wtoken.animation = null;
3730 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003731 applyAnimationLocked(wtoken, lp, transit, visible, bgFiller);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003732 changed = true;
3733 if (wtoken.animation != null) {
3734 delayed = runningAppAnimation = true;
3735 }
3736 }
Romain Guy06882f82009-06-10 13:36:04 -07003737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003738 for (int i=0; i<N; i++) {
3739 WindowState win = wtoken.allAppWindows.get(i);
3740 if (win == wtoken.startingWindow) {
3741 continue;
3742 }
3743
3744 if (win.isAnimating()) {
3745 delayed = true;
3746 }
Romain Guy06882f82009-06-10 13:36:04 -07003747
Joe Onorato8a9b2202010-02-26 18:56:32 -08003748 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 //win.dump(" ");
3750 if (visible) {
3751 if (!win.isVisibleNow()) {
3752 if (!runningAppAnimation) {
3753 applyAnimationLocked(win,
3754 WindowManagerPolicy.TRANSIT_ENTER, true);
3755 }
3756 changed = true;
3757 }
3758 } else if (win.isVisibleNow()) {
3759 if (!runningAppAnimation) {
3760 applyAnimationLocked(win,
3761 WindowManagerPolicy.TRANSIT_EXIT, false);
3762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003763 changed = true;
3764 }
3765 }
3766
3767 wtoken.hidden = wtoken.hiddenRequested = !visible;
3768 if (!visible) {
3769 unsetAppFreezingScreenLocked(wtoken, true, true);
3770 } else {
3771 // If we are being set visible, and the starting window is
3772 // not yet displayed, then make sure it doesn't get displayed.
3773 WindowState swin = wtoken.startingWindow;
3774 if (swin != null && (swin.mDrawPending
3775 || swin.mCommitDrawPending)) {
3776 swin.mPolicyVisibility = false;
3777 swin.mPolicyVisibilityAfterAnim = false;
3778 }
3779 }
Romain Guy06882f82009-06-10 13:36:04 -07003780
Joe Onorato8a9b2202010-02-26 18:56:32 -08003781 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 + ": hidden=" + wtoken.hidden + " hiddenRequested="
3783 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07003784
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003785 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003786 mLayoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08003787 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003788 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08003789 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
3790 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08003791 performLayoutAndPlaceSurfacesLocked();
3792 }
Jeff Brown2e44b072011-01-24 15:21:56 -08003793 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 }
3795 }
3796
3797 if (wtoken.animation != null) {
3798 delayed = true;
3799 }
Romain Guy06882f82009-06-10 13:36:04 -07003800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003801 return delayed;
3802 }
3803
3804 public void setAppVisibility(IBinder token, boolean visible) {
3805 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3806 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003807 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003808 }
3809
3810 AppWindowToken wtoken;
3811
3812 synchronized(mWindowMap) {
3813 wtoken = findAppWindowToken(token);
3814 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003815 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003816 return;
3817 }
3818
3819 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003820 RuntimeException e = null;
3821 if (!HIDE_STACK_CRAWLS) {
3822 e = new RuntimeException();
3823 e.fillInStackTrace();
3824 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003825 Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003826 + "): mNextAppTransition=" + mNextAppTransition
3827 + " hidden=" + wtoken.hidden
3828 + " hiddenRequested=" + wtoken.hiddenRequested, e);
3829 }
Romain Guy06882f82009-06-10 13:36:04 -07003830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 // If we are preparing an app transition, then delay changing
3832 // the visibility of this token until we execute that transition.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003833 if (!mDisplayFrozen && mPolicy.isScreenOn()
3834 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 // Already in requested state, don't do anything more.
3836 if (wtoken.hiddenRequested != visible) {
3837 return;
3838 }
3839 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07003840
Joe Onorato8a9b2202010-02-26 18:56:32 -08003841 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 TAG, "Setting dummy animation on: " + wtoken);
3843 wtoken.setDummyAnimation();
3844 mOpeningApps.remove(wtoken);
3845 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07003846 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003847 wtoken.inPendingTransaction = true;
3848 if (visible) {
3849 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 wtoken.startingDisplayed = false;
3851 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003852
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003853 // If the token is currently hidden (should be the
3854 // common case), then we need to set up to wait for
3855 // its windows to be ready.
3856 if (wtoken.hidden) {
3857 wtoken.allDrawn = false;
3858 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003859
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003860 if (wtoken.clientHidden) {
3861 // In the case where we are making an app visible
3862 // but holding off for a transition, we still need
3863 // to tell the client to make its windows visible so
3864 // they get drawn. Otherwise, we will wait on
3865 // performing the transition until all windows have
3866 // been drawn, they never will be, and we are sad.
3867 wtoken.clientHidden = false;
3868 wtoken.sendAppVisibilityToClients();
3869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 }
3871 } else {
3872 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003873
Dianne Hackborn195f6a02009-11-24 11:26:00 -08003874 // If the token is currently visible (should be the
3875 // common case), then set up to wait for it to be hidden.
3876 if (!wtoken.hidden) {
3877 wtoken.waitingToHide = true;
3878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 }
3880 return;
3881 }
Romain Guy06882f82009-06-10 13:36:04 -07003882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003883 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003884 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
3885 true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 wtoken.updateReportedVisibilityLocked();
3887 Binder.restoreCallingIdentity(origId);
3888 }
3889 }
3890
3891 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
3892 boolean unfreezeSurfaceNow, boolean force) {
3893 if (wtoken.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003894 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 + " force=" + force);
3896 final int N = wtoken.allAppWindows.size();
3897 boolean unfrozeWindows = false;
3898 for (int i=0; i<N; i++) {
3899 WindowState w = wtoken.allAppWindows.get(i);
3900 if (w.mAppFreezing) {
3901 w.mAppFreezing = false;
3902 if (w.mSurface != null && !w.mOrientationChanging) {
3903 w.mOrientationChanging = true;
3904 }
3905 unfrozeWindows = true;
3906 }
3907 }
3908 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003909 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 wtoken.freezingScreen = false;
3911 mAppsFreezingScreen--;
3912 }
3913 if (unfreezeSurfaceNow) {
3914 if (unfrozeWindows) {
3915 mLayoutNeeded = true;
3916 performLayoutAndPlaceSurfacesLocked();
3917 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003918 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 }
3920 }
3921 }
Romain Guy06882f82009-06-10 13:36:04 -07003922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
3924 int configChanges) {
3925 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003926 RuntimeException e = null;
3927 if (!HIDE_STACK_CRAWLS) {
3928 e = new RuntimeException();
3929 e.fillInStackTrace();
3930 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003931 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 + ": hidden=" + wtoken.hidden + " freezing="
3933 + wtoken.freezingScreen, e);
3934 }
3935 if (!wtoken.hiddenRequested) {
3936 if (!wtoken.freezingScreen) {
3937 wtoken.freezingScreen = true;
3938 mAppsFreezingScreen++;
3939 if (mAppsFreezingScreen == 1) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003940 startFreezingDisplayLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
3942 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
3943 5000);
3944 }
3945 }
3946 final int N = wtoken.allAppWindows.size();
3947 for (int i=0; i<N; i++) {
3948 WindowState w = wtoken.allAppWindows.get(i);
3949 w.mAppFreezing = true;
3950 }
3951 }
3952 }
Romain Guy06882f82009-06-10 13:36:04 -07003953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003954 public void startAppFreezingScreen(IBinder token, int configChanges) {
3955 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3956 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003957 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 }
3959
3960 synchronized(mWindowMap) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08003961 if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003962 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 return;
3964 }
Romain Guy06882f82009-06-10 13:36:04 -07003965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 AppWindowToken wtoken = findAppWindowToken(token);
3967 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003968 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 return;
3970 }
3971 final long origId = Binder.clearCallingIdentity();
3972 startAppFreezingScreenLocked(wtoken, configChanges);
3973 Binder.restoreCallingIdentity(origId);
3974 }
3975 }
Romain Guy06882f82009-06-10 13:36:04 -07003976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 public void stopAppFreezingScreen(IBinder token, boolean force) {
3978 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3979 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003980 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 }
3982
3983 synchronized(mWindowMap) {
3984 AppWindowToken wtoken = findAppWindowToken(token);
3985 if (wtoken == null || wtoken.appToken == null) {
3986 return;
3987 }
3988 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08003989 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
3991 unsetAppFreezingScreenLocked(wtoken, true, force);
3992 Binder.restoreCallingIdentity(origId);
3993 }
3994 }
Romain Guy06882f82009-06-10 13:36:04 -07003995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 public void removeAppToken(IBinder token) {
3997 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3998 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003999 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 }
4001
4002 AppWindowToken wtoken = null;
4003 AppWindowToken startingToken = null;
4004 boolean delayed = false;
4005
4006 final long origId = Binder.clearCallingIdentity();
4007 synchronized(mWindowMap) {
4008 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004010 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004011 delayed = setTokenVisibilityLocked(wtoken, null, false,
4012 WindowManagerPolicy.TRANSIT_UNSET, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004013 wtoken.inPendingTransaction = false;
4014 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004015 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 if (mClosingApps.contains(wtoken)) {
4017 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004018 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004020 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 delayed = true;
4022 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004023 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 TAG, "Removing app " + wtoken + " delayed=" + delayed
4025 + " animation=" + wtoken.animation
4026 + " animating=" + wtoken.animating);
4027 if (delayed) {
4028 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004029 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4030 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004032 } else {
4033 // Make sure there is no animation running on this token,
4034 // so any windows associated with it will be removed as
4035 // soon as their animations are complete
4036 wtoken.animation = null;
4037 wtoken.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004038 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004039 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4040 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 mAppTokens.remove(wtoken);
4042 wtoken.removed = true;
4043 if (wtoken.startingData != null) {
4044 startingToken = wtoken;
4045 }
4046 unsetAppFreezingScreenLocked(wtoken, true, true);
4047 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004048 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004050 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004051 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 }
4053 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004054 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055 }
Romain Guy06882f82009-06-10 13:36:04 -07004056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 if (!delayed && wtoken != null) {
4058 wtoken.updateReportedVisibilityLocked();
4059 }
4060 }
4061 Binder.restoreCallingIdentity(origId);
4062
4063 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004064 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004065 + startingToken + ": app token removed");
4066 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4067 mH.sendMessage(m);
4068 }
4069 }
4070
4071 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4072 final int NW = token.windows.size();
4073 for (int i=0; i<NW; i++) {
4074 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004075 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 mWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004077 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004078 int j = win.mChildWindows.size();
4079 while (j > 0) {
4080 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004081 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004082 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004083 "Tmp removing child window " + cwin);
4084 mWindows.remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 }
4086 }
4087 return NW > 0;
4088 }
4089
4090 void dumpAppTokensLocked() {
4091 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004092 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 }
4094 }
Romain Guy06882f82009-06-10 13:36:04 -07004095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 void dumpWindowsLocked() {
4097 for (int i=mWindows.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004098 Slog.v(TAG, " #" + i + ": " + mWindows.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004099 }
4100 }
Romain Guy06882f82009-06-10 13:36:04 -07004101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 private int findWindowOffsetLocked(int tokenPos) {
4103 final int NW = mWindows.size();
4104
4105 if (tokenPos >= mAppTokens.size()) {
4106 int i = NW;
4107 while (i > 0) {
4108 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07004109 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 if (win.getAppToken() != null) {
4111 return i+1;
4112 }
4113 }
4114 }
4115
4116 while (tokenPos > 0) {
4117 // Find the first app token below the new position that has
4118 // a window displayed.
4119 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004120 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004121 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004122 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004123 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004124 "Skipping token -- currently sending to bottom");
4125 tokenPos--;
4126 continue;
4127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 int i = wtoken.windows.size();
4129 while (i > 0) {
4130 i--;
4131 WindowState win = wtoken.windows.get(i);
4132 int j = win.mChildWindows.size();
4133 while (j > 0) {
4134 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004135 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004136 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004137 for (int pos=NW-1; pos>=0; pos--) {
4138 if (mWindows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004139 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 "Found child win @" + (pos+1));
4141 return pos+1;
4142 }
4143 }
4144 }
4145 }
4146 for (int pos=NW-1; pos>=0; pos--) {
4147 if (mWindows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004148 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004149 return pos+1;
4150 }
4151 }
4152 }
4153 tokenPos--;
4154 }
4155
4156 return 0;
4157 }
4158
4159 private final int reAddWindowLocked(int index, WindowState win) {
4160 final int NCW = win.mChildWindows.size();
4161 boolean added = false;
4162 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004163 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004165 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004166 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004167 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 mWindows.add(index, win);
4169 index++;
4170 added = true;
4171 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004172 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004173 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004174 cwin.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004175 mWindows.add(index, cwin);
4176 index++;
4177 }
4178 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004179 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004180 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004181 win.mRebuilding = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004182 mWindows.add(index, win);
4183 index++;
4184 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004185 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004186 return index;
4187 }
Romain Guy06882f82009-06-10 13:36:04 -07004188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 private final int reAddAppWindowsLocked(int index, WindowToken token) {
4190 final int NW = token.windows.size();
4191 for (int i=0; i<NW; i++) {
4192 index = reAddWindowLocked(index, token.windows.get(i));
4193 }
4194 return index;
4195 }
4196
4197 public void moveAppToken(int index, IBinder token) {
4198 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4199 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004200 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 }
4202
4203 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004204 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004205 if (DEBUG_REORDER) dumpAppTokensLocked();
4206 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004207 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4208 "Start moving token " + wtoken + " initially at "
4209 + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004210 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004211 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 + token + " (" + wtoken + ")");
4213 return;
4214 }
4215 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004216 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004217 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004218 if (DEBUG_REORDER) dumpAppTokensLocked();
Romain Guy06882f82009-06-10 13:36:04 -07004219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004221 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004222 if (DEBUG_REORDER) dumpWindowsLocked();
4223 if (tmpRemoveAppWindowsLocked(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004224 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 if (DEBUG_REORDER) dumpWindowsLocked();
4226 reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004227 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 if (DEBUG_REORDER) dumpWindowsLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004229 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4230 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004231 mLayoutNeeded = true;
Jeff Brown2e44b072011-01-24 15:21:56 -08004232 mInputMonitor.setUpdateInputWindowsNeededLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004233 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004234 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004235 }
4236 Binder.restoreCallingIdentity(origId);
4237 }
4238 }
4239
4240 private void removeAppTokensLocked(List<IBinder> tokens) {
4241 // XXX This should be done more efficiently!
4242 // (take advantage of the fact that both lists should be
4243 // ordered in the same way.)
4244 int N = tokens.size();
4245 for (int i=0; i<N; i++) {
4246 IBinder token = tokens.get(i);
4247 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004248 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4249 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004251 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 + token + " (" + wtoken + ")");
4253 i--;
4254 N--;
4255 }
4256 }
4257 }
4258
Dianne Hackborna8f60182009-09-01 19:01:50 -07004259 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
4260 boolean updateFocusAndLayout) {
4261 // First remove all of the windows from the list.
4262 tmpRemoveAppWindowsLocked(wtoken);
4263
4264 // Where to start adding?
4265 int pos = findWindowOffsetLocked(tokenPos);
4266
4267 // And now add them back at the correct place.
4268 pos = reAddAppWindowsLocked(pos, wtoken);
4269
4270 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08004271 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004272 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4273 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004274 assignLayersLocked();
4275 }
4276 mLayoutNeeded = true;
4277 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004278 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004279 }
4280 }
4281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004282 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
4283 // First remove all of the windows from the list.
4284 final int N = tokens.size();
4285 int i;
4286 for (i=0; i<N; i++) {
4287 WindowToken token = mTokenMap.get(tokens.get(i));
4288 if (token != null) {
4289 tmpRemoveAppWindowsLocked(token);
4290 }
4291 }
4292
4293 // Where to start adding?
4294 int pos = findWindowOffsetLocked(tokenPos);
4295
4296 // And now add them back at the correct place.
4297 for (i=0; i<N; i++) {
4298 WindowToken token = mTokenMap.get(tokens.get(i));
4299 if (token != null) {
4300 pos = reAddAppWindowsLocked(pos, token);
4301 }
4302 }
4303
Jeff Brown2e44b072011-01-24 15:21:56 -08004304 mInputMonitor.setUpdateInputWindowsNeededLw();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004305 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4306 false /*updateInputWindows*/)) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004307 assignLayersLocked();
4308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004309 mLayoutNeeded = true;
4310 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08004311 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312
4313 //dump();
4314 }
4315
4316 public void moveAppTokensToTop(List<IBinder> tokens) {
4317 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4318 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004319 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 }
4321
4322 final long origId = Binder.clearCallingIdentity();
4323 synchronized(mWindowMap) {
4324 removeAppTokensLocked(tokens);
4325 final int N = tokens.size();
4326 for (int i=0; i<N; i++) {
4327 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4328 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004329 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4330 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004332 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004333 mToTopApps.remove(wt);
4334 mToBottomApps.remove(wt);
4335 mToTopApps.add(wt);
4336 wt.sendingToBottom = false;
4337 wt.sendingToTop = true;
4338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004339 }
4340 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004341
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004342 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004343 moveAppWindowsLocked(tokens, mAppTokens.size());
4344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004345 }
4346 Binder.restoreCallingIdentity(origId);
4347 }
4348
4349 public void moveAppTokensToBottom(List<IBinder> tokens) {
4350 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4351 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004352 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 }
4354
4355 final long origId = Binder.clearCallingIdentity();
4356 synchronized(mWindowMap) {
4357 removeAppTokensLocked(tokens);
4358 final int N = tokens.size();
4359 int pos = 0;
4360 for (int i=0; i<N; i++) {
4361 AppWindowToken wt = findAppWindowToken(tokens.get(i));
4362 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004363 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4364 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004366 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004367 mToTopApps.remove(wt);
4368 mToBottomApps.remove(wt);
4369 mToBottomApps.add(i, wt);
4370 wt.sendingToTop = false;
4371 wt.sendingToBottom = true;
4372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004373 pos++;
4374 }
4375 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004376
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004377 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07004378 moveAppWindowsLocked(tokens, 0);
4379 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 }
4381 Binder.restoreCallingIdentity(origId);
4382 }
4383
4384 // -------------------------------------------------------------
4385 // Misc IWindowSession methods
4386 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07004387
Jim Miller284b62e2010-06-08 14:27:42 -07004388 private boolean shouldAllowDisableKeyguard()
Jim Millerd6b57052010-06-07 17:52:42 -07004389 {
Jim Miller284b62e2010-06-08 14:27:42 -07004390 // We fail safe and prevent disabling keyguard in the unlikely event this gets
4391 // called before DevicePolicyManagerService has started.
4392 if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
4393 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
4394 Context.DEVICE_POLICY_SERVICE);
4395 if (dpm != null) {
4396 mAllowDisableKeyguard = dpm.getPasswordQuality(null)
4397 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
4398 ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
4399 }
Jim Millerd6b57052010-06-07 17:52:42 -07004400 }
Jim Miller284b62e2010-06-08 14:27:42 -07004401 return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
Jim Millerd6b57052010-06-07 17:52:42 -07004402 }
4403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004405 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004406 != PackageManager.PERMISSION_GRANTED) {
4407 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4408 }
Jim Millerd6b57052010-06-07 17:52:42 -07004409
Jim Miller284b62e2010-06-08 14:27:42 -07004410 synchronized (mKeyguardTokenWatcher) {
4411 mKeyguardTokenWatcher.acquire(token, tag);
Mike Lockwooddd884682009-10-11 16:57:08 -04004412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004413 }
4414
4415 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004416 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 != PackageManager.PERMISSION_GRANTED) {
4418 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420
Jim Miller284b62e2010-06-08 14:27:42 -07004421 synchronized (mKeyguardTokenWatcher) {
4422 mKeyguardTokenWatcher.release(token);
Jim Millerd6b57052010-06-07 17:52:42 -07004423
Jim Miller284b62e2010-06-08 14:27:42 -07004424 if (!mKeyguardTokenWatcher.isAcquired()) {
4425 // If we are the last one to reenable the keyguard wait until
4426 // we have actually finished reenabling until returning.
4427 // It is possible that reenableKeyguard() can be called before
4428 // the previous disableKeyguard() is handled, in which case
4429 // neither mKeyguardTokenWatcher.acquired() or released() would
4430 // be called. In that case mKeyguardDisabled will be false here
4431 // and we have nothing to wait for.
4432 while (mKeyguardDisabled) {
4433 try {
4434 mKeyguardTokenWatcher.wait();
4435 } catch (InterruptedException e) {
4436 Thread.currentThread().interrupt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 }
4438 }
4439 }
4440 }
4441 }
4442
4443 /**
4444 * @see android.app.KeyguardManager#exitKeyguardSecurely
4445 */
4446 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04004447 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448 != PackageManager.PERMISSION_GRANTED) {
4449 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4450 }
4451 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4452 public void onKeyguardExitResult(boolean success) {
4453 try {
4454 callback.onKeyguardExitResult(success);
4455 } catch (RemoteException e) {
4456 // Client has died, we don't care.
4457 }
4458 }
4459 });
4460 }
4461
4462 public boolean inKeyguardRestrictedInputMode() {
4463 return mPolicy.inKeyguardRestrictedKeyInputMode();
4464 }
Romain Guy06882f82009-06-10 13:36:04 -07004465
Mike Lockwood520d8bc2011-02-18 13:23:13 -05004466 public boolean isKeyguardLocked() {
4467 return mPolicy.isKeyguardLocked();
4468 }
4469
4470 public boolean isKeyguardSecure() {
4471 return mPolicy.isKeyguardSecure();
4472 }
4473
Dianne Hackbornffa42482009-09-23 22:20:11 -07004474 public void closeSystemDialogs(String reason) {
4475 synchronized(mWindowMap) {
4476 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07004477 WindowState w = mWindows.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07004478 if (w.mSurface != null) {
4479 try {
4480 w.mClient.closeSystemDialogs(reason);
4481 } catch (RemoteException e) {
4482 }
4483 }
4484 }
4485 }
4486 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 static float fixScale(float scale) {
4489 if (scale < 0) scale = 0;
4490 else if (scale > 20) scale = 20;
4491 return Math.abs(scale);
4492 }
Romain Guy06882f82009-06-10 13:36:04 -07004493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 public void setAnimationScale(int which, float scale) {
4495 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4496 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004497 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 }
4499
4500 if (scale < 0) scale = 0;
4501 else if (scale > 20) scale = 20;
4502 scale = Math.abs(scale);
4503 switch (which) {
4504 case 0: mWindowAnimationScale = fixScale(scale); break;
4505 case 1: mTransitionAnimationScale = fixScale(scale); break;
4506 }
Romain Guy06882f82009-06-10 13:36:04 -07004507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 // Persist setting
4509 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4510 }
Romain Guy06882f82009-06-10 13:36:04 -07004511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 public void setAnimationScales(float[] scales) {
4513 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
4514 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004515 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 }
4517
4518 if (scales != null) {
4519 if (scales.length >= 1) {
4520 mWindowAnimationScale = fixScale(scales[0]);
4521 }
4522 if (scales.length >= 2) {
4523 mTransitionAnimationScale = fixScale(scales[1]);
4524 }
4525 }
Romain Guy06882f82009-06-10 13:36:04 -07004526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004527 // Persist setting
4528 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
4529 }
Romain Guy06882f82009-06-10 13:36:04 -07004530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004531 public float getAnimationScale(int which) {
4532 switch (which) {
4533 case 0: return mWindowAnimationScale;
4534 case 1: return mTransitionAnimationScale;
4535 }
4536 return 0;
4537 }
Romain Guy06882f82009-06-10 13:36:04 -07004538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 public float[] getAnimationScales() {
4540 return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
4541 }
Romain Guy06882f82009-06-10 13:36:04 -07004542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004543 public int getSwitchState(int sw) {
4544 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4545 "getSwitchState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004546 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004547 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004548 return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004549 }
Romain Guy06882f82009-06-10 13:36:04 -07004550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 public int getSwitchStateForDevice(int devid, int sw) {
4552 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4553 "getSwitchStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004554 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004555 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004556 return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 }
Romain Guy06882f82009-06-10 13:36:04 -07004558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004559 public int getScancodeState(int sw) {
4560 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4561 "getScancodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004562 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004564 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004565 }
Romain Guy06882f82009-06-10 13:36:04 -07004566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 public int getScancodeStateForDevice(int devid, int sw) {
4568 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4569 "getScancodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004570 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004572 return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 }
Romain Guy06882f82009-06-10 13:36:04 -07004574
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004575 public int getTrackballScancodeState(int sw) {
4576 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4577 "getTrackballScancodeState()")) {
4578 throw new SecurityException("Requires READ_INPUT_STATE permission");
4579 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004580 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004581 }
4582
4583 public int getDPadScancodeState(int sw) {
4584 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4585 "getDPadScancodeState()")) {
4586 throw new SecurityException("Requires READ_INPUT_STATE permission");
4587 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004588 return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004589 }
4590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004591 public int getKeycodeState(int sw) {
4592 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4593 "getKeycodeState()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004594 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004596 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 }
Romain Guy06882f82009-06-10 13:36:04 -07004598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 public int getKeycodeStateForDevice(int devid, int sw) {
4600 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4601 "getKeycodeStateForDevice()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004602 throw new SecurityException("Requires READ_INPUT_STATE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004604 return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 }
Romain Guy06882f82009-06-10 13:36:04 -07004606
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004607 public int getTrackballKeycodeState(int sw) {
4608 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4609 "getTrackballKeycodeState()")) {
4610 throw new SecurityException("Requires READ_INPUT_STATE permission");
4611 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004612 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004613 }
4614
4615 public int getDPadKeycodeState(int sw) {
4616 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4617 "getDPadKeycodeState()")) {
4618 throw new SecurityException("Requires READ_INPUT_STATE permission");
4619 }
Jeff Brown6d0fec22010-07-23 21:28:06 -07004620 return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
Dianne Hackborn1d62ea92009-11-17 12:49:50 -08004621 }
Jeff Browna41ca772010-08-11 14:46:32 -07004622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
Jeff Brown6d0fec22010-07-23 21:28:06 -07004624 return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 }
Romain Guy06882f82009-06-10 13:36:04 -07004626
Jeff Browna41ca772010-08-11 14:46:32 -07004627 public InputChannel monitorInput(String inputChannelName) {
4628 if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
4629 "monitorInput()")) {
4630 throw new SecurityException("Requires READ_INPUT_STATE permission");
4631 }
4632 return mInputManager.monitorInput(inputChannelName);
4633 }
4634
Jeff Brown0029c662011-03-30 02:25:18 -07004635 public void setInputFilter(InputFilter filter) {
4636 mInputManager.setInputFilter(filter);
4637 }
4638
Jeff Brown8d608662010-08-30 03:02:23 -07004639 public InputDevice getInputDevice(int deviceId) {
4640 return mInputManager.getInputDevice(deviceId);
4641 }
4642
4643 public int[] getInputDeviceIds() {
4644 return mInputManager.getInputDeviceIds();
4645 }
4646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 public void enableScreenAfterBoot() {
4648 synchronized(mWindowMap) {
4649 if (mSystemBooted) {
4650 return;
4651 }
4652 mSystemBooted = true;
4653 }
Romain Guy06882f82009-06-10 13:36:04 -07004654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 performEnableScreen();
4656 }
Romain Guy06882f82009-06-10 13:36:04 -07004657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 public void enableScreenIfNeededLocked() {
4659 if (mDisplayEnabled) {
4660 return;
4661 }
4662 if (!mSystemBooted) {
4663 return;
4664 }
4665 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
4666 }
Romain Guy06882f82009-06-10 13:36:04 -07004667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004668 public void performEnableScreen() {
4669 synchronized(mWindowMap) {
4670 if (mDisplayEnabled) {
4671 return;
4672 }
4673 if (!mSystemBooted) {
4674 return;
4675 }
Romain Guy06882f82009-06-10 13:36:04 -07004676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004677 // Don't enable the screen until all existing windows
4678 // have been drawn.
4679 final int N = mWindows.size();
4680 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004681 WindowState w = mWindows.get(i);
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08004682 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004683 return;
4684 }
4685 }
Romain Guy06882f82009-06-10 13:36:04 -07004686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 mDisplayEnabled = true;
4688 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004689 Slog.i(TAG, "ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 StringWriter sw = new StringWriter();
4691 PrintWriter pw = new PrintWriter(sw);
4692 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004693 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 }
4695 try {
4696 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
4697 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004698 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004699 Parcel data = Parcel.obtain();
4700 data.writeInterfaceToken("android.ui.ISurfaceComposer");
4701 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
4702 data, null, 0);
4703 data.recycle();
4704 }
4705 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004706 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004707 }
4708 }
Romain Guy06882f82009-06-10 13:36:04 -07004709
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07004711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 // Make sure the last requested orientation has been applied.
Dianne Hackborn321ae682009-03-27 16:16:03 -07004713 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
4714 mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 }
Romain Guy06882f82009-06-10 13:36:04 -07004716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004717 public void setInTouchMode(boolean mode) {
4718 synchronized(mWindowMap) {
4719 mInTouchMode = mode;
4720 }
4721 }
4722
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004723 // TODO: more accounting of which pid(s) turned it on, keep count,
4724 // only allow disables from pids which have count on, etc.
4725 public void showStrictModeViolation(boolean on) {
4726 int pid = Binder.getCallingPid();
4727 synchronized(mWindowMap) {
4728 // Ignoring requests to enable the red border from clients
4729 // which aren't on screen. (e.g. Broadcast Receivers in
4730 // the background..)
4731 if (on) {
4732 boolean isVisible = false;
4733 for (WindowState ws : mWindows) {
4734 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
4735 isVisible = true;
4736 break;
4737 }
4738 }
4739 if (!isVisible) {
4740 return;
4741 }
4742 }
4743
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004744 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004745 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004746 try {
4747 if (mStrictModeFlash == null) {
4748 mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession);
4749 }
4750 mStrictModeFlash.setVisibility(on);
4751 } finally {
4752 Surface.closeTransaction();
4753 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004754 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08004755 }
4756 }
4757
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08004758 public void setStrictModeVisualIndicatorPreference(String value) {
4759 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
4760 }
4761
Jim Millere70d5062011-03-08 21:38:39 -08004762 /**
4763 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
4764 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
4765 * of the target image.
4766 *
4767 * @param width the width of the target bitmap
4768 * @param height the height of the target bitmap
4769 */
4770 public Bitmap screenshotApplications(IBinder appToken, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004771 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
4772 "screenshotApplications()")) {
4773 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
4774 }
4775
4776 Bitmap rawss;
4777
Dianne Hackbornd2835932010-12-13 16:28:46 -08004778 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004779 final Rect frame = new Rect();
4780
4781 float scale;
Jim Millere70d5062011-03-08 21:38:39 -08004782 int dw, dh;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004783 int rot;
4784
4785 synchronized(mWindowMap) {
4786 long ident = Binder.clearCallingIdentity();
4787
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07004788 dw = mPolicy.getNonDecorDisplayWidth(mCurDisplayWidth);
4789 dh = mPolicy.getNonDecorDisplayHeight(mCurDisplayHeight);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004790
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004791 int aboveAppLayer = mPolicy.windowTypeToLayerLw(
4792 WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
4793 + TYPE_LAYER_OFFSET;
4794 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
4795
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004796 boolean isImeTarget = mInputMethodTarget != null
4797 && mInputMethodTarget.mAppToken != null
4798 && mInputMethodTarget.mAppToken.appToken != null
4799 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
4800
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004801 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004802 boolean including = false;
4803 for (int i=mWindows.size()-1; i>=0; i--) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004804 WindowState ws = mWindows.get(i);
4805 if (ws.mSurface == null) {
4806 continue;
4807 }
4808 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004809 continue;
4810 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004811 // When we will skip windows: when we are not including
4812 // ones behind a window we didn't skip, and we are actually
4813 // taking a screenshot of a specific app.
4814 if (!including && appToken != null) {
4815 // Also, we can possibly skip this window if it is not
4816 // an IME target or the application for the screenshot
4817 // is not the current IME target.
4818 if (!ws.mIsImWindow || !isImeTarget) {
4819 // And finally, this window is of no interest if it
4820 // is not associated with the screenshot app.
4821 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
4822 continue;
4823 }
4824 }
4825 }
4826
4827 // We keep on including windows until we go past a full-screen
4828 // window.
4829 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
4830
Dianne Hackbornd2835932010-12-13 16:28:46 -08004831 if (maxLayer < ws.mAnimLayer) {
4832 maxLayer = ws.mAnimLayer;
4833 }
Jim Miller2aded182011-03-08 15:32:42 -08004834
4835 // Don't include wallpaper in bounds calculation
4836 if (!ws.mIsWallpaper) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004837 final Rect wf = ws.mScaledFrame;
Jim Miller2aded182011-03-08 15:32:42 -08004838 final Rect cr = ws.mContentInsets;
4839 int left = wf.left + cr.left;
4840 int top = wf.top + cr.top;
4841 int right = wf.right - cr.right;
4842 int bottom = wf.bottom - cr.bottom;
4843 frame.union(left, top, right, bottom);
4844 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004845 }
4846 Binder.restoreCallingIdentity(ident);
4847
Dianne Hackborndd962ee2011-02-02 11:11:50 -08004848 // Constrain frame to the screen size.
4849 frame.intersect(0, 0, dw, dh);
Jim Millere70d5062011-03-08 21:38:39 -08004850
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08004851 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004852 return null;
4853 }
4854
4855 // The screenshot API does not apply the current screen rotation.
4856 rot = mDisplay.getRotation();
4857 int fw = frame.width();
4858 int fh = frame.height();
4859
4860 // First try reducing to fit in x dimension.
Jim Millere70d5062011-03-08 21:38:39 -08004861 scale = width/(float)fw;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004862
4863 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08004864 dw = (int)(dw*scale);
4865 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004866 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
4867 int tmp = dw;
4868 dw = dh;
4869 dh = tmp;
4870 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
4871 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08004872 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004873 }
4874
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08004875 if (rawss == null) {
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08004876 Log.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
4877 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08004878 return null;
4879 }
Jim Millere70d5062011-03-08 21:38:39 -08004880
4881 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004882 Matrix matrix = new Matrix();
4883 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
4884 matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
4885 Canvas canvas = new Canvas(bm);
4886 canvas.drawBitmap(rawss, matrix, null);
4887
4888 rawss.recycle();
4889 return bm;
4890 }
4891
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004892 public void freezeRotation() {
4893 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05004894 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004895 throw new SecurityException("Requires SET_ORIENTATION permission");
4896 }
4897
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05004898 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
4899
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004900 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
4901 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4902 }
4903
4904 public void thawRotation() {
4905 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05004906 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004907 throw new SecurityException("Requires SET_ORIENTATION permission");
4908 }
4909
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05004910 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
4911
4912 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
Daniel Sandlerb73617d2010-08-17 00:41:00 -04004913 setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
4914 }
4915
Romain Guy06882f82009-06-10 13:36:04 -07004916 public void setRotation(int rotation,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004917 boolean alwaysSendConfiguration, int animFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004918 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004919 "setRotation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004920 throw new SecurityException("Requires SET_ORIENTATION permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004921 }
4922
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004923 setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004924 }
Romain Guy06882f82009-06-10 13:36:04 -07004925
Dianne Hackborn1e880db2009-03-27 16:04:08 -07004926 public void setRotationUnchecked(int rotation,
4927 boolean alwaysSendConfiguration, int animFlags) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004928 if(DEBUG_ORIENTATION) Slog.v(TAG,
David 'Digit' Turner910a0682011-02-05 00:34:46 +01004929 "setRotationUnchecked(rotation=" + rotation +
4930 " alwaysSendConfiguration=" + alwaysSendConfiguration +
4931 " animFlags=" + animFlags);
Romain Guy06882f82009-06-10 13:36:04 -07004932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 long origId = Binder.clearCallingIdentity();
4934 boolean changed;
4935 synchronized(mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004936 changed = setRotationUncheckedLocked(rotation, animFlags, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004937 }
Romain Guy06882f82009-06-10 13:36:04 -07004938
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004939 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004940 sendNewConfiguration();
4941 }
Romain Guy06882f82009-06-10 13:36:04 -07004942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943 Binder.restoreCallingIdentity(origId);
4944 }
Romain Guy06882f82009-06-10 13:36:04 -07004945
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004946 /**
4947 * Apply a new rotation to the screen, respecting the requests of
4948 * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply
4949 * re-evaluate the desired rotation.
4950 *
4951 * Returns null if the rotation has been changed. In this case YOU
4952 * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
4953 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08004954 public boolean setRotationUncheckedLocked(int rotation, int animFlags, boolean inTransaction) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004955 if (mDragState != null || mScreenRotationAnimation != null) {
Christopher Tateccd24de2011-01-12 15:02:55 -08004956 // Potential rotation during a drag. Don't do the rotation now, but make
4957 // a note to perform the rotation later.
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004958 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation.");
4959 if (rotation != WindowManagerPolicy.USE_LAST_ROTATION) {
4960 mDeferredRotation = rotation;
4961 mDeferredRotationAnimFlags = animFlags;
4962 }
Christopher Tateccd24de2011-01-12 15:02:55 -08004963 return false;
4964 }
4965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004966 boolean changed;
4967 if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004968 if (mDeferredRotation != WindowManagerPolicy.USE_LAST_ROTATION) {
4969 rotation = mDeferredRotation;
4970 mRequestedRotation = rotation;
4971 mLastRotationFlags = mDeferredRotationAnimFlags;
4972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004973 rotation = mRequestedRotation;
4974 } else {
4975 mRequestedRotation = rotation;
Dianne Hackborn321ae682009-03-27 16:16:03 -07004976 mLastRotationFlags = animFlags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004977 }
Dianne Hackborn89ba6752011-01-23 16:51:16 -08004978 mDeferredRotation = WindowManagerPolicy.USE_LAST_ROTATION;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004979 if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07004980 rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004981 mRotation, mDisplayEnabled);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004982 if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -07004983
4984 int desiredRotation = rotation;
4985 int lockedRotation = mPolicy.getLockedRotationLw();
4986 if (lockedRotation >= 0 && rotation != lockedRotation) {
4987 // We are locked in a rotation but something is requesting
4988 // a different rotation... we will either keep the locked
4989 // rotation if it results in the same orientation, or have to
4990 // switch into an emulated orientation mode.
4991
4992 // First, we know that our rotation is actually going to be
4993 // the locked rotation.
4994 rotation = lockedRotation;
4995
4996 // Now the difference between the desired and lockedRotation
4997 // may mean that the orientation is different... if that is
4998 // not the case, we can just make the desired rotation be the
4999 // same as the new locked rotation.
5000 switch (lockedRotation) {
5001 case Surface.ROTATION_0:
5002 if (rotation == Surface.ROTATION_180) {
5003 desiredRotation = lockedRotation;
5004 }
5005 break;
5006 case Surface.ROTATION_90:
5007 if (rotation == Surface.ROTATION_270) {
5008 desiredRotation = lockedRotation;
5009 }
5010 break;
5011 case Surface.ROTATION_180:
5012 if (rotation == Surface.ROTATION_0) {
5013 desiredRotation = lockedRotation;
5014 }
5015 break;
5016 case Surface.ROTATION_270:
5017 if (rotation == Surface.ROTATION_90) {
5018 desiredRotation = lockedRotation;
5019 }
5020 break;
5021 }
5022 }
5023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 changed = mDisplayEnabled && mRotation != rotation;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005025 if (mAltOrientation != (rotation != desiredRotation)) {
5026 changed = true;
5027 mAltOrientation = rotation != desiredRotation;
5028 }
Romain Guy06882f82009-06-10 13:36:04 -07005029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005030 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005031 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005032 "Rotation changed to " + rotation
5033 + " from " + mRotation
5034 + " (forceApp=" + mForcedAppOrientation
5035 + ", req=" + mRequestedRotation + ")");
5036 mRotation = rotation;
5037 mWindowsFreezingScreen = true;
5038 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5039 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
5040 2000);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005041 mWaitingForConfig = true;
5042 mLayoutNeeded = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005043 startFreezingDisplayLocked(inTransaction);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005044 Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005045 mInputManager.setDisplayOrientation(0, rotation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005046 if (mDisplayEnabled) {
David 'Digit' Turner910a0682011-02-05 00:34:46 +01005047 // NOTE: We disable the rotation in the emulator because
5048 // it doesn't support hardware OpenGL emulation yet.
Dianne Hackbornde75cb42011-03-02 17:11:21 -08005049 if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
5050 && mScreenRotationAnimation.hasScreenshot()) {
Dianne Hackborna1111872010-11-23 20:55:11 -08005051 Surface.freezeDisplay(0);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005052 if (!inTransaction) {
5053 if (SHOW_TRANSACTIONS) Slog.i(TAG,
5054 ">>> OPEN TRANSACTION setRotationUnchecked");
5055 Surface.openTransaction();
Dianne Hackborna1111872010-11-23 20:55:11 -08005056 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005057 try {
5058 if (mScreenRotationAnimation != null) {
5059 mScreenRotationAnimation.setRotation(rotation);
5060 }
5061 } finally {
5062 if (!inTransaction) {
5063 Surface.closeTransaction();
5064 if (SHOW_TRANSACTIONS) Slog.i(TAG,
5065 "<<< CLOSE TRANSACTION setRotationUnchecked");
5066 }
5067 }
Dianne Hackborna1111872010-11-23 20:55:11 -08005068 Surface.setOrientation(0, rotation, animFlags);
5069 Surface.unfreezeDisplay(0);
5070 } else {
5071 Surface.setOrientation(0, rotation, animFlags);
5072 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07005073 rebuildBlackFrame(inTransaction);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005074 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07005077 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005078 if (w.mSurface != null) {
5079 w.mOrientationChanging = true;
5080 }
5081 }
5082 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5083 try {
5084 mRotationWatchers.get(i).onRotationChanged(rotation);
5085 } catch (RemoteException e) {
5086 }
5087 }
5088 } //end if changed
Romain Guy06882f82009-06-10 13:36:04 -07005089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005090 return changed;
5091 }
Romain Guy06882f82009-06-10 13:36:04 -07005092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005093 public int getRotation() {
5094 return mRotation;
5095 }
5096
5097 public int watchRotation(IRotationWatcher watcher) {
5098 final IBinder watcherBinder = watcher.asBinder();
5099 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5100 public void binderDied() {
5101 synchronized (mWindowMap) {
5102 for (int i=0; i<mRotationWatchers.size(); i++) {
5103 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07005104 IRotationWatcher removed = mRotationWatchers.remove(i);
5105 if (removed != null) {
5106 removed.asBinder().unlinkToDeath(this, 0);
5107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005108 i--;
5109 }
5110 }
5111 }
5112 }
5113 };
Romain Guy06882f82009-06-10 13:36:04 -07005114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005115 synchronized (mWindowMap) {
5116 try {
5117 watcher.asBinder().linkToDeath(dr, 0);
5118 mRotationWatchers.add(watcher);
5119 } catch (RemoteException e) {
5120 // Client died, no cleanup needed.
5121 }
Romain Guy06882f82009-06-10 13:36:04 -07005122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 return mRotation;
5124 }
5125 }
5126
5127 /**
5128 * Starts the view server on the specified port.
5129 *
5130 * @param port The port to listener to.
5131 *
5132 * @return True if the server was successfully started, false otherwise.
5133 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005134 * @see com.android.server.wm.ViewServer
5135 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005136 */
5137 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07005138 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005139 return false;
5140 }
5141
5142 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
5143 return false;
5144 }
5145
5146 if (port < 1024) {
5147 return false;
5148 }
5149
5150 if (mViewServer != null) {
5151 if (!mViewServer.isRunning()) {
5152 try {
5153 return mViewServer.start();
5154 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005155 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156 }
5157 }
5158 return false;
5159 }
5160
5161 try {
5162 mViewServer = new ViewServer(this, port);
5163 return mViewServer.start();
5164 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005165 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005166 }
5167 return false;
5168 }
5169
Romain Guy06882f82009-06-10 13:36:04 -07005170 private boolean isSystemSecure() {
5171 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
5172 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5173 }
5174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005175 /**
5176 * Stops the view server if it exists.
5177 *
5178 * @return True if the server stopped, false if it wasn't started or
5179 * couldn't be stopped.
5180 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005181 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005182 */
5183 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07005184 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 return false;
5186 }
5187
5188 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
5189 return false;
5190 }
5191
5192 if (mViewServer != null) {
5193 return mViewServer.stop();
5194 }
5195 return false;
5196 }
5197
5198 /**
5199 * Indicates whether the view server is running.
5200 *
5201 * @return True if the server is running, false otherwise.
5202 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08005203 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 */
5205 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07005206 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 return false;
5208 }
5209
5210 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
5211 return false;
5212 }
5213
5214 return mViewServer != null && mViewServer.isRunning();
5215 }
5216
5217 /**
5218 * Lists all availble windows in the system. The listing is written in the
5219 * specified Socket's output stream with the following syntax:
5220 * windowHashCodeInHexadecimal windowName
5221 * Each line of the ouput represents a different window.
5222 *
5223 * @param client The remote client to send the listing to.
5224 * @return False if an error occured, true otherwise.
5225 */
5226 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07005227 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005228 return false;
5229 }
5230
5231 boolean result = true;
5232
Jeff Browne33348b2010-07-15 23:54:05 -07005233 WindowState[] windows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005234 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005235 //noinspection unchecked
Jeff Browne33348b2010-07-15 23:54:05 -07005236 windows = mWindows.toArray(new WindowState[mWindows.size()]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005237 }
5238
5239 BufferedWriter out = null;
5240
5241 // Any uncaught exception will crash the system process
5242 try {
5243 OutputStream clientStream = client.getOutputStream();
5244 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5245
5246 final int count = windows.length;
5247 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005248 final WindowState w = windows[i];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 out.write(Integer.toHexString(System.identityHashCode(w)));
5250 out.write(' ');
5251 out.append(w.mAttrs.getTitle());
5252 out.write('\n');
5253 }
5254
5255 out.write("DONE.\n");
5256 out.flush();
5257 } catch (Exception e) {
5258 result = false;
5259 } finally {
5260 if (out != null) {
5261 try {
5262 out.close();
5263 } catch (IOException e) {
5264 result = false;
5265 }
5266 }
5267 }
5268
5269 return result;
5270 }
5271
5272 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07005273 * Returns the focused window in the following format:
5274 * windowHashCodeInHexadecimal windowName
5275 *
5276 * @param client The remote client to send the listing to.
5277 * @return False if an error occurred, true otherwise.
5278 */
5279 boolean viewServerGetFocusedWindow(Socket client) {
5280 if (isSystemSecure()) {
5281 return false;
5282 }
5283
5284 boolean result = true;
5285
5286 WindowState focusedWindow = getFocusedWindow();
5287
5288 BufferedWriter out = null;
5289
5290 // Any uncaught exception will crash the system process
5291 try {
5292 OutputStream clientStream = client.getOutputStream();
5293 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
5294
5295 if(focusedWindow != null) {
5296 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
5297 out.write(' ');
5298 out.append(focusedWindow.mAttrs.getTitle());
5299 }
5300 out.write('\n');
5301 out.flush();
5302 } catch (Exception e) {
5303 result = false;
5304 } finally {
5305 if (out != null) {
5306 try {
5307 out.close();
5308 } catch (IOException e) {
5309 result = false;
5310 }
5311 }
5312 }
5313
5314 return result;
5315 }
5316
5317 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 * Sends a command to a target window. The result of the command, if any, will be
5319 * written in the output stream of the specified socket.
5320 *
5321 * The parameters must follow this syntax:
5322 * windowHashcode extra
5323 *
5324 * Where XX is the length in characeters of the windowTitle.
5325 *
5326 * The first parameter is the target window. The window with the specified hashcode
5327 * will be the target. If no target can be found, nothing happens. The extra parameters
5328 * will be delivered to the target window and as parameters to the command itself.
5329 *
5330 * @param client The remote client to sent the result, if any, to.
5331 * @param command The command to execute.
5332 * @param parameters The command parameters.
5333 *
5334 * @return True if the command was successfully delivered, false otherwise. This does
5335 * not indicate whether the command itself was successful.
5336 */
5337 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07005338 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005339 return false;
5340 }
5341
5342 boolean success = true;
5343 Parcel data = null;
5344 Parcel reply = null;
5345
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005346 BufferedWriter out = null;
5347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 // Any uncaught exception will crash the system process
5349 try {
5350 // Find the hashcode of the window
5351 int index = parameters.indexOf(' ');
5352 if (index == -1) {
5353 index = parameters.length();
5354 }
5355 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08005356 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005357
5358 // Extract the command's parameter after the window description
5359 if (index < parameters.length()) {
5360 parameters = parameters.substring(index + 1);
5361 } else {
5362 parameters = "";
5363 }
5364
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005365 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005366 if (window == null) {
5367 return false;
5368 }
5369
5370 data = Parcel.obtain();
5371 data.writeInterfaceToken("android.view.IWindow");
5372 data.writeString(command);
5373 data.writeString(parameters);
5374 data.writeInt(1);
5375 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
5376
5377 reply = Parcel.obtain();
5378
5379 final IBinder binder = window.mClient.asBinder();
5380 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
5381 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
5382
5383 reply.readException();
5384
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005385 if (!client.isOutputShutdown()) {
5386 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
5387 out.write("DONE\n");
5388 out.flush();
5389 }
5390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005391 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005392 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 success = false;
5394 } finally {
5395 if (data != null) {
5396 data.recycle();
5397 }
5398 if (reply != null) {
5399 reply.recycle();
5400 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07005401 if (out != null) {
5402 try {
5403 out.close();
5404 } catch (IOException e) {
5405
5406 }
5407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005408 }
5409
5410 return success;
5411 }
5412
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07005413 public void addWindowChangeListener(WindowChangeListener listener) {
5414 synchronized(mWindowMap) {
5415 mWindowChangeListeners.add(listener);
5416 }
5417 }
5418
5419 public void removeWindowChangeListener(WindowChangeListener listener) {
5420 synchronized(mWindowMap) {
5421 mWindowChangeListeners.remove(listener);
5422 }
5423 }
5424
5425 private void notifyWindowsChanged() {
5426 WindowChangeListener[] windowChangeListeners;
5427 synchronized(mWindowMap) {
5428 if(mWindowChangeListeners.isEmpty()) {
5429 return;
5430 }
5431 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5432 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5433 }
5434 int N = windowChangeListeners.length;
5435 for(int i = 0; i < N; i++) {
5436 windowChangeListeners[i].windowsChanged();
5437 }
5438 }
5439
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07005440 private void notifyFocusChanged() {
5441 WindowChangeListener[] windowChangeListeners;
5442 synchronized(mWindowMap) {
5443 if(mWindowChangeListeners.isEmpty()) {
5444 return;
5445 }
5446 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
5447 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
5448 }
5449 int N = windowChangeListeners.length;
5450 for(int i = 0; i < N; i++) {
5451 windowChangeListeners[i].focusChanged();
5452 }
5453 }
5454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005455 private WindowState findWindow(int hashCode) {
5456 if (hashCode == -1) {
5457 return getFocusedWindow();
5458 }
5459
5460 synchronized (mWindowMap) {
Jeff Browne33348b2010-07-15 23:54:05 -07005461 final ArrayList<WindowState> windows = mWindows;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 final int count = windows.size();
5463
5464 for (int i = 0; i < count; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07005465 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 if (System.identityHashCode(w) == hashCode) {
5467 return w;
5468 }
5469 }
5470 }
5471
5472 return null;
5473 }
5474
5475 /*
5476 * Instruct the Activity Manager to fetch the current configuration and broadcast
5477 * that to config-changed listeners if appropriate.
5478 */
5479 void sendNewConfiguration() {
5480 try {
5481 mActivityManager.updateConfiguration(null);
5482 } catch (RemoteException e) {
5483 }
5484 }
Romain Guy06882f82009-06-10 13:36:04 -07005485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005486 public Configuration computeNewConfiguration() {
5487 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005488 Configuration config = computeNewConfigurationLocked();
5489 if (config == null && mWaitingForConfig) {
5490 // Nothing changed but we are waiting for something... stop that!
5491 mWaitingForConfig = false;
5492 performLayoutAndPlaceSurfacesLocked();
5493 }
5494 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07005495 }
5496 }
Romain Guy06882f82009-06-10 13:36:04 -07005497
Dianne Hackbornc485a602009-03-24 22:39:49 -07005498 Configuration computeNewConfigurationLocked() {
5499 Configuration config = new Configuration();
5500 if (!computeNewConfigurationLocked(config)) {
5501 return null;
5502 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07005503 return config;
5504 }
Romain Guy06882f82009-06-10 13:36:04 -07005505
Dianne Hackbornc485a602009-03-24 22:39:49 -07005506 boolean computeNewConfigurationLocked(Configuration config) {
5507 if (mDisplay == null) {
5508 return false;
5509 }
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005510
5511 mInputManager.getInputConfiguration(config);
Christopher Tateb696aee2010-04-02 19:08:30 -07005512
5513 // Use the effective "visual" dimensions based on current rotation
5514 final boolean rotated = (mRotation == Surface.ROTATION_90
5515 || mRotation == Surface.ROTATION_270);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07005516 final int realdw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
5517 final int realdh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005518
5519 if (mAltOrientation) {
5520 mCurDisplayWidth = realdw;
5521 mCurDisplayHeight = realdh;
5522 if (realdw > realdh) {
5523 // Turn landscape into portrait.
5524 int maxw = (int)(realdh/1.3f);
5525 if (maxw < realdw) {
5526 mCurDisplayWidth = maxw;
5527 }
5528 } else {
5529 // Turn portrait into landscape.
5530 int maxh = (int)(realdw/1.3f);
5531 if (maxh < realdh) {
5532 mCurDisplayHeight = maxh;
5533 }
5534 }
5535 } else {
5536 mCurDisplayWidth = realdw;
5537 mCurDisplayHeight = realdh;
5538 }
5539
5540 final int dw = mCurDisplayWidth;
5541 final int dh = mCurDisplayHeight;
Christopher Tateb696aee2010-04-02 19:08:30 -07005542
Dianne Hackbornc485a602009-03-24 22:39:49 -07005543 int orientation = Configuration.ORIENTATION_SQUARE;
5544 if (dw < dh) {
5545 orientation = Configuration.ORIENTATION_PORTRAIT;
5546 } else if (dw > dh) {
5547 orientation = Configuration.ORIENTATION_LANDSCAPE;
5548 }
5549 config.orientation = orientation;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005550
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005551 DisplayMetrics dm = new DisplayMetrics();
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005552 mDisplay.getRealMetrics(dm);
5553
5554 // Override display width and height with what we are computing,
5555 // to be sure they remain consistent.
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07005556 dm.widthPixels = mPolicy.getNonDecorDisplayWidth(dw);
5557 dm.heightPixels = mPolicy.getNonDecorDisplayHeight(dh);
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005558
Dianne Hackborne2515ee2011-04-27 18:52:56 -04005559 mCompatibleScreenScale = CompatibilityInfo.updateCompatibleScreenFrame(
5560 dm, mCompatibleScreenFrame, null);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005561
Dianne Hackborn3fc982f2011-03-30 16:20:26 -07005562 config.screenWidthDp = (int)(dm.widthPixels / dm.density);
5563 config.screenHeightDp = (int)(dm.heightPixels / dm.density);
5564
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005565 // Compute the screen layout size class.
5566 int screenLayout;
5567 int longSize = dw;
5568 int shortSize = dh;
5569 if (longSize < shortSize) {
5570 int tmp = longSize;
5571 longSize = shortSize;
5572 shortSize = tmp;
5573 }
5574 longSize = (int)(longSize/dm.density);
5575 shortSize = (int)(shortSize/dm.density);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07005576
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005577 // These semi-magic numbers define our compatibility modes for
5578 // applications with different screens. These are guarantees to
5579 // app developers about the space they can expect for a particular
5580 // configuration. DO NOT CHANGE!
5581 if (longSize < 470) {
5582 // This is shorter than an HVGA normal density screen (which
5583 // is 480 pixels on its long side).
5584 screenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5585 | Configuration.SCREENLAYOUT_LONG_NO;
5586 } else {
5587 // What size is this screen screen?
5588 if (longSize >= 960 && shortSize >= 720) {
5589 // 1.5xVGA or larger screens at medium density are the point
5590 // at which we consider it to be an extra large screen.
5591 screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5592 } else if (longSize >= 640 && shortSize >= 480) {
5593 // VGA or larger screens at medium density are the point
5594 // at which we consider it to be a large screen.
5595 screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005596 } else {
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005597 screenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
5598 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005599
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005600 // If this screen is wider than normal HVGA, or taller
5601 // than FWVGA, then for old apps we want to run in size
5602 // compatibility mode.
5603 if (shortSize > 321 || longSize > 570) {
5604 screenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5605 }
5606
5607 // Is this a long screen?
5608 if (((longSize*3)/5) >= (shortSize-1)) {
5609 // Anything wider than WVGA (5:3) is considering to be long.
5610 screenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5611 } else {
5612 screenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
Dianne Hackborn723738c2009-06-25 19:48:04 -07005613 }
5614 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07005615 config.screenLayout = screenLayout;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005616
Jeff Brown597eec82011-01-31 17:12:25 -08005617 // Determine whether a hard keyboard is available and enabled.
Jeff Brown2992ea72011-01-28 22:04:14 -08005618 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
5619 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
5620 mHardKeyboardAvailable = hardKeyboardAvailable;
5621 mHardKeyboardEnabled = hardKeyboardAvailable;
5622
5623 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5624 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
5625 }
5626 if (!mHardKeyboardEnabled) {
5627 config.keyboard = Configuration.KEYBOARD_NOKEYS;
Jeff Brown2992ea72011-01-28 22:04:14 -08005628 }
Jeff Brown597eec82011-01-31 17:12:25 -08005629
5630 // Update value of keyboardHidden, hardKeyboardHidden and navigationHidden
5631 // based on whether a hard or soft keyboard is present, whether navigation keys
5632 // are present and the lid switch state.
5633 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
5634 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
5635 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
5636 mPolicy.adjustConfigurationLw(config);
Dianne Hackbornc485a602009-03-24 22:39:49 -07005637 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005639
Jeff Brown2992ea72011-01-28 22:04:14 -08005640 public boolean isHardKeyboardAvailable() {
5641 synchronized (mWindowMap) {
5642 return mHardKeyboardAvailable;
5643 }
5644 }
5645
5646 public boolean isHardKeyboardEnabled() {
5647 synchronized (mWindowMap) {
5648 return mHardKeyboardEnabled;
5649 }
5650 }
5651
5652 public void setHardKeyboardEnabled(boolean enabled) {
5653 synchronized (mWindowMap) {
5654 if (mHardKeyboardEnabled != enabled) {
5655 mHardKeyboardEnabled = enabled;
5656 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5657 }
5658 }
5659 }
5660
5661 public void setOnHardKeyboardStatusChangeListener(
5662 OnHardKeyboardStatusChangeListener listener) {
5663 synchronized (mWindowMap) {
5664 mHardKeyboardStatusChangeListener = listener;
5665 }
5666 }
5667
5668 void notifyHardKeyboardStatusChange() {
5669 final boolean available, enabled;
5670 final OnHardKeyboardStatusChangeListener listener;
5671 synchronized (mWindowMap) {
5672 listener = mHardKeyboardStatusChangeListener;
5673 available = mHardKeyboardAvailable;
5674 enabled = mHardKeyboardEnabled;
5675 }
5676 if (listener != null) {
5677 listener.onHardKeyboardStatusChange(available, enabled);
5678 }
5679 }
5680
Christopher Tatea53146c2010-09-07 11:57:52 -07005681 // -------------------------------------------------------------
5682 // Drag and drop
5683 // -------------------------------------------------------------
5684
5685 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005686 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07005687 if (DEBUG_DRAG) {
5688 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08005689 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07005690 + " asbinder=" + window.asBinder());
5691 }
5692
5693 final int callerPid = Binder.getCallingPid();
5694 final long origId = Binder.clearCallingIdentity();
5695 IBinder token = null;
5696
5697 try {
5698 synchronized (mWindowMap) {
5699 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07005700 if (mDragState == null) {
5701 Surface surface = new Surface(session, callerPid, "drag surface", 0,
5702 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Dianne Hackbornac1471a2011-02-03 13:46:06 -08005703 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
5704 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07005705 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07005706 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07005707 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005708 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005709 mDragState.mSurface = surface;
Christopher Tatea53146c2010-09-07 11:57:52 -07005710 token = mDragState.mToken = new Binder();
5711
5712 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07005713 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
5714 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07005715 mH.sendMessageDelayed(msg, 5000);
5716 } else {
5717 Slog.w(TAG, "Drag already in progress");
5718 }
5719 } catch (Surface.OutOfResourcesException e) {
5720 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
5721 if (mDragState != null) {
5722 mDragState.reset();
5723 mDragState = null;
5724 }
Christopher Tatea53146c2010-09-07 11:57:52 -07005725 }
5726 }
5727 } finally {
5728 Binder.restoreCallingIdentity(origId);
5729 }
5730
5731 return token;
5732 }
5733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005734 // -------------------------------------------------------------
5735 // Input Events and Focus Management
5736 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07005737
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005738 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown349703e2010-06-22 01:27:15 -07005739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 public void pauseKeyDispatching(IBinder _token) {
5741 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5742 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005743 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744 }
5745
5746 synchronized (mWindowMap) {
5747 WindowToken token = mTokenMap.get(_token);
5748 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005749 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005750 }
5751 }
5752 }
5753
5754 public void resumeKeyDispatching(IBinder _token) {
5755 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5756 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005757 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005758 }
5759
5760 synchronized (mWindowMap) {
5761 WindowToken token = mTokenMap.get(_token);
5762 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005763 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005764 }
5765 }
5766 }
5767
5768 public void setEventDispatching(boolean enabled) {
5769 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5770 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005771 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005772 }
5773
5774 synchronized (mWindowMap) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005775 mInputMonitor.setEventDispatchingLw(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005776 }
5777 }
Romain Guy06882f82009-06-10 13:36:04 -07005778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 /**
5780 * Injects a keystroke event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005781 * Even when sync is false, this method may block while waiting for current
5782 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005783 *
5784 * @param ev A motion event describing the keystroke action. (Be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005785 * {@link SystemClock#uptimeMillis()} as the timebase.)
5786 * @param sync If true, wait for the event to be completed before returning to the caller.
5787 * @return Returns true if event was dispatched, false if it was dropped for any reason
5788 */
5789 public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
5790 long downTime = ev.getDownTime();
5791 long eventTime = ev.getEventTime();
5792
5793 int action = ev.getAction();
5794 int code = ev.getKeyCode();
5795 int repeatCount = ev.getRepeatCount();
5796 int metaState = ev.getMetaState();
5797 int deviceId = ev.getDeviceId();
5798 int scancode = ev.getScanCode();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005799 int source = ev.getSource();
Mike Playlec6ded102010-11-29 16:01:03 +00005800 int flags = ev.getFlags();
Jeff Brownc5ed5912010-07-14 18:48:53 -07005801
5802 if (source == InputDevice.SOURCE_UNKNOWN) {
5803 source = InputDevice.SOURCE_KEYBOARD;
5804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005805
5806 if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
5807 if (downTime == 0) downTime = eventTime;
5808
5809 KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
Jean-Baptiste Queru4a880132010-12-02 15:16:53 -08005810 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005811
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005812 final int pid = Binder.getCallingPid();
5813 final int uid = Binder.getCallingUid();
5814 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005815
Jeff Brownbbda99d2010-07-28 15:48:59 -07005816 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5817 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5818 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5819 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07005820
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005821 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005822 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005823 }
5824
5825 /**
5826 * Inject a pointer (touch) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005827 * Even when sync is false, this method may block while waiting for current
5828 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005829 *
5830 * @param ev A motion event describing the pointer (touch) action. (As noted in
5831 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005832 * {@link SystemClock#uptimeMillis()} as the timebase.)
5833 * @param sync If true, wait for the event to be completed before returning to the caller.
5834 * @return Returns true if event was dispatched, false if it was dropped for any reason
5835 */
5836 public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005837 final int pid = Binder.getCallingPid();
5838 final int uid = Binder.getCallingUid();
5839 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005840
Jeff Brownc5ed5912010-07-14 18:48:53 -07005841 MotionEvent newEvent = MotionEvent.obtain(ev);
5842 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
5843 newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
5844 }
5845
Jeff Brownbbda99d2010-07-28 15:48:59 -07005846 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5847 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5848 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5849 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07005850
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005851 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005852 return reportInjectionResult(result);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005853 }
Romain Guy06882f82009-06-10 13:36:04 -07005854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005855 /**
5856 * Inject a trackball (navigation device) event into the UI.
Jeff Brownbbda99d2010-07-28 15:48:59 -07005857 * Even when sync is false, this method may block while waiting for current
5858 * input events to be dispatched.
Romain Guy06882f82009-06-10 13:36:04 -07005859 *
5860 * @param ev A motion event describing the trackball action. (As noted in
5861 * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 * {@link SystemClock#uptimeMillis()} as the timebase.)
5863 * @param sync If true, wait for the event to be completed before returning to the caller.
5864 * @return Returns true if event was dispatched, false if it was dropped for any reason
5865 */
5866 public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005867 final int pid = Binder.getCallingPid();
5868 final int uid = Binder.getCallingUid();
5869 final long ident = Binder.clearCallingIdentity();
Jeff Brown46b9ac02010-04-22 18:58:52 -07005870
Jeff Brownc5ed5912010-07-14 18:48:53 -07005871 MotionEvent newEvent = MotionEvent.obtain(ev);
5872 if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
5873 newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
5874 }
5875
Jeff Brownbbda99d2010-07-28 15:48:59 -07005876 final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
5877 sync ? InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
5878 : InputManager.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
5879 INJECTION_TIMEOUT_MILLIS);
5880
5881 Binder.restoreCallingIdentity(ident);
5882 return reportInjectionResult(result);
5883 }
5884
5885 /**
5886 * Inject an input event into the UI without waiting for dispatch to commence.
5887 * This variant is useful for fire-and-forget input event injection. It does not
5888 * block any longer than it takes to enqueue the input event.
5889 *
5890 * @param ev An input event. (Be sure to set the input source correctly.)
5891 * @return Returns true if event was dispatched, false if it was dropped for any reason
5892 */
5893 public boolean injectInputEventNoWait(InputEvent ev) {
5894 final int pid = Binder.getCallingPid();
5895 final int uid = Binder.getCallingUid();
5896 final long ident = Binder.clearCallingIdentity();
5897
5898 final int result = mInputManager.injectInputEvent(ev, pid, uid,
5899 InputManager.INPUT_EVENT_INJECTION_SYNC_NONE,
5900 INJECTION_TIMEOUT_MILLIS);
Jeff Brown46b9ac02010-04-22 18:58:52 -07005901
Dianne Hackborn2bd33d72009-06-26 18:59:01 -07005902 Binder.restoreCallingIdentity(ident);
Jeff Brown7fbdc842010-06-17 20:52:56 -07005903 return reportInjectionResult(result);
5904 }
5905
5906 private boolean reportInjectionResult(int result) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005907 switch (result) {
5908 case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
5909 Slog.w(TAG, "Input event injection permission denied.");
5910 throw new SecurityException(
5911 "Injecting to another application requires INJECT_EVENTS permission");
5912 case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
Christopher Tate09e85dc2010-08-02 11:54:41 -07005913 //Slog.v(TAG, "Input event injection succeeded.");
Jeff Brown00fa7bd2010-07-02 15:37:36 -07005914 return true;
5915 case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
5916 Slog.w(TAG, "Input event injection timed out.");
5917 return false;
5918 case InputManager.INPUT_EVENT_INJECTION_FAILED:
5919 default:
5920 Slog.w(TAG, "Input event injection failed.");
5921 return false;
Dianne Hackborncfaef692009-06-15 14:24:44 -07005922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005923 }
Romain Guy06882f82009-06-10 13:36:04 -07005924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005925 private WindowState getFocusedWindow() {
5926 synchronized (mWindowMap) {
5927 return getFocusedWindowLocked();
5928 }
5929 }
5930
5931 private WindowState getFocusedWindowLocked() {
5932 return mCurrentFocus;
5933 }
Romain Guy06882f82009-06-10 13:36:04 -07005934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005935 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08005936 if (!mInputMonitor.waitForInputDevicesReady(
5937 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
5938 Slog.w(TAG, "Devices still not ready after waiting "
5939 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
5940 + " milliseconds before attempting to detect safe mode.");
5941 }
5942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005943 mSafeMode = mPolicy.detectSafeMode();
5944 return mSafeMode;
5945 }
Romain Guy06882f82009-06-10 13:36:04 -07005946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 public void systemReady() {
Dianne Hackborn5132b372010-07-29 12:51:35 -07005948 synchronized(mWindowMap) {
5949 if (mDisplay != null) {
5950 throw new IllegalStateException("Display already initialized");
5951 }
5952 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
5953 mDisplay = wm.getDefaultDisplay();
Dianne Hackborn7916ac62011-05-16 20:45:48 -07005954 mInitialDisplayWidth = mDisplay.getRealWidth();
5955 mInitialDisplayHeight = mDisplay.getRealHeight();
5956 int rot = mDisplay.getRotation();
5957 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5958 // If the screen is currently rotated, we need to swap the
5959 // initial width and height to get the true natural values.
5960 int tmp = mInitialDisplayWidth;
5961 mInitialDisplayWidth = mInitialDisplayHeight;
5962 mInitialDisplayHeight = tmp;
5963 }
5964 mBaseDisplayWidth = mCurDisplayWidth = mInitialDisplayWidth;
5965 mBaseDisplayHeight = mCurDisplayHeight = mInitialDisplayHeight;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07005966 mInputManager.setDisplaySize(0, mDisplay.getRawWidth(), mDisplay.getRawHeight());
Dianne Hackborn9d132642011-04-21 17:26:39 -07005967 mPolicy.setInitialDisplaySize(mInitialDisplayWidth, mInitialDisplayHeight);
Dianne Hackborn5132b372010-07-29 12:51:35 -07005968 }
5969
5970 try {
5971 mActivityManager.updateConfiguration(null);
5972 } catch (RemoteException e) {
5973 }
Dianne Hackborn154db5f2010-07-29 19:15:19 -07005974
5975 mPolicy.systemReady();
Dianne Hackborn5132b372010-07-29 12:51:35 -07005976 }
5977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 // This is an animation that does nothing: it just immediately finishes
5979 // itself every time it is called. It is used as a stub animation in cases
5980 // where we want to synchronize multiple things that may be animating.
5981 static final class DummyAnimation extends Animation {
5982 public boolean getTransformation(long currentTime, Transformation outTransformation) {
5983 return false;
5984 }
5985 }
5986 static final Animation sDummyAnimation = new DummyAnimation();
Romain Guy06882f82009-06-10 13:36:04 -07005987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005988 // -------------------------------------------------------------
5989 // Async Handler
5990 // -------------------------------------------------------------
5991
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08005992 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005993 public static final int REPORT_FOCUS_CHANGE = 2;
5994 public static final int REPORT_LOSING_FOCUS = 3;
5995 public static final int ANIMATE = 4;
5996 public static final int ADD_STARTING = 5;
5997 public static final int REMOVE_STARTING = 6;
5998 public static final int FINISHED_STARTING = 7;
5999 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006000 public static final int WINDOW_FREEZE_TIMEOUT = 11;
6001 public static final int HOLD_SCREEN_CHANGED = 12;
6002 public static final int APP_TRANSITION_TIMEOUT = 13;
6003 public static final int PERSIST_ANIMATION_SCALE = 14;
6004 public static final int FORCE_GC = 15;
6005 public static final int ENABLE_SCREEN = 16;
6006 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006007 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006008 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07006009 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07006010 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08006011 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Romain Guy06882f82009-06-10 13:36:04 -07006012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006013 private Session mLastReportedHold;
Romain Guy06882f82009-06-10 13:36:04 -07006014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006015 public H() {
6016 }
Romain Guy06882f82009-06-10 13:36:04 -07006017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006018 @Override
6019 public void handleMessage(Message msg) {
6020 switch (msg.what) {
6021 case REPORT_FOCUS_CHANGE: {
6022 WindowState lastFocus;
6023 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07006024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006025 synchronized(mWindowMap) {
6026 lastFocus = mLastFocus;
6027 newFocus = mCurrentFocus;
6028 if (lastFocus == newFocus) {
6029 // Focus is not changing, so nothing to do.
6030 return;
6031 }
6032 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006033 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006034 // + " to " + newFocus);
6035 if (newFocus != null && lastFocus != null
6036 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006037 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006038 mLosingFocus.add(lastFocus);
6039 lastFocus = null;
6040 }
6041 }
6042
6043 if (lastFocus != newFocus) {
6044 //System.out.println("Changing focus from " + lastFocus
6045 // + " to " + newFocus);
6046 if (newFocus != null) {
6047 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006048 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006049 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
6050 } catch (RemoteException e) {
6051 // Ignore if process has died.
6052 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07006053 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006054 }
6055
6056 if (lastFocus != null) {
6057 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006058 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006059 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
6060 } catch (RemoteException e) {
6061 // Ignore if process has died.
6062 }
6063 }
Joe Onorato664644d2011-01-23 17:53:23 -08006064
6065 mPolicy.focusChanged(lastFocus, newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 }
6067 } break;
6068
6069 case REPORT_LOSING_FOCUS: {
6070 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07006071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006072 synchronized(mWindowMap) {
6073 losers = mLosingFocus;
6074 mLosingFocus = new ArrayList<WindowState>();
6075 }
6076
6077 final int N = losers.size();
6078 for (int i=0; i<N; i++) {
6079 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006080 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006081 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
6082 } catch (RemoteException e) {
6083 // Ignore if process has died.
6084 }
6085 }
6086 } break;
6087
6088 case ANIMATE: {
6089 synchronized(mWindowMap) {
6090 mAnimationPending = false;
6091 performLayoutAndPlaceSurfacesLocked();
6092 }
6093 } break;
6094
6095 case ADD_STARTING: {
6096 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6097 final StartingData sd = wtoken.startingData;
6098
6099 if (sd == null) {
6100 // Animation has been canceled... do nothing.
6101 return;
6102 }
Romain Guy06882f82009-06-10 13:36:04 -07006103
Joe Onorato8a9b2202010-02-26 18:56:32 -08006104 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07006106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006107 View view = null;
6108 try {
6109 view = mPolicy.addStartingWindow(
6110 wtoken.token, sd.pkg,
6111 sd.theme, sd.nonLocalizedLabel, sd.labelRes,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08006112 sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006114 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006115 }
6116
6117 if (view != null) {
6118 boolean abort = false;
6119
6120 synchronized(mWindowMap) {
6121 if (wtoken.removed || wtoken.startingData == null) {
6122 // If the window was successfully added, then
6123 // we need to remove it.
6124 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006125 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006126 "Aborted starting " + wtoken
6127 + ": removed=" + wtoken.removed
6128 + " startingData=" + wtoken.startingData);
6129 wtoken.startingWindow = null;
6130 wtoken.startingData = null;
6131 abort = true;
6132 }
6133 } else {
6134 wtoken.startingView = view;
6135 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006136 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006137 "Added starting " + wtoken
6138 + ": startingWindow="
6139 + wtoken.startingWindow + " startingView="
6140 + wtoken.startingView);
6141 }
6142
6143 if (abort) {
6144 try {
6145 mPolicy.removeStartingWindow(wtoken.token, view);
6146 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006147 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006148 }
6149 }
6150 }
6151 } break;
6152
6153 case REMOVE_STARTING: {
6154 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6155 IBinder token = null;
6156 View view = null;
6157 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006158 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006159 + wtoken + ": startingWindow="
6160 + wtoken.startingWindow + " startingView="
6161 + wtoken.startingView);
6162 if (wtoken.startingWindow != null) {
6163 view = wtoken.startingView;
6164 token = wtoken.token;
6165 wtoken.startingData = null;
6166 wtoken.startingView = null;
6167 wtoken.startingWindow = null;
6168 }
6169 }
6170 if (view != null) {
6171 try {
6172 mPolicy.removeStartingWindow(token, view);
6173 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006174 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006175 }
6176 }
6177 } break;
6178
6179 case FINISHED_STARTING: {
6180 IBinder token = null;
6181 View view = null;
6182 while (true) {
6183 synchronized (mWindowMap) {
6184 final int N = mFinishedStarting.size();
6185 if (N <= 0) {
6186 break;
6187 }
6188 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
6189
Joe Onorato8a9b2202010-02-26 18:56:32 -08006190 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006191 "Finished starting " + wtoken
6192 + ": startingWindow=" + wtoken.startingWindow
6193 + " startingView=" + wtoken.startingView);
6194
6195 if (wtoken.startingWindow == null) {
6196 continue;
6197 }
6198
6199 view = wtoken.startingView;
6200 token = wtoken.token;
6201 wtoken.startingData = null;
6202 wtoken.startingView = null;
6203 wtoken.startingWindow = null;
6204 }
6205
6206 try {
6207 mPolicy.removeStartingWindow(token, view);
6208 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006209 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006210 }
6211 }
6212 } break;
6213
6214 case REPORT_APPLICATION_TOKEN_WINDOWS: {
6215 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
6216
6217 boolean nowVisible = msg.arg1 != 0;
6218 boolean nowGone = msg.arg2 != 0;
6219
6220 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006221 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006222 TAG, "Reporting visible in " + wtoken
6223 + " visible=" + nowVisible
6224 + " gone=" + nowGone);
6225 if (nowVisible) {
6226 wtoken.appToken.windowsVisible();
6227 } else {
6228 wtoken.appToken.windowsGone();
6229 }
6230 } catch (RemoteException ex) {
6231 }
6232 } break;
Romain Guy06882f82009-06-10 13:36:04 -07006233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006234 case WINDOW_FREEZE_TIMEOUT: {
6235 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006236 Slog.w(TAG, "Window freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 int i = mWindows.size();
6238 while (i > 0) {
6239 i--;
Jeff Browne33348b2010-07-15 23:54:05 -07006240 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006241 if (w.mOrientationChanging) {
6242 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006243 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006244 }
6245 }
6246 performLayoutAndPlaceSurfacesLocked();
6247 }
6248 break;
6249 }
Romain Guy06882f82009-06-10 13:36:04 -07006250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006251 case HOLD_SCREEN_CHANGED: {
6252 Session oldHold;
6253 Session newHold;
6254 synchronized (mWindowMap) {
6255 oldHold = mLastReportedHold;
6256 newHold = (Session)msg.obj;
6257 mLastReportedHold = newHold;
6258 }
Romain Guy06882f82009-06-10 13:36:04 -07006259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006260 if (oldHold != newHold) {
6261 try {
6262 if (oldHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006263 mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006264 "window",
6265 BatteryStats.WAKE_TYPE_WINDOW);
6266 }
6267 if (newHold != null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006268 mBatteryStats.noteStartWakelock(newHold.mUid, -1,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006269 "window",
6270 BatteryStats.WAKE_TYPE_WINDOW);
6271 }
6272 } catch (RemoteException e) {
6273 }
6274 }
6275 break;
6276 }
Romain Guy06882f82009-06-10 13:36:04 -07006277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006278 case APP_TRANSITION_TIMEOUT: {
6279 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07006280 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006281 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006282 "*** APP TRANSITION TIMEOUT");
6283 mAppTransitionReady = true;
6284 mAppTransitionTimeout = true;
6285 performLayoutAndPlaceSurfacesLocked();
6286 }
6287 }
6288 break;
6289 }
Romain Guy06882f82009-06-10 13:36:04 -07006290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006291 case PERSIST_ANIMATION_SCALE: {
6292 Settings.System.putFloat(mContext.getContentResolver(),
6293 Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
6294 Settings.System.putFloat(mContext.getContentResolver(),
6295 Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
6296 break;
6297 }
Romain Guy06882f82009-06-10 13:36:04 -07006298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 case FORCE_GC: {
6300 synchronized(mWindowMap) {
6301 if (mAnimationPending) {
6302 // If we are animating, don't do the gc now but
6303 // delay a bit so we don't interrupt the animation.
6304 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
6305 2000);
6306 return;
6307 }
6308 // If we are currently rotating the display, it will
6309 // schedule a new message when done.
6310 if (mDisplayFrozen) {
6311 return;
6312 }
6313 mFreezeGcPending = 0;
6314 }
6315 Runtime.getRuntime().gc();
6316 break;
6317 }
Romain Guy06882f82009-06-10 13:36:04 -07006318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319 case ENABLE_SCREEN: {
6320 performEnableScreen();
6321 break;
6322 }
Romain Guy06882f82009-06-10 13:36:04 -07006323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006324 case APP_FREEZE_TIMEOUT: {
6325 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006326 Slog.w(TAG, "App freeze timeout expired.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 int i = mAppTokens.size();
6328 while (i > 0) {
6329 i--;
6330 AppWindowToken tok = mAppTokens.get(i);
6331 if (tok.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006332 Slog.w(TAG, "Force clearing freeze: " + tok);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006333 unsetAppFreezingScreenLocked(tok, true, true);
6334 }
6335 }
6336 }
6337 break;
6338 }
Romain Guy06882f82009-06-10 13:36:04 -07006339
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006340 case SEND_NEW_CONFIGURATION: {
6341 removeMessages(SEND_NEW_CONFIGURATION);
6342 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07006343 break;
6344 }
Romain Guy06882f82009-06-10 13:36:04 -07006345
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006346 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006347 if (mWindowsChanged) {
6348 synchronized (mWindowMap) {
6349 mWindowsChanged = false;
6350 }
6351 notifyWindowsChanged();
6352 }
6353 break;
6354 }
6355
Christopher Tatea53146c2010-09-07 11:57:52 -07006356 case DRAG_START_TIMEOUT: {
6357 IBinder win = (IBinder)msg.obj;
6358 if (DEBUG_DRAG) {
6359 Slog.w(TAG, "Timeout starting drag by win " + win);
6360 }
6361 synchronized (mWindowMap) {
6362 // !!! TODO: ANR the app that has failed to start the drag in time
6363 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07006364 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08006365 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07006366 mDragState.reset();
6367 mDragState = null;
6368 }
6369 }
Chris Tated4533f12010-10-19 15:15:08 -07006370 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07006371 }
6372
Chris Tated4533f12010-10-19 15:15:08 -07006373 case DRAG_END_TIMEOUT: {
6374 IBinder win = (IBinder)msg.obj;
6375 if (DEBUG_DRAG) {
6376 Slog.w(TAG, "Timeout ending drag to win " + win);
6377 }
6378 synchronized (mWindowMap) {
6379 // !!! TODO: ANR the drag-receiving app
6380 mDragState.mDragResult = false;
6381 mDragState.endDragLw();
6382 }
6383 break;
6384 }
Jeff Brown2992ea72011-01-28 22:04:14 -08006385
6386 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
6387 notifyHardKeyboardStatusChange();
6388 break;
6389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006390 }
6391 }
6392 }
6393
6394 // -------------------------------------------------------------
6395 // IWindowManager API
6396 // -------------------------------------------------------------
6397
6398 public IWindowSession openSession(IInputMethodClient client,
6399 IInputContext inputContext) {
6400 if (client == null) throw new IllegalArgumentException("null client");
6401 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006402 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07006403 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006404 }
6405
6406 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
6407 synchronized (mWindowMap) {
6408 // The focus for the client is the window immediately below
6409 // where we would place the input method window.
6410 int idx = findDesiredInputMethodWindowIndexLocked(false);
6411 WindowState imFocus;
6412 if (idx > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07006413 imFocus = mWindows.get(idx-1);
Dianne Hackborne75d8722011-01-27 19:37:40 -08006414 //Log.i(TAG, "Desired input method target: " + imFocus);
6415 //Log.i(TAG, "Current focus: " + this.mCurrentFocus);
6416 //Log.i(TAG, "Last focus: " + this.mLastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08006418 // This may be a starting window, in which case we still want
6419 // to count it as okay.
6420 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
6421 && imFocus.mAppToken != null) {
6422 // The client has definitely started, so it really should
6423 // have a window in this app token. Let's look for it.
6424 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
6425 WindowState w = imFocus.mAppToken.windows.get(i);
6426 if (w != imFocus) {
6427 //Log.i(TAG, "Switching to real app window: " + w);
6428 imFocus = w;
6429 break;
6430 }
6431 }
6432 }
6433 //Log.i(TAG, "IM target client: " + imFocus.mSession.mClient);
6434 //if (imFocus.mSession.mClient != null) {
6435 // Log.i(TAG, "IM target client binder: " + imFocus.mSession.mClient.asBinder());
6436 // Log.i(TAG, "Requesting client binder: " + client.asBinder());
6437 //}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 if (imFocus.mSession.mClient != null &&
6439 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
6440 return true;
6441 }
Dianne Hackborne75d8722011-01-27 19:37:40 -08006442
6443 // Okay, how about this... what is the current focus?
6444 // It seems in some cases we may not have moved the IM
6445 // target window, such as when it was in a pop-up window,
6446 // so let's also look at the current focus. (An example:
6447 // go to Gmail, start searching so the keyboard goes up,
6448 // press home. Sometimes the IME won't go down.)
6449 // Would be nice to fix this more correctly, but it's
6450 // way at the end of a release, and this should be good enough.
6451 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null &&
6452 mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
6453 return true;
6454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006455 }
6456 }
6457 }
6458 return false;
6459 }
Romain Guy06882f82009-06-10 13:36:04 -07006460
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07006461 public void getDisplaySize(Point size) {
6462 synchronized(mWindowMap) {
6463 size.x = mCurDisplayWidth;
6464 size.y = mCurDisplayHeight;
6465 }
6466 }
6467
6468 public int getMaximumSizeDimension() {
6469 synchronized(mWindowMap) {
6470 // Do this based on the raw screen size, until we are smarter.
Dianne Hackborn7916ac62011-05-16 20:45:48 -07006471 return mBaseDisplayWidth > mBaseDisplayHeight
6472 ? mBaseDisplayWidth : mBaseDisplayHeight;
6473 }
6474 }
6475
6476 public void setForcedDisplaySize(int longDimen, int shortDimen) {
6477 synchronized(mWindowMap) {
6478 int width, height;
6479 if (mInitialDisplayWidth < mInitialDisplayHeight) {
6480 width = shortDimen < mInitialDisplayWidth
6481 ? shortDimen : mInitialDisplayWidth;
6482 height = longDimen < mInitialDisplayHeight
6483 ? longDimen : mInitialDisplayHeight;
6484 } else {
6485 width = longDimen < mInitialDisplayWidth
6486 ? longDimen : mInitialDisplayWidth;
6487 height = shortDimen < mInitialDisplayHeight
6488 ? shortDimen : mInitialDisplayHeight;
6489 }
6490 setForcedDisplaySizeLocked(width, height);
6491 }
6492 }
6493
6494 private void rebuildBlackFrame(boolean inTransaction) {
6495 if (!inTransaction) {
6496 if (SHOW_TRANSACTIONS) Slog.i(TAG,
6497 ">>> OPEN TRANSACTION rebuildBlackFrame");
6498 Surface.openTransaction();
6499 }
6500 try {
6501 if (mBlackFrame != null) {
6502 mBlackFrame.kill();
6503 mBlackFrame = null;
6504 }
6505 if (mBaseDisplayWidth < mInitialDisplayWidth
6506 || mBaseDisplayHeight < mInitialDisplayHeight) {
6507 Rect outer = new Rect(0, 0, mInitialDisplayWidth, mInitialDisplayHeight);
6508 Rect inner = new Rect(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
6509 try {
6510 mBlackFrame = new BlackFrame(mFxSession, outer, inner, MASK_LAYER);
6511 } catch (Surface.OutOfResourcesException e) {
6512 }
6513 }
6514 } finally {
6515 if (!inTransaction) {
6516 Surface.closeTransaction();
6517 if (SHOW_TRANSACTIONS) Slog.i(TAG,
6518 "<<< CLOSE TRANSACTION rebuildBlackFrame");
6519 }
6520 }
6521 }
6522
6523 private void setForcedDisplaySizeLocked(int width, int height) {
6524 mBaseDisplayWidth = width;
6525 mBaseDisplayHeight = height;
6526 mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight);
6527
6528 mLayoutNeeded = true;
6529
6530 boolean configChanged = updateOrientationFromAppTokensLocked(false);
6531 mTempConfiguration.setToDefaults();
6532 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
6533 if (computeNewConfigurationLocked(mTempConfiguration)) {
6534 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
6535 configChanged = true;
6536 }
6537 }
6538
6539 if (configChanged) {
6540 mWaitingForConfig = true;
6541 startFreezingDisplayLocked(false);
6542 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6543 }
6544
6545 rebuildBlackFrame(false);
6546
6547 performLayoutAndPlaceSurfacesLocked();
6548 }
6549
6550 public void clearForcedDisplaySize() {
6551 synchronized(mWindowMap) {
6552 setForcedDisplaySizeLocked(mInitialDisplayWidth, mInitialDisplayHeight);
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07006553 }
6554 }
6555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006556 // -------------------------------------------------------------
6557 // Internals
6558 // -------------------------------------------------------------
6559
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006560 final WindowState windowForClientLocked(Session session, IWindow client,
6561 boolean throwOnError) {
6562 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006563 }
Romain Guy06882f82009-06-10 13:36:04 -07006564
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006565 final WindowState windowForClientLocked(Session session, IBinder client,
6566 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006568 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 TAG, "Looking up client " + client + ": " + win);
6570 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006571 RuntimeException ex = new IllegalArgumentException(
6572 "Requested window " + client + " does not exist");
6573 if (throwOnError) {
6574 throw ex;
6575 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006576 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006577 return null;
6578 }
6579 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006580 RuntimeException ex = new IllegalArgumentException(
6581 "Requested window " + client + " is in session " +
6582 win.mSession + ", not " + session);
6583 if (throwOnError) {
6584 throw ex;
6585 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006586 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006587 return null;
6588 }
6589
6590 return win;
6591 }
6592
Dianne Hackborna8f60182009-09-01 19:01:50 -07006593 final void rebuildAppWindowListLocked() {
6594 int NW = mWindows.size();
6595 int i;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006596 int lastWallpaper = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006597 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006598
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006599 if (mRebuildTmp.length < NW) {
6600 mRebuildTmp = new WindowState[NW+10];
6601 }
6602
Dianne Hackborna8f60182009-09-01 19:01:50 -07006603 // First remove all existing app windows.
6604 i=0;
6605 while (i < NW) {
Jeff Browne33348b2010-07-15 23:54:05 -07006606 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006607 if (w.mAppToken != null) {
Jeff Browne33348b2010-07-15 23:54:05 -07006608 WindowState win = mWindows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006609 win.mRebuilding = true;
6610 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006611 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006612 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006613 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07006614 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006615 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07006616 continue;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006617 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
6618 && lastWallpaper == i-1) {
6619 lastWallpaper = i;
Dianne Hackborna8f60182009-09-01 19:01:50 -07006620 }
6621 i++;
6622 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006623
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006624 // The wallpaper window(s) typically live at the bottom of the stack,
6625 // so skip them before adding app tokens.
6626 lastWallpaper++;
6627 i = lastWallpaper;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006628
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006629 // First add all of the exiting app tokens... these are no longer
6630 // in the main app list, but still have windows shown. We put them
6631 // in the back because now that the animation is over we no longer
6632 // will care about them.
6633 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07006634 for (int j=0; j<NT; j++) {
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006635 i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
6636 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006637
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07006638 // And add in the still active app tokens in Z order.
6639 NT = mAppTokens.size();
6640 for (int j=0; j<NT; j++) {
6641 i = reAddAppWindowsLocked(i, mAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07006642 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006643
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07006644 i -= lastWallpaper;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006645 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006646 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006647 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006648 for (i=0; i<numRemoved; i++) {
6649 WindowState ws = mRebuildTmp[i];
6650 if (ws.mRebuilding) {
6651 StringWriter sw = new StringWriter();
6652 PrintWriter pw = new PrintWriter(sw);
6653 ws.dump(pw, "");
6654 pw.flush();
6655 Slog.w(TAG, "This window was lost: " + ws);
6656 Slog.w(TAG, sw.toString());
6657 }
6658 }
6659 Slog.w(TAG, "Current app token list:");
6660 dumpAppTokensLocked();
6661 Slog.w(TAG, "Final window list:");
6662 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006663 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07006664 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006666 private final void assignLayersLocked() {
6667 int N = mWindows.size();
6668 int curBaseLayer = 0;
6669 int curLayer = 0;
6670 int i;
Romain Guy06882f82009-06-10 13:36:04 -07006671
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08006672 if (DEBUG_LAYERS) {
6673 RuntimeException here = new RuntimeException("here");
6674 here.fillInStackTrace();
6675 Log.v(TAG, "Assigning layers", here);
6676 }
6677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006678 for (i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07006679 WindowState w = mWindows.get(i);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07006680 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
6681 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006682 curLayer += WINDOW_LAYER_MULTIPLIER;
6683 w.mLayer = curLayer;
6684 } else {
6685 curBaseLayer = curLayer = w.mBaseLayer;
6686 w.mLayer = curLayer;
6687 }
6688 if (w.mTargetAppToken != null) {
6689 w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
6690 } else if (w.mAppToken != null) {
6691 w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
6692 } else {
6693 w.mAnimLayer = w.mLayer;
6694 }
6695 if (w.mIsImWindow) {
6696 w.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07006697 } else if (w.mIsWallpaper) {
6698 w.mAnimLayer += mWallpaperAnimLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006699 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006700 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 + w.mAnimLayer);
6702 //System.out.println(
6703 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
6704 }
6705 }
6706
6707 private boolean mInLayout = false;
6708 private final void performLayoutAndPlaceSurfacesLocked() {
6709 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07006710 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006711 throw new RuntimeException("Recursive call!");
6712 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006713 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 return;
6715 }
6716
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006717 if (mWaitingForConfig) {
6718 // Our configuration has changed (most likely rotation), but we
6719 // don't yet have the complete configuration to report to
6720 // applications. Don't do any window layout until we have it.
6721 return;
6722 }
6723
Dianne Hackbornce2ef762010-09-20 11:39:14 -07006724 if (mDisplay == null) {
6725 // Not yet initialized, nothing to do.
6726 return;
6727 }
6728
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006729 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006730 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006731
6732 try {
6733 if (mForceRemoves != null) {
6734 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006735 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006736 for (int i=0; i<mForceRemoves.size(); i++) {
6737 WindowState ws = mForceRemoves.get(i);
6738 Slog.i(TAG, "Force removing: " + ws);
6739 removeWindowInnerLocked(ws.mSession, ws);
6740 }
6741 mForceRemoves = null;
6742 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
6743 Object tmp = new Object();
6744 synchronized (tmp) {
6745 try {
6746 tmp.wait(250);
6747 } catch (InterruptedException e) {
6748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006749 }
6750 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006751 } catch (RuntimeException e) {
6752 Slog.e(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006753 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08006754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 try {
6756 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Romain Guy06882f82009-06-10 13:36:04 -07006757
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006758 int N = mPendingRemove.size();
6759 if (N > 0) {
6760 if (mPendingRemoveTmp.length < N) {
6761 mPendingRemoveTmp = new WindowState[N+10];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006763 mPendingRemove.toArray(mPendingRemoveTmp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006764 mPendingRemove.clear();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08006765 for (int i=0; i<N; i++) {
6766 WindowState w = mPendingRemoveTmp[i];
6767 removeWindowInnerLocked(w.mSession, w);
6768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769
6770 mInLayout = false;
6771 assignLayersLocked();
6772 mLayoutNeeded = true;
6773 performLayoutAndPlaceSurfacesLocked();
6774
6775 } else {
6776 mInLayout = false;
6777 if (mLayoutNeeded) {
6778 requestAnimationLocked(0);
6779 }
6780 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006781 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006782 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
6783 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006784 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 } catch (RuntimeException e) {
6786 mInLayout = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006787 Slog.e(TAG, "Unhandled exception while layout out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 }
6789 }
6790
Jeff Brown3a22cd92011-01-21 13:59:04 -08006791 private final int performLayoutLockedInner(boolean initial, boolean updateInputWindows) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006792 if (!mLayoutNeeded) {
6793 return 0;
6794 }
6795
6796 mLayoutNeeded = false;
6797
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07006798 final int dw = mCurDisplayWidth;
6799 final int dh = mCurDisplayHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006800
Dianne Hackborne2515ee2011-04-27 18:52:56 -04006801 final int innerDw = mPolicy.getNonDecorDisplayWidth(dw);
6802 final int innerDh = mPolicy.getNonDecorDisplayHeight(dh);
6803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006804 final int N = mWindows.size();
6805 int i;
6806
Joe Onorato8a9b2202010-02-26 18:56:32 -08006807 if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
Dianne Hackborn9b52a212009-12-11 14:51:35 -08006808 + mLayoutNeeded + " dw=" + dw + " dh=" + dh);
6809
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006810 mPolicy.beginLayoutLw(dw, dh);
Romain Guy06882f82009-06-10 13:36:04 -07006811
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006812 int seq = mLayoutSeq+1;
6813 if (seq < 0) seq = 0;
6814 mLayoutSeq = seq;
6815
6816 // First perform layout of any root windows (not attached
6817 // to another window).
6818 int topAttached = -1;
6819 for (i = N-1; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07006820 WindowState win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006821
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006822 // Don't do layout of a window if it is not visible, or
6823 // soon won't be visible, to avoid wasting time and funky
6824 // changes while a window is animating away.
6825 final AppWindowToken atoken = win.mAppToken;
6826 final boolean gone = win.mViewVisibility == View.GONE
6827 || !win.mRelayoutCalled
Dianne Hackbornff801ec2011-01-22 18:05:38 -08006828 || (atoken == null && win.mRootToken.hidden)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006829 || (atoken != null && atoken.hiddenRequested)
6830 || win.mAttachedHidden
6831 || win.mExiting || win.mDestroying;
6832
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006833 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
6834 Slog.v(TAG, "First pass " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006835 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
6836 + " mLayoutAttached=" + win.mLayoutAttached);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006837 if (gone) Slog.v(TAG, " (mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006838 + win.mViewVisibility + " mRelayoutCalled="
6839 + win.mRelayoutCalled + " hidden="
6840 + win.mRootToken.hidden + " hiddenRequested="
6841 + (atoken != null && atoken.hiddenRequested)
6842 + " mAttachedHidden=" + win.mAttachedHidden);
6843 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006844
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006845 // If this view is GONE, then skip it -- keep the current
6846 // frame, and let the caller know so they can ignore it
6847 // if they want. (We do the normal layout for INVISIBLE
6848 // windows, since that means "perform layout as normal,
6849 // just don't display").
6850 if (!gone || !win.mHaveFrame) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006851 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006852 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08006853 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006854 win.mContentChanged = false;
6855 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04006856 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006857 mPolicy.layoutWindowLw(win, win.mAttrs, null);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04006858 win.evalNeedsBackgroundFiller(innerDw, innerDh);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006859 win.mLayoutSeq = seq;
6860 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
6861 + win.mFrame + " mContainingFrame="
6862 + win.mContainingFrame + " mDisplayFrame="
6863 + win.mDisplayFrame);
6864 } else {
6865 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07006866 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07006867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006869
6870 // Now perform layout of attached windows, which usually
6871 // depend on the position of the window they are attached to.
6872 // XXX does not deal with windows that are attached to windows
6873 // that are themselves attached.
6874 for (i = topAttached; i >= 0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07006875 WindowState win = mWindows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006876
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006877 if (win.mLayoutAttached) {
6878 if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
6879 + " mHaveFrame=" + win.mHaveFrame
6880 + " mViewVisibility=" + win.mViewVisibility
6881 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08006882 // If this view is GONE, then skip it -- keep the current
6883 // frame, and let the caller know so they can ignore it
6884 // if they want. (We do the normal layout for INVISIBLE
6885 // windows, since that means "perform layout as normal,
6886 // just don't display").
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006887 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
6888 || !win.mHaveFrame) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006889 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08006890 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08006891 win.mContentChanged = false;
6892 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04006893 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006894 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04006895 win.evalNeedsBackgroundFiller(innerDw, innerDh);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006896 win.mLayoutSeq = seq;
6897 if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
6898 + win.mFrame + " mContainingFrame="
6899 + win.mContainingFrame + " mDisplayFrame="
6900 + win.mDisplayFrame);
6901 }
6902 }
6903 }
Jeff Brown349703e2010-06-22 01:27:15 -07006904
6905 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08006906 mInputMonitor.setUpdateInputWindowsNeededLw();
6907 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08006908 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08006909 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006910
6911 return mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006912 }
Romain Guy06882f82009-06-10 13:36:04 -07006913
Brad Fitzpatrick68044332010-11-22 18:19:48 -08006914 // "Something has changed! Let's make it correct now."
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006915 private final void performLayoutAndPlaceSurfacesLockedInner(
6916 boolean recoveringMemory) {
Joe Onorato34bcebc2010-07-07 18:05:01 -04006917 if (mDisplay == null) {
6918 Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
6919 return;
6920 }
6921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006922 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006923 final int dw = mCurDisplayWidth;
6924 final int dh = mCurDisplayHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006925
Dianne Hackborne2515ee2011-04-27 18:52:56 -04006926 final int innerDw = mPolicy.getNonDecorDisplayWidth(dw);
6927 final int innerDh = mPolicy.getNonDecorDisplayHeight(dh);
6928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929 int i;
6930
Dianne Hackbornb601ce12010-03-01 23:36:02 -08006931 if (mFocusMayChange) {
6932 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08006933 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
6934 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08006935 }
6936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006937 // Initialize state of exiting tokens.
6938 for (i=mExitingTokens.size()-1; i>=0; i--) {
6939 mExitingTokens.get(i).hasVisible = false;
6940 }
6941
6942 // Initialize state of exiting applications.
6943 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
6944 mExitingAppTokens.get(i).hasVisible = false;
6945 }
6946
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006947 boolean orientationChangeComplete = true;
6948 Session holdScreen = null;
6949 float screenBrightness = -1;
Mike Lockwoodfb73f792009-11-20 11:31:18 -05006950 float buttonBrightness = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006951 boolean focusDisplayed = false;
6952 boolean animating = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006953 boolean createWatermark = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08006954 boolean updateRotation = false;
Dianne Hackborn50660e22011-02-02 17:12:25 -08006955 boolean screenRotationFinished = false;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006956
6957 if (mFxSession == null) {
6958 mFxSession = new SurfaceSession();
6959 createWatermark = true;
6960 }
6961
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006962 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006963
6964 Surface.openTransaction();
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006965
6966 if (createWatermark) {
6967 createWatermark();
6968 }
6969 if (mWatermark != null) {
6970 mWatermark.positionSurface(dw, dh);
6971 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08006972 if (mStrictModeFlash != null) {
6973 mStrictModeFlash.positionSurface(dw, dh);
6974 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07006975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006976 try {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08006977 boolean wallpaperForceHidingChanged = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006978 int repeats = 0;
6979 int changes = 0;
6980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006981 do {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08006982 repeats++;
6983 if (repeats > 6) {
6984 Slog.w(TAG, "Animation repeat aborted after too many iterations");
6985 mLayoutNeeded = false;
6986 break;
6987 }
6988
6989 if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
6990 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
6991 | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
6992 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
6993 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
6994 assignLayersLocked();
6995 mLayoutNeeded = true;
6996 }
6997 }
6998 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
6999 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007000 if (updateOrientationFromAppTokensLocked(true)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007001 mLayoutNeeded = true;
7002 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7003 }
7004 }
7005 if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
7006 mLayoutNeeded = true;
7007 }
7008 }
7009
7010 // FIRST LOOP: Perform a layout, if needed.
7011 if (repeats < 4) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08007012 changes = performLayoutLockedInner(repeats == 0, false /*updateInputWindows*/);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007013 if (changes != 0) {
7014 continue;
7015 }
7016 } else {
7017 Slog.w(TAG, "Layout repeat skipped after too many iterations");
7018 changes = 0;
7019 }
7020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007021 final int transactionSequence = ++mTransactionSequence;
7022
7023 // Update animations of all applications, including those
7024 // associated with exiting/removed apps
7025 boolean tokensAnimating = false;
7026 final int NAT = mAppTokens.size();
7027 for (i=0; i<NAT; i++) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007028 if (mAppTokens.get(i).stepAnimationLocked(currentTime,
7029 innerDw, innerDh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007030 tokensAnimating = true;
7031 }
7032 }
7033 final int NEAT = mExitingAppTokens.size();
7034 for (i=0; i<NEAT; i++) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007035 if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime,
7036 innerDw, innerDh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007037 tokensAnimating = true;
7038 }
7039 }
7040
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007041 // SECOND LOOP: Execute animations and update visibility of windows.
7042
Joe Onorato8a9b2202010-02-26 18:56:32 -08007043 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007044 + transactionSequence + " tokensAnimating="
7045 + tokensAnimating);
7046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007047 animating = tokensAnimating;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007048
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007049 if (mScreenRotationAnimation != null) {
7050 if (mScreenRotationAnimation.isAnimating()) {
7051 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
7052 animating = true;
7053 } else {
Dianne Hackborn50660e22011-02-02 17:12:25 -08007054 screenRotationFinished = true;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08007055 updateRotation = true;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08007056 }
7057 }
7058 }
7059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007060 boolean tokenMayBeDrawn = false;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007061 boolean wallpaperMayChange = false;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007062 boolean forceHiding = false;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007063 WindowState windowDetachedWallpaper = null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007064 WindowState windowAnimationBackground = null;
7065 int windowAnimationBackgroundColor = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007066
7067 mPolicy.beginAnimationLw(dw, dh);
7068
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007069 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007071 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007072 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007073
7074 final WindowManager.LayoutParams attrs = w.mAttrs;
7075
7076 if (w.mSurface != null) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007077 // Take care of the window being ready to display.
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007078 if (w.commitFinishDrawingLocked(currentTime)) {
7079 if ((w.mAttrs.flags
7080 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007081 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007082 "First draw done in potential wallpaper target " + w);
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007083 wallpaperMayChange = true;
7084 }
7085 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007086
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007087 final boolean wasAnimating = w.mAnimating;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007088
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007089 int animDw = innerDw;
7090 int animDh = innerDh;
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007091
7092 // If the window has moved due to its containing
7093 // content frame changing, then we'd like to animate
7094 // it. The checks here are ordered by what is least
Joe Onorato3fe7f2f2010-11-20 13:48:58 -08007095 // likely to be true first.
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007096 if (w.shouldAnimateMove()) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08007097 // Frame has moved, containing content frame
7098 // has also moved, and we're not currently animating...
7099 // let's do something.
7100 Animation a = AnimationUtils.loadAnimation(mContext,
7101 com.android.internal.R.anim.window_move_from_decor);
7102 w.setAnimation(a);
7103 animDw = w.mLastFrame.left - w.mFrame.left;
7104 animDh = w.mLastFrame.top - w.mFrame.top;
7105 }
7106
7107 // Execute animation.
7108 final boolean nowAnimating = w.stepAnimationLocked(currentTime,
7109 animDw, animDh);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007110
7111 // If this window is animating, make a note that we have
7112 // an animating window and take care of a request to run
7113 // a detached wallpaper animation.
7114 if (nowAnimating) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007115 if (w.mAnimation != null) {
7116 if (w.mAnimation.getDetachWallpaper()) {
7117 windowDetachedWallpaper = w;
7118 }
7119 if (w.mAnimation.getBackgroundColor() != 0) {
7120 windowAnimationBackground = w;
7121 windowAnimationBackgroundColor =
7122 w.mAnimation.getBackgroundColor();
7123 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007124 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007125 animating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007126 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007127
7128 // If this window's app token is running a detached wallpaper
7129 // animation, make a note so we can ensure the wallpaper is
7130 // displayed behind it.
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007131 if (w.mAppToken != null && w.mAppToken.animation != null) {
7132 if (w.mAppToken.animation.getDetachWallpaper()) {
7133 windowDetachedWallpaper = w;
7134 }
7135 if (w.mAppToken.animation.getBackgroundColor() != 0) {
7136 windowAnimationBackground = w;
7137 windowAnimationBackgroundColor =
7138 w.mAppToken.animation.getBackgroundColor();
7139 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007140 }
7141
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07007142 if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
7143 wallpaperMayChange = true;
7144 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007145
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007146 if (mPolicy.doesForceHide(w, attrs)) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007147 if (!wasAnimating && nowAnimating) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007148 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007149 "Animation started that could impact force hide: "
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007150 + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007151 wallpaperForceHidingChanged = true;
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007152 mFocusMayChange = true;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007153 } else if (w.isReadyForDisplay() && w.mAnimation == null) {
7154 forceHiding = true;
7155 }
7156 } else if (mPolicy.canBeForceHidden(w, attrs)) {
7157 boolean changed;
7158 if (forceHiding) {
7159 changed = w.hideLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007160 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
7161 "Now policy hidden: " + w);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007162 } else {
7163 changed = w.showLw(false, false);
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007164 if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
7165 "Now policy shown: " + w);
7166 if (changed) {
7167 if (wallpaperForceHidingChanged
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007168 && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007169 // Assume we will need to animate. If
7170 // we don't (because the wallpaper will
7171 // stay with the lock screen), then we will
7172 // clean up later.
7173 Animation a = mPolicy.createForceHideEnterAnimation();
7174 if (a != null) {
7175 w.setAnimation(a);
7176 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007177 }
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08007178 if (mCurrentFocus == null ||
7179 mCurrentFocus.mLayer < w.mLayer) {
7180 // We are showing on to of the current
7181 // focus, so re-evaluate focus to make
7182 // sure it is correct.
7183 mFocusMayChange = true;
7184 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007185 }
7186 }
7187 if (changed && (attrs.flags
7188 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
7189 wallpaperMayChange = true;
7190 }
7191 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 mPolicy.animatingWindowLw(w, attrs);
7194 }
7195
7196 final AppWindowToken atoken = w.mAppToken;
7197 if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
7198 if (atoken.lastTransactionSequence != transactionSequence) {
7199 atoken.lastTransactionSequence = transactionSequence;
7200 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
7201 atoken.startingDisplayed = false;
7202 }
7203 if ((w.isOnScreen() || w.mAttrs.type
7204 == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
7205 && !w.mExiting && !w.mDestroying) {
7206 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007207 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007208 + w.isDrawnLw()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007209 + ", isAnimating=" + w.isAnimating());
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007210 if (!w.isDrawnLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007211 Slog.v(TAG, "Not displayed: s=" + w.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212 + " pv=" + w.mPolicyVisibility
7213 + " dp=" + w.mDrawPending
7214 + " cdp=" + w.mCommitDrawPending
7215 + " ah=" + w.mAttachedHidden
7216 + " th=" + atoken.hiddenRequested
7217 + " a=" + w.mAnimating);
7218 }
7219 }
7220 if (w != atoken.startingWindow) {
7221 if (!atoken.freezingScreen || !w.mAppFreezing) {
7222 atoken.numInterestingWindows++;
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007223 if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007224 atoken.numDrawnWindows++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007225 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007226 "tokenMayBeDrawn: " + atoken
7227 + " freezingScreen=" + atoken.freezingScreen
7228 + " mAppFreezing=" + w.mAppFreezing);
7229 tokenMayBeDrawn = true;
7230 }
7231 }
Dianne Hackborn7433e8a2009-09-27 13:21:20 -07007232 } else if (w.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007233 atoken.startingDisplayed = true;
7234 }
7235 }
7236 } else if (w.mReadyToShow) {
7237 w.performShowLocked();
7238 }
7239 }
7240
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007241 changes |= mPolicy.finishAnimationLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007242
7243 if (tokenMayBeDrawn) {
7244 // See if any windows have been drawn, so they (and others
7245 // associated with them) can now be shown.
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007246 final int NT = mAppTokens.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007247 for (i=0; i<NT; i++) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08007248 AppWindowToken wtoken = mAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007249 if (wtoken.freezingScreen) {
7250 int numInteresting = wtoken.numInterestingWindows;
7251 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007252 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 "allDrawn: " + wtoken
7254 + " interesting=" + numInteresting
7255 + " drawn=" + wtoken.numDrawnWindows);
7256 wtoken.showAllWindowsLocked();
7257 unsetAppFreezingScreenLocked(wtoken, false, true);
7258 orientationChangeComplete = true;
7259 }
7260 } else if (!wtoken.allDrawn) {
7261 int numInteresting = wtoken.numInterestingWindows;
7262 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007263 if (DEBUG_VISIBILITY) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 "allDrawn: " + wtoken
7265 + " interesting=" + numInteresting
7266 + " drawn=" + wtoken.numDrawnWindows);
7267 wtoken.allDrawn = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007268 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007269
7270 // We can now show all of the drawn windows!
7271 if (!mOpeningApps.contains(wtoken)) {
7272 wtoken.showAllWindowsLocked();
7273 }
7274 }
7275 }
7276 }
7277 }
7278
7279 // If we are ready to perform an app transition, check through
7280 // all of the app tokens to be shown and see if they are ready
7281 // to go.
7282 if (mAppTransitionReady) {
7283 int NN = mOpeningApps.size();
7284 boolean goodToGo = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007285 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007286 "Checking " + NN + " opening apps (frozen="
7287 + mDisplayFrozen + " timeout="
7288 + mAppTransitionTimeout + ")...");
7289 if (!mDisplayFrozen && !mAppTransitionTimeout) {
7290 // If the display isn't frozen, wait to do anything until
7291 // all of the apps are ready. Otherwise just go because
7292 // we'll unfreeze the display when everyone is ready.
7293 for (i=0; i<NN && goodToGo; i++) {
7294 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007295 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007296 "Check opening app" + wtoken + ": allDrawn="
7297 + wtoken.allDrawn + " startingDisplayed="
7298 + wtoken.startingDisplayed);
7299 if (!wtoken.allDrawn && !wtoken.startingDisplayed
7300 && !wtoken.startingMoved) {
7301 goodToGo = false;
7302 }
7303 }
7304 }
7305 if (goodToGo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007306 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007307 int transit = mNextAppTransition;
7308 if (mSkipAppTransitionAnimation) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007309 transit = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007310 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007311 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007312 mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007313 mAppTransitionRunning = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007314 mAppTransitionTimeout = false;
7315 mStartingIconInTransition = false;
7316 mSkipAppTransitionAnimation = false;
7317
7318 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
7319
Dianne Hackborna8f60182009-09-01 19:01:50 -07007320 // If there are applications waiting to come to the
7321 // top of the stack, now is the time to move their windows.
7322 // (Note that we don't do apps going to the bottom
7323 // here -- we want to keep their windows in the old
7324 // Z-order until the animation completes.)
7325 if (mToTopApps.size() > 0) {
7326 NN = mAppTokens.size();
7327 for (i=0; i<NN; i++) {
7328 AppWindowToken wtoken = mAppTokens.get(i);
7329 if (wtoken.sendingToTop) {
7330 wtoken.sendingToTop = false;
7331 moveAppWindowsLocked(wtoken, NN, false);
7332 }
7333 }
7334 mToTopApps.clear();
7335 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007336
Dianne Hackborn25994b42009-09-04 14:21:19 -07007337 WindowState oldWallpaper = mWallpaperTarget;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007338
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007339 adjustWallpaperWindowsLocked();
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007340 wallpaperMayChange = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007341
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007342 // The top-most window will supply the layout params,
7343 // and we will determine it below.
7344 LayoutParams animLp = null;
7345 int bestAnimLayer = -1;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007346 boolean fullscreenAnim = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007347 boolean needBgFiller = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007348
Joe Onorato8a9b2202010-02-26 18:56:32 -08007349 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07007350 "New wallpaper target=" + mWallpaperTarget
7351 + ", lower target=" + mLowerWallpaperTarget
7352 + ", upper target=" + mUpperWallpaperTarget);
Dianne Hackborn25994b42009-09-04 14:21:19 -07007353 int foundWallpapers = 0;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007354 // Do a first pass through the tokens for two
7355 // things:
7356 // (1) Determine if both the closing and opening
7357 // app token sets are wallpaper targets, in which
7358 // case special animations are needed
7359 // (since the wallpaper needs to stay static
7360 // behind them).
7361 // (2) Find the layout params of the top-most
7362 // application window in the tokens, which is
7363 // what will control the animation theme.
7364 final int NC = mClosingApps.size();
7365 NN = NC + mOpeningApps.size();
7366 for (i=0; i<NN; i++) {
7367 AppWindowToken wtoken;
7368 int mode;
7369 if (i < NC) {
7370 wtoken = mClosingApps.get(i);
7371 mode = 1;
7372 } else {
7373 wtoken = mOpeningApps.get(i-NC);
7374 mode = 2;
7375 }
7376 if (mLowerWallpaperTarget != null) {
7377 if (mLowerWallpaperTarget.mAppToken == wtoken
7378 || mUpperWallpaperTarget.mAppToken == wtoken) {
7379 foundWallpapers |= mode;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007380 }
7381 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007382 if (wtoken.appFullscreen) {
7383 WindowState ws = wtoken.findMainWindow();
7384 if (ws != null) {
7385 // If this is a compatibility mode
7386 // window, we will always use its anim.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007387 if (ws.mNeedsBackgroundFiller) {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007388 animLp = ws.mAttrs;
7389 bestAnimLayer = Integer.MAX_VALUE;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007390 needBgFiller = true;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007391 } else if (!fullscreenAnim || ws.mLayer > bestAnimLayer) {
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007392 animLp = ws.mAttrs;
Dianne Hackborn08121bc2011-01-17 17:54:31 -08007393 bestAnimLayer = ws.mLayer;
7394 }
7395 fullscreenAnim = true;
7396 }
7397 } else if (!fullscreenAnim) {
7398 WindowState ws = wtoken.findMainWindow();
7399 if (ws != null) {
7400 if (ws.mLayer > bestAnimLayer) {
7401 animLp = ws.mAttrs;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07007402 bestAnimLayer = ws.mLayer;
7403 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07007404 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07007405 }
7406 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007407
Dianne Hackborn25994b42009-09-04 14:21:19 -07007408 if (foundWallpapers == 3) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007409 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007410 "Wallpaper animation!");
7411 switch (transit) {
7412 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
7413 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
7414 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
7415 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
7416 break;
7417 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
7418 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
7419 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
7420 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
7421 break;
7422 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007423 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007424 "New transit: " + transit);
7425 } else if (oldWallpaper != null) {
7426 // We are transitioning from an activity with
7427 // a wallpaper to one without.
7428 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007429 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007430 "New transit away from wallpaper: " + transit);
7431 } else if (mWallpaperTarget != null) {
7432 // We are transitioning from an activity without
7433 // a wallpaper to now showing the wallpaper
7434 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007435 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Dianne Hackborn25994b42009-09-04 14:21:19 -07007436 "New transit into wallpaper: " + transit);
7437 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007438
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007439 // If all closing windows are obscured, then there is
7440 // no need to do an animation. This is the case, for
7441 // example, when this transition is being done behind
7442 // the lock screen.
7443 if (!mPolicy.allowAppAnimationsLw()) {
7444 animLp = null;
7445 }
7446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007447 NN = mOpeningApps.size();
7448 for (i=0; i<NN; i++) {
7449 AppWindowToken wtoken = mOpeningApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007450 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007451 "Now opening app" + wtoken);
7452 wtoken.reportedVisible = false;
7453 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07007454 wtoken.animation = null;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007455 setTokenVisibilityLocked(wtoken, animLp, true,
7456 transit, false, needBgFiller);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007457 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007458 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007459 wtoken.showAllWindowsLocked();
7460 }
7461 NN = mClosingApps.size();
7462 for (i=0; i<NN; i++) {
7463 AppWindowToken wtoken = mClosingApps.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007464 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007465 "Now closing app" + wtoken);
7466 wtoken.inPendingTransaction = false;
Dianne Hackborn83360b32009-08-24 18:43:32 -07007467 wtoken.animation = null;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007468 setTokenVisibilityLocked(wtoken, animLp, false,
7469 transit, false, needBgFiller);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007470 wtoken.updateReportedVisibilityLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07007471 wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007472 // Force the allDrawn flag, because we want to start
7473 // this guy's animations regardless of whether it's
7474 // gotten drawn.
7475 wtoken.allDrawn = true;
7476 }
7477
Dianne Hackborn8b571a82009-09-25 16:09:43 -07007478 mNextAppTransitionPackage = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007480 mOpeningApps.clear();
7481 mClosingApps.clear();
7482
7483 // This has changed the visibility of windows, so perform
7484 // a new layout to get them all up-to-date.
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007485 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT
7486 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007487 mLayoutNeeded = true;
Dianne Hackborn20583ff2009-07-27 21:51:05 -07007488 if (!moveInputMethodWindowsIfNeededLocked(true)) {
7489 assignLayersLocked();
7490 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08007491 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
7492 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007493 mFocusMayChange = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007494 }
7495 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007496
Dianne Hackborn16064f92010-03-25 00:47:24 -07007497 int adjResult = 0;
7498
Dianne Hackborna8f60182009-09-01 19:01:50 -07007499 if (!animating && mAppTransitionRunning) {
7500 // We have finished the animation of an app transition. To do
7501 // this, we have delayed a lot of operations like showing and
7502 // hiding apps, moving apps in Z-order, etc. The app token list
7503 // reflects the correct Z-order, but the window list may now
7504 // be out of sync with it. So here we will just rebuild the
7505 // entire app window list. Fun!
7506 mAppTransitionRunning = false;
7507 // Clear information about apps that were moving.
7508 mToBottomApps.clear();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007509
Dianne Hackborna8f60182009-09-01 19:01:50 -07007510 rebuildAppWindowListLocked();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007511 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007512 adjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007513 moveInputMethodWindowsIfNeededLocked(false);
7514 wallpaperMayChange = true;
Suchi Amalapurapuc9568e32009-11-05 18:51:16 -08007515 // Since the window list has been rebuilt, focus might
7516 // have to be recomputed since the actual order of windows
7517 // might have changed again.
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007518 mFocusMayChange = true;
Dianne Hackborna8f60182009-09-01 19:01:50 -07007519 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007520
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007521 if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007522 // At this point, there was a window with a wallpaper that
7523 // was force hiding other windows behind it, but now it
7524 // is going away. This may be simple -- just animate
7525 // away the wallpaper and its window -- or it may be
7526 // hard -- the wallpaper now needs to be shown behind
7527 // something that was hidden.
7528 WindowState oldWallpaper = mWallpaperTarget;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007529 if (mLowerWallpaperTarget != null
7530 && mLowerWallpaperTarget.mAppToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007531 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007532 "wallpaperForceHiding changed with lower="
7533 + mLowerWallpaperTarget);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007534 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007535 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
7536 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
7537 if (mLowerWallpaperTarget.mAppToken.hidden) {
7538 // The lower target has become hidden before we
7539 // actually started the animation... let's completely
7540 // re-evaluate everything.
7541 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007542 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007543 }
7544 }
Dianne Hackborn16064f92010-03-25 00:47:24 -07007545 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007546 wallpaperMayChange = false;
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007547 wallpaperForceHidingChanged = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007548 if (DEBUG_WALLPAPER) Slog.v(TAG, "****** OLD: " + oldWallpaper
Dianne Hackbornde2606d2009-12-18 16:53:55 -08007549 + " NEW: " + mWallpaperTarget
7550 + " LOWER: " + mLowerWallpaperTarget);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007551 if (mLowerWallpaperTarget == null) {
7552 // Whoops, we don't need a special wallpaper animation.
7553 // Clear them out.
7554 forceHiding = false;
7555 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007556 WindowState w = mWindows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007557 if (w.mSurface != null) {
7558 final WindowManager.LayoutParams attrs = w.mAttrs;
Suchi Amalapurapuc03d28b2009-10-28 14:32:05 -07007559 if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007560 if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007561 forceHiding = true;
7562 } else if (mPolicy.canBeForceHidden(w, attrs)) {
7563 if (!w.mAnimating) {
7564 // We set the animation above so it
7565 // is not yet running.
7566 w.clearAnimation();
7567 }
7568 }
7569 }
7570 }
7571 }
7572 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007573
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08007574 if (mWindowDetachedWallpaper != windowDetachedWallpaper) {
7575 if (DEBUG_WALLPAPER) Slog.v(TAG,
7576 "Detached wallpaper changed from " + mWindowDetachedWallpaper
7577 + windowDetachedWallpaper);
7578 mWindowDetachedWallpaper = windowDetachedWallpaper;
7579 wallpaperMayChange = true;
7580 }
7581
Dianne Hackbornde75cb42011-03-02 17:11:21 -08007582 if (windowAnimationBackgroundColor != 0) {
7583 if (mWindowAnimationBackgroundSurface == null) {
7584 mWindowAnimationBackgroundSurface = new DimSurface(mFxSession);
7585 }
7586 mWindowAnimationBackgroundSurface.show(dw, dh,
7587 windowAnimationBackground.mAnimLayer - LAYER_OFFSET_DIM,
7588 windowAnimationBackgroundColor);
7589 } else if (mWindowAnimationBackgroundSurface != null) {
7590 mWindowAnimationBackgroundSurface.hide();
7591 }
7592
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007593 if (wallpaperMayChange) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007594 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007595 "Wallpaper may change! Adjusting");
Dianne Hackborn16064f92010-03-25 00:47:24 -07007596 adjResult |= adjustWallpaperWindowsLocked();
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007597 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007598
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007599 if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007600 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007601 "Wallpaper layer changed: assigning layers + relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007602 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007603 assignLayersLocked();
7604 } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007605 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007606 "Wallpaper visibility changed: relayout");
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007607 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007608 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007609
Dianne Hackbornb601ce12010-03-01 23:36:02 -08007610 if (mFocusMayChange) {
7611 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08007612 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
7613 false /*updateInputWindows*/)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007614 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007615 adjResult = 0;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007616 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007617 }
7618
7619 if (mLayoutNeeded) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007620 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
Dianne Hackborn6c3f5712009-08-25 18:42:59 -07007621 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007622
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007623 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
7624 + Integer.toHexString(changes));
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007625 } while (changes != 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626
7627 // THIRD LOOP: Update the surfaces of all windows.
7628
7629 final boolean someoneLosingFocus = mLosingFocus.size() != 0;
7630
7631 boolean obscured = false;
7632 boolean blurring = false;
7633 boolean dimming = false;
7634 boolean covered = false;
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07007635 boolean syswin = false;
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007636 boolean backgroundFillerWasShown = mBackgroundFillerTarget != null;
7637 mBackgroundFillerTarget = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007638
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07007639 final int N = mWindows.size();
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007641 for (i=N-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07007642 WindowState w = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007643
7644 boolean displayed = false;
7645 final WindowManager.LayoutParams attrs = w.mAttrs;
7646 final int attrFlags = attrs.flags;
7647
7648 if (w.mSurface != null) {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007649 // XXX NOTE: The logic here could be improved. We have
7650 // the decision about whether to resize a window separated
7651 // from whether to hide the surface. This can cause us to
7652 // resize a surface even if we are going to hide it. You
7653 // can see this by (1) holding device in landscape mode on
7654 // home screen; (2) tapping browser icon (device will rotate
7655 // to landscape; (3) tap home. The wallpaper will be resized
7656 // in step 2 but then immediately hidden, causing us to
7657 // have to resize and then redraw it again in step 3. It
7658 // would be nice to figure out how to avoid this, but it is
7659 // difficult because we do need to resize surfaces in some
7660 // cases while they are hidden such as when first showing a
7661 // window.
7662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007663 w.computeShownFrameLocked();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007664 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 TAG, "Placing surface #" + i + " " + w.mSurface
7666 + ": new=" + w.mShownFrame + ", old="
7667 + w.mLastShownFrame);
7668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 int width, height;
7670 if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 // for a scaled surface, we just want to use
7672 // the requested size.
7673 width = w.mRequestedWidth;
7674 height = w.mRequestedHeight;
7675 w.mLastRequestedWidth = width;
7676 w.mLastRequestedHeight = height;
7677 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007678 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007679 width = w.mShownFrame.width();
7680 height = w.mShownFrame.height();
7681 w.mLastShownFrame.set(w.mShownFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007682 }
7683
Jeff Brownfbae7222011-01-23 13:07:25 -08007684 if (w.mSurface != null) {
7685 if (w.mSurfaceX != w.mShownFrame.left
7686 || w.mSurfaceY != w.mShownFrame.top) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007687 try {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007688 if (SHOW_TRANSACTIONS) logSurface(w,
Jeff Brownfbae7222011-01-23 13:07:25 -08007689 "POS " + w.mShownFrame.left
7690 + ", " + w.mShownFrame.top, null);
7691 w.mSurfaceX = w.mShownFrame.left;
7692 w.mSurfaceY = w.mShownFrame.top;
7693 w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
7694 } catch (RuntimeException e) {
7695 Slog.w(TAG, "Error positioning surface of " + w
7696 + " pos=(" + w.mShownFrame.left
7697 + "," + w.mShownFrame.top + ")", e);
7698 if (!recoveringMemory) {
Dianne Hackborn64825172011-03-02 21:32:58 -08007699 reclaimSomeSurfaceMemoryLocked(w, "position", true);
Jeff Brownfbae7222011-01-23 13:07:25 -08007700 }
7701 }
7702 }
7703
7704 if (width < 1) {
7705 width = 1;
7706 }
7707 if (height < 1) {
7708 height = 1;
7709 }
7710
7711 if (w.mSurfaceW != width || w.mSurfaceH != height) {
7712 try {
7713 if (SHOW_TRANSACTIONS) logSurface(w,
7714 "SIZE " + w.mShownFrame.width() + "x"
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007715 + w.mShownFrame.height(), null);
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007716 w.mSurfaceResized = true;
Dianne Hackborn16064f92010-03-25 00:47:24 -07007717 w.mSurfaceW = width;
7718 w.mSurfaceH = height;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007719 w.mSurface.setSize(width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 } catch (RuntimeException e) {
7721 // If something goes wrong with the surface (such
7722 // as running out of memory), don't take down the
7723 // entire system.
Jeff Brownfbae7222011-01-23 13:07:25 -08007724 Slog.e(TAG, "Error resizing surface of " + w
7725 + " size=(" + width + "x" + height + ")", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007726 if (!recoveringMemory) {
Dianne Hackborn64825172011-03-02 21:32:58 -08007727 reclaimSomeSurfaceMemoryLocked(w, "size", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007728 }
7729 }
7730 }
7731 }
Jeff Brownfbae7222011-01-23 13:07:25 -08007732
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007733 if (!w.mAppFreezing && w.mLayoutSeq == mLayoutSeq) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007734 w.mContentInsetsChanged =
7735 !w.mLastContentInsets.equals(w.mContentInsets);
7736 w.mVisibleInsetsChanged =
7737 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007738 boolean configChanged =
7739 w.mConfiguration != mCurConfiguration
7740 && (w.mConfiguration == null
7741 || mCurConfiguration.diff(w.mConfiguration) != 0);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07007742 if (DEBUG_CONFIGURATION && configChanged) {
7743 Slog.v(TAG, "Win " + w + " config changed: "
7744 + mCurConfiguration);
7745 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007746 if (localLOGV) Slog.v(TAG, "Resizing " + w
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007747 + ": configChanged=" + configChanged
7748 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
Jeff Brownfbae7222011-01-23 13:07:25 -08007749 boolean frameChanged = !w.mLastFrame.equals(w.mFrame);
7750 if (frameChanged
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007751 || w.mContentInsetsChanged
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007752 || w.mVisibleInsetsChanged
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007753 || w.mSurfaceResized
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007754 || configChanged) {
Jeff Brownfbae7222011-01-23 13:07:25 -08007755 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
7756 Slog.v(TAG, "Resize reasons: "
7757 + "frameChanged=" + frameChanged
7758 + " contentInsetsChanged=" + w.mContentInsetsChanged
7759 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
7760 + " surfaceResized=" + w.mSurfaceResized
7761 + " configChanged=" + configChanged);
7762 }
7763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007764 w.mLastFrame.set(w.mFrame);
7765 w.mLastContentInsets.set(w.mContentInsets);
7766 w.mLastVisibleInsets.set(w.mVisibleInsets);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007767 // If the screen is currently frozen, then keep
7768 // it frozen until this window draws at its new
7769 // orientation.
7770 if (mDisplayFrozen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007771 if (DEBUG_ORIENTATION) Slog.v(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007772 "Resizing while display frozen: " + w);
7773 w.mOrientationChanging = true;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007774 if (!mWindowsFreezingScreen) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007775 mWindowsFreezingScreen = true;
7776 // XXX should probably keep timeout from
7777 // when we first froze the display.
7778 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
7779 mH.sendMessageDelayed(mH.obtainMessage(
7780 H.WINDOW_FREEZE_TIMEOUT), 2000);
7781 }
7782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007783 // If the orientation is changing, then we need to
7784 // hold off on unfreezing the display until this
7785 // window has been redrawn; to do that, we need
7786 // to go through the process of getting informed
7787 // by the application when it has finished drawing.
7788 if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007789 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007790 "Orientation start waiting for draw in "
7791 + w + ", surface " + w.mSurface);
7792 w.mDrawPending = true;
7793 w.mCommitDrawPending = false;
7794 w.mReadyToShow = false;
7795 if (w.mAppToken != null) {
7796 w.mAppToken.allDrawn = false;
7797 }
7798 }
Dianne Hackbornac3587d2010-03-11 11:12:11 -08007799 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007800 "Resizing window " + w + " to " + w.mFrame);
7801 mResizingWindows.add(w);
7802 } else if (w.mOrientationChanging) {
7803 if (!w.mDrawPending && !w.mCommitDrawPending) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007804 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007805 "Orientation not waiting for draw in "
7806 + w + ", surface " + w.mSurface);
7807 w.mOrientationChanging = false;
7808 }
7809 }
7810 }
7811
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007812 if (w.mAttachedHidden || !w.isReadyForDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007813 if (!w.mLastHidden) {
7814 //dump();
7815 w.mLastHidden = true;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007816 if (SHOW_TRANSACTIONS) logSurface(w,
7817 "HIDE (performLayout)", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007818 if (w.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007819 w.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007820 try {
7821 w.mSurface.hide();
7822 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007823 Slog.w(TAG, "Exception hiding surface in " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007824 }
7825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007826 }
7827 // If we are waiting for this window to handle an
7828 // orientation change, well, it is hidden, so
7829 // doesn't really matter. Note that this does
7830 // introduce a potential glitch if the window
7831 // becomes unhidden before it has drawn for the
7832 // new orientation.
7833 if (w.mOrientationChanging) {
7834 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007835 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007836 "Orientation change skips hidden " + w);
7837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007838 } else if (w.mLastLayer != w.mAnimLayer
7839 || w.mLastAlpha != w.mShownAlpha
7840 || w.mLastDsDx != w.mDsDx
7841 || w.mLastDtDx != w.mDtDx
7842 || w.mLastDsDy != w.mDsDy
7843 || w.mLastDtDy != w.mDtDy
7844 || w.mLastHScale != w.mHScale
7845 || w.mLastVScale != w.mVScale
7846 || w.mLastHidden) {
7847 displayed = true;
7848 w.mLastAlpha = w.mShownAlpha;
7849 w.mLastLayer = w.mAnimLayer;
7850 w.mLastDsDx = w.mDsDx;
7851 w.mLastDtDx = w.mDtDx;
7852 w.mLastDsDy = w.mDsDy;
7853 w.mLastDtDy = w.mDtDy;
7854 w.mLastHScale = w.mHScale;
7855 w.mLastVScale = w.mVScale;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007856 if (SHOW_TRANSACTIONS) logSurface(w,
7857 "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07007858 + " matrix=[" + (w.mDsDx*w.mHScale)
7859 + "," + (w.mDtDx*w.mVScale)
7860 + "][" + (w.mDsDy*w.mHScale)
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007861 + "," + (w.mDtDy*w.mVScale) + "]", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007862 if (w.mSurface != null) {
7863 try {
Dianne Hackborn16064f92010-03-25 00:47:24 -07007864 w.mSurfaceAlpha = w.mShownAlpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007865 w.mSurface.setAlpha(w.mShownAlpha);
Dianne Hackborn16064f92010-03-25 00:47:24 -07007866 w.mSurfaceLayer = w.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007867 w.mSurface.setLayer(w.mAnimLayer);
7868 w.mSurface.setMatrix(
7869 w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
7870 w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
7871 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007872 Slog.w(TAG, "Error updating surface in " + w, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007873 if (!recoveringMemory) {
Dianne Hackborn64825172011-03-02 21:32:58 -08007874 reclaimSomeSurfaceMemoryLocked(w, "update", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007875 }
7876 }
7877 }
7878
7879 if (w.mLastHidden && !w.mDrawPending
7880 && !w.mCommitDrawPending
7881 && !w.mReadyToShow) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08007882 if (SHOW_TRANSACTIONS) logSurface(w,
7883 "SHOW (performLayout)", null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007884 if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 + " during relayout");
7886 if (showSurfaceRobustlyLocked(w)) {
7887 w.mHasDrawn = true;
7888 w.mLastHidden = false;
7889 } else {
7890 w.mOrientationChanging = false;
7891 }
7892 }
7893 if (w.mSurface != null) {
7894 w.mToken.hasVisible = true;
7895 }
7896 } else {
7897 displayed = true;
7898 }
7899
7900 if (displayed) {
7901 if (!covered) {
Romain Guy980a9382010-01-08 15:06:28 -08007902 if (attrs.width == LayoutParams.MATCH_PARENT
7903 && attrs.height == LayoutParams.MATCH_PARENT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007904 covered = true;
7905 }
7906 }
7907 if (w.mOrientationChanging) {
7908 if (w.mDrawPending || w.mCommitDrawPending) {
7909 orientationChangeComplete = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007910 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007911 "Orientation continue waiting for draw in " + w);
7912 } else {
7913 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007914 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007915 "Orientation change complete in " + w);
7916 }
7917 }
7918 w.mToken.hasVisible = true;
7919 }
7920 } else if (w.mOrientationChanging) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007921 if (DEBUG_ORIENTATION) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007922 "Orientation change skips hidden " + w);
7923 w.mOrientationChanging = false;
7924 }
7925
Dianne Hackborn0f761d62010-11-30 22:06:10 -08007926 if (w.mContentChanged) {
7927 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
7928 w.mContentChanged = false;
7929 }
7930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007931 final boolean canBeSeen = w.isDisplayedLw();
7932
7933 if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
7934 focusDisplayed = true;
7935 }
7936
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07007937 final boolean obscuredChanged = w.mObscured != obscured;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08007938
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007939 if (mBackgroundFillerTarget != null) {
7940 if (w.isAnimating()) {
7941 // Background filler is below all other windows that
7942 // are animating.
7943 mBackgroundFillerTarget = w;
7944 } else if (w.mIsWallpaper) {
7945 mBackgroundFillerTarget = w;
7946 }
7947 }
7948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007949 // Update effect.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07007950 if (!(w.mObscured=obscured)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007951 if (w.mSurface != null) {
7952 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
7953 holdScreen = w.mSession;
7954 }
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07007955 if (!syswin && w.mAttrs.screenBrightness >= 0
7956 && screenBrightness < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007957 screenBrightness = w.mAttrs.screenBrightness;
7958 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05007959 if (!syswin && w.mAttrs.buttonBrightness >= 0
7960 && buttonBrightness < 0) {
7961 buttonBrightness = w.mAttrs.buttonBrightness;
7962 }
Mike Lockwood46af6a82010-03-09 08:28:22 -05007963 if (canBeSeen
7964 && (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
7965 || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
7966 || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR)) {
Dianne Hackborn9ed4a4b2009-03-25 17:10:37 -07007967 syswin = true;
7968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969 }
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007970
Dianne Hackborn25994b42009-09-04 14:21:19 -07007971 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007972 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007973 // This window completely covers everything behind it,
7974 // so we want to leave all of them as unblurred (for
7975 // performance reasons).
7976 obscured = true;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007977 } else if (w.mNeedsBackgroundFiller && w.mHasDrawn
7978 && w.mViewVisibility == View.VISIBLE
7979 && (canBeSeen || w.isAnimating())) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007980 // This window is in compatibility mode, and needs background filler.
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07007981 obscured = true;
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007982 mBackgroundFillerTarget = w;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07007983 } else if (canBeSeen && !obscured &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007984 (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007985 if (localLOGV) Slog.v(TAG, "Win " + w
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 + ": blurring=" + blurring
7987 + " obscured=" + obscured
7988 + " displayed=" + displayed);
7989 if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
7990 if (!dimming) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007991 //Slog.i(TAG, "DIM BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007992 dimming = true;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007993 if (mDimAnimator == null) {
7994 mDimAnimator = new DimAnimator(mFxSession);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007995 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07007996 mDimAnimator.show(dw, dh);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08007997 mDimAnimator.updateParameters(mContext.getResources(),
7998 w, currentTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008000 }
8001 if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
8002 if (!blurring) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008003 //Slog.i(TAG, "BLUR BEHIND: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008004 blurring = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008005 if (mBlurSurface == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008006 try {
Romain Guy06882f82009-06-10 13:36:04 -07008007 mBlurSurface = new Surface(mFxSession, 0,
Mathias Agopian5d26c1e2010-03-01 16:09:43 -08008008 "BlurSurface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008009 -1, 16, 16,
8010 PixelFormat.OPAQUE,
8011 Surface.FX_SURFACE_BLUR);
8012 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008013 Slog.e(TAG, "Exception creating Blur surface", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008014 }
Dianne Hackbornac1471a2011-02-03 13:46:06 -08008015 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
8016 + mBlurSurface + ": CREATE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008018 if (mBlurSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008019 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
8020 + mBlurSurface + ": pos=(0,0) (" +
8021 dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008022 mBlurSurface.setPosition(0, 0);
8023 mBlurSurface.setSize(dw, dh);
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008024 mBlurSurface.setLayer(w.mAnimLayer-LAYER_OFFSET_BLUR);
Dianne Hackborn16064f92010-03-25 00:47:24 -07008025 if (!mBlurShown) {
8026 try {
8027 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR "
8028 + mBlurSurface + ": SHOW");
8029 mBlurSurface.show();
8030 } catch (RuntimeException e) {
8031 Slog.w(TAG, "Failure showing blur surface", e);
8032 }
8033 mBlurShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008034 }
8035 }
8036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008037 }
8038 }
8039 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008040
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07008041 if (obscuredChanged && mWallpaperTarget == w) {
8042 // This is the wallpaper target and its obscured state
8043 // changed... make sure the current wallaper's visibility
8044 // has been updated accordingly.
8045 updateWallpaperVisibilityLocked();
8046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008048
Dianne Hackbornac1471a2011-02-03 13:46:06 -08008049 if (mBackgroundFillerTarget != null) {
8050 if (mBackgroundFillerSurface == null) {
8051 try {
8052 mBackgroundFillerSurface = new Surface(mFxSession, 0,
8053 "BackGroundFiller",
8054 0, dw, dh,
8055 PixelFormat.OPAQUE,
8056 Surface.FX_SURFACE_NORMAL);
8057 } catch (Exception e) {
8058 Slog.e(TAG, "Exception creating filler surface", e);
8059 }
8060 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
8061 + mBackgroundFillerSurface + ": CREATE");
8062 }
8063 try {
8064 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
8065 + mBackgroundFillerSurface + " SHOW: pos=(0,0) ("
8066 + dw + "x" + dh + ") layer="
8067 + (mBackgroundFillerTarget.mLayer - 1));
8068 mBackgroundFillerSurface.setPosition(0, 0);
8069 mBackgroundFillerSurface.setSize(dw, dh);
8070 // Using the same layer as Dim because they will never be shown at the
8071 // same time. NOTE: we do NOT use mAnimLayer, because we don't
8072 // want this surface dragged up in front of stuff that is animating.
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008073 mBackgroundFillerSurface.setLayer(mBackgroundFillerTarget.mLayer
8074 - LAYER_OFFSET_DIM);
Dianne Hackbornac1471a2011-02-03 13:46:06 -08008075 mBackgroundFillerSurface.show();
8076 } catch (RuntimeException e) {
8077 Slog.e(TAG, "Exception showing filler surface");
8078 }
8079 } else if (backgroundFillerWasShown) {
8080 mBackgroundFillerTarget = null;
8081 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BG FILLER "
8082 + mBackgroundFillerSurface + " HIDE");
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008083 try {
8084 mBackgroundFillerSurface.hide();
8085 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008086 Slog.e(TAG, "Exception hiding filler surface", e);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07008087 }
8088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008089
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008090 if (mDimAnimator != null && mDimAnimator.mDimShown) {
Dianne Hackbornde2606d2009-12-18 16:53:55 -08008091 animating |= mDimAnimator.updateSurface(dimming, currentTime,
8092 mDisplayFrozen || !mPolicy.isScreenOn());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008093 }
Romain Guy06882f82009-06-10 13:36:04 -07008094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008095 if (!blurring && mBlurShown) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008096 if (SHOW_TRANSACTIONS) Slog.i(TAG, " BLUR " + mBlurSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008097 + ": HIDE");
8098 try {
8099 mBlurSurface.hide();
8100 } catch (IllegalArgumentException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008101 Slog.w(TAG, "Illegal argument exception hiding blur surface");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008102 }
8103 mBlurShown = false;
8104 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008105
8106 if (mBlackFrame != null) {
8107 if (mScreenRotationAnimation != null) {
8108 mBlackFrame.setMatrix(
8109 mScreenRotationAnimation.getEnterTransformation().getMatrix());
8110 } else {
8111 mBlackFrame.clearMatrix();
8112 }
8113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008114 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008115 Slog.e(TAG, "Unhandled exception in Window Manager", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008116 }
8117
8118 Surface.closeTransaction();
Romain Guy06882f82009-06-10 13:36:04 -07008119
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008120 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
8121
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008122 if (mWatermark != null) {
8123 mWatermark.drawIfNeeded();
8124 }
8125
Joe Onorato8a9b2202010-02-26 18:56:32 -08008126 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008127 "With display frozen, orientationChangeComplete="
8128 + orientationChangeComplete);
8129 if (orientationChangeComplete) {
8130 if (mWindowsFreezingScreen) {
8131 mWindowsFreezingScreen = false;
8132 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8133 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008134 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008135 }
Romain Guy06882f82009-06-10 13:36:04 -07008136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 i = mResizingWindows.size();
8138 if (i > 0) {
8139 do {
8140 i--;
8141 WindowState win = mResizingWindows.get(i);
8142 try {
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008143 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
8144 "Reporting new frame to " + win + ": " + win.mFrame);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008145 int diff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008146 boolean configChanged =
8147 win.mConfiguration != mCurConfiguration
8148 && (win.mConfiguration == null
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008149 || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0);
8150 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
8151 && configChanged) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008152 Slog.i(TAG, "Sending new config to window " + win + ": "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008153 + win.mFrame.width() + "x" + win.mFrame.height()
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008154 + " / " + mCurConfiguration + " / 0x"
8155 + Integer.toHexString(diff));
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008156 }
Dianne Hackborn694f79b2010-03-17 19:44:59 -07008157 win.mConfiguration = mCurConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008158 win.mClient.resized(win.mFrame.width(),
8159 win.mFrame.height(), win.mLastContentInsets,
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008160 win.mLastVisibleInsets, win.mDrawPending,
8161 configChanged ? win.mConfiguration : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008162 win.mContentInsetsChanged = false;
8163 win.mVisibleInsetsChanged = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -08008164 win.mSurfaceResized = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008165 } catch (RemoteException e) {
8166 win.mOrientationChanging = false;
8167 }
8168 } while (i > 0);
8169 mResizingWindows.clear();
8170 }
Romain Guy06882f82009-06-10 13:36:04 -07008171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008172 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008173 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 i = mDestroySurface.size();
8175 if (i > 0) {
8176 do {
8177 i--;
8178 WindowState win = mDestroySurface.get(i);
8179 win.mDestroying = false;
8180 if (mInputMethodWindow == win) {
8181 mInputMethodWindow = null;
8182 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008183 if (win == mWallpaperTarget) {
8184 wallpaperDestroyed = true;
8185 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008186 win.destroySurfaceLocked();
8187 } while (i > 0);
8188 mDestroySurface.clear();
8189 }
8190
8191 // Time to remove any exiting tokens?
8192 for (i=mExitingTokens.size()-1; i>=0; i--) {
8193 WindowToken token = mExitingTokens.get(i);
8194 if (!token.hasVisible) {
8195 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008196 if (token.windowType == TYPE_WALLPAPER) {
8197 mWallpaperTokens.remove(token);
8198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 }
8200 }
8201
8202 // Time to remove any exiting applications?
8203 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
8204 AppWindowToken token = mExitingAppTokens.get(i);
8205 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008206 // Make sure there is no animation running on this token,
8207 // so any windows associated with it will be removed as
8208 // soon as their animations are complete
8209 token.animation = null;
8210 token.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008211 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
8212 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008213 mAppTokens.remove(token);
8214 mExitingAppTokens.remove(i);
8215 }
8216 }
8217
Dianne Hackborna8f60182009-09-01 19:01:50 -07008218 boolean needRelayout = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008219
Dianne Hackborna8f60182009-09-01 19:01:50 -07008220 if (!animating && mAppTransitionRunning) {
8221 // We have finished the animation of an app transition. To do
8222 // this, we have delayed a lot of operations like showing and
8223 // hiding apps, moving apps in Z-order, etc. The app token list
8224 // reflects the correct Z-order, but the window list may now
8225 // be out of sync with it. So here we will just rebuild the
8226 // entire app window list. Fun!
8227 mAppTransitionRunning = false;
8228 needRelayout = true;
8229 rebuildAppWindowListLocked();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008230 assignLayersLocked();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008231 // Clear information about apps that were moving.
8232 mToBottomApps.clear();
8233 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008234
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008235 if (focusDisplayed) {
8236 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
8237 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008238 if (wallpaperDestroyed) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008239 needRelayout = adjustWallpaperWindowsLocked() != 0;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008240 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008241 if (needRelayout) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008242 requestAnimationLocked(0);
8243 } else if (animating) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008244 requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
8245 }
Jeff Browneb857f12010-07-16 10:06:33 -07008246
Jeff Brown3a22cd92011-01-21 13:59:04 -08008247 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08008248 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07008249
Jeff Brown8e03b752010-06-13 19:16:55 -07008250 setHoldScreenLocked(holdScreen != null);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08008251 if (!mDisplayFrozen) {
8252 if (screenBrightness < 0 || screenBrightness > 1.0f) {
8253 mPowerManager.setScreenBrightnessOverride(-1);
8254 } else {
8255 mPowerManager.setScreenBrightnessOverride((int)
8256 (screenBrightness * Power.BRIGHTNESS_ON));
8257 }
8258 if (buttonBrightness < 0 || buttonBrightness > 1.0f) {
8259 mPowerManager.setButtonBrightnessOverride(-1);
8260 } else {
8261 mPowerManager.setButtonBrightnessOverride((int)
8262 (buttonBrightness * Power.BRIGHTNESS_ON));
8263 }
Mike Lockwoodfb73f792009-11-20 11:31:18 -05008264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008265 if (holdScreen != mHoldingScreenOn) {
8266 mHoldingScreenOn = holdScreen;
8267 Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
8268 mH.sendMessage(m);
8269 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008270
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008271 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008272 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008273 mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
8274 LocalPowerManager.BUTTON_EVENT, true);
8275 mTurnOnScreen = false;
8276 }
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008277
Dianne Hackborn50660e22011-02-02 17:12:25 -08008278 if (screenRotationFinished && mScreenRotationAnimation != null) {
8279 mScreenRotationAnimation.kill();
8280 mScreenRotationAnimation = null;
8281 }
8282
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008283 if (updateRotation) {
8284 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
8285 boolean changed = setRotationUncheckedLocked(
8286 WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
8287 if (changed) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08008288 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008289 }
8290 }
8291
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08008292 // Check to see if we are now in a state where the screen should
8293 // be enabled, because the window obscured flags have changed.
8294 enableScreenIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008295 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07008296
8297 /**
8298 * Must be called with the main window manager lock held.
8299 */
8300 void setHoldScreenLocked(boolean holding) {
8301 boolean state = mHoldingScreenWakeLock.isHeld();
8302 if (holding != state) {
8303 if (holding) {
Daniel Sandler0601eb72011-04-13 01:01:32 -04008304 mPolicy.screenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07008305 mHoldingScreenWakeLock.acquire();
8306 } else {
8307 mPolicy.screenOnStoppedLw();
8308 mHoldingScreenWakeLock.release();
8309 }
8310 }
8311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008312
8313 void requestAnimationLocked(long delay) {
8314 if (!mAnimationPending) {
8315 mAnimationPending = true;
8316 mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
8317 }
8318 }
Romain Guy06882f82009-06-10 13:36:04 -07008319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008320 /**
8321 * Have the surface flinger show a surface, robustly dealing with
8322 * error conditions. In particular, if there is not enough memory
8323 * to show the surface, then we will try to get rid of other surfaces
8324 * in order to succeed.
Romain Guy06882f82009-06-10 13:36:04 -07008325 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 * @return Returns true if the surface was successfully shown.
8327 */
8328 boolean showSurfaceRobustlyLocked(WindowState win) {
8329 try {
8330 if (win.mSurface != null) {
Dianne Hackborn16064f92010-03-25 00:47:24 -07008331 win.mSurfaceShown = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008332 win.mSurface.show();
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008333 if (win.mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08008334 if (DEBUG_VISIBILITY) Slog.v(TAG,
8335 "Show surface turning screen on: " + win);
Dianne Hackborn93e462b2009-09-15 22:50:40 -07008336 win.mTurnOnScreen = false;
8337 mTurnOnScreen = true;
8338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008339 }
8340 return true;
8341 } catch (RuntimeException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008342 Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008343 }
Romain Guy06882f82009-06-10 13:36:04 -07008344
Dianne Hackborn64825172011-03-02 21:32:58 -08008345 reclaimSomeSurfaceMemoryLocked(win, "show", true);
Romain Guy06882f82009-06-10 13:36:04 -07008346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008347 return false;
8348 }
Romain Guy06882f82009-06-10 13:36:04 -07008349
Dianne Hackborn64825172011-03-02 21:32:58 -08008350 boolean reclaimSomeSurfaceMemoryLocked(WindowState win, String operation, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008351 final Surface surface = win.mSurface;
Dianne Hackborn64825172011-03-02 21:32:58 -08008352 boolean leakedSurface = false;
8353 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07008354
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008355 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008356 win.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07008357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008358 if (mForceRemoves == null) {
8359 mForceRemoves = new ArrayList<WindowState>();
8360 }
Romain Guy06882f82009-06-10 13:36:04 -07008361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 long callingIdentity = Binder.clearCallingIdentity();
8363 try {
8364 // There was some problem... first, do a sanity check of the
8365 // window list to make sure we haven't left any dangling surfaces
8366 // around.
8367 int N = mWindows.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008368 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008369 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008370 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008371 if (ws.mSurface != null) {
8372 if (!mSessions.contains(ws.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008373 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008374 + ws + " surface=" + ws.mSurface
8375 + " token=" + win.mToken
8376 + " pid=" + ws.mSession.mPid
8377 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008378 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008379 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008380 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008381 ws.mSurface = null;
8382 mForceRemoves.add(ws);
8383 i--;
8384 N--;
8385 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008386 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008387 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 + ws + " surface=" + ws.mSurface
8389 + " token=" + win.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008390 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008391 ws.mSurface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008392 ws.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008393 ws.mSurface = null;
8394 leakedSurface = true;
8395 }
8396 }
8397 }
Romain Guy06882f82009-06-10 13:36:04 -07008398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008399 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008400 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008401 SparseIntArray pidCandidates = new SparseIntArray();
8402 for (int i=0; i<N; i++) {
Jeff Browne33348b2010-07-15 23:54:05 -07008403 WindowState ws = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008404 if (ws.mSurface != null) {
8405 pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
8406 }
8407 }
8408 if (pidCandidates.size() > 0) {
8409 int[] pids = new int[pidCandidates.size()];
8410 for (int i=0; i<pids.length; i++) {
8411 pids[i] = pidCandidates.keyAt(i);
8412 }
8413 try {
Dianne Hackborn64825172011-03-02 21:32:58 -08008414 if (mActivityManager.killPids(pids, "Free memory", secure)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008415 killedApps = true;
8416 }
8417 } catch (RemoteException e) {
8418 }
8419 }
8420 }
Romain Guy06882f82009-06-10 13:36:04 -07008421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008422 if (leakedSurface || killedApps) {
8423 // We managed to reclaim some memory, so get rid of the trouble
8424 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08008425 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008426 if (surface != null) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008427 if (SHOW_TRANSACTIONS) logSurface(win, "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008428 surface.destroy();
Dianne Hackborn16064f92010-03-25 00:47:24 -07008429 win.mSurfaceShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008430 win.mSurface = null;
8431 }
Romain Guy06882f82009-06-10 13:36:04 -07008432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 try {
8434 win.mClient.dispatchGetNewSurface();
8435 } catch (RemoteException e) {
8436 }
8437 }
8438 } finally {
8439 Binder.restoreCallingIdentity(callingIdentity);
8440 }
Dianne Hackborn64825172011-03-02 21:32:58 -08008441
8442 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008443 }
Romain Guy06882f82009-06-10 13:36:04 -07008444
Jeff Brown3a22cd92011-01-21 13:59:04 -08008445 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008446 WindowState newFocus = computeFocusedWindowLocked();
8447 if (mCurrentFocus != newFocus) {
8448 // This check makes sure that we don't already have the focus
8449 // change message pending.
8450 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
8451 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008452 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
8454 final WindowState oldFocus = mCurrentFocus;
8455 mCurrentFocus = newFocus;
8456 mLosingFocus.remove(newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07008457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008458 final WindowState imWindow = mInputMethodWindow;
8459 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008460 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008461 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008462 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
8463 mLayoutNeeded = true;
8464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08008466 performLayoutLockedInner(true /*initial*/, updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008467 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
8468 // Client will do the layout, but we need to assign layers
8469 // for handleNewWindowLocked() below.
8470 assignLayersLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008471 }
8472 }
Jeff Brown349703e2010-06-22 01:27:15 -07008473
8474 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
8475 // If we defer assigning layers, then the caller is responsible for
8476 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008477 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08008478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008479 return true;
8480 }
8481 return false;
8482 }
Jeff Brown349703e2010-06-22 01:27:15 -07008483
Jeff Brown3a22cd92011-01-21 13:59:04 -08008484 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
8485 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07008486 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008487
8488 private WindowState computeFocusedWindowLocked() {
8489 WindowState result = null;
8490 WindowState win;
8491
8492 int i = mWindows.size() - 1;
8493 int nextAppIndex = mAppTokens.size()-1;
8494 WindowToken nextApp = nextAppIndex >= 0
8495 ? mAppTokens.get(nextAppIndex) : null;
8496
8497 while (i >= 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07008498 win = mWindows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008499
Joe Onorato8a9b2202010-02-26 18:56:32 -08008500 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 TAG, "Looking for focus: " + i
8502 + " = " + win
8503 + ", flags=" + win.mAttrs.flags
8504 + ", canReceive=" + win.canReceiveKeys());
8505
8506 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -07008507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508 // If this window's application has been removed, just skip it.
8509 if (thisApp != null && thisApp.removed) {
8510 i--;
8511 continue;
8512 }
Romain Guy06882f82009-06-10 13:36:04 -07008513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008514 // If there is a focused app, don't allow focus to go to any
8515 // windows below it. If this is an application window, step
8516 // through the app tokens until we find its app.
8517 if (thisApp != null && nextApp != null && thisApp != nextApp
8518 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
8519 int origAppIndex = nextAppIndex;
8520 while (nextAppIndex > 0) {
8521 if (nextApp == mFocusedApp) {
8522 // Whoops, we are below the focused app... no focus
8523 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008524 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 TAG, "Reached focused app: " + mFocusedApp);
8526 return null;
8527 }
8528 nextAppIndex--;
8529 nextApp = mAppTokens.get(nextAppIndex);
8530 if (nextApp == thisApp) {
8531 break;
8532 }
8533 }
8534 if (thisApp != nextApp) {
8535 // Uh oh, the app token doesn't exist! This shouldn't
8536 // happen, but if it does we can get totally hosed...
8537 // so restart at the original app.
8538 nextAppIndex = origAppIndex;
8539 nextApp = mAppTokens.get(nextAppIndex);
8540 }
8541 }
8542
8543 // Dispatch to this window if it is wants key events.
8544 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008545 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008546 TAG, "Found focus @ " + i + " = " + win);
8547 result = win;
8548 break;
8549 }
8550
8551 i--;
8552 }
8553
8554 return result;
8555 }
8556
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008557 private void startFreezingDisplayLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008558 if (mDisplayFrozen) {
8559 return;
8560 }
Romain Guy06882f82009-06-10 13:36:04 -07008561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008562 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -07008563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008564 long now = SystemClock.uptimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008565 //Slog.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008566 if (mFreezeGcPending != 0) {
8567 if (now > (mFreezeGcPending+1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008568 //Slog.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008569 mH.removeMessages(H.FORCE_GC);
8570 Runtime.getRuntime().gc();
8571 mFreezeGcPending = now;
8572 }
8573 } else {
8574 mFreezeGcPending = now;
8575 }
Romain Guy06882f82009-06-10 13:36:04 -07008576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008577 mDisplayFrozen = true;
Jeff Brown349703e2010-06-22 01:27:15 -07008578
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008579 mInputMonitor.freezeInputDispatchingLw();
Jeff Brown349703e2010-06-22 01:27:15 -07008580
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07008581 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
8582 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008583 mNextAppTransitionPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008584 mAppTransitionReady = true;
8585 }
Romain Guy06882f82009-06-10 13:36:04 -07008586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587 if (PROFILE_ORIENTATION) {
8588 File file = new File("/data/system/frozen");
8589 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
8590 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008591
8592 if (CUSTOM_SCREEN_ROTATION) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08008593 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
8594 mScreenRotationAnimation.kill();
8595 mScreenRotationAnimation = null;
8596 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008597 if (mScreenRotationAnimation == null) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08008598 mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008599 mDisplay, mFxSession, inTransaction);
Dianne Hackborna1111872010-11-23 20:55:11 -08008600 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008601 if (!mScreenRotationAnimation.hasScreenshot()) {
8602 Surface.freezeDisplay(0);
8603 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008604 } else {
8605 Surface.freezeDisplay(0);
8606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008607 }
Romain Guy06882f82009-06-10 13:36:04 -07008608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008609 private void stopFreezingDisplayLocked() {
8610 if (!mDisplayFrozen) {
8611 return;
8612 }
Romain Guy06882f82009-06-10 13:36:04 -07008613
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008614 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
8615 return;
8616 }
8617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 mDisplayFrozen = false;
8619 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
8620 if (PROFILE_ORIENTATION) {
8621 Debug.stopMethodTracing();
8622 }
Dianne Hackborna1111872010-11-23 20:55:11 -08008623
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008624 boolean updateRotation = false;
8625
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008626 if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
8627 && mScreenRotationAnimation.hasScreenshot()) {
8628 if (mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
8629 mTransitionAnimationScale)) {
8630 requestAnimationLocked(0);
8631 } else {
8632 mScreenRotationAnimation = null;
8633 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08008634 }
8635 } else {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008636 if (mScreenRotationAnimation != null) {
8637 mScreenRotationAnimation.kill();
8638 mScreenRotationAnimation = null;
8639 }
8640 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -08008641 Surface.unfreezeDisplay(0);
8642 }
Romain Guy06882f82009-06-10 13:36:04 -07008643
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008644 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008645
Dianne Hackborn420829e2011-01-28 11:30:35 -08008646 boolean configChanged;
8647
Christopher Tateb696aee2010-04-02 19:08:30 -07008648 // While the display is frozen we don't re-compute the orientation
8649 // to avoid inconsistent states. However, something interesting
8650 // could have actually changed during that time so re-evaluate it
8651 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -08008652 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -07008653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008654 // A little kludge: a lot could have happened while the
8655 // display was frozen, so now that we are coming back we
8656 // do a gc so that any remote references the system
8657 // processes holds on others can be released if they are
8658 // no longer needed.
8659 mH.removeMessages(H.FORCE_GC);
8660 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
8661 2000);
Romain Guy06882f82009-06-10 13:36:04 -07008662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008663 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008664
8665 if (updateRotation) {
8666 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Dianne Hackborn420829e2011-01-28 11:30:35 -08008667 configChanged |= setRotationUncheckedLocked(
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008668 WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
Dianne Hackborn420829e2011-01-28 11:30:35 -08008669 }
8670
8671 if (configChanged) {
8672 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008673 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 }
Romain Guy06882f82009-06-10 13:36:04 -07008675
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008676 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
8677 DisplayMetrics dm) {
8678 if (index < tokens.length) {
8679 String str = tokens[index];
8680 if (str != null && str.length() > 0) {
8681 try {
8682 int val = Integer.parseInt(str);
8683 return val;
8684 } catch (Exception e) {
8685 }
8686 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008687 }
8688 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
8689 return defDps;
8690 }
8691 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
8692 return val;
8693 }
8694
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008695 void createWatermark() {
8696 if (mWatermark != null) {
8697 return;
8698 }
8699
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008700 File file = new File("/system/etc/setup.conf");
8701 FileInputStream in = null;
8702 try {
8703 in = new FileInputStream(file);
8704 DataInputStream ind = new DataInputStream(in);
8705 String line = ind.readLine();
8706 if (line != null) {
8707 String[] toks = line.split("%");
8708 if (toks != null && toks.length > 0) {
Dianne Hackborned7bfbf2010-11-05 13:08:35 -07008709 mWatermark = new Watermark(mDisplay, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -07008710 }
8711 }
8712 } catch (FileNotFoundException e) {
8713 } catch (IOException e) {
8714 } finally {
8715 if (in != null) {
8716 try {
8717 in.close();
8718 } catch (IOException e) {
8719 }
8720 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008721 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07008722 }
8723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008724 @Override
Joe Onorato664644d2011-01-23 17:53:23 -08008725 public void statusBarVisibilityChanged(int visibility) {
Jeff Brown05dc66a2011-03-02 14:41:58 -08008726 mInputManager.setSystemUiVisibility(visibility);
Joe Onorato664644d2011-01-23 17:53:23 -08008727 synchronized (mWindowMap) {
8728 final int N = mWindows.size();
8729 for (int i = 0; i < N; i++) {
8730 WindowState ws = mWindows.get(i);
8731 try {
8732 if (ws.getAttrs().hasSystemUiListeners) {
8733 ws.mClient.dispatchSystemUiVisibilityChanged(visibility);
8734 }
8735 } catch (RemoteException e) {
8736 // so sorry
8737 }
8738 }
8739 }
8740 }
8741
8742 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008743 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8744 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
8745 != PackageManager.PERMISSION_GRANTED) {
8746 pw.println("Permission Denial: can't dump WindowManager from from pid="
8747 + Binder.getCallingPid()
8748 + ", uid=" + Binder.getCallingUid());
8749 return;
8750 }
Romain Guy06882f82009-06-10 13:36:04 -07008751
Jeff Brown00fa7bd2010-07-02 15:37:36 -07008752 mInputManager.dump(pw);
Dianne Hackborna2e92262010-03-02 17:19:29 -08008753 pw.println(" ");
8754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008755 synchronized(mWindowMap) {
8756 pw.println("Current Window Manager state:");
8757 for (int i=mWindows.size()-1; i>=0; i--) {
Jeff Browne33348b2010-07-15 23:54:05 -07008758 WindowState w = mWindows.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008759 pw.print(" Window #"); pw.print(i); pw.print(' ');
8760 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008761 w.dump(pw, " ");
8762 }
8763 if (mInputMethodDialogs.size() > 0) {
8764 pw.println(" ");
8765 pw.println(" Input method dialogs:");
8766 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
8767 WindowState w = mInputMethodDialogs.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008768 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008769 }
8770 }
8771 if (mPendingRemove.size() > 0) {
8772 pw.println(" ");
8773 pw.println(" Remove pending for:");
8774 for (int i=mPendingRemove.size()-1; i>=0; i--) {
8775 WindowState w = mPendingRemove.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008776 pw.print(" Remove #"); pw.print(i); pw.print(' ');
8777 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008778 w.dump(pw, " ");
8779 }
8780 }
8781 if (mForceRemoves != null && mForceRemoves.size() > 0) {
8782 pw.println(" ");
8783 pw.println(" Windows force removing:");
8784 for (int i=mForceRemoves.size()-1; i>=0; i--) {
8785 WindowState w = mForceRemoves.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008786 pw.print(" Removing #"); pw.print(i); pw.print(' ');
8787 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008788 w.dump(pw, " ");
8789 }
8790 }
8791 if (mDestroySurface.size() > 0) {
8792 pw.println(" ");
8793 pw.println(" Windows waiting to destroy their surface:");
8794 for (int i=mDestroySurface.size()-1; i>=0; i--) {
8795 WindowState w = mDestroySurface.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008796 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
8797 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008798 w.dump(pw, " ");
8799 }
8800 }
8801 if (mLosingFocus.size() > 0) {
8802 pw.println(" ");
8803 pw.println(" Windows losing focus:");
8804 for (int i=mLosingFocus.size()-1; i>=0; i--) {
8805 WindowState w = mLosingFocus.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008806 pw.print(" Losing #"); pw.print(i); pw.print(' ');
8807 pw.print(w); pw.println(":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008808 w.dump(pw, " ");
8809 }
8810 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07008811 if (mResizingWindows.size() > 0) {
8812 pw.println(" ");
8813 pw.println(" Windows waiting to resize:");
8814 for (int i=mResizingWindows.size()-1; i>=0; i--) {
8815 WindowState w = mResizingWindows.get(i);
8816 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
8817 pw.print(w); pw.println(":");
8818 w.dump(pw, " ");
8819 }
8820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008821 if (mSessions.size() > 0) {
8822 pw.println(" ");
8823 pw.println(" All active sessions:");
8824 Iterator<Session> it = mSessions.iterator();
8825 while (it.hasNext()) {
8826 Session s = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008827 pw.print(" Session "); pw.print(s); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008828 s.dump(pw, " ");
8829 }
8830 }
8831 if (mTokenMap.size() > 0) {
8832 pw.println(" ");
8833 pw.println(" All tokens:");
8834 Iterator<WindowToken> it = mTokenMap.values().iterator();
8835 while (it.hasNext()) {
8836 WindowToken token = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008837 pw.print(" Token "); pw.print(token.token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008838 token.dump(pw, " ");
8839 }
8840 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07008841 if (mWallpaperTokens.size() > 0) {
8842 pw.println(" ");
8843 pw.println(" Wallpaper tokens:");
8844 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
8845 WindowToken token = mWallpaperTokens.get(i);
8846 pw.print(" Wallpaper #"); pw.print(i);
8847 pw.print(' '); pw.print(token); pw.println(':');
8848 token.dump(pw, " ");
8849 }
8850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008851 if (mAppTokens.size() > 0) {
8852 pw.println(" ");
8853 pw.println(" Application tokens in Z order:");
8854 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008855 pw.print(" App #"); pw.print(i); pw.print(": ");
8856 pw.println(mAppTokens.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008857 }
8858 }
8859 if (mFinishedStarting.size() > 0) {
8860 pw.println(" ");
8861 pw.println(" Finishing start of application tokens:");
8862 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
8863 WindowToken token = mFinishedStarting.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008864 pw.print(" Finished Starting #"); pw.print(i);
8865 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 token.dump(pw, " ");
8867 }
8868 }
8869 if (mExitingTokens.size() > 0) {
8870 pw.println(" ");
8871 pw.println(" Exiting tokens:");
8872 for (int i=mExitingTokens.size()-1; i>=0; i--) {
8873 WindowToken token = mExitingTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008874 pw.print(" Exiting #"); pw.print(i);
8875 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008876 token.dump(pw, " ");
8877 }
8878 }
8879 if (mExitingAppTokens.size() > 0) {
8880 pw.println(" ");
8881 pw.println(" Exiting application tokens:");
8882 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
8883 WindowToken token = mExitingAppTokens.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008884 pw.print(" Exiting App #"); pw.print(i);
8885 pw.print(' '); pw.print(token); pw.println(':');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008886 token.dump(pw, " ");
8887 }
8888 }
8889 pw.println(" ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008890 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
8891 pw.print(" mLastFocus="); pw.println(mLastFocus);
8892 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
8893 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
8894 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
Dianne Hackbornf21adf62009-08-13 10:20:21 -07008895 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn284ac932009-08-28 10:34:25 -07008896 if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
8897 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
8898 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
8899 }
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008900 if (mWindowDetachedWallpaper != null) {
8901 pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
8902 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008903 if (mWindowAnimationBackgroundSurface != null) {
8904 pw.println(" mWindowAnimationBackgroundSurface:");
8905 mWindowAnimationBackgroundSurface.printTo(" ", pw);
8906 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008907 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
8908 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
8909 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008910 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
8911 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
8912 pw.print(" mLayoutNeeded="); pw.print(mLayoutNeeded);
8913 pw.print(" mBlurShown="); pw.println(mBlurShown);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008914 if (mDimAnimator != null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -08008915 pw.println(" mDimAnimator:");
8916 mDimAnimator.printTo(" ", pw);
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008917 } else {
Dianne Hackborna2e92262010-03-02 17:19:29 -08008918 pw.println( " no DimAnimator ");
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07008919 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008920 pw.print(" mInputMethodAnimLayerAdjustment=");
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008921 pw.print(mInputMethodAnimLayerAdjustment);
8922 pw.print(" mWallpaperAnimLayerAdjustment=");
8923 pw.println(mWallpaperAnimLayerAdjustment);
Dianne Hackborn284ac932009-08-28 10:34:25 -07008924 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
8925 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008926 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
8927 pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008928 pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
8929 pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008930 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -07008931 pw.print(" mForcedAppOrientation="); pw.print(mForcedAppOrientation);
8932 pw.print(" mRequestedRotation="); pw.print(mRequestedRotation);
8933 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Dianne Hackborn89ba6752011-01-23 16:51:16 -08008934 pw.print(" mDeferredRotation="); pw.print(mDeferredRotation);
Dianne Hackborn9d132642011-04-21 17:26:39 -07008935 pw.print(", mDeferredRotationAnimFlags="); pw.println(mDeferredRotationAnimFlags);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008936 pw.print(" mAnimationPending="); pw.print(mAnimationPending);
8937 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
8938 pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
8939 pw.print(" mNextAppTransition=0x");
8940 pw.print(Integer.toHexString(mNextAppTransition));
Dianne Hackborn9d132642011-04-21 17:26:39 -07008941 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
8942 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
8943 pw.print(" mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008944 if (mNextAppTransitionPackage != null) {
8945 pw.print(" mNextAppTransitionPackage=");
8946 pw.print(mNextAppTransitionPackage);
Dianne Hackborn9d132642011-04-21 17:26:39 -07008947 pw.print(" mNextAppTransitionEnter=0x");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008948 pw.print(Integer.toHexString(mNextAppTransitionEnter));
Dianne Hackborn9d132642011-04-21 17:26:39 -07008949 pw.print(" mNextAppTransitionExit=0x");
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008950 pw.print(Integer.toHexString(mNextAppTransitionExit));
8951 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008952 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
8953 pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
8954 if (mOpeningApps.size() > 0) {
8955 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
8956 }
8957 if (mClosingApps.size() > 0) {
8958 pw.print(" mClosingApps="); pw.println(mClosingApps);
8959 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008960 if (mToTopApps.size() > 0) {
8961 pw.print(" mToTopApps="); pw.println(mToTopApps);
8962 }
8963 if (mToBottomApps.size() > 0) {
8964 pw.print(" mToBottomApps="); pw.println(mToBottomApps);
8965 }
Dianne Hackborn87fc3082010-12-03 13:09:12 -08008966 if (mDisplay != null) {
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07008967 pw.print(" Display: init="); pw.print(mInitialDisplayWidth); pw.print("x");
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008968 pw.print(mInitialDisplayHeight); pw.print(" base=");
8969 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
8970 pw.print(" cur=");
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07008971 pw.print(mCurDisplayWidth); pw.print("x"); pw.print(mCurDisplayHeight);
8972 pw.print(" real="); pw.print(mDisplay.getRealWidth());
8973 pw.print("x"); pw.print(mDisplay.getRealHeight());
8974 pw.print(" raw="); pw.print(mDisplay.getRawWidth());
8975 pw.print("x"); pw.println(mDisplay.getRawHeight());
Dianne Hackborn87fc3082010-12-03 13:09:12 -08008976 } else {
8977 pw.println(" NO DISPLAY");
8978 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008979 pw.println(" Policy:");
8980 mPolicy.dump(" ", fd, pw, args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008981 }
8982 }
8983
Jeff Brown349703e2010-06-22 01:27:15 -07008984 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 public void monitor() {
8986 synchronized (mWindowMap) { }
Mike Lockwood983ee092009-11-22 01:42:24 -05008987 synchronized (mKeyguardTokenWatcher) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -07008988 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008989
Jeff Brown2992ea72011-01-28 22:04:14 -08008990 public interface OnHardKeyboardStatusChangeListener {
8991 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
8992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008993}