blob: 51edb44f2db1f9c1358b13f1e66621c096bbe4eb [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;
Craig Mautner65d11b32012-10-01 13:59:52 -070021import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Dianne Hackborn5fd21692011-06-07 14:09:47 -070022import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
24import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
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;
Craig Mautner65d11b32012-10-01 13:59:52 -070029import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
31import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Craig Mautner65d11b32012-10-01 13:59:52 -070032import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
Daniel Sandler7d276c32012-01-30 14:33:52 -050033import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
35import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
Craig Mautner65d11b32012-10-01 13:59:52 -070036import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;
Craig Mautner88400d32012-09-30 12:35:45 -070037import static android.view.WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY;
Craig Mautner65d11b32012-10-01 13:59:52 -070038import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
39import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070040import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070041import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
43import com.android.internal.app.IBatteryStats;
44import com.android.internal.policy.PolicyManager;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080045import com.android.internal.policy.impl.PhoneWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import com.android.internal.view.IInputContext;
47import com.android.internal.view.IInputMethodClient;
48import com.android.internal.view.IInputMethodManager;
Dianne Hackbornac3587d2010-03-11 11:12:11 -080049import com.android.internal.view.WindowManagerPolicyThread;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080050import com.android.server.AttributeCache;
51import com.android.server.EventLogTags;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080052import com.android.server.Watchdog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import com.android.server.am.BatteryStatsService;
Jeff Brownfa25bf52012-07-23 19:26:30 -070054import com.android.server.display.DisplayManagerService;
Jeff Brown4532e612012-04-05 14:27:12 -070055import com.android.server.input.InputManagerService;
Jeff Brown4f8ecd82012-06-18 18:29:13 -070056import com.android.server.power.PowerManagerService;
57import com.android.server.power.ShutdownThread;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59import android.Manifest;
60import android.app.ActivityManagerNative;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070061import android.app.ActivityOptions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.app.IActivityManager;
Joe Onoratoac0ee892011-01-30 15:38:30 -080063import android.app.StatusBarManager;
Jim Millerd6b57052010-06-07 17:52:42 -070064import android.app.admin.DevicePolicyManager;
Jeff Brownff7e6ef2012-08-15 02:05:18 -070065import android.animation.ValueAnimator;
Jim Miller284b62e2010-06-08 14:27:42 -070066import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.content.Context;
Jim Miller284b62e2010-06-08 14:27:42 -070068import android.content.Intent;
69import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.content.pm.ActivityInfo;
71import android.content.pm.PackageManager;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -070072import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.res.Configuration;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080074import android.graphics.Bitmap;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070075import android.graphics.Canvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.graphics.Matrix;
77import android.graphics.PixelFormat;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070078import android.graphics.Point;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.graphics.Rect;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070080import android.graphics.RectF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.graphics.Region;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070082import android.hardware.display.DisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.Binder;
Dianne Hackborn75804932009-10-20 20:15:20 -070084import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.os.Debug;
86import android.os.Handler;
87import android.os.IBinder;
Dianne Hackborn38e29a62011-09-18 14:43:08 -070088import android.os.IRemoteCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.Looper;
90import android.os.Message;
91import android.os.Parcel;
92import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.os.PowerManager;
94import android.os.Process;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -070095import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.os.RemoteException;
97import android.os.ServiceManager;
Brad Fitzpatrickec062f62010-11-03 09:56:54 -070098import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.os.SystemClock;
100import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -0700101import android.os.Trace;
Craig Mautner259328c2012-08-21 19:30:58 -0700102import android.os.WorkSource;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import android.provider.Settings;
Dianne Hackborn723738c2009-06-25 19:48:04 -0700104import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.util.EventLog;
Michael Jurka4accb6a2012-03-26 09:18:46 -0700106import android.util.FloatMath;
Jim Millerd6b57052010-06-07 17:52:42 -0700107import android.util.Log;
Craig Mautner59c00972012-07-30 12:10:24 -0700108import android.util.SparseArray;
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.SparseIntArray;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700112import android.util.TypedValue;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800113import android.view.Choreographer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Display;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700115import android.view.DisplayInfo;
Adam Powelldfee59a2011-08-05 20:48:30 -0700116import android.view.Gravity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117import android.view.IApplicationToken;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700118import android.view.IDisplayContentChangeListener;
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -0700119import android.view.IInputFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120import android.view.IOnKeyguardExitResult;
121import android.view.IRotationWatcher;
122import android.view.IWindow;
123import android.view.IWindowManager;
124import android.view.IWindowSession;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700125import android.view.InputChannel;
Jeff Brownc5ed5912010-07-14 18:48:53 -0700126import android.view.InputDevice;
Jeff Brownbbda99d2010-07-28 15:48:59 -0700127import android.view.InputEvent;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800128import android.view.InputEventReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import android.view.KeyEvent;
130import android.view.MotionEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import android.view.Surface;
132import android.view.SurfaceSession;
133import android.view.View;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700134import android.view.ViewTreeObserver;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700135import android.view.WindowInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -0700137import android.view.WindowManagerGlobal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import android.view.WindowManagerPolicy;
139import android.view.WindowManager.LayoutParams;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700140import android.view.WindowManagerPolicy.FakeWindow;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700141import android.view.animation.AlphaAnimation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142import android.view.animation.Animation;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700143import android.view.animation.AnimationSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144import android.view.animation.AnimationUtils;
Michael Jurkac016aaa2012-06-05 17:22:24 -0700145import android.view.animation.DecelerateInterpolator;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700146import android.view.animation.Interpolator;
147import android.view.animation.ScaleAnimation;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700148import android.view.animation.Transformation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
150import java.io.BufferedWriter;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700151import java.io.DataInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152import java.io.File;
153import java.io.FileDescriptor;
Dianne Hackbornb9fb1702010-08-23 16:49:02 -0700154import java.io.FileInputStream;
155import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156import java.io.IOException;
157import java.io.OutputStream;
158import java.io.OutputStreamWriter;
159import java.io.PrintWriter;
160import java.io.StringWriter;
161import java.net.Socket;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700162import java.text.DateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163import java.util.ArrayList;
Jeff Brownd7a04de2012-06-17 14:17:52 -0700164import java.util.Date;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165import java.util.HashMap;
166import java.util.HashSet;
167import java.util.Iterator;
168import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -0700169import java.util.NoSuchElementException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170
171/** {@hide} */
Dianne Hackbornddca3ee2009-07-23 19:01:31 -0700172public class WindowManagerService extends IWindowManager.Stub
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700173 implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
Craig Mautner722285e2012-09-07 13:55:58 -0700174 DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 static final String TAG = "WindowManager";
176 static final boolean DEBUG = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700177 static final boolean DEBUG_ADD_REMOVE = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800178 static final boolean DEBUG_FOCUS = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 static final boolean DEBUG_ANIM = false;
Dianne Hackborn9b52a212009-12-11 14:51:35 -0800180 static final boolean DEBUG_LAYOUT = false;
Dianne Hackbornac3587d2010-03-11 11:12:11 -0800181 static final boolean DEBUG_RESIZE = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 static final boolean DEBUG_LAYERS = false;
183 static final boolean DEBUG_INPUT = false;
184 static final boolean DEBUG_INPUT_METHOD = false;
185 static final boolean DEBUG_VISIBILITY = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700186 static final boolean DEBUG_WINDOW_MOVEMENT = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800187 static final boolean DEBUG_TOKEN_MOVEMENT = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 static final boolean DEBUG_ORIENTATION = false;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700189 static final boolean DEBUG_APP_ORIENTATION = false;
Dianne Hackborn694f79b2010-03-17 19:44:59 -0700190 static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 static final boolean DEBUG_APP_TRANSITIONS = false;
192 static final boolean DEBUG_STARTING_WINDOW = false;
193 static final boolean DEBUG_REORDER = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800194 static final boolean DEBUG_WALLPAPER = false;
Dianne Hackborn98129732012-11-01 16:28:16 -0700195 static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
Christopher Tate994ef922011-01-12 20:06:07 -0800196 static final boolean DEBUG_DRAG = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700197 static final boolean DEBUG_SCREEN_ON = false;
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -0700198 static final boolean DEBUG_SCREENSHOT = false;
Dianne Hackborn38cc8962011-10-13 11:33:55 -0700199 static final boolean DEBUG_BOOT = false;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700200 static final boolean DEBUG_LAYOUT_REPEATS = true;
Craig Mautner7358fbf2012-04-12 21:06:33 -0700201 static final boolean DEBUG_SURFACE_TRACE = false;
Craig Mautner7d8df392012-04-06 15:26:23 -0700202 static final boolean DEBUG_WINDOW_TRACE = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700203 static final boolean SHOW_SURFACE_ALLOC = false;
Craig Mautner343511c2012-02-28 17:30:50 -0800204 static final boolean SHOW_TRANSACTIONS = false;
Dianne Hackborn36991742011-10-11 21:35:26 -0700205 static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700206 static final boolean HIDE_STACK_CRAWLS = true;
Craig Mautnercf8cbbe2012-03-25 21:54:36 -0700207 static final int LAYOUT_REPEAT_THRESHOLD = 4;
Michael Chan53071d62009-05-13 17:29:48 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 static final boolean PROFILE_ORIENTATION = false;
Dave Bortcfe65242009-04-09 14:51:04 -0700210 static final boolean localLOGV = DEBUG;
Romain Guy06882f82009-06-10 13:36:04 -0700211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 /** How much to multiply the policy's type layer, to reserve room
213 * for multiple windows of the same type and Z-ordering adjustment
214 * with TYPE_LAYER_OFFSET. */
215 static final int TYPE_LAYER_MULTIPLIER = 10000;
Romain Guy06882f82009-06-10 13:36:04 -0700216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
218 * or below others in the same layer. */
219 static final int TYPE_LAYER_OFFSET = 1000;
Romain Guy06882f82009-06-10 13:36:04 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 /** How much to increment the layer for each window, to reserve room
222 * for effect surfaces between them.
223 */
224 static final int WINDOW_LAYER_MULTIPLIER = 5;
Romain Guy06882f82009-06-10 13:36:04 -0700225
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800226 /**
227 * Dim surface layer is immediately below target window.
228 */
229 static final int LAYER_OFFSET_DIM = 1;
230
231 /**
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700232 * Blur surface layer is immediately below dim layer.
233 */
234 static final int LAYER_OFFSET_BLUR = 2;
235
236 /**
237 * Animation thumbnail is as far as possible below the window above
238 * the thumbnail (or in other words as far as possible above the window
239 * below it).
240 */
241 static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
242
243 /**
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700244 * Layer at which to put the rotation freeze snapshot.
245 */
246 static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
247
248 /**
249 * Layer at which to put the mask for emulated screen sizes.
250 */
251 static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 /** The maximum length we will accept for a loaded animation duration:
254 * this is 10 seconds.
255 */
256 static final int MAX_ANIMATION_DURATION = 10*1000;
257
258 /** Amount of time (in milliseconds) to animate the dim surface from one
259 * value to another, when no window animation is driving it.
260 */
261 static final int DEFAULT_DIM_DURATION = 200;
262
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -0700263 /** Amount of time (in milliseconds) to animate the fade-in-out transition for
264 * compatible windows.
265 */
266 static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
267
Craig Mautner7dfcb012012-10-10 10:24:47 -0700268 /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
Craig Mautnera4942c92012-10-16 09:06:53 -0700269 static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
Craig Mautner7dfcb012012-10-10 10:24:47 -0700270
Dianne Hackborna1111872010-11-23 20:55:11 -0800271 /**
272 * If true, the window manager will do its own custom freezing and general
273 * management of the screen during rotation.
274 */
275 static final boolean CUSTOM_SCREEN_ROTATION = true;
276
Jeff Brownb09abc12011-01-13 21:08:27 -0800277 // Maximum number of milliseconds to wait for input devices to be enumerated before
278 // proceding with safe mode detection.
279 private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
Jim Miller28637ba2011-07-06 19:57:05 -0700280
Jeff Brown349703e2010-06-22 01:27:15 -0700281 // Default input dispatching timeout in nanoseconds.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800282 static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
Romain Guy06882f82009-06-10 13:36:04 -0700283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 static final int UPDATE_FOCUS_NORMAL = 0;
285 static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
286 static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
287 static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
Romain Guy06882f82009-06-10 13:36:04 -0700288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 private static final String SYSTEM_SECURE = "ro.secure";
Romain Guy06882f82009-06-10 13:36:04 -0700290 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291
Craig Mautner5642a482012-08-23 12:16:53 -0700292 final private KeyguardDisableHandler mKeyguardDisableHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700294 private final boolean mHeadless;
295
Michael Jurkac016aaa2012-06-05 17:22:24 -0700296 private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
297
Jim Miller284b62e2010-06-08 14:27:42 -0700298 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
299 @Override
300 public void onReceive(Context context, Intent intent) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700301 final String action = intent.getAction();
302 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
Craig Mautner5642a482012-08-23 12:16:53 -0700303 mKeyguardDisableHandler.sendEmptyMessage(
304 KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
Jim Miller284b62e2010-06-08 14:27:42 -0700305 }
306 }
307 };
308
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700309 // Current user when multi-user is enabled. Don't show windows of non-current user.
310 int mCurrentUserId;
311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 final Context mContext;
313
314 final boolean mHaveInputMethods;
Romain Guy06882f82009-06-10 13:36:04 -0700315
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700316 final boolean mAllowBootMessages;
317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 final boolean mLimitedAlphaCompositing;
Romain Guy06882f82009-06-10 13:36:04 -0700319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
321
322 final IActivityManager mActivityManager;
Romain Guy06882f82009-06-10 13:36:04 -0700323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 final IBatteryStats mBatteryStats;
Romain Guy06882f82009-06-10 13:36:04 -0700325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 /**
327 * All currently active sessions with clients.
328 */
329 final HashSet<Session> mSessions = new HashSet<Session>();
Romain Guy06882f82009-06-10 13:36:04 -0700330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 /**
332 * Mapping from an IWindow IBinder to the server's Window object.
333 * This is also used as the lock for all of our state.
334 */
335 final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
336
337 /**
338 * Mapping from a token IBinder to a WindowToken object.
339 */
340 final HashMap<IBinder, WindowToken> mTokenMap =
341 new HashMap<IBinder, WindowToken>();
342
343 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 * Window tokens that are in the process of exiting, but still
345 * on screen for animations.
346 */
347 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
348
349 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700350 * List controlling the ordering of windows in different applications which must
351 * be kept in sync with ActivityManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 */
Craig Mautnerbec53f72012-04-05 11:49:05 -0700353 final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354
355 /**
Craig Mautneref25d7a2012-05-15 23:01:47 -0700356 * AppWindowTokens in the Z order they were in at the start of an animation. Between
357 * animations this list is maintained in the exact order of mAppTokens. If tokens
358 * are added to mAppTokens during an animation an attempt is made to insert them at the same
359 * logical location in this list. Note that this list is always in sync with mWindows.
360 */
361 ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
362
363 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 * Application tokens that are in the process of exiting, but still
365 * on screen for animations.
366 */
367 final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
368
369 /**
370 * List of window tokens that have finished starting their application,
371 * and now need to have the policy remove their windows.
372 */
373 final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
374
375 /**
Dianne Hackborndf89e652011-10-06 22:35:11 -0700376 * Fake windows added to the window manager. Note: ordered from top to
377 * bottom, opposite of mWindows.
378 */
379 final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
380
381 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 * Windows that are being resized. Used so we can tell the client about
383 * the resize after closing the transaction in which we resized the
384 * underlying surface.
385 */
386 final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
387
388 /**
389 * Windows whose animations have ended and now must be removed.
390 */
391 final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
392
393 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800394 * Used when processing mPendingRemove to avoid working on the original array.
395 */
396 WindowState[] mPendingRemoveTmp = new WindowState[20];
397
398 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 * Windows whose surface should be destroyed.
400 */
401 final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
402
403 /**
404 * Windows that have lost input focus and are waiting for the new
405 * focus window to be displayed before they are told about this.
406 */
407 ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
408
409 /**
410 * This is set when we have run out of memory, and will either be an empty
411 * list or contain windows that need to be force removed.
412 */
413 ArrayList<WindowState> mForceRemoves;
Romain Guy06882f82009-06-10 13:36:04 -0700414
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800415 /**
Dianne Hackborn38e29a62011-09-18 14:43:08 -0700416 * Windows that clients are waiting to have drawn.
417 */
418 ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
419 = new ArrayList<Pair<WindowState, IRemoteCallback>>();
420
421 /**
Dianne Hackborn12d3a942012-04-27 14:16:30 -0700422 * Windows that have called relayout() while we were running animations,
423 * so we need to tell when the animation is done.
424 */
425 final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
426
427 /**
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800428 * Used when rebuilding window list to keep track of windows that have
429 * been removed.
430 */
431 WindowState[] mRebuildTmp = new WindowState[20];
432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 IInputMethodManager mInputMethodManager;
Romain Guy06882f82009-06-10 13:36:04 -0700434
Craig Mautner7358fbf2012-04-12 21:06:33 -0700435 final SurfaceSession mFxSession;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -0700436 Watermark mWatermark;
Brad Fitzpatrick68044332010-11-22 18:19:48 -0800437 StrictModeFlash mStrictModeFlash;
Romain Guy06882f82009-06-10 13:36:04 -0700438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 final float[] mTmpFloats = new float[9];
440
Jeff Browne215f262012-09-10 16:01:14 -0700441 boolean mDisplayReady;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 boolean mSafeMode;
443 boolean mDisplayEnabled = false;
444 boolean mSystemBooted = false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -0700445 boolean mForceDisplayEnabled = false;
Dianne Hackborn661cd522011-08-22 00:26:20 -0700446 boolean mShowingBootMessages = false;
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800447
Jeff Brownd7a04de2012-06-17 14:17:52 -0700448 String mLastANRState;
449
Craig Mautner59c00972012-07-30 12:10:24 -0700450 /** All DisplayDontents in the world, kept here */
451 private SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>();
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 int mRotation = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Dianne Hackborndacea8c2011-04-21 17:26:39 -0700455 boolean mAltOrientation = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 ArrayList<IRotationWatcher> mRotationWatchers
457 = new ArrayList<IRotationWatcher>();
Jeff Brown01a98dd2011-09-20 15:08:29 -0700458 int mDeferredRotationPauseCount;
Romain Guy06882f82009-06-10 13:36:04 -0700459
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700460 final Rect mSystemDecorRect = new Rect();
461 int mSystemDecorLayer = 0;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700462 final Rect mScreenRect = new Rect();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -0700463
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800464 boolean mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 boolean mDisplayFrozen = false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800466 boolean mWaitingForConfig = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 boolean mWindowsFreezingScreen = false;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700468 boolean mClientFreezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 int mAppsFreezingScreen = 0;
Dianne Hackbornbc7386c2011-06-06 17:27:54 -0700470 int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800472 int mLayoutSeq = 0;
Dianne Hackborndf89e652011-10-06 22:35:11 -0700473
474 int mLastStatusBarVisibility = 0;
475
Dianne Hackbornb601ce12010-03-01 23:36:02 -0800476 // State while inside of layoutAndPlaceSurfacesLocked().
477 boolean mFocusMayChange;
Craig Mautner01cd0e72012-06-18 10:19:11 -0700478
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800479 Configuration mCurConfiguration = new Configuration();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 // This is held as long as we have the screen frozen, to give us time to
482 // perform a rotation animation when turning off shows the lock screen which
483 // changes the orientation.
484 PowerManager.WakeLock mScreenFrozenLock;
Romain Guy06882f82009-06-10 13:36:04 -0700485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 // State management of app transitions. When we are preparing for a
487 // transition, mNextAppTransition will be the kind of transition to
488 // perform or TRANSIT_NONE if we are not waiting. If we are waiting,
489 // mOpeningApps and mClosingApps are the lists of tokens that will be
490 // made visible or hidden at the next transition.
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700491 int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700492 int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700493 String mNextAppTransitionPackage;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700494 Bitmap mNextAppTransitionThumbnail;
Michael Jurka832cb222012-04-13 09:32:47 -0700495 // Used for thumbnail transitions. True if we're scaling up, false if scaling down
496 boolean mNextAppTransitionScaleUp;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700497 IRemoteCallback mNextAppTransitionCallback;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -0700498 int mNextAppTransitionEnter;
499 int mNextAppTransitionExit;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -0700500 int mNextAppTransitionStartX;
501 int mNextAppTransitionStartY;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -0700502 int mNextAppTransitionStartWidth;
503 int mNextAppTransitionStartHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 boolean mAppTransitionReady = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -0700505 boolean mAppTransitionRunning = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 boolean mAppTransitionTimeout = false;
507 boolean mStartingIconInTransition = false;
508 boolean mSkipAppTransitionAnimation = false;
509 final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
510 final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
Romain Guy06882f82009-06-10 13:36:04 -0700511
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -0700512 boolean mIsTouchDevice;
513
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700514 final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Jeff Brownbc68a592011-07-25 12:58:12 -0700515 final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
Dianne Hackborn48a76512011-06-08 21:51:44 -0700516 final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700517 final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
518
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -0800519 final H mH = new H();
520
521 final Choreographer mChoreographer = Choreographer.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522
523 WindowState mCurrentFocus = null;
524 WindowState mLastFocus = null;
Romain Guy06882f82009-06-10 13:36:04 -0700525
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800526 /** This just indicates the window the input method is on top of, not
527 * necessarily the window its input is going to. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 WindowState mInputMethodTarget = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800529
530 /** If true hold off on modifying the animation layer of mInputMethodTarget */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 boolean mInputMethodTargetWaitingAnim;
532 int mInputMethodAnimLayerAdjustment;
Romain Guy06882f82009-06-10 13:36:04 -0700533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 WindowState mInputMethodWindow = null;
535 final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
536
Jeff Brown2992ea72011-01-28 22:04:14 -0800537 boolean mHardKeyboardAvailable;
538 boolean mHardKeyboardEnabled;
539 OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
540
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700541 final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800542
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700543 // If non-null, this is the currently visible window that is associated
544 // with the wallpaper.
545 WindowState mWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700546 // If non-null, we are in the middle of animating from one wallpaper target
547 // to another, and this is the lower one in Z-order.
Dianne Hackborn98129732012-11-01 16:28:16 -0700548 WindowState mLowerWallpaperTarget = null;
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700549 // If non-null, we are in the middle of animating from one wallpaper target
550 // to another, and this is the higher one in Z-order.
Craig Mautner918b53b2012-07-09 14:15:54 -0700551 private WindowState mUpperWallpaperTarget = null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700552 int mWallpaperAnimLayerAdjustment;
Dianne Hackborn73e92b42009-10-15 14:29:19 -0700553 float mLastWallpaperX = -1;
554 float mLastWallpaperY = -1;
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800555 float mLastWallpaperXStep = -1;
556 float mLastWallpaperYStep = -1;
Dianne Hackborn19382ac2009-09-11 21:13:37 -0700557 // This is set when we are waiting for a wallpaper to tell us it is done
558 // changing its scroll position.
559 WindowState mWaitingOnWallpaper;
560 // The last time we had a timeout when waiting for a wallpaper.
561 long mLastWallpaperTimeoutTime;
562 // We give a wallpaper up to 150ms to finish scrolling.
563 static final long WALLPAPER_TIMEOUT = 150;
564 // Time we wait after a timeout before trying to wait again.
565 static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 AppWindowToken mFocusedApp = null;
568
569 PowerManagerService mPowerManager;
Romain Guy06882f82009-06-10 13:36:04 -0700570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 float mWindowAnimationScale = 1.0f;
572 float mTransitionAnimationScale = 1.0f;
Chet Haasec38fa1f2012-02-01 16:37:46 -0800573 float mAnimatorDurationScale = 1.0f;
Romain Guy06882f82009-06-10 13:36:04 -0700574
Jeff Brown4532e612012-04-05 14:27:12 -0700575 final InputManagerService mInputManager;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700576 final DisplayManagerService mDisplayManagerService;
577 final DisplayManager mDisplayManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 // Who is holding the screen on.
580 Session mHoldingScreenOn;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700581 PowerManager.WakeLock mHoldingScreenWakeLock;
Romain Guy06882f82009-06-10 13:36:04 -0700582
Dianne Hackborn93e462b2009-09-15 22:50:40 -0700583 boolean mTurnOnScreen;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800584
Christopher Tatea53146c2010-09-07 11:57:52 -0700585 DragState mDragState = null;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800586
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800587 /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
588 * methods. */
Craig Mautnera608b882012-03-30 13:03:49 -0700589 class LayoutFields {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700590 static final int SET_UPDATE_ROTATION = 1 << 0;
591 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
592 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
Craig Mautner2639da52012-07-09 09:39:06 -0700593 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
Craig Mautner7d8df392012-04-06 15:26:23 -0700594 static final int SET_TURN_ON_SCREEN = 1 << 4;
Craig Mautnera608b882012-03-30 13:03:49 -0700595
Craig Mautner764983d2012-03-22 11:37:36 -0700596 boolean mWallpaperForceHidingChanged = false;
597 boolean mWallpaperMayChange = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700598 boolean mOrientationChangeComplete = true;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700599 int mAdjResult = 0;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800600 private Session mHoldScreen = null;
601 private boolean mObscured = false;
Craig Mautner764983d2012-03-22 11:37:36 -0700602 boolean mDimming = false;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800603 private boolean mSyswin = false;
604 private float mScreenBrightness = -1;
605 private float mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -0700606 private long mUserActivityTimeout = -1;
Craig Mautnera608b882012-03-30 13:03:49 -0700607 private boolean mUpdateRotation = false;
Craig Mautner65d11b32012-10-01 13:59:52 -0700608
609 private static final int DISPLAY_CONTENT_UNKNOWN = 0;
610 private static final int DISPLAY_CONTENT_MIRROR = 1;
611 private static final int DISPLAY_CONTENT_UNIQUE = 2;
612 private int mDisplayHasContent = DISPLAY_CONTENT_UNKNOWN;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800613 }
Craig Mautner01cd0e72012-06-18 10:19:11 -0700614 final LayoutFields mInnerFields = new LayoutFields();
615
Craig Mautner322e4032012-07-13 13:35:20 -0700616 static class AppWindowAnimParams {
617 AppWindowAnimator mAppAnimator;
618 ArrayList<WindowStateAnimator> mWinAnimators;
619
620 public AppWindowAnimParams(final AppWindowAnimator appAnimator) {
621 mAppAnimator = appAnimator;
622
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700623 final AppWindowToken atoken = appAnimator.mAppToken;
Craig Mautner322e4032012-07-13 13:35:20 -0700624 mWinAnimators = new ArrayList<WindowStateAnimator>();
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700625 final int N = atoken.allAppWindows.size();
Craig Mautner322e4032012-07-13 13:35:20 -0700626 for (int i = 0; i < N; i++) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700627 mWinAnimators.add(atoken.allAppWindows.get(i).mWinAnimator);
Craig Mautner322e4032012-07-13 13:35:20 -0700628 }
629 }
630 }
631
Craig Mautner711f90a2012-07-03 18:43:52 -0700632 static class LayoutToAnimatorParams {
Craig Mautner322e4032012-07-13 13:35:20 -0700633 boolean mParamsModified;
634
Craig Mautner918b53b2012-07-09 14:15:54 -0700635 static final long WALLPAPER_TOKENS_CHANGED = 1 << 0;
636 long mChanges;
637
Craig Mautner711f90a2012-07-03 18:43:52 -0700638 boolean mAnimationScheduled;
Craig Mautnera91f9e22012-09-14 16:22:08 -0700639 SparseArray<WinAnimatorList> mWinAnimatorLists = new SparseArray<WinAnimatorList>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700640 WindowState mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -0700641 WindowState mLowerWallpaperTarget;
642 WindowState mUpperWallpaperTarget;
Craig Mautnera91f9e22012-09-14 16:22:08 -0700643 SparseArray<DimAnimator.Parameters> mDimParams = new SparseArray<DimAnimator.Parameters>();
Craig Mautner918b53b2012-07-09 14:15:54 -0700644 ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
Craig Mautner322e4032012-07-13 13:35:20 -0700645 ArrayList<AppWindowAnimParams> mAppWindowAnimParams = new ArrayList<AppWindowAnimParams>();
Craig Mautner711f90a2012-07-03 18:43:52 -0700646 }
Craig Mautner918b53b2012-07-09 14:15:54 -0700647 /** Params from WindowManagerService to WindowAnimator. Do not modify or read without first
648 * locking on either mWindowMap or mAnimator and then on mLayoutToAnim */
Craig Mautner711f90a2012-07-03 18:43:52 -0700649 final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams();
Craig Mautner01cd0e72012-06-18 10:19:11 -0700650
651 /** The lowest wallpaper target with a detached wallpaper animation on it. */
652 WindowState mWindowDetachedWallpaper = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -0800653
Craig Mautner6fbda632012-07-03 09:26:39 -0700654 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
655 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
656 private int mTransactionSequence;
657
Craig Mautnerbb1449b2012-03-23 16:11:14 -0700658 /** Only do a maximum of 6 repeated layouts. After that quit */
659 private int mLayoutRepeatCount;
660
Craig Mautner764983d2012-03-22 11:37:36 -0700661 final WindowAnimator mAnimator;
Jeff Brown4a06c802012-02-15 15:06:01 -0800662
Jeff Brown32cbc38552011-12-01 14:01:49 -0800663 final class DragInputEventReceiver extends InputEventReceiver {
664 public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
665 super(inputChannel, looper);
666 }
667
Christopher Tatea53146c2010-09-07 11:57:52 -0700668 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -0800669 public void onInputEvent(InputEvent event) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700670 boolean handled = false;
Christopher Tatea53146c2010-09-07 11:57:52 -0700671 try {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800672 if (event instanceof MotionEvent
673 && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
Jeff Brown3915bb82010-11-05 15:02:16 -0700674 && mDragState != null) {
Jeff Brown4952dfd2011-11-30 19:23:22 -0800675 final MotionEvent motionEvent = (MotionEvent)event;
Jeff Brown3915bb82010-11-05 15:02:16 -0700676 boolean endDrag = false;
Jeff Brown4952dfd2011-11-30 19:23:22 -0800677 final float newX = motionEvent.getRawX();
678 final float newY = motionEvent.getRawY();
Jeff Brown3915bb82010-11-05 15:02:16 -0700679
Jeff Brown4952dfd2011-11-30 19:23:22 -0800680 switch (motionEvent.getAction()) {
Christopher Tatea53146c2010-09-07 11:57:52 -0700681 case MotionEvent.ACTION_DOWN: {
682 if (DEBUG_DRAG) {
683 Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
684 }
685 } break;
686
687 case MotionEvent.ACTION_MOVE: {
688 synchronized (mWindowMap) {
Christopher Tate2c095f32010-10-04 14:13:40 -0700689 // move the surface and tell the involved window(s) where we are
Christopher Tatea53146c2010-09-07 11:57:52 -0700690 mDragState.notifyMoveLw(newX, newY);
691 }
692 } break;
693
694 case MotionEvent.ACTION_UP: {
695 if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
696 + newX + "," + newY);
697 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700698 endDrag = mDragState.notifyDropLw(newX, newY);
Christopher Tatea53146c2010-09-07 11:57:52 -0700699 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700700 } break;
701
702 case MotionEvent.ACTION_CANCEL: {
703 if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
704 endDrag = true;
705 } break;
706 }
707
708 if (endDrag) {
709 if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
710 // tell all the windows that the drag has ended
Chris Tate59943592010-10-11 20:33:44 -0700711 synchronized (mWindowMap) {
Chris Tated4533f12010-10-19 15:15:08 -0700712 mDragState.endDragLw();
Chris Tate59943592010-10-11 20:33:44 -0700713 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700714 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700715
716 handled = true;
Christopher Tatea53146c2010-09-07 11:57:52 -0700717 }
718 } catch (Exception e) {
719 Slog.e(TAG, "Exception caught by drag handleMotion", e);
720 } finally {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800721 finishInputEvent(event, handled);
Christopher Tatea53146c2010-09-07 11:57:52 -0700722 }
723 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800724 }
Christopher Tatea53146c2010-09-07 11:57:52 -0700725
726 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 * Whether the UI is currently running in touch mode (not showing
728 * navigational focus because the user is directly pressing the screen).
729 */
Michael Jurkae99adc72011-08-11 18:28:01 -0700730 boolean mInTouchMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700732 // Temp regions for intermediary calculations.
733 private final Region mTempRegion = new Region();
734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 private ViewServer mViewServer;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700736 private ArrayList<WindowChangeListener> mWindowChangeListeners =
737 new ArrayList<WindowChangeListener>();
738 private boolean mWindowsChanged = false;
739
740 public interface WindowChangeListener {
741 public void windowsChanged();
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -0700742 public void focusChanged();
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744
Dianne Hackbornc485a602009-03-24 22:39:49 -0700745 final Configuration mTempConfiguration = new Configuration();
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700746
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700747 // The desired scaling factor for compatible apps.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400748 float mCompatibleScreenScale;
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -0700749
Jeff Brown780c46f2012-06-24 12:15:38 -0700750 // If true, only the core apps and services are being launched because the device
751 // is in a special boot mode, such as being encrypted or waiting for a decryption password.
752 // For example, when this flag is true, there will be no wallpaper service.
753 final boolean mOnlyCore;
754
Jeff Brownbd6e1502012-08-28 03:27:37 -0700755 public static WindowManagerService main(final Context context,
756 final PowerManagerService pm, final DisplayManagerService dm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700757 final InputManagerService im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700758 final Handler uiHandler, final Handler wmHandler,
759 final boolean haveInputMethods, final boolean showBootMsgs,
760 final boolean onlyCore) {
761 final WindowManagerService[] holder = new WindowManagerService[1];
762 wmHandler.runWithScissors(new Runnable() {
763 @Override
764 public void run() {
Jeff Browna9d131c2012-09-20 16:48:17 -0700765 holder[0] = new WindowManagerService(context, pm, dm, im,
Jeff Brownbd6e1502012-08-28 03:27:37 -0700766 uiHandler, haveInputMethods, showBootMsgs, onlyCore);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700768 }, 0);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700769 return holder[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 }
Romain Guy06882f82009-06-10 13:36:04 -0700771
Jeff Brownbd6e1502012-08-28 03:27:37 -0700772 private void initPolicy(Handler uiHandler) {
773 uiHandler.runWithScissors(new Runnable() {
774 @Override
775 public void run() {
776 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
Romain Guy06882f82009-06-10 13:36:04 -0700777
Jeff Brownbd6e1502012-08-28 03:27:37 -0700778 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
779 mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
780 * TYPE_LAYER_MULTIPLIER
781 + TYPE_LAYER_OFFSET;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700783 }, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 }
785
786 private WindowManagerService(Context context, PowerManagerService pm,
Jeff Browna9d131c2012-09-20 16:48:17 -0700787 DisplayManagerService displayManager, InputManagerService inputManager,
788 Handler uiHandler,
Jeff Brown780c46f2012-06-24 12:15:38 -0700789 boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 mContext = context;
791 mHaveInputMethods = haveInputMethods;
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700792 mAllowBootMessages = showBootMsgs;
Jeff Brown780c46f2012-06-24 12:15:38 -0700793 mOnlyCore = onlyCore;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 mLimitedAlphaCompositing = context.getResources().getBoolean(
795 com.android.internal.R.bool.config_sf_limitedAlpha);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700796 mDisplayManagerService = displayManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700797 mHeadless = displayManager.isHeadless();
Romain Guy06882f82009-06-10 13:36:04 -0700798
Craig Mautner722285e2012-09-07 13:55:58 -0700799 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
800 mDisplayManager.registerDisplayListener(this, null);
801 Display[] displays = mDisplayManager.getDisplays();
802 for (Display display : displays) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -0700803 createDisplayContentLocked(display);
Craig Mautner722285e2012-09-07 13:55:58 -0700804 }
805
Craig Mautner5642a482012-08-23 12:16:53 -0700806 mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 mPowerManager = pm;
809 mPowerManager.setPolicy(mPolicy);
810 PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
811 mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
812 "SCREEN_FROZEN");
813 mScreenFrozenLock.setReferenceCounted(false);
814
815 mActivityManager = ActivityManagerNative.getDefault();
816 mBatteryStats = BatteryStatsService.getService();
817
818 // Get persisted window scale setting
Jeff Sharkey6e2bee72012-10-01 13:39:08 -0700819 mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
820 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
821 mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
822 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
823 setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
824 Settings.Global.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale));
Romain Guy06882f82009-06-10 13:36:04 -0700825
Jim Miller284b62e2010-06-08 14:27:42 -0700826 // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
827 IntentFilter filter = new IntentFilter();
828 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
829 mContext.registerReceiver(mBroadcastReceiver, filter);
830
Dianne Hackbornb80395c2012-06-14 19:38:20 -0700831 mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
Craig Mautner259328c2012-08-21 19:30:58 -0700832 | PowerManager.ON_AFTER_RELEASE, TAG);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700833 mHoldingScreenWakeLock.setReferenceCounted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834
Jeff Browna9d131c2012-09-20 16:48:17 -0700835 mInputManager = inputManager;
Craig Mautner9e809442012-06-22 17:13:04 -0700836 mFxSession = new SurfaceSession();
Craig Mautner918b53b2012-07-09 14:15:54 -0700837 mAnimator = new WindowAnimator(this);
Romain Guy06882f82009-06-10 13:36:04 -0700838
Jeff Brownbd6e1502012-08-28 03:27:37 -0700839 initPolicy(uiHandler);
Romain Guy06882f82009-06-10 13:36:04 -0700840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 // Add ourself to the Watchdog monitors.
842 Watchdog.getInstance().addMonitor(this);
Craig Mautner7358fbf2012-04-12 21:06:33 -0700843
844 Surface.openTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700845 try {
846 createWatermarkInTransaction();
847 } finally {
848 Surface.closeTransaction();
849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 }
851
Jeff Browna9d131c2012-09-20 16:48:17 -0700852 public InputMonitor getInputMonitor() {
853 return mInputMonitor;
Jeff Brown4532e612012-04-05 14:27:12 -0700854 }
855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 @Override
857 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
858 throws RemoteException {
859 try {
860 return super.onTransact(code, data, reply, flags);
861 } catch (RuntimeException e) {
862 // The window manager only throws security exceptions, so let's
863 // log all others.
864 if (!(e instanceof SecurityException)) {
Dianne Hackborn89620282011-09-11 12:47:45 -0700865 Log.wtf(TAG, "Window Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 }
867 throw e;
868 }
869 }
870
Jeff Browne33348b2010-07-15 23:54:05 -0700871 private void placeWindowAfter(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700872 final WindowList windows = pos.getWindowList();
873 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800874 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700876 + (i+1) + " of " + windows.size() + " (after " + pos + ")");
877 windows.add(i+1, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700878 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 }
880
Jeff Browne33348b2010-07-15 23:54:05 -0700881 private void placeWindowBefore(WindowState pos, WindowState window) {
Craig Mautner59c00972012-07-30 12:10:24 -0700882 final WindowList windows = pos.getWindowList();
883 final int i = windows.indexOf(pos);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -0800884 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 TAG, "Adding window " + window + " at "
Craig Mautner59c00972012-07-30 12:10:24 -0700886 + i + " of " + windows.size() + " (before " + pos + ")");
887 windows.add(i, window);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -0700888 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 }
890
891 //This method finds out the index of a window that has the same app token as
892 //win. used for z ordering the windows in mWindows
893 private int findIdxBasedOnAppTokens(WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -0700894 WindowList windows = win.getWindowList();
895 for(int j = windows.size() - 1; j >= 0; j--) {
896 WindowState wentry = windows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 if(wentry.mAppToken == win.mAppToken) {
898 return j;
899 }
900 }
901 return -1;
902 }
Romain Guy06882f82009-06-10 13:36:04 -0700903
Craig Mautnerefb735d2012-09-07 15:40:24 -0700904 /**
905 * Return the list of Windows from the passed token on the given Display.
906 * @param token The token with all the windows.
907 * @param displayContent The display we are interested in.
908 * @return List of windows from token that are on displayContent.
909 */
Craig Mautner69b08182012-09-05 13:07:13 -0700910 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
911 final WindowList windowList = new WindowList();
912 final int count = token.windows.size();
913 for (int i = 0; i < count; i++) {
914 final WindowState win = token.windows.get(i);
915 if (win.mDisplayContent == displayContent) {
916 windowList.add(win);
917 }
918 }
919 return windowList;
920 }
921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
923 final IWindow client = win.mClient;
924 final WindowToken token = win.mToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700925 final DisplayContent displayContent = win.mDisplayContent;
Romain Guy06882f82009-06-10 13:36:04 -0700926
Craig Mautner59c00972012-07-30 12:10:24 -0700927 final WindowList windows = win.getWindowList();
928 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 final WindowState attached = win.mAttachedWindow;
930 int i;
Craig Mautner69b08182012-09-05 13:07:13 -0700931 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 if (attached == null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700933 int tokenWindowsPos = 0;
934 int windowListPos = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 if (token.appWindowToken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -0700936 int index = windowListPos - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 if (index >= 0) {
938 // If this application has existing windows, we
939 // simply place the new window on top of them... but
940 // keep the starting window on top.
941 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
942 // Base windows go behind everything else.
Craig Mautner69b08182012-09-05 13:07:13 -0700943 WindowState lowestWindow = tokenWindowList.get(0);
944 placeWindowBefore(lowestWindow, win);
945 tokenWindowsPos = token.windows.indexOf(lowestWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 } else {
947 AppWindowToken atoken = win.mAppToken;
Craig Mautner69b08182012-09-05 13:07:13 -0700948 WindowState lastWindow = tokenWindowList.get(index);
949 if (atoken != null && lastWindow == atoken.startingWindow) {
950 placeWindowBefore(lastWindow, win);
Craig Mautnerefb735d2012-09-07 15:40:24 -0700951 tokenWindowsPos = token.windows.indexOf(lastWindow);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700953 int newIdx = findIdxBasedOnAppTokens(win);
954 //there is a window above this one associated with the same
955 //apptoken note that the window could be a floating window
956 //that was created later or a window at the top of the list of
957 //windows associated with this token.
958 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
959 Slog.v(TAG, "Adding window " + win + " at "
Craig Mautnerefb735d2012-09-07 15:40:24 -0700960 + (newIdx + 1) + " of " + N);
Romain Guy06882f82009-06-10 13:36:04 -0700961 }
Craig Mautnerefb735d2012-09-07 15:40:24 -0700962 windows.add(newIdx + 1, win);
963 if (newIdx < 0) {
964 // No window from token found on win's display.
965 tokenWindowsPos = 0;
966 } else {
967 tokenWindowsPos = token.windows.indexOf(windows.get(newIdx)) + 1;
968 }
Craig Mautner69b08182012-09-05 13:07:13 -0700969 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 }
971 }
972 } else {
Craig Mautner69b08182012-09-05 13:07:13 -0700973 // No windows from this token on this display
Joe Onorato8a9b2202010-02-26 18:56:32 -0800974 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 TAG, "Figuring out where to add app window "
976 + client.asBinder() + " (token=" + token + ")");
977 // Figure out where the window should go, based on the
978 // order of applications.
Craig Mautneref25d7a2012-05-15 23:01:47 -0700979 final int NA = mAnimatingAppTokens.size();
Jeff Browne33348b2010-07-15 23:54:05 -0700980 WindowState pos = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 for (i=NA-1; i>=0; i--) {
Craig Mautneref25d7a2012-05-15 23:01:47 -0700982 AppWindowToken t = mAnimatingAppTokens.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 if (t == token) {
984 i--;
985 break;
986 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800987
Dianne Hackborna8f60182009-09-01 19:01:50 -0700988 // We haven't reached the token yet; if this token
Craig Mautner69b08182012-09-05 13:07:13 -0700989 // is not going to the bottom and has windows on this display, we can
Dianne Hackborna8f60182009-09-01 19:01:50 -0700990 // use it as an anchor for when we do reach the token.
Craig Mautner69b08182012-09-05 13:07:13 -0700991 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
992 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
993 pos = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995 }
996 // We now know the index into the apps. If we found
997 // an app window above, that gives us the position; else
998 // we need to look some more.
999 if (pos != null) {
1000 // Move behind any windows attached to this one.
Jeff Browne33348b2010-07-15 23:54:05 -07001001 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 if (atoken != null) {
Craig Mautner69b08182012-09-05 13:07:13 -07001003 tokenWindowList =
1004 getTokenWindowsOnDisplay(atoken, win.mDisplayContent);
1005 final int NC = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 if (NC > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001007 WindowState bottom = tokenWindowList.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 if (bottom.mSubLayer < 0) {
1009 pos = bottom;
1010 }
1011 }
1012 }
1013 placeWindowBefore(pos, win);
1014 } else {
Dianne Hackborna8f60182009-09-01 19:01:50 -07001015 // Continue looking down until we find the first
Craig Mautner69b08182012-09-05 13:07:13 -07001016 // token that has windows on this display.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 while (i >= 0) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07001018 AppWindowToken t = mAnimatingAppTokens.get(i);
Craig Mautner69b08182012-09-05 13:07:13 -07001019 tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
1020 final int NW = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 if (NW > 0) {
Craig Mautner69b08182012-09-05 13:07:13 -07001022 pos = tokenWindowList.get(NW-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 break;
1024 }
1025 i--;
1026 }
1027 if (pos != null) {
1028 // Move in front of any windows attached to this
1029 // one.
Jeff Browne33348b2010-07-15 23:54:05 -07001030 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 if (atoken != null) {
1032 final int NC = atoken.windows.size();
1033 if (NC > 0) {
1034 WindowState top = atoken.windows.get(NC-1);
1035 if (top.mSubLayer >= 0) {
1036 pos = top;
1037 }
1038 }
1039 }
1040 placeWindowAfter(pos, win);
1041 } else {
1042 // Just search for the start of this layer.
1043 final int myLayer = win.mBaseLayer;
1044 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07001045 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001046 if (w.mBaseLayer > myLayer) {
1047 break;
1048 }
1049 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001050 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
1051 Slog.v(TAG, "Adding window " + win + " at "
1052 + i + " of " + N);
1053 }
Craig Mautner59c00972012-07-30 12:10:24 -07001054 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001055 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056 }
1057 }
1058 }
1059 } else {
1060 // Figure out where window should go, based on layer.
1061 final int myLayer = win.mBaseLayer;
1062 for (i=N-1; i>=0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07001063 if (windows.get(i).mBaseLayer <= myLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 break;
1065 }
1066 }
Craig Mautner69b08182012-09-05 13:07:13 -07001067 i++;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001068 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001069 TAG, "Adding window " + win + " at "
1070 + i + " of " + N);
Craig Mautner59c00972012-07-30 12:10:24 -07001071 windows.add(i, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001072 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 }
Craig Mautner59c00972012-07-30 12:10:24 -07001074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001075 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001076 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 token.windows.add(tokenWindowsPos, win);
1078 }
1079
1080 } else {
1081 // Figure out this window's ordering relative to the window
1082 // it is attached to.
Craig Mautner69b08182012-09-05 13:07:13 -07001083 final int NA = tokenWindowList.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 final int sublayer = win.mSubLayer;
1085 int largestSublayer = Integer.MIN_VALUE;
1086 WindowState windowWithLargestSublayer = null;
1087 for (i=0; i<NA; i++) {
Craig Mautner69b08182012-09-05 13:07:13 -07001088 WindowState w = tokenWindowList.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 final int wSublayer = w.mSubLayer;
1090 if (wSublayer >= largestSublayer) {
1091 largestSublayer = wSublayer;
1092 windowWithLargestSublayer = w;
1093 }
1094 if (sublayer < 0) {
1095 // For negative sublayers, we go below all windows
1096 // in the same sublayer.
1097 if (wSublayer >= sublayer) {
1098 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001099 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 token.windows.add(i, win);
1101 }
Craig Mautner59c00972012-07-30 12:10:24 -07001102 placeWindowBefore(wSublayer >= 0 ? attached : w, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 break;
1104 }
1105 } else {
1106 // For positive sublayers, we go above all windows
1107 // in the same sublayer.
1108 if (wSublayer > sublayer) {
1109 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001110 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 token.windows.add(i, win);
1112 }
1113 placeWindowBefore(w, win);
1114 break;
1115 }
1116 }
1117 }
1118 if (i >= NA) {
1119 if (addToToken) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001120 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 token.windows.add(win);
1122 }
1123 if (sublayer < 0) {
1124 placeWindowBefore(attached, win);
1125 } else {
1126 placeWindowAfter(largestSublayer >= 0
1127 ? windowWithLargestSublayer
1128 : attached,
1129 win);
1130 }
1131 }
1132 }
Romain Guy06882f82009-06-10 13:36:04 -07001133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 if (win.mAppToken != null && addToToken) {
1135 win.mAppToken.allAppWindows.add(win);
1136 }
1137 }
Romain Guy06882f82009-06-10 13:36:04 -07001138
Craig Mautneref25d7a2012-05-15 23:01:47 -07001139 /** TODO(cmautner): Is this the same as {@link WindowState#canReceiveKeys()} */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 static boolean canBeImeTarget(WindowState w) {
1141 final int fl = w.mAttrs.flags
1142 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
Dianne Hackborne75d8722011-01-27 19:37:40 -08001143 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
Craig Mautner65d11b32012-10-01 13:59:52 -07001144 || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08001145 if (DEBUG_INPUT_METHOD) {
1146 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1147 if (!w.isVisibleOrAdding()) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07001148 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurface
Dianne Hackborne75d8722011-01-27 19:37:40 -08001149 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
Dianne Hackbornac920872012-05-22 11:49:49 -07001150 + " policyVis=" + w.mPolicyVisibility
1151 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1152 + " attachHid=" + w.mAttachedHidden
Dianne Hackborne75d8722011-01-27 19:37:40 -08001153 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
1154 if (w.mAppToken != null) {
1155 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1156 }
1157 }
1158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001159 return w.isVisibleOrAdding();
1160 }
1161 return false;
1162 }
Romain Guy06882f82009-06-10 13:36:04 -07001163
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001164 /**
1165 * Dig through the WindowStates and find the one that the Input Method will target.
1166 * @param willMove
1167 * @return The index+1 in mWindows of the discovered target.
1168 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001170 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1171 // same display. Or even when the current IME/target are not on the same screen as the next
1172 // IME/target. For now only look for input windows on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001173 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001174 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 WindowState w = null;
1176 int i = N;
1177 while (i > 0) {
1178 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001179 w = windows.get(i);
Romain Guy06882f82009-06-10 13:36:04 -07001180
Dianne Hackborne75d8722011-01-27 19:37:40 -08001181 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
1182 + " " + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 if (canBeImeTarget(w)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001184 //Slog.i(TAG, "Putting input method here!");
Romain Guy06882f82009-06-10 13:36:04 -07001185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 // Yet more tricksyness! If this window is a "starting"
1187 // window, we do actually want to be on top of it, but
1188 // it is not -really- where input will go. So if the caller
1189 // is not actually looking to move the IME, look down below
1190 // for a real window to target...
1191 if (!willMove
Craig Mautner65d11b32012-10-01 13:59:52 -07001192 && w.mAttrs.type == TYPE_APPLICATION_STARTING
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 && i > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001194 WindowState wb = windows.get(i-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1196 i--;
1197 w = wb;
1198 }
1199 }
1200 break;
1201 }
1202 }
Romain Guy06882f82009-06-10 13:36:04 -07001203
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001204 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1205
Dianne Hackborne75d8722011-01-27 19:37:40 -08001206 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08001207
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001208 // Now, a special case -- if the last target's window is in the
1209 // process of exiting, and is above the new target, keep on the
1210 // last target to avoid flicker. Consider for example a Dialog with
1211 // the IME shown: when the Dialog is dismissed, we want to keep
1212 // the IME above it until it is completely gone so it doesn't drop
1213 // behind the dialog or its full-screen scrim.
Craig Mautner59c00972012-07-30 12:10:24 -07001214 final WindowState curTarget = mInputMethodTarget;
1215 if (curTarget != null && w != null
1216 && curTarget.isDisplayedLw()
Craig Mautnera987d432012-10-11 14:07:58 -07001217 && curTarget.isClosing()
Craig Mautnere6f7d5052012-10-08 10:34:17 -07001218 && (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
1219 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
1220 return windows.indexOf(curTarget) + 1;
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001221 }
Romain Guy06882f82009-06-10 13:36:04 -07001222
Joe Onorato8a9b2202010-02-26 18:56:32 -08001223 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 + w + " willMove=" + willMove);
Romain Guy06882f82009-06-10 13:36:04 -07001225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 if (willMove && w != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001227 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1228 if (token != null) {
Romain Guy06882f82009-06-10 13:36:04 -07001229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 // Now some fun for dealing with window animations that
1231 // modify the Z order. We need to look at all windows below
1232 // the current target that are in this app, finding the highest
1233 // visible one in layering.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 WindowState highestTarget = null;
1235 int highestPos = 0;
Craig Mautner59431632012-04-04 11:56:44 -07001236 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07001237 WindowList curWindows = curTarget.getWindowList();
1238 int pos = curWindows.indexOf(curTarget);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001240 WindowState win = curWindows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 if (win.mAppToken != token) {
1242 break;
1243 }
1244 if (!win.mRemoved) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001245 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1246 highestTarget.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001247 highestTarget = win;
1248 highestPos = pos;
1249 }
1250 }
1251 pos--;
1252 }
1253 }
Romain Guy06882f82009-06-10 13:36:04 -07001254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255 if (highestTarget != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001256 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257 + mNextAppTransition + " " + highestTarget
Craig Mautnera2c77052012-03-26 12:14:43 -07001258 + " animating=" + highestTarget.mWinAnimator.isAnimating()
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001259 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1260 + " new layer=" + w.mWinAnimator.mAnimLayer);
Romain Guy06882f82009-06-10 13:36:04 -07001261
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001262 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 // If we are currently setting up for an animation,
1264 // hold everything until we can find out what will happen.
1265 mInputMethodTargetWaitingAnim = true;
1266 mInputMethodTarget = highestTarget;
1267 return highestPos + 1;
Craig Mautnera2c77052012-03-26 12:14:43 -07001268 } else if (highestTarget.mWinAnimator.isAnimating() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001269 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 // If the window we are currently targeting is involved
1271 // with an animation, and it is on top of the next target
1272 // we will be over, then hold off on moving until
1273 // that is done.
Dianne Hackborne75d8722011-01-27 19:37:40 -08001274 mInputMethodTargetWaitingAnim = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 mInputMethodTarget = highestTarget;
1276 return highestPos + 1;
1277 }
1278 }
1279 }
1280 }
Romain Guy06882f82009-06-10 13:36:04 -07001281
Joe Onorato8a9b2202010-02-26 18:56:32 -08001282 //Slog.i(TAG, "Placing input method @" + (i+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 if (w != null) {
1284 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001285 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1286 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 mInputMethodTarget = w;
Dianne Hackborne75d8722011-01-27 19:37:40 -08001288 mInputMethodTargetWaitingAnim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 if (w.mAppToken != null) {
Craig Mautner59431632012-04-04 11:56:44 -07001290 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 } else {
1292 setInputMethodAnimLayerAdjustment(0);
1293 }
1294 }
1295 return i+1;
1296 }
1297 if (willMove) {
Craig Mautner59c00972012-07-30 12:10:24 -07001298 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
1299 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 mInputMethodTarget = null;
1301 setInputMethodAnimLayerAdjustment(0);
1302 }
1303 return -1;
1304 }
Romain Guy06882f82009-06-10 13:36:04 -07001305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 void addInputMethodWindowToListLocked(WindowState win) {
1307 int pos = findDesiredInputMethodWindowIndexLocked(true);
1308 if (pos >= 0) {
1309 win.mTargetAppToken = mInputMethodTarget.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001310 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001311 TAG, "Adding input method window " + win + " at " + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001312 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001313 getDefaultWindowListLocked().add(pos, win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001314 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 moveInputMethodDialogsLocked(pos+1);
1316 return;
1317 }
1318 win.mTargetAppToken = null;
1319 addWindowToListInOrderLocked(win, true);
1320 moveInputMethodDialogsLocked(pos);
1321 }
Romain Guy06882f82009-06-10 13:36:04 -07001322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 void setInputMethodAnimLayerAdjustment(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001324 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 mInputMethodAnimLayerAdjustment = adj;
1326 WindowState imw = mInputMethodWindow;
1327 if (imw != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001328 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001329 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001330 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 int wi = imw.mChildWindows.size();
1332 while (wi > 0) {
1333 wi--;
Jeff Browne33348b2010-07-15 23:54:05 -07001334 WindowState cw = imw.mChildWindows.get(wi);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001335 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001336 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001337 + " anim layer: " + cw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 }
1339 }
1340 int di = mInputMethodDialogs.size();
1341 while (di > 0) {
1342 di --;
1343 imw = mInputMethodDialogs.get(di);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001344 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001345 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001346 + " anim layer: " + imw.mWinAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001347 }
1348 }
Romain Guy06882f82009-06-10 13:36:04 -07001349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001350 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07001351 WindowList windows = win.getWindowList();
1352 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 if (wpos >= 0) {
1354 if (wpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001355 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07001356 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001357 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 int NC = win.mChildWindows.size();
1359 while (NC > 0) {
1360 NC--;
Jeff Browne33348b2010-07-15 23:54:05 -07001361 WindowState cw = win.mChildWindows.get(NC);
Craig Mautner59c00972012-07-30 12:10:24 -07001362 int cpos = windows.indexOf(cw);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 if (cpos >= 0) {
1364 if (cpos < interestingPos) interestingPos--;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001365 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001366 + cpos + ": " + cw);
Craig Mautner59c00972012-07-30 12:10:24 -07001367 windows.remove(cpos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 }
1369 }
1370 }
1371 return interestingPos;
1372 }
Romain Guy06882f82009-06-10 13:36:04 -07001373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 private void reAddWindowToListInOrderLocked(WindowState win) {
1375 addWindowToListInOrderLocked(win, false);
1376 // This is a hack to get all of the child windows added as well
1377 // at the right position. Child windows should be rare and
1378 // this case should be rare, so it shouldn't be that big a deal.
Craig Mautner59c00972012-07-30 12:10:24 -07001379 WindowList windows = win.getWindowList();
1380 int wpos = windows.indexOf(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 if (wpos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001382 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
1383 windows.remove(wpos);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001384 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 reAddWindowLocked(wpos, win);
1386 }
1387 }
Romain Guy06882f82009-06-10 13:36:04 -07001388
Craig Mautner59c00972012-07-30 12:10:24 -07001389 void logWindowList(final WindowList windows, String prefix) {
1390 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 while (N > 0) {
1392 N--;
Craig Mautner59c00972012-07-30 12:10:24 -07001393 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 }
1395 }
Romain Guy06882f82009-06-10 13:36:04 -07001396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 void moveInputMethodDialogsLocked(int pos) {
1398 ArrayList<WindowState> dialogs = mInputMethodDialogs;
Romain Guy06882f82009-06-10 13:36:04 -07001399
Craig Mautner59c00972012-07-30 12:10:24 -07001400 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001401 WindowList windows = getDefaultWindowListLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 final int N = dialogs.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001403 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 for (int i=0; i<N; i++) {
1405 pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1406 }
1407 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001408 Slog.v(TAG, "Window list w/pos=" + pos);
Craig Mautner59c00972012-07-30 12:10:24 -07001409 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 }
Romain Guy06882f82009-06-10 13:36:04 -07001411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 if (pos >= 0) {
1413 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
Craig Mautner59c00972012-07-30 12:10:24 -07001414 if (pos < windows.size()) {
1415 WindowState wp = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 if (wp == mInputMethodWindow) {
1417 pos++;
1418 }
1419 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001420 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 for (int i=0; i<N; i++) {
1422 WindowState win = dialogs.get(i);
1423 win.mTargetAppToken = targetAppToken;
1424 pos = reAddWindowLocked(pos, win);
1425 }
1426 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001427 Slog.v(TAG, "Final window list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001428 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 }
1430 return;
1431 }
1432 for (int i=0; i<N; i++) {
1433 WindowState win = dialogs.get(i);
1434 win.mTargetAppToken = null;
1435 reAddWindowToListInOrderLocked(win);
1436 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001437 Slog.v(TAG, "No IM target, final list:");
Craig Mautner59c00972012-07-30 12:10:24 -07001438 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 }
1440 }
1441 }
Romain Guy06882f82009-06-10 13:36:04 -07001442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
1444 final WindowState imWin = mInputMethodWindow;
1445 final int DN = mInputMethodDialogs.size();
1446 if (imWin == null && DN == 0) {
1447 return false;
1448 }
Romain Guy06882f82009-06-10 13:36:04 -07001449
Craig Mautner59c00972012-07-30 12:10:24 -07001450 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001451 WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 int imPos = findDesiredInputMethodWindowIndexLocked(true);
1454 if (imPos >= 0) {
1455 // In this case, the input method windows are to be placed
1456 // immediately above the window they are targeting.
Romain Guy06882f82009-06-10 13:36:04 -07001457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 // First check to see if the input method windows are already
1459 // located here, and contiguous.
Craig Mautner59c00972012-07-30 12:10:24 -07001460 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 WindowState firstImWin = imPos < N
Craig Mautner59c00972012-07-30 12:10:24 -07001462 ? windows.get(imPos) : null;
Romain Guy06882f82009-06-10 13:36:04 -07001463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 // Figure out the actual input method window that should be
1465 // at the bottom of their stack.
1466 WindowState baseImWin = imWin != null
1467 ? imWin : mInputMethodDialogs.get(0);
1468 if (baseImWin.mChildWindows.size() > 0) {
Jeff Browne33348b2010-07-15 23:54:05 -07001469 WindowState cw = baseImWin.mChildWindows.get(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 if (cw.mSubLayer < 0) baseImWin = cw;
1471 }
Romain Guy06882f82009-06-10 13:36:04 -07001472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 if (firstImWin == baseImWin) {
1474 // The windows haven't moved... but are they still contiguous?
1475 // First find the top IM window.
1476 int pos = imPos+1;
1477 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001478 if (!(windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 break;
1480 }
1481 pos++;
1482 }
1483 pos++;
1484 // Now there should be no more input method windows above.
1485 while (pos < N) {
Craig Mautner59c00972012-07-30 12:10:24 -07001486 if ((windows.get(pos)).mIsImWindow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 break;
1488 }
1489 pos++;
1490 }
1491 if (pos >= N) {
1492 // All is good!
1493 return false;
1494 }
1495 }
Romain Guy06882f82009-06-10 13:36:04 -07001496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 if (imWin != null) {
1498 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001499 Slog.v(TAG, "Moving IM from " + imPos);
Craig Mautner59c00972012-07-30 12:10:24 -07001500 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 }
1502 imPos = tmpRemoveWindowLocked(imPos, imWin);
1503 if (DEBUG_INPUT_METHOD) {
Dianne Hackborn7eab0942011-01-01 13:21:50 -08001504 Slog.v(TAG, "List after removing with new pos " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001505 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 }
1507 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1508 reAddWindowLocked(imPos, imWin);
1509 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001510 Slog.v(TAG, "List after moving IM to " + imPos + ":");
Craig Mautner59c00972012-07-30 12:10:24 -07001511 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 }
1513 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
1514 } else {
1515 moveInputMethodDialogsLocked(imPos);
1516 }
Romain Guy06882f82009-06-10 13:36:04 -07001517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 } else {
1519 // In this case, the input method windows go in a fixed layer,
1520 // because they aren't currently associated with a focus window.
Romain Guy06882f82009-06-10 13:36:04 -07001521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 if (imWin != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001523 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 tmpRemoveWindowLocked(0, imWin);
1525 imWin.mTargetAppToken = null;
1526 reAddWindowToListInOrderLocked(imWin);
1527 if (DEBUG_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001528 Slog.v(TAG, "List with no IM target:");
Craig Mautner59c00972012-07-30 12:10:24 -07001529 logWindowList(windows, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001530 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07001531 if (DN > 0) moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 } else {
Craig Mautner01cd0e72012-06-18 10:19:11 -07001533 moveInputMethodDialogsLocked(-1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 }
Romain Guy06882f82009-06-10 13:36:04 -07001535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 }
Romain Guy06882f82009-06-10 13:36:04 -07001537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 if (needAssignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07001539 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 }
Romain Guy06882f82009-06-10 13:36:04 -07001541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 return true;
1543 }
Romain Guy06882f82009-06-10 13:36:04 -07001544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 void adjustInputMethodDialogsLocked() {
1546 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
1547 }
Romain Guy06882f82009-06-10 13:36:04 -07001548
Dianne Hackborn25994b42009-09-04 14:21:19 -07001549 final boolean isWallpaperVisible(WindowState wallpaperTarget) {
Craig Mautnerad3a9bb2012-03-09 11:31:06 -08001550 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
Dianne Hackborn25994b42009-09-04 14:21:19 -07001551 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1552 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001553 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
Dianne Hackborn25994b42009-09-04 14:21:19 -07001554 + " upper=" + mUpperWallpaperTarget
1555 + " lower=" + mLowerWallpaperTarget);
1556 return (wallpaperTarget != null
1557 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001558 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
Dianne Hackborn25994b42009-09-04 14:21:19 -07001559 || mUpperWallpaperTarget != null
1560 || mLowerWallpaperTarget != null;
1561 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001562
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001563 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1564 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001565
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001566 int adjustWallpaperWindowsLocked() {
Craig Mautnera608b882012-03-30 13:03:49 -07001567 mInnerFields.mWallpaperMayChange = false;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001568 int changed = 0;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001569 boolean targetChanged = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001570
Craig Mautner59c00972012-07-30 12:10:24 -07001571 // TODO(multidisplay): Wallpapers on main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001572 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -07001573 final int dw = displayInfo.appWidth;
1574 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001575
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001576 // First find top-most window that has asked to be on top of the
1577 // wallpaper; all wallpapers go behind it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001578 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07001579 int N = windows.size();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001580 WindowState w = null;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001581 WindowState foundW = null;
1582 int foundI = 0;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001583 WindowState topCurW = null;
1584 int topCurI = 0;
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001585 int windowDetachedI = -1;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001586 int i = N;
1587 while (i > 0) {
1588 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07001589 w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07001590 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001591 if (topCurW == null) {
1592 topCurW = w;
1593 topCurI = i;
1594 }
1595 continue;
1596 }
1597 topCurW = null;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001598 if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001599 // If this window's app token is hidden and not animating,
1600 // it is of no interest to us.
Craig Mautner59431632012-04-04 11:56:44 -07001601 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001602 if (DEBUG_WALLPAPER) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07001603 "Skipping hidden and not animating token: " + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001604 continue;
1605 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001606 }
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001607 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": readyfordisplay="
Craig Mautner749a7bb2012-04-02 13:49:53 -07001608 + w.isReadyForDisplay() + " mDrawState=" + w.mWinAnimator.mDrawState);
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001609 if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07001610 && (mWallpaperTarget == w || w.isDrawnLw())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001611 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001612 "Found wallpaper target: #" + i + "=" + w);
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001613 foundW = w;
1614 foundI = i;
Craig Mautner4d7349b2012-04-20 14:52:47 -07001615 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001616 // The current wallpaper target is animating, so we'll
1617 // look behind it for another possible target and figure
1618 // out what is going on below.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001619 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001620 + ": token animating, looking behind.");
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001621 continue;
1622 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001623 break;
Craig Mautner01cd0e72012-06-18 10:19:11 -07001624 } else if (w == mWindowDetachedWallpaper) {
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001625 windowDetachedI = i;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001626 }
1627 }
1628
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001629 if (foundW == null && windowDetachedI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001630 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08001631 "Found animating detached wallpaper activity: #" + i + "=" + w);
1632 foundW = w;
1633 foundI = windowDetachedI;
1634 }
1635
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07001636 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001637 // If we are currently waiting for an app transition, and either
1638 // the current target or the next target are involved with it,
1639 // then hold off on doing anything with the wallpaper.
1640 // Note that we are checking here for just whether the target
1641 // is part of an app token... which is potentially overly aggressive
1642 // (the app token may not be involved in the transition), but good
1643 // enough (we'll just wait until whatever transition is pending
1644 // executes).
1645 if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001646 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001647 "Wallpaper not changing: waiting for app anim in current target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001648 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001649 }
1650 if (foundW != null && foundW.mAppToken != null) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001651 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001652 "Wallpaper not changing: waiting for app anim in found target");
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001653 return 0;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001654 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001655 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001656
Craig Mautner8863cca2012-09-18 15:04:34 -07001657 if (mWallpaperTarget != foundW
1658 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001659 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001660 Slog.v(TAG, "New wallpaper target: " + foundW
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001661 + " oldTarget: " + mWallpaperTarget);
1662 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001663
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001664 mLowerWallpaperTarget = null;
1665 mUpperWallpaperTarget = null;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001666
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001667 WindowState oldW = mWallpaperTarget;
1668 mWallpaperTarget = foundW;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001669 targetChanged = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001670
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001671 // Now what is happening... if the current and new targets are
1672 // animating, then we are in our super special mode!
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001673 if (foundW != null && oldW != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -07001674 boolean oldAnim = oldW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001675 || (oldW.mAppToken != null
1676 && oldW.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001677 boolean foundAnim = foundW.mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001678 || (foundW.mAppToken != null &&
1679 foundW.mAppToken.mAppAnimator.animation != null);
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001680 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001681 Slog.v(TAG, "New animation: " + foundAnim
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001682 + " old animation: " + oldAnim);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001683 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001684 if (foundAnim && oldAnim) {
Craig Mautner59c00972012-07-30 12:10:24 -07001685 int oldI = windows.indexOf(oldW);
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001686 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001687 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001688 }
1689 if (oldI >= 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001690 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001691 Slog.v(TAG, "Animating wallpapers: old#" + oldI
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001692 + "=" + oldW + "; new#" + foundI
1693 + "=" + foundW);
1694 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001695
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001696 // Set the new target correctly.
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001697 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001698 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001699 Slog.v(TAG, "Old wallpaper still the target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001700 }
1701 mWallpaperTarget = oldW;
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001702 foundW = oldW;
1703 foundI = oldI;
Craig Mautner711f90a2012-07-03 18:43:52 -07001704 }
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001705 // Now set the upper and lower wallpaper targets
1706 // correctly, and make sure that we are positioning
1707 // the wallpaper below the lower.
Craig Mautner8e4df6c2012-05-23 16:57:23 -07001708 else if (foundI > oldI) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001709 // The new target is on top of the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001710 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001711 Slog.v(TAG, "Found target above old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001712 }
1713 mUpperWallpaperTarget = foundW;
1714 mLowerWallpaperTarget = oldW;
1715 foundW = oldW;
1716 foundI = oldI;
1717 } else {
1718 // The new target is below the old one.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001719 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001720 Slog.v(TAG, "Found target below old target.");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001721 }
1722 mUpperWallpaperTarget = oldW;
1723 mLowerWallpaperTarget = foundW;
1724 }
1725 }
1726 }
1727 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001728
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001729 } else if (mLowerWallpaperTarget != null) {
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001730 // Is it time to stop animating?
Craig Mautnera2c77052012-03-26 12:14:43 -07001731 boolean lowerAnimating = mLowerWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001732 || (mLowerWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001733 && mLowerWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Craig Mautnera2c77052012-03-26 12:14:43 -07001734 boolean upperAnimating = mUpperWallpaperTarget.mWinAnimator.mAnimation != null
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001735 || (mUpperWallpaperTarget.mAppToken != null
Craig Mautner59431632012-04-04 11:56:44 -07001736 && mUpperWallpaperTarget.mAppToken.mAppAnimator.animation != null);
Dianne Hackborn6b1cb352009-09-28 18:27:26 -07001737 if (!lowerAnimating || !upperAnimating) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001738 if (DEBUG_WALLPAPER_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001739 Slog.v(TAG, "No longer animating wallpaper targets!");
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001740 }
1741 mLowerWallpaperTarget = null;
1742 mUpperWallpaperTarget = null;
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001743 mWallpaperTarget = foundW;
1744 targetChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001745 }
1746 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001747
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001748 boolean visible = foundW != null;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001749 if (visible) {
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001750 // The window is visible to the compositor... but is it visible
1751 // to the user? That is what the wallpaper cares about.
Dianne Hackborn25994b42009-09-04 14:21:19 -07001752 visible = isWallpaperVisible(foundW);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001753 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001754
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001755 // If the wallpaper target is animating, we may need to copy
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001756 // its layer adjustment. Only do this if we are not transfering
1757 // between two wallpaper targets.
1758 mWallpaperAnimLayerAdjustment =
Dianne Hackborn3be63c02009-08-20 19:31:38 -07001759 (mLowerWallpaperTarget == null && foundW.mAppToken != null)
Craig Mautner59431632012-04-04 11:56:44 -07001760 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001761
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001762 final int maxLayer = mPolicy.getMaxWallpaperLayer()
1763 * TYPE_LAYER_MULTIPLIER
1764 + TYPE_LAYER_OFFSET;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001765
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001766 // Now w is the window we are supposed to be behind... but we
1767 // need to be sure to also be behind any of its attached windows,
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001768 // AND any starting window associated with it, AND below the
1769 // maximum layer the policy allows for wallpapers.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001770 while (foundI > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001771 WindowState wb = windows.get(foundI-1);
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07001772 if (wb.mBaseLayer < maxLayer &&
1773 wb.mAttachedWindow != foundW &&
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001774 (foundW.mAttachedWindow == null ||
1775 wb.mAttachedWindow != foundW.mAttachedWindow) &&
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001776 (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
Dianne Hackborn428ecb62011-01-26 14:53:23 -08001777 foundW.mToken == null || wb.mToken != foundW.mToken)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001778 // This window is not related to the previous one in any
1779 // interesting way, so stop here.
1780 break;
1781 }
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001782 foundW = wb;
1783 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001784 }
Dianne Hackborn25994b42009-09-04 14:21:19 -07001785 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001786 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001787 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001788
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001789 if (foundW == null && topCurW != null) {
1790 // There is no wallpaper target, so it goes at the bottom.
1791 // We will assume it is the same place as last time, if known.
1792 foundW = topCurW;
1793 foundI = topCurI+1;
1794 } else {
1795 // Okay i is the position immediately above the wallpaper. Look at
1796 // what is below it for later.
Craig Mautner59c00972012-07-30 12:10:24 -07001797 foundW = foundI > 0 ? windows.get(foundI-1) : null;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07001798 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001799
Dianne Hackborn284ac932009-08-28 10:34:25 -07001800 if (visible) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001801 if (mWallpaperTarget.mWallpaperX >= 0) {
1802 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001803 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001804 }
1805 if (mWallpaperTarget.mWallpaperY >= 0) {
1806 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001807 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001808 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07001809 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001810
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001811 // Start stepping backwards from here, ensuring that our wallpaper windows
1812 // are correctly placed.
1813 int curTokenIndex = mWallpaperTokens.size();
1814 while (curTokenIndex > 0) {
1815 curTokenIndex--;
1816 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001817 if (token.hidden == visible) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001818 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
1819 "Wallpaper token " + token + " hidden=" + !visible);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001820 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
1821 token.hidden = !visible;
1822 // Need to do a layout to ensure the wallpaper now has the
1823 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07001824 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001825 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001826
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001827 int curWallpaperIndex = token.windows.size();
1828 while (curWallpaperIndex > 0) {
1829 curWallpaperIndex--;
1830 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001831
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001832 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001833 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001834 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001835
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001836 // First, make sure the client has the current visibility
1837 // state.
Craig Mautner507a2ee2012-06-13 08:39:38 -07001838 dispatchWallpaperVisibility(wallpaper, visible);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001839
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001840 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001841 if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001842 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001843
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001844 // First, if this window is at the current index, then all
1845 // is well.
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001846 if (wallpaper == foundW) {
1847 foundI--;
1848 foundW = foundI > 0
Craig Mautner59c00972012-07-30 12:10:24 -07001849 ? windows.get(foundI-1) : null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001850 continue;
1851 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001852
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001853 // The window didn't match... the current wallpaper window,
1854 // wherever it is, is in the wrong place, so make sure it is
1855 // not in the list.
Craig Mautner59c00972012-07-30 12:10:24 -07001856 int oldIndex = windows.indexOf(wallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001857 if (oldIndex >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001858 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001859 + oldIndex + ": " + wallpaper);
Craig Mautner59c00972012-07-30 12:10:24 -07001860 windows.remove(oldIndex);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001861 mWindowsChanged = true;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07001862 if (oldIndex < foundI) {
1863 foundI--;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001864 }
1865 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001866
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001867 // Now stick it in.
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07001868 if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08001869 Slog.v(TAG, "Moving wallpaper " + wallpaper
1870 + " from " + oldIndex + " to " + foundI);
1871 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001872
Craig Mautner59c00972012-07-30 12:10:24 -07001873 windows.add(foundI, wallpaper);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07001874 mWindowsChanged = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07001875 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001876 }
1877 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001878
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07001879 if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
1880 Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
1881 + " lower=" + mLowerWallpaperTarget + " upper="
1882 + mUpperWallpaperTarget);
1883 }
1884
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001885 return changed;
1886 }
1887
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001888 void setWallpaperAnimLayerAdjustmentLocked(int adj) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001889 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001890 "Setting wallpaper layer adj to " + adj);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001891 mWallpaperAnimLayerAdjustment = adj;
1892 int curTokenIndex = mWallpaperTokens.size();
1893 while (curTokenIndex > 0) {
1894 curTokenIndex--;
1895 WindowToken token = mWallpaperTokens.get(curTokenIndex);
1896 int curWallpaperIndex = token.windows.size();
1897 while (curWallpaperIndex > 0) {
1898 curWallpaperIndex--;
1899 WindowState wallpaper = token.windows.get(curWallpaperIndex);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001900 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
Craig Mautneref25d7a2012-05-15 23:01:47 -07001901 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001902 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
Dianne Hackborn759a39e2009-08-09 17:20:27 -07001903 }
1904 }
1905 }
1906
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001907 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
1908 boolean sync) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001909 boolean changed = false;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07001910 boolean rawChanged = false;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001911 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001912 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001913 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001914 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
1915 changed = wallpaperWin.mXOffset != offset;
1916 if (changed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001917 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001918 + wallpaperWin + " x: " + offset);
1919 wallpaperWin.mXOffset = offset;
1920 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001921 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001922 wallpaperWin.mWallpaperX = wpx;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001923 wallpaperWin.mWallpaperXStep = wpxs;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001924 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001925 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001926
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001927 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001928 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001929 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1930 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1931 if (wallpaperWin.mYOffset != offset) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001932 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001933 + wallpaperWin + " y: " + offset);
1934 changed = true;
1935 wallpaperWin.mYOffset = offset;
1936 }
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001937 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001938 wallpaperWin.mWallpaperY = wpy;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001939 wallpaperWin.mWallpaperYStep = wpys;
Dianne Hackborn73e92b42009-10-15 14:29:19 -07001940 rawChanged = true;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001941 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001942
Craig Mautnerbb1449b2012-03-23 16:11:14 -07001943 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001944 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001945 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001946 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07001947 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
1948 + " y=" + wallpaperWin.mWallpaperY);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001949 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001950 mWaitingOnWallpaper = wallpaperWin;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001951 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001952 wallpaperWin.mClient.dispatchWallpaperOffsets(
Marco Nelissenbf6956b2009-11-09 15:21:13 -08001953 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
1954 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001955 if (sync) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001956 if (mWaitingOnWallpaper != null) {
1957 long start = SystemClock.uptimeMillis();
1958 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1959 < start) {
1960 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001961 if (DEBUG_WALLPAPER) Slog.v(TAG,
Dianne Hackborn75804932009-10-20 20:15:20 -07001962 "Waiting for offset complete...");
1963 mWindowMap.wait(WALLPAPER_TIMEOUT);
1964 } catch (InterruptedException e) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001965 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001966 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
Dianne Hackborn75804932009-10-20 20:15:20 -07001967 if ((start+WALLPAPER_TIMEOUT)
1968 < SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001969 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
Dianne Hackborn75804932009-10-20 20:15:20 -07001970 + wallpaperWin);
1971 mLastWallpaperTimeoutTime = start;
1972 }
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001973 }
Dianne Hackborn75804932009-10-20 20:15:20 -07001974 mWaitingOnWallpaper = null;
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001975 }
1976 }
Dianne Hackborn72c82ab2009-08-11 21:13:54 -07001977 } catch (RemoteException e) {
1978 }
1979 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001980
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07001981 return changed;
1982 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001983
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001984 void wallpaperOffsetsComplete(IBinder window) {
Dianne Hackborn75804932009-10-20 20:15:20 -07001985 synchronized (mWindowMap) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001986 if (mWaitingOnWallpaper != null &&
1987 mWaitingOnWallpaper.mClient.asBinder() == window) {
1988 mWaitingOnWallpaper = null;
Dianne Hackborn75804932009-10-20 20:15:20 -07001989 mWindowMap.notifyAll();
Dianne Hackborn19382ac2009-09-11 21:13:37 -07001990 }
1991 }
1992 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001993
Chet Haasea8e5a2b2011-10-28 13:18:16 -07001994 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Craig Mautner59c00972012-07-30 12:10:24 -07001995 final DisplayContent displayContent = changingTarget.mDisplayContent;
1996 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1997 final int dw = displayInfo.appWidth;
1998 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08001999
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002000 WindowState target = mWallpaperTarget;
2001 if (target != null) {
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002002 if (target.mWallpaperX >= 0) {
2003 mLastWallpaperX = target.mWallpaperX;
2004 } else if (changingTarget.mWallpaperX >= 0) {
2005 mLastWallpaperX = changingTarget.mWallpaperX;
2006 }
2007 if (target.mWallpaperY >= 0) {
2008 mLastWallpaperY = target.mWallpaperY;
2009 } else if (changingTarget.mWallpaperY >= 0) {
2010 mLastWallpaperY = changingTarget.mWallpaperY;
2011 }
2012 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002013
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002014 int curTokenIndex = mWallpaperTokens.size();
2015 while (curTokenIndex > 0) {
2016 curTokenIndex--;
2017 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2018 int curWallpaperIndex = token.windows.size();
2019 while (curWallpaperIndex > 0) {
2020 curWallpaperIndex--;
2021 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2022 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002023 WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
2024 winAnimator.computeShownFrameLocked();
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002025 // No need to lay out the windows - we can just set the wallpaper position
2026 // directly.
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07002027 // TODO(cmautner): Don't move this from here, just lock the WindowAnimator.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002028 if (winAnimator.mSurfaceX != wallpaper.mShownFrame.left
2029 || winAnimator.mSurfaceY != wallpaper.mShownFrame.top) {
Craig Mautner12670b52012-07-03 19:15:35 -07002030 winAnimator.setWallpaperOffset((int) wallpaper.mShownFrame.left,
Craig Mautner48ba1e72012-04-02 13:18:16 -07002031 (int) wallpaper.mShownFrame.top);
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002032 }
Dianne Hackborn73e92b42009-10-15 14:29:19 -07002033 // We only want to be synchronous with one wallpaper.
2034 sync = false;
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002035 }
2036 }
2037 }
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002038 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002039
Craig Mautner507a2ee2012-06-13 08:39:38 -07002040 /**
2041 * Check wallpaper for visiblity change and notify window if so.
2042 * @param wallpaper The wallpaper to test and notify.
2043 * @param visible Current visibility.
2044 */
2045 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2046 if (wallpaper.mWallpaperVisible != visible) {
2047 wallpaper.mWallpaperVisible = visible;
2048 try {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07002049 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
2050 "Updating vis of wallpaper " + wallpaper
2051 + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
Craig Mautner507a2ee2012-06-13 08:39:38 -07002052 wallpaper.mClient.dispatchAppVisibility(visible);
2053 } catch (RemoteException e) {
2054 }
2055 }
2056 }
2057
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002058 void updateWallpaperVisibilityLocked() {
Dianne Hackborn25994b42009-09-04 14:21:19 -07002059 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Craig Mautner59c00972012-07-30 12:10:24 -07002060 final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
2061 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2062 final int dw = displayInfo.appWidth;
2063 final int dh = displayInfo.appHeight;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002064
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002065 int curTokenIndex = mWallpaperTokens.size();
2066 while (curTokenIndex > 0) {
2067 curTokenIndex--;
2068 WindowToken token = mWallpaperTokens.get(curTokenIndex);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002069 if (token.hidden == visible) {
2070 token.hidden = !visible;
2071 // Need to do a layout to ensure the wallpaper now has the
2072 // correct size.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002073 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002074 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002075
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002076 int curWallpaperIndex = token.windows.size();
2077 while (curWallpaperIndex > 0) {
2078 curWallpaperIndex--;
2079 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2080 if (visible) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002081 updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002082 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002083
Craig Mautner507a2ee2012-06-13 08:39:38 -07002084 dispatchWallpaperVisibility(wallpaper, visible);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002085 }
2086 }
2087 }
Craig Mautner711f90a2012-07-03 18:43:52 -07002088
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002089 public int addWindow(Session session, IWindow client, int seq,
Craig Mautner6881a102012-07-27 13:04:51 -07002090 WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002091 Rect outContentInsets, InputChannel outInputChannel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002092 int res = mPolicy.checkAddPermission(attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002093 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 return res;
2095 }
Romain Guy06882f82009-06-10 13:36:04 -07002096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002097 boolean reportNewConfig = false;
2098 WindowState attachedWindow = null;
2099 WindowState win = null;
Dianne Hackborn5132b372010-07-29 12:51:35 -07002100 long origId;
Craig Mautner88400d32012-09-30 12:35:45 -07002101 final int type = attrs.type;
Romain Guy06882f82009-06-10 13:36:04 -07002102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002103 synchronized(mWindowMap) {
Jeff Browne215f262012-09-10 16:01:14 -07002104 if (!mDisplayReady) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07002105 throw new IllegalStateException("Display has not been initialialized");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002106 }
Romain Guy06882f82009-06-10 13:36:04 -07002107
Craig Mautner2d5618c2012-10-18 13:55:47 -07002108 final DisplayContent displayContent = getDisplayContentLocked(displayId);
2109 if (displayContent == null) {
2110 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
2111 }
2112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002113 if (mWindowMap.containsKey(client.asBinder())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002114 Slog.w(TAG, "Window " + client + " is already added");
Jeff Brown98365d72012-08-19 20:30:52 -07002115 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 }
2117
Craig Mautner88400d32012-09-30 12:35:45 -07002118 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002119 attachedWindow = windowForClientLocked(null, attrs.token, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 if (attachedWindow == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002121 Slog.w(TAG, "Attempted to add window with token that is not a window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002122 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002123 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124 }
2125 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2126 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002127 Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002128 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002129 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002130 }
2131 }
2132
2133 boolean addToken = false;
2134 WindowToken token = mTokenMap.get(attrs.token);
2135 if (token == null) {
Craig Mautner88400d32012-09-30 12:35:45 -07002136 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002137 Slog.w(TAG, "Attempted to add application window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002139 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002140 }
Craig Mautner88400d32012-09-30 12:35:45 -07002141 if (type == TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002142 Slog.w(TAG, "Attempted to add input method window with unknown token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002144 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002145 }
Craig Mautner88400d32012-09-30 12:35:45 -07002146 if (type == TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002147 Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002148 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002149 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002150 }
Craig Mautner88400d32012-09-30 12:35:45 -07002151 if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002152 Slog.w(TAG, "Attempted to add Dream window with unknown token "
2153 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002154 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002155 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002156 token = new WindowToken(this, attrs.token, -1, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 addToken = true;
Craig Mautner88400d32012-09-30 12:35:45 -07002158 } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 AppWindowToken atoken = token.appWindowToken;
2160 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002161 Slog.w(TAG, "Attempted to add window with non-application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002163 return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 } else if (atoken.removed) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002165 Slog.w(TAG, "Attempted to add window with exiting application token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002166 + token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002167 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002168 }
Craig Mautner88400d32012-09-30 12:35:45 -07002169 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170 // No need for this guy!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002171 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 TAG, "**** NO NEED TO START: " + attrs.getTitle());
Jeff Brown98365d72012-08-19 20:30:52 -07002173 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002174 }
Craig Mautner88400d32012-09-30 12:35:45 -07002175 } else if (type == TYPE_INPUT_METHOD) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 if (token.windowType != TYPE_INPUT_METHOD) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002177 Slog.w(TAG, "Attempted to add input method window with bad token "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002179 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002180 }
Craig Mautner88400d32012-09-30 12:35:45 -07002181 } else if (type == TYPE_WALLPAPER) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002182 if (token.windowType != TYPE_WALLPAPER) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002183 Slog.w(TAG, "Attempted to add wallpaper window with bad token "
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002184 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002185 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002186 }
Craig Mautner88400d32012-09-30 12:35:45 -07002187 } else if (type == TYPE_DREAM) {
Daniel Sandler7d276c32012-01-30 14:33:52 -05002188 if (token.windowType != TYPE_DREAM) {
2189 Slog.w(TAG, "Attempted to add Dream window with bad token "
2190 + attrs.token + ". Aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002191 return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
Daniel Sandler7d276c32012-01-30 14:33:52 -05002192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002193 }
2194
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002195 win = new WindowState(this, session, client, token,
Craig Mautner59c00972012-07-30 12:10:24 -07002196 attachedWindow, seq, attrs, viewVisibility, displayContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 if (win.mDeathRecipient == null) {
2198 // Client has apparently died, so there is no reason to
2199 // continue.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002200 Slog.w(TAG, "Adding window client " + client.asBinder()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201 + " that is dead, aborting.");
Jeff Brown98365d72012-08-19 20:30:52 -07002202 return WindowManagerGlobal.ADD_APP_EXITING;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203 }
2204
2205 mPolicy.adjustWindowParamsLw(win.mAttrs);
Craig Mautner88400d32012-09-30 12:35:45 -07002206 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
Romain Guy06882f82009-06-10 13:36:04 -07002207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002208 res = mPolicy.prepareAddWindowLw(win, attrs);
Jeff Brown98365d72012-08-19 20:30:52 -07002209 if (res != WindowManagerGlobal.ADD_OKAY) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210 return res;
2211 }
Craig Mautner918b53b2012-07-09 14:15:54 -07002212
Jeff Browncc4f7db2011-08-30 20:34:48 -07002213 if (outInputChannel != null && (attrs.inputFeatures
2214 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07002215 String name = win.makeInputChannelName();
2216 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002217 win.setInputChannel(inputChannels[0]);
Jeff Brown0a0ab122011-08-12 18:08:08 -07002218 inputChannels[1].transferTo(outInputChannel);
Craig Mautner918b53b2012-07-09 14:15:54 -07002219
Jeff Brown928e0542011-01-10 11:17:36 -08002220 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002222
2223 // From now on, no exceptions or errors allowed!
2224
Jeff Brown98365d72012-08-19 20:30:52 -07002225 res = WindowManagerGlobal.ADD_OKAY;
Romain Guy06882f82009-06-10 13:36:04 -07002226
Dianne Hackborn5132b372010-07-29 12:51:35 -07002227 origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002229 if (addToken) {
2230 mTokenMap.put(attrs.token, token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 }
2232 win.attach();
2233 mWindowMap.put(client.asBinder(), win);
2234
Craig Mautner88400d32012-09-30 12:35:45 -07002235 if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002236 token.appWindowToken.startingWindow = win;
Craig Mautner38b24782012-07-02 16:21:28 -07002237 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2238 + " startingWindow=" + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002239 }
2240
2241 boolean imMayMove = true;
Romain Guy06882f82009-06-10 13:36:04 -07002242
Craig Mautner88400d32012-09-30 12:35:45 -07002243 if (type == TYPE_INPUT_METHOD) {
satok1bc0a492012-04-25 22:47:12 +09002244 win.mGivenInsetsPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 mInputMethodWindow = win;
2246 addInputMethodWindowToListLocked(win);
2247 imMayMove = false;
Craig Mautner88400d32012-09-30 12:35:45 -07002248 } else if (type == TYPE_INPUT_METHOD_DIALOG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 mInputMethodDialogs.add(win);
2250 addWindowToListInOrderLocked(win, true);
2251 adjustInputMethodDialogsLocked();
2252 imMayMove = false;
2253 } else {
2254 addWindowToListInOrderLocked(win, true);
Craig Mautner88400d32012-09-30 12:35:45 -07002255 if (type == TYPE_WALLPAPER) {
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002256 mLastWallpaperTimeoutTime = 0;
2257 adjustWallpaperWindowsLocked();
2258 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002259 adjustWallpaperWindowsLocked();
Dianne Hackborn7ad44382012-10-18 17:46:00 -07002260 } else if (mWallpaperTarget != null
2261 && mWallpaperTarget.mLayer >= win.mBaseLayer) {
2262 // If there is currently a wallpaper being shown, and
2263 // the base layer of the new window is below the current
2264 // layer of the target window, then adjust the wallpaper.
2265 // This is to avoid a new window being placed between the
2266 // wallpaper and its target.
2267 adjustWallpaperWindowsLocked();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 }
Romain Guy06882f82009-06-10 13:36:04 -07002270
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002271 win.mWinAnimator.mEnterAnimationPending = true;
Romain Guy06882f82009-06-10 13:36:04 -07002272
Craig Mautner69b08182012-09-05 13:07:13 -07002273 if (displayContent.isDefaultDisplay) {
2274 mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2275 } else {
2276 outContentInsets.setEmpty();
2277 }
Romain Guy06882f82009-06-10 13:36:04 -07002278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 if (mInTouchMode) {
Jeff Brown98365d72012-08-19 20:30:52 -07002280 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 }
Craig Mautner764983d2012-03-22 11:37:36 -07002282 if (win.mAppToken == null || !win.mAppToken.clientHidden) {
Jeff Brown98365d72012-08-19 20:30:52 -07002283 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 }
Romain Guy06882f82009-06-10 13:36:04 -07002285
Jeff Brown2e44b072011-01-24 15:21:56 -08002286 mInputMonitor.setUpdateInputWindowsNeededLw();
2287
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002288 boolean focusChanged = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289 if (win.canReceiveKeys()) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002290 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2291 false /*updateInputWindows*/);
Jeff Brown349703e2010-06-22 01:27:15 -07002292 if (focusChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 imMayMove = false;
2294 }
2295 }
Romain Guy06882f82009-06-10 13:36:04 -07002296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 if (imMayMove) {
Romain Guy06882f82009-06-10 13:36:04 -07002298 moveInputMethodWindowsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 }
Romain Guy06882f82009-06-10 13:36:04 -07002300
Craig Mautner59c00972012-07-30 12:10:24 -07002301 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 // Don't do layout here, the window must call
2303 // relayout to be displayed, so we'll do it there.
Romain Guy06882f82009-06-10 13:36:04 -07002304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002305 //dump();
2306
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002307 if (focusChanged) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08002308 finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002309 }
Jeff Brown2e44b072011-01-24 15:21:56 -08002310 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08002311
Joe Onorato8a9b2202010-02-26 18:56:32 -08002312 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 TAG, "New client " + client.asBinder()
2314 + ": window=" + win);
Craig Mautner9e809442012-06-22 17:13:04 -07002315
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002316 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002317 reportNewConfig = true;
2318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 }
2320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 if (reportNewConfig) {
2322 sendNewConfiguration();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07002324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07002326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 return res;
2328 }
Romain Guy06882f82009-06-10 13:36:04 -07002329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 public void removeWindow(Session session, IWindow client) {
2331 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002332 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 if (win == null) {
2334 return;
2335 }
2336 removeWindowLocked(session, win);
2337 }
2338 }
Romain Guy06882f82009-06-10 13:36:04 -07002339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340 public void removeWindowLocked(Session session, WindowState win) {
2341
Joe Onorato8a9b2202010-02-26 18:56:32 -08002342 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 TAG, "Remove " + win + " client="
2344 + Integer.toHexString(System.identityHashCode(
2345 win.mClient.asBinder()))
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002346 + ", surface=" + win.mWinAnimator.mSurface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002347
2348 final long origId = Binder.clearCallingIdentity();
Craig Mautner764983d2012-03-22 11:37:36 -07002349
Jeff Brownc5ed5912010-07-14 18:48:53 -07002350 win.disposeInputChannel();
Romain Guy06882f82009-06-10 13:36:04 -07002351
Joe Onorato8a9b2202010-02-26 18:56:32 -08002352 if (DEBUG_APP_TRANSITIONS) Slog.v(
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002353 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 + " mExiting=" + win.mExiting
Craig Mautnera2c77052012-03-26 12:14:43 -07002355 + " isAnimating=" + win.mWinAnimator.isAnimating()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 + " app-animation="
Craig Mautner59431632012-04-04 11:56:44 -07002357 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 + " inPendingTransaction="
2359 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2360 + " mDisplayFrozen=" + mDisplayFrozen);
2361 // Visibility of the removed window. Will be used later to update orientation later on.
2362 boolean wasVisible = false;
2363 // First, see if we need to run an animation. If we do, we have
2364 // to hold off on removing the window until the animation is done.
2365 // If the display is frozen, just remove immediately, since the
2366 // animation wouldn't be seen.
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002367 if (win.mHasSurface && okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 // If we are not currently running the exit animation, we
2369 // need to see about starting one.
Craig Mautner764983d2012-03-22 11:37:36 -07002370 wasVisible = win.isWinVisibleLw();
2371 if (wasVisible) {
Romain Guy06882f82009-06-10 13:36:04 -07002372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002374 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2376 }
2377 // Try starting an animation.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002378 if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002379 win.mExiting = true;
2380 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002381 scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002382 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002383 if (win.mExiting || win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 // The exit animation is running... wait for it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002385 //Slog.i(TAG, "*** Running exit animation...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 win.mExiting = true;
2387 win.mRemoveOnExit = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002388 win.mDisplayContent.layoutNeeded = true;
Jeff Brown3a22cd92011-01-21 13:59:04 -08002389 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2390 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002391 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08002392 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 if (win.mAppToken != null) {
2394 win.mAppToken.updateReportedVisibilityLocked();
2395 }
2396 //dump();
2397 Binder.restoreCallingIdentity(origId);
2398 return;
2399 }
2400 }
2401
2402 removeWindowInnerLocked(session, win);
2403 // Removing a visible window will effect the computed orientation
2404 // So just update orientation if needed.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07002405 if (wasVisible && computeForcedAppOrientationLocked()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002406 != mForcedAppOrientation
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002407 && updateOrientationFromAppTokensLocked(false)) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002408 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 }
Jeff Brown3a22cd92011-01-21 13:59:04 -08002410 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002411 Binder.restoreCallingIdentity(origId);
2412 }
Romain Guy06882f82009-06-10 13:36:04 -07002413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 private void removeWindowInnerLocked(Session session, WindowState win) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002415 if (win.mRemoved) {
2416 // Nothing to do.
2417 return;
2418 }
2419
2420 for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2421 WindowState cwin = win.mChildWindows.get(i);
2422 Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2423 + win);
2424 removeWindowInnerLocked(cwin.mSession, cwin);
2425 }
2426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002427 win.mRemoved = true;
Romain Guy06882f82009-06-10 13:36:04 -07002428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 if (mInputMethodTarget == win) {
2430 moveInputMethodWindowsIfNeededLocked(false);
2431 }
Romain Guy06882f82009-06-10 13:36:04 -07002432
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002433 if (false) {
2434 RuntimeException e = new RuntimeException("here");
2435 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002436 Slog.w(TAG, "Removing window " + win, e);
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07002437 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 mPolicy.removeWindowLw(win);
2440 win.removeLocked();
2441
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002442 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 mWindowMap.remove(win.mClient.asBinder());
Craig Mautner59c00972012-07-30 12:10:24 -07002444
2445 final WindowList windows = win.getWindowList();
2446 windows.remove(win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002447 mPendingRemove.remove(win);
Craig Mautner860f6602012-10-18 09:38:10 -07002448 mResizingWindows.remove(win);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07002449 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002450 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451
2452 if (mInputMethodWindow == win) {
2453 mInputMethodWindow = null;
2454 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2455 mInputMethodDialogs.remove(win);
2456 }
Romain Guy06882f82009-06-10 13:36:04 -07002457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002458 final WindowToken token = win.mToken;
2459 final AppWindowToken atoken = win.mAppToken;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08002460 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002461 token.windows.remove(win);
2462 if (atoken != null) {
2463 atoken.allAppWindows.remove(win);
2464 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08002465 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002466 TAG, "**** Removing window " + win + ": count="
2467 + token.windows.size());
2468 if (token.windows.size() == 0) {
2469 if (!token.explicit) {
2470 mTokenMap.remove(token.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002471 } else if (atoken != null) {
2472 atoken.firstWindowDrawn = false;
2473 }
2474 }
2475
2476 if (atoken != null) {
2477 if (atoken.startingWindow == win) {
Craig Mautner38b24782012-07-02 16:21:28 -07002478 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002479 atoken.startingWindow = null;
2480 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2481 // If this is the last window and we had requested a starting
2482 // transition window, well there is no point now.
Craig Mautner38b24782012-07-02 16:21:28 -07002483 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 atoken.startingData = null;
2485 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2486 // If this is the last window except for a starting transition
2487 // window, we need to get rid of the starting transition.
2488 if (DEBUG_STARTING_WINDOW) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002489 Slog.v(TAG, "Schedule remove starting " + token
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002490 + ": no more real windows");
2491 }
2492 Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
2493 mH.sendMessage(m);
2494 }
2495 }
Romain Guy06882f82009-06-10 13:36:04 -07002496
Dianne Hackborn19382ac2009-09-11 21:13:37 -07002497 if (win.mAttrs.type == TYPE_WALLPAPER) {
2498 mLastWallpaperTimeoutTime = 0;
2499 adjustWallpaperWindowsLocked();
2500 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackborne9e9bca2009-08-18 15:08:22 -07002501 adjustWallpaperWindowsLocked();
2502 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002504 if (!mInLayout) {
Craig Mautner59c00972012-07-30 12:10:24 -07002505 assignLayersLocked(windows);
Craig Mautner19d59bc2012-09-04 11:15:56 -07002506 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507 performLayoutAndPlaceSurfacesLocked();
2508 if (win.mAppToken != null) {
2509 win.mAppToken.updateReportedVisibilityLocked();
2510 }
2511 }
Craig Mautner9e809442012-06-22 17:13:04 -07002512
Jeff Brown2e44b072011-01-24 15:21:56 -08002513 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 }
2515
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002516 static void logSurface(WindowState w, String msg, RuntimeException where) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002517 String str = " SURFACE " + msg + ": " + w;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08002518 if (where != null) {
2519 Slog.i(TAG, str, where);
2520 } else {
2521 Slog.i(TAG, str);
2522 }
2523 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002524
2525 static void logSurface(Surface s, String title, String msg, RuntimeException where) {
2526 String str = " SURFACE " + s + ": " + msg + " / " + title;
2527 if (where != null) {
2528 Slog.i(TAG, str, where);
2529 } else {
2530 Slog.i(TAG, str);
2531 }
2532 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07002533
2534 // TODO(cmautner): Move to WindowStateAnimator.
2535 void setTransparentRegionHint(final WindowStateAnimator winAnimator, final Region region) {
2536 mH.sendMessage(mH.obtainMessage(H.SET_TRANSPARENT_REGION,
2537 new Pair<WindowStateAnimator, Region>(winAnimator, region)));
2538 }
2539
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002540 void setTransparentRegionWindow(Session session, IWindow client, Region region) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002541 long origId = Binder.clearCallingIdentity();
2542 try {
2543 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002544 WindowState w = windowForClientLocked(session, client, false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002545 if ((w != null) && w.mHasSurface) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002546 setTransparentRegionHint(w.mWinAnimator, region);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002547 }
2548 }
2549 } finally {
2550 Binder.restoreCallingIdentity(origId);
2551 }
2552 }
2553
2554 void setInsetsWindow(Session session, IWindow client,
Romain Guy06882f82009-06-10 13:36:04 -07002555 int touchableInsets, Rect contentInsets,
Jeff Brownfbf09772011-01-16 14:06:57 -08002556 Rect visibleInsets, Region touchableRegion) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002557 long origId = Binder.clearCallingIdentity();
2558 try {
2559 synchronized (mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002560 WindowState w = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561 if (w != null) {
2562 w.mGivenInsetsPending = false;
2563 w.mGivenContentInsets.set(contentInsets);
2564 w.mGivenVisibleInsets.set(visibleInsets);
Jeff Brownfbf09772011-01-16 14:06:57 -08002565 w.mGivenTouchableRegion.set(touchableRegion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002566 w.mTouchableInsets = touchableInsets;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002567 if (w.mGlobalScale != 1) {
2568 w.mGivenContentInsets.scale(w.mGlobalScale);
2569 w.mGivenVisibleInsets.scale(w.mGlobalScale);
2570 w.mGivenTouchableRegion.scale(w.mGlobalScale);
2571 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07002572 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002573 performLayoutAndPlaceSurfacesLocked();
2574 }
2575 }
2576 } finally {
2577 Binder.restoreCallingIdentity(origId);
2578 }
2579 }
Romain Guy06882f82009-06-10 13:36:04 -07002580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 public void getWindowDisplayFrame(Session session, IWindow client,
2582 Rect outDisplayFrame) {
2583 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002584 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 if (win == null) {
2586 outDisplayFrame.setEmpty();
2587 return;
2588 }
2589 outDisplayFrame.set(win.mDisplayFrame);
2590 }
2591 }
2592
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002593 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
2594 float xStep, float yStep) {
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002595 if (window.mWallpaperX != x || window.mWallpaperY != y) {
2596 window.mWallpaperX = x;
2597 window.mWallpaperY = y;
Marco Nelissenbf6956b2009-11-09 15:21:13 -08002598 window.mWallpaperXStep = xStep;
2599 window.mWallpaperYStep = yStep;
Chet Haasea8e5a2b2011-10-28 13:18:16 -07002600 updateWallpaperOffsetLocked(window, true);
Dianne Hackbornc8a0a752009-08-10 23:05:49 -07002601 }
2602 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002603
Dianne Hackborn75804932009-10-20 20:15:20 -07002604 void wallpaperCommandComplete(IBinder window, Bundle result) {
2605 synchronized (mWindowMap) {
2606 if (mWaitingOnWallpaper != null &&
2607 mWaitingOnWallpaper.mClient.asBinder() == window) {
2608 mWaitingOnWallpaper = null;
2609 mWindowMap.notifyAll();
2610 }
2611 }
2612 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002613
Dianne Hackborn75804932009-10-20 20:15:20 -07002614 public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2615 String action, int x, int y, int z, Bundle extras, boolean sync) {
2616 if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2617 || window == mUpperWallpaperTarget) {
2618 boolean doWait = sync;
2619 int curTokenIndex = mWallpaperTokens.size();
2620 while (curTokenIndex > 0) {
2621 curTokenIndex--;
2622 WindowToken token = mWallpaperTokens.get(curTokenIndex);
2623 int curWallpaperIndex = token.windows.size();
2624 while (curWallpaperIndex > 0) {
2625 curWallpaperIndex--;
2626 WindowState wallpaper = token.windows.get(curWallpaperIndex);
2627 try {
2628 wallpaper.mClient.dispatchWallpaperCommand(action,
2629 x, y, z, extras, sync);
2630 // We only want to be synchronous with one wallpaper.
2631 sync = false;
2632 } catch (RemoteException e) {
2633 }
2634 }
2635 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002636
Dianne Hackborn75804932009-10-20 20:15:20 -07002637 if (doWait) {
2638 // XXX Need to wait for result.
2639 }
2640 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002641
Dianne Hackborn75804932009-10-20 20:15:20 -07002642 return null;
2643 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002644
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002645 public void setUniverseTransformLocked(WindowState window, float alpha,
2646 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
2647 Transformation transform = window.mWinAnimator.mUniverseTransform;
2648 transform.setAlpha(alpha);
2649 Matrix matrix = transform.getMatrix();
2650 matrix.getValues(mTmpFloats);
2651 mTmpFloats[Matrix.MTRANS_X] = offx;
2652 mTmpFloats[Matrix.MTRANS_Y] = offy;
2653 mTmpFloats[Matrix.MSCALE_X] = dsdx;
2654 mTmpFloats[Matrix.MSKEW_Y] = dtdx;
2655 mTmpFloats[Matrix.MSKEW_X] = dsdy;
2656 mTmpFloats[Matrix.MSCALE_Y] = dtdy;
2657 matrix.setValues(mTmpFloats);
Craig Mautner59c00972012-07-30 12:10:24 -07002658 final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002659 final RectF dispRect = new RectF(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002660 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002661 matrix.mapRect(dispRect);
Jeff Brownfa25bf52012-07-23 19:26:30 -07002662 window.mGivenTouchableRegion.set(0, 0,
Craig Mautner59c00972012-07-30 12:10:24 -07002663 displayInfo.logicalWidth, displayInfo.logicalHeight);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002664 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
2665 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
2666 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
Craig Mautner19d59bc2012-09-04 11:15:56 -07002667 window.mDisplayContent.layoutNeeded = true;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07002668 performLayoutAndPlaceSurfacesLocked();
2669 }
2670
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002671 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2672 synchronized (mWindowMap) {
2673 WindowState window = mWindowMap.get(token);
2674 if (window != null) {
2675 scheduleNotifyRectangleOnScreenRequestedIfNeededLocked(window, rectangle,
2676 immediate);
2677 }
2678 }
2679 }
2680
2681 private void scheduleNotifyRectangleOnScreenRequestedIfNeededLocked(WindowState window,
2682 Rect rectangle, boolean immediate) {
2683 DisplayContent displayContent = window.mDisplayContent;
2684 if (displayContent.mDisplayContentChangeListeners != null
2685 && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
2686 mH.obtainMessage(H.NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED, displayContent.getDisplayId(),
2687 immediate? 1 : 0, new Rect(rectangle)).sendToTarget();
2688 }
2689 }
2690
2691 private void handleNotifyRectangleOnScreenRequested(int displayId, Rect rectangle,
2692 boolean immediate) {
2693 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
2694 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002695 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002696 if (displayContent == null) {
2697 return;
2698 }
2699 callbacks = displayContent.mDisplayContentChangeListeners;
2700 if (callbacks == null) {
2701 return;
2702 }
2703 }
2704 final int callbackCount = callbacks.beginBroadcast();
2705 try {
2706 for (int i = 0; i < callbackCount; i++) {
2707 try {
2708 callbacks.getBroadcastItem(i).onRectangleOnScreenRequested(displayId,
2709 rectangle, immediate);
2710 } catch (RemoteException re) {
2711 /* ignore */
2712 }
2713 }
2714 } finally {
2715 callbacks.finishBroadcast();
2716 }
2717 }
2718
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002719 public int relayoutWindow(Session session, IWindow client, int seq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 WindowManager.LayoutParams attrs, int requestedWidth,
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002721 int requestedHeight, int viewVisibility, int flags,
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07002722 Rect outFrame, Rect outContentInsets,
Dianne Hackborn5c58de32012-04-28 19:52:37 -07002723 Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002724 boolean toBeDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002725 boolean inTouchMode;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002726 boolean configChanged;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002727 boolean surfaceChanged = false;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07002728 boolean animating;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002729
2730 // if they don't have this permission, mask out the status bar bits
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002731 int systemUiVisibility = 0;
Joe Onoratoac0ee892011-01-30 15:38:30 -08002732 if (attrs != null) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002733 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2734 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002735 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2736 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002737 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
Dianne Hackborna44abeb2011-08-08 19:24:01 -07002738 }
Joe Onoratoac0ee892011-01-30 15:38:30 -08002739 }
2740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002741 long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07002742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002743 synchronized(mWindowMap) {
Craig Mautner48ba1e72012-04-02 13:18:16 -07002744 // TODO(cmautner): synchronize on mAnimator or win.mWinAnimator.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002745 WindowState win = windowForClientLocked(session, client, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 if (win == null) {
2747 return 0;
2748 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002749 WindowStateAnimator winAnimator = win.mWinAnimator;
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002750 if (win.mRequestedWidth != requestedWidth
2751 || win.mRequestedHeight != requestedHeight) {
2752 win.mLayoutNeeded = true;
2753 win.mRequestedWidth = requestedWidth;
2754 win.mRequestedHeight = requestedHeight;
2755 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -07002756 if (attrs != null && seq == win.mSeq) {
2757 win.mSystemUiVisibility = systemUiVisibility;
2758 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759
2760 if (attrs != null) {
2761 mPolicy.adjustWindowParamsLw(attrs);
2762 }
Romain Guy06882f82009-06-10 13:36:04 -07002763
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002764 winAnimator.mSurfaceDestroyDeferred =
Jeff Brown98365d72012-08-19 20:30:52 -07002765 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 int attrChanges = 0;
2768 int flagChanges = 0;
2769 if (attrs != null) {
Dianne Hackborn0e60db22011-09-01 11:17:57 -07002770 if (win.mAttrs.type != attrs.type) {
2771 throw new IllegalArgumentException(
2772 "Window type can not be changed after the window is added.");
2773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 flagChanges = win.mAttrs.flags ^= attrs.flags;
2775 attrChanges = win.mAttrs.copyFrom(attrs);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07002776 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2777 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08002778 win.mLayoutNeeded = true;
2779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002780 }
2781
Dianne Hackborn7ff30112012-11-08 11:12:09 -08002782 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
Chet Haased5d11af2012-10-31 08:57:17 -07002783 + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002784
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002785 win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
2786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002787 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002788 winAnimator.mAlpha = attrs.alpha;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 }
2790
2791 final boolean scaledWindow =
2792 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2793
2794 if (scaledWindow) {
2795 // requested{Width|Height} Surface's physical size
2796 // attrs.{width|height} Size on screen
2797 win.mHScale = (attrs.width != requestedWidth) ?
2798 (attrs.width / (float)requestedWidth) : 1.0f;
2799 win.mVScale = (attrs.height != requestedHeight) ?
2800 (attrs.height / (float)requestedHeight) : 1.0f;
Dianne Hackborn9b52a212009-12-11 14:51:35 -08002801 } else {
2802 win.mHScale = win.mVScale = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 }
2804
Craig Mautner65d11b32012-10-01 13:59:52 -07002805 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
Romain Guy06882f82009-06-10 13:36:04 -07002806
Craig Mautner69b08182012-09-05 13:07:13 -07002807 final boolean isDefaultDisplay = win.isDefaultDisplay();
2808 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
Craig Mautner65d11b32012-10-01 13:59:52 -07002809 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
Craig Mautner69b08182012-09-05 13:07:13 -07002810 || (!win.mRelayoutCalled));
Romain Guy06882f82009-06-10 13:36:04 -07002811
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002812 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2813 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Dianne Hackborn9e4e7272011-08-30 14:06:51 -07002814 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 win.mRelayoutCalled = true;
2817 final int oldVisibility = win.mViewVisibility;
2818 win.mViewVisibility = viewVisibility;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07002819 if (DEBUG_SCREEN_ON) {
2820 RuntimeException stack = new RuntimeException();
2821 stack.fillInStackTrace();
2822 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2823 + " newVis=" + viewVisibility, stack);
2824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 if (viewVisibility == View.VISIBLE &&
2826 (win.mAppToken == null || !win.mAppToken.clientHidden)) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002827 toBeDisplayed = !win.isVisibleLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002828 if (win.mExiting) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002829 winAnimator.cancelExitAnimationForNextAnimationLocked();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002830 win.mExiting = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831 }
2832 if (win.mDestroying) {
2833 win.mDestroying = false;
2834 mDestroySurface.remove(win);
2835 }
2836 if (oldVisibility == View.GONE) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002837 winAnimator.mEnterAnimationPending = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002839 if (toBeDisplayed) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002840 if (win.isDrawnLw() && okToDisplay()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002841 winAnimator.applyEnterAnimationLocked();
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002842 }
2843 if ((win.mAttrs.flags
2844 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2845 if (DEBUG_VISIBILITY) Slog.v(TAG,
2846 "Relayout window turning screen on: " + win);
2847 win.mTurnOnScreen = true;
2848 }
Craig Mautnera3f4bf52012-10-10 20:37:48 -07002849 if (win.isConfigChanged()) {
2850 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
2851 + " visible with new config: " + win.mConfiguration);
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002852 outConfig.setTo(mCurConfiguration);
2853 }
Dianne Hackborn93e462b2009-09-15 22:50:40 -07002854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002855 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2856 // To change the format, we need to re-build the surface.
Dianne Hackborn98129732012-11-01 16:28:16 -07002857 winAnimator.destroySurfaceLocked(false);
Craig Mautnerbf08af32012-05-16 19:43:42 -07002858 toBeDisplayed = true;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002859 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 }
2861 try {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07002862 if (!win.mHasSurface) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002863 surfaceChanged = true;
2864 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002865 Surface surface = winAnimator.createSurfaceLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002866 if (surface != null) {
2867 outSurface.copyFrom(surface);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002868 if (SHOW_TRANSACTIONS) Slog.i(TAG,
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002869 " OUT SURFACE " + outSurface + ": copied");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002870 } else {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002871 // For some reason there isn't a surface. Clear the
2872 // caller's object so they see the same state.
2873 outSurface.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002874 }
2875 } catch (Exception e) {
Jeff Brown2e44b072011-01-24 15:21:56 -08002876 mInputMonitor.updateInputWindowsLw(true /*force*/);
Craig Mautner9e809442012-06-22 17:13:04 -07002877
Joe Onorato8a9b2202010-02-26 18:56:32 -08002878 Slog.w(TAG, "Exception thrown when creating surface for client "
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002879 + client + " (" + win.mAttrs.getTitle() + ")",
2880 e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002881 Binder.restoreCallingIdentity(origId);
2882 return 0;
2883 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002884 if (toBeDisplayed) {
Craig Mautner69b08182012-09-05 13:07:13 -07002885 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002886 }
2887 if (win.mAttrs.type == TYPE_INPUT_METHOD
2888 && mInputMethodWindow == null) {
2889 mInputMethodWindow = win;
2890 imMayMove = true;
2891 }
Dianne Hackborn558947c2009-12-18 16:02:50 -08002892 if (win.mAttrs.type == TYPE_BASE_APPLICATION
2893 && win.mAppToken != null
2894 && win.mAppToken.startingWindow != null) {
2895 // Special handling of starting window over the base
2896 // window of the app: propagate lock screen flags to it,
2897 // to provide the correct semantics while starting.
2898 final int mask =
2899 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
Mike Lockwoodef731622010-01-27 17:51:34 -05002900 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2901 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Dianne Hackborn558947c2009-12-18 16:02:50 -08002902 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2903 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 } else {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002906 winAnimator.mEnterAnimationPending = false;
2907 if (winAnimator.mSurface != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002908 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
Craig Mautnerbf08af32012-05-16 19:43:42 -07002909 + ": mExiting=" + win.mExiting);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 // If we are not currently running the exit animation, we
2911 // need to see about starting one.
Craig Mautnerbf08af32012-05-16 19:43:42 -07002912 if (!win.mExiting) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08002913 surfaceChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 // Try starting an animation; if there isn't one, we
2915 // can destroy the surface right away.
2916 int transit = WindowManagerPolicy.TRANSIT_EXIT;
Craig Mautnerbb1449b2012-03-23 16:11:14 -07002917 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002918 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2919 }
Craig Mautnerbf08af32012-05-16 19:43:42 -07002920 if (win.isWinVisibleLw() &&
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002921 winAnimator.applyAnimationLocked(transit, false)) {
Craig Mautner69b08182012-09-05 13:07:13 -07002922 focusMayChange = isDefaultDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002924 } else if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002925 // Currently in a hide animation... turn this into
2926 // an exit.
2927 win.mExiting = true;
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07002928 } else if (win == mWallpaperTarget) {
2929 // If the wallpaper is currently behind this
2930 // window, we need to change both of them inside
2931 // of a transaction to avoid artifacts.
2932 win.mExiting = true;
Craig Mautnera2c77052012-03-26 12:14:43 -07002933 win.mWinAnimator.mAnimating = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 } else {
2935 if (mInputMethodWindow == win) {
2936 mInputMethodWindow = null;
2937 }
Dianne Hackborn98129732012-11-01 16:28:16 -07002938 winAnimator.destroySurfaceLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002939 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07002940 scheduleNotifyWindowTranstionIfNeededLocked(win, transit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 }
2942 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08002943
Craig Mautnerbf08af32012-05-16 19:43:42 -07002944 outSurface.release();
2945 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002946 }
2947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 if (focusMayChange) {
2949 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
Jeff Brown3a22cd92011-01-21 13:59:04 -08002950 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2951 false /*updateInputWindows*/)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 imMayMove = false;
2953 }
2954 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2955 }
Romain Guy06882f82009-06-10 13:36:04 -07002956
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08002957 // updateFocusedWindowLocked() already assigned layers so we only need to
2958 // reassign them at this point if the IM window state gets shuffled
2959 boolean assignLayers = false;
Romain Guy06882f82009-06-10 13:36:04 -07002960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961 if (imMayMove) {
Craig Mautnerbf08af32012-05-16 19:43:42 -07002962 if (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed) {
Dianne Hackborn8abd5f02009-11-20 18:09:03 -08002963 // Little hack here -- we -should- be able to rely on the
2964 // function to return true if the IME has moved and needs
2965 // its layer recomputed. However, if the IME was hidden
2966 // and isn't actually moved in the list, its layer may be
2967 // out of data so we make sure to recompute it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002968 assignLayers = true;
2969 }
2970 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002971 if (wallpaperMayMove) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07002972 if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07002973 assignLayers = true;
2974 }
2975 }
Romain Guy06882f82009-06-10 13:36:04 -07002976
Craig Mautner19d59bc2012-09-04 11:15:56 -07002977 win.mDisplayContent.layoutNeeded = true;
Jeff Brown98365d72012-08-19 20:30:52 -07002978 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 if (assignLayers) {
Craig Mautner59c00972012-07-30 12:10:24 -07002980 assignLayersLocked(win.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002981 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002982 configChanged = updateOrientationFromAppTokensLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerbf08af32012-05-16 19:43:42 -07002984 if (toBeDisplayed && win.mIsWallpaper) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07002985 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Brownfa25bf52012-07-23 19:26:30 -07002986 updateWallpaperOffsetLocked(win,
Craig Mautner59c00972012-07-30 12:10:24 -07002987 displayInfo.appWidth, displayInfo.appHeight, false);
Dianne Hackborn284ac932009-08-28 10:34:25 -07002988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 if (win.mAppToken != null) {
2990 win.mAppToken.updateReportedVisibilityLocked();
2991 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002992 outFrame.set(win.mCompatFrame);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002993 outContentInsets.set(win.mContentInsets);
2994 outVisibleInsets.set(win.mVisibleInsets);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002995 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002996 TAG, "Relayout given client " + client.asBinder()
Romain Guy06882f82009-06-10 13:36:04 -07002997 + ", requestedWidth=" + requestedWidth
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002998 + ", requestedHeight=" + requestedHeight
2999 + ", viewVisibility=" + viewVisibility
3000 + "\nRelayout returning frame=" + outFrame
3001 + ", surface=" + outSurface);
3002
Joe Onorato8a9b2202010-02-26 18:56:32 -08003003 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3005
3006 inTouchMode = mInTouchMode;
Dianne Hackborn12d3a942012-04-27 14:16:30 -07003007 animating = mAnimator.mAnimating;
3008 if (animating && !mRelayoutWhileAnimating.contains(win)) {
3009 mRelayoutWhileAnimating.add(win);
3010 }
3011
Jeff Brown2e44b072011-01-24 15:21:56 -08003012 mInputMonitor.updateInputWindowsLw(true /*force*/);
Chet Haased5d11af2012-10-31 08:57:17 -07003013
3014 if (DEBUG_LAYOUT) {
3015 Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
3016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 }
3018
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003019 if (configChanged) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003020 sendNewConfiguration();
3021 }
Romain Guy06882f82009-06-10 13:36:04 -07003022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003023 Binder.restoreCallingIdentity(origId);
Romain Guy06882f82009-06-10 13:36:04 -07003024
Jeff Brown98365d72012-08-19 20:30:52 -07003025 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3026 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3027 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
3028 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003029 }
3030
3031 public void performDeferredDestroyWindow(Session session, IWindow client) {
3032 long origId = Binder.clearCallingIdentity();
3033
3034 try {
3035 synchronized(mWindowMap) {
3036 WindowState win = windowForClientLocked(session, client, false);
3037 if (win == null) {
3038 return;
3039 }
Dianne Hackborn98129732012-11-01 16:28:16 -07003040 win.mWinAnimator.destroyDeferredSurfaceLocked(false);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003041 }
3042 } finally {
3043 Binder.restoreCallingIdentity(origId);
3044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003045 }
3046
Dianne Hackborn64825172011-03-02 21:32:58 -08003047 public boolean outOfMemoryWindow(Session session, IWindow client) {
3048 long origId = Binder.clearCallingIdentity();
3049
3050 try {
3051 synchronized(mWindowMap) {
3052 WindowState win = windowForClientLocked(session, client, false);
3053 if (win == null) {
3054 return false;
3055 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003056 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
Dianne Hackborn64825172011-03-02 21:32:58 -08003057 }
3058 } finally {
3059 Binder.restoreCallingIdentity(origId);
3060 }
3061 }
3062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003063 public void finishDrawingWindow(Session session, IWindow client) {
3064 final long origId = Binder.clearCallingIdentity();
3065 synchronized(mWindowMap) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003066 WindowState win = windowForClientLocked(session, client, false);
Craig Mautnera608b882012-03-30 13:03:49 -07003067 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
Dianne Hackborn759a39e2009-08-09 17:20:27 -07003068 if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
3069 adjustWallpaperWindowsLocked();
3070 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07003071 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 performLayoutAndPlaceSurfacesLocked();
3073 }
3074 }
3075 Binder.restoreCallingIdentity(origId);
3076 }
3077
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003078 @Override
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003079 public float getWindowCompatibilityScale(IBinder windowToken) {
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07003080 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3081 "getWindowCompatibilityScale()")) {
3082 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3083 }
Svetoslav Ganov7961be72011-06-21 12:31:56 -07003084 synchronized (mWindowMap) {
3085 WindowState windowState = mWindowMap.get(windowToken);
3086 return (windowState != null) ? windowState.mGlobalScale : 1.0f;
3087 }
3088 }
3089
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003090 @Override
3091 public WindowInfo getWindowInfo(IBinder token) {
3092 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3093 "getWindowInfo()")) {
3094 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3095 }
3096 synchronized (mWindowMap) {
3097 WindowState window = mWindowMap.get(token);
3098 if (window != null) {
3099 return getWindowInfoForWindowStateLocked(window);
3100 }
3101 return null;
3102 }
3103 }
3104
3105 @Override
3106 public void getVisibleWindowsForDisplay(int displayId, List<WindowInfo> outInfos) {
3107 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3108 "getWindowInfos()")) {
3109 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
3110 }
3111 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003112 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003113 if (displayContent == null) {
3114 return;
3115 }
3116 WindowList windows = displayContent.getWindowList();
3117 final int windowCount = windows.size();
3118 for (int i = 0; i < windowCount; i++) {
3119 WindowState window = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07003120 if (window.isVisibleLw() || window.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003121 WindowInfo info = getWindowInfoForWindowStateLocked(window);
3122 outInfos.add(info);
3123 }
3124 }
3125 }
3126 }
3127
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003128 @Override
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003129 public void magnifyDisplay(int displayId, float scale, float offsetX, float offsetY) {
3130 if (!checkCallingPermission(
3131 android.Manifest.permission.MAGNIFY_DISPLAY, "magnifyDisplay()")) {
3132 throw new SecurityException("Requires MAGNIFY_DISPLAY permission");
3133 }
3134 synchronized (mWindowMap) {
3135 MagnificationSpec spec = getDisplayMagnificationSpecLocked(displayId);
3136 if (spec != null) {
3137 final boolean scaleChanged = spec.mScale != scale;
3138 final boolean offsetChanged = spec.mOffsetX != offsetX || spec.mOffsetY != offsetY;
3139 if (!scaleChanged && !offsetChanged) {
3140 return;
3141 }
3142 spec.initialize(scale, offsetX, offsetY);
3143 // If the offset has changed we need to re-add the input windows
3144 // since the offsets have to be propagated to the input system.
3145 if (offsetChanged) {
3146 // TODO(multidisplay): Input only occurs on the default display.
3147 if (displayId == Display.DEFAULT_DISPLAY) {
3148 mInputMonitor.updateInputWindowsLw(true);
3149 }
3150 }
3151 scheduleAnimationLocked();
3152 }
3153 }
3154 }
3155
3156 MagnificationSpec getDisplayMagnificationSpecLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003157 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003158 if (displayContent != null) {
3159 if (displayContent.mMagnificationSpec == null) {
3160 displayContent.mMagnificationSpec = new MagnificationSpec();
3161 }
3162 return displayContent.mMagnificationSpec;
3163 }
3164 return null;
3165 }
3166
3167 private WindowInfo getWindowInfoForWindowStateLocked(WindowState window) {
3168 WindowInfo info = WindowInfo.obtain();
3169 info.token = window.mToken.token;
3170 info.frame.set(window.mFrame);
3171 info.type = window.mAttrs.type;
3172 info.displayId = window.getDisplayId();
3173 info.compatibilityScale = window.mGlobalScale;
Craig Mautner65d11b32012-10-01 13:59:52 -07003174 info.visible = window.isVisibleLw() || info.type == TYPE_UNIVERSE_BACKGROUND;
Svetoslav Ganov9b4125e2012-09-11 15:36:44 -07003175 info.layer = window.mLayer;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003176 window.getTouchableRegion(mTempRegion);
3177 mTempRegion.getBounds(info.touchableRegion);
3178 return info;
3179 }
3180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003181 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003182 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003183 + (lp != null ? lp.packageName : null)
3184 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
3185 if (lp != null && lp.windowAnimations != 0) {
3186 // If this is a system resource, don't try to load it from the
3187 // application resources. It is nice to avoid loading application
3188 // resources if we can.
3189 String packageName = lp.packageName != null ? lp.packageName : "android";
3190 int resId = lp.windowAnimations;
3191 if ((resId&0xFF000000) == 0x01000000) {
3192 packageName = "android";
3193 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003194 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003195 + packageName);
3196 return AttributeCache.instance().get(packageName, resId,
3197 com.android.internal.R.styleable.WindowAnimation);
3198 }
3199 return null;
3200 }
Romain Guy06882f82009-06-10 13:36:04 -07003201
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003202 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
Dianne Hackborn08121bc2011-01-17 17:54:31 -08003203 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003204 + packageName + " resId=0x" + Integer.toHexString(resId));
3205 if (packageName != null) {
3206 if ((resId&0xFF000000) == 0x01000000) {
3207 packageName = "android";
3208 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003209 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003210 + packageName);
3211 return AttributeCache.instance().get(packageName, resId,
3212 com.android.internal.R.styleable.WindowAnimation);
3213 }
3214 return null;
3215 }
3216
Craig Mautnere7ae2502012-03-26 17:11:19 -07003217 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003218 int anim = 0;
3219 Context context = mContext;
3220 if (animAttr >= 0) {
3221 AttributeCache.Entry ent = getCachedAnimations(lp);
3222 if (ent != null) {
3223 context = ent.context;
3224 anim = ent.array.getResourceId(animAttr, 0);
3225 }
3226 }
3227 if (anim != 0) {
3228 return AnimationUtils.loadAnimation(context, anim);
3229 }
3230 return null;
3231 }
Romain Guy06882f82009-06-10 13:36:04 -07003232
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003233 private Animation loadAnimation(String packageName, int resId) {
3234 int anim = 0;
3235 Context context = mContext;
3236 if (resId >= 0) {
3237 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
3238 if (ent != null) {
3239 context = ent.context;
3240 anim = resId;
3241 }
3242 }
3243 if (anim != 0) {
3244 return AnimationUtils.loadAnimation(context, anim);
3245 }
3246 return null;
3247 }
3248
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003249 private Animation createExitAnimationLocked(int transit, int duration) {
3250 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
3251 transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
3252 // If we are on top of the wallpaper, we need an animation that
3253 // correctly handles the wallpaper staying static behind all of
3254 // the animated elements. To do this, will just have the existing
3255 // element fade out.
3256 Animation a = new AlphaAnimation(1, 0);
3257 a.setDetachWallpaper(true);
3258 a.setDuration(duration);
3259 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003260 }
Craig Mautner01cd0e72012-06-18 10:19:11 -07003261 // For normal animations, the exiting element just holds in place.
3262 Animation a = new AlphaAnimation(1, 1);
3263 a.setDuration(duration);
3264 return a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003265 }
3266
3267 /**
3268 * Compute the pivot point for an animation that is scaling from a small
3269 * rect on screen to a larger rect. The pivot point varies depending on
3270 * the distance between the inner and outer edges on both sides. This
3271 * function computes the pivot point for one dimension.
3272 * @param startPos Offset from left/top edge of outer rectangle to
3273 * left/top edge of inner rectangle.
3274 * @param finalScale The scaling factor between the size of the outer
3275 * and inner rectangles.
3276 */
3277 private static float computePivot(int startPos, float finalScale) {
3278 final float denom = finalScale-1;
3279 if (Math.abs(denom) < .0001f) {
3280 return startPos;
3281 }
3282 return -startPos / denom;
3283 }
3284
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003285 private Animation createScaleUpAnimationLocked(int transit, boolean enter) {
3286 Animation a;
3287 // Pick the desired duration. If this is an inter-activity transition,
3288 // it is the standard duration for that. Otherwise we use the longer
3289 // task transition duration.
3290 int duration;
3291 switch (transit) {
3292 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3293 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3294 duration = mContext.getResources().getInteger(
3295 com.android.internal.R.integer.config_shortAnimTime);
3296 break;
3297 default:
Winson Chungdc6f79b2012-04-17 17:27:31 -07003298 duration = 300;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003299 break;
3300 }
Craig Mautner59c00972012-07-30 12:10:24 -07003301 // TODO(multidisplay): For now assume all app animation is on main display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003302 final DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003303 if (enter) {
3304 // Entering app zooms out from the center of the initial rect.
Craig Mautner59c00972012-07-30 12:10:24 -07003305 float scaleW = mNextAppTransitionStartWidth / (float) displayInfo.appWidth;
3306 float scaleH = mNextAppTransitionStartHeight / (float) displayInfo.appHeight;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003307 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3308 computePivot(mNextAppTransitionStartX, scaleW),
3309 computePivot(mNextAppTransitionStartY, scaleH));
3310 scale.setDuration(duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003311 AnimationSet set = new AnimationSet(true);
3312 Animation alpha = new AlphaAnimation(0, 1);
3313 scale.setDuration(duration);
3314 set.addAnimation(scale);
3315 alpha.setDuration(duration);
3316 set.addAnimation(alpha);
Craig Mautnera8033712012-06-12 15:50:45 -07003317 set.setDetachWallpaper(true);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003318 a = set;
3319 } else {
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003320 a = createExitAnimationLocked(transit, duration);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003321 }
3322 a.setFillAfter(true);
3323 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Winson Chungdc6f79b2012-04-17 17:27:31 -07003324 com.android.internal.R.interpolator.decelerate_cubic);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003325 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003326 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3327 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003328 return a;
3329 }
3330
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003331 private Animation createThumbnailAnimationLocked(int transit,
Michael Jurka832cb222012-04-13 09:32:47 -07003332 boolean enter, boolean thumb, boolean scaleUp) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003333 Animation a;
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003334 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
3335 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
3336 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
3337 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003338 // Pick the desired duration. If this is an inter-activity transition,
3339 // it is the standard duration for that. Otherwise we use the longer
3340 // task transition duration.
3341 int duration;
3342 switch (transit) {
3343 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3344 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3345 duration = mContext.getResources().getInteger(
3346 com.android.internal.R.integer.config_shortAnimTime);
3347 break;
3348 default:
Michael Jurka832cb222012-04-13 09:32:47 -07003349 duration = 250;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003350 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003351 }
Craig Mautner59c00972012-07-30 12:10:24 -07003352 // TOOD(multidisplay): For now assume all app animation is on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003353 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003354 if (thumb) {
3355 // Animation for zooming thumbnail from its initial size to
3356 // filling the screen.
Michael Jurka832cb222012-04-13 09:32:47 -07003357 if (scaleUp) {
3358 float scaleW = displayInfo.appWidth / thumbWidth;
3359 float scaleH = displayInfo.appHeight / thumbHeight;
Michael Jurka21385cd2012-05-03 10:57:31 -07003360
Michael Jurka832cb222012-04-13 09:32:47 -07003361 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
3362 computePivot(mNextAppTransitionStartX, 1 / scaleW),
3363 computePivot(mNextAppTransitionStartY, 1 / scaleH));
3364 AnimationSet set = new AnimationSet(true);
3365 Animation alpha = new AlphaAnimation(1, 0);
3366 scale.setDuration(duration);
3367 scale.setInterpolator(
3368 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3369 set.addAnimation(scale);
3370 alpha.setDuration(duration);
3371 set.addAnimation(alpha);
3372 set.setFillBefore(true);
3373 a = set;
3374 } else {
3375 float scaleW = displayInfo.appWidth / thumbWidth;
3376 float scaleH = displayInfo.appHeight / thumbHeight;
3377
3378 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3379 computePivot(mNextAppTransitionStartX, 1 / scaleW),
3380 computePivot(mNextAppTransitionStartY, 1 / scaleH));
3381 AnimationSet set = new AnimationSet(true);
3382 Animation alpha = new AlphaAnimation(1, 1);
3383 scale.setDuration(duration);
3384 scale.setInterpolator(
3385 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3386 set.addAnimation(scale);
3387 alpha.setDuration(duration);
3388 set.addAnimation(alpha);
3389 set.setFillBefore(true);
3390
3391 a = set;
Michael Jurka21385cd2012-05-03 10:57:31 -07003392 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003393 } else if (enter) {
3394 // Entering app zooms out from the center of the thumbnail.
Michael Jurka832cb222012-04-13 09:32:47 -07003395 if (scaleUp) {
3396 float scaleW = thumbWidth / displayInfo.appWidth;
3397 float scaleH = thumbHeight / displayInfo.appHeight;
3398 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
3399 computePivot(mNextAppTransitionStartX, scaleW),
3400 computePivot(mNextAppTransitionStartY, scaleH));
3401 scale.setDuration(duration);
3402 scale.setInterpolator(
3403 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3404 scale.setFillBefore(true);
3405 a = scale;
Michael Jurkad5895a72012-05-12 13:24:58 -07003406 } else {
Michael Jurka832cb222012-04-13 09:32:47 -07003407 // noop animation
3408 a = new AlphaAnimation(1, 1);
3409 a.setDuration(duration);
3410 }
3411 } else {
3412 // Exiting app
3413 if (scaleUp) {
Michael Jurka738cfc92012-10-19 14:56:47 +02003414 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN) {
3415 // Fade out while bringing up selected activity. This keeps the
3416 // current activity from showing through a launching wallpaper
3417 // activity.
3418 a = new AlphaAnimation(1, 0);
3419 } else {
3420 // noop animation
3421 a = new AlphaAnimation(1, 1);
3422 }
Michael Jurka832cb222012-04-13 09:32:47 -07003423 a.setDuration(duration);
3424 } else {
3425 float scaleW = thumbWidth / displayInfo.appWidth;
3426 float scaleH = thumbHeight / displayInfo.appHeight;
3427 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
3428 computePivot(mNextAppTransitionStartX, scaleW),
3429 computePivot(mNextAppTransitionStartY, scaleH));
3430 scale.setDuration(duration);
3431 scale.setInterpolator(
3432 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3433 scale.setFillBefore(true);
3434 AnimationSet set = new AnimationSet(true);
3435 Animation alpha = new AlphaAnimation(1, 0);
3436 set.addAnimation(scale);
3437 alpha.setDuration(duration);
3438 alpha.setInterpolator(new DecelerateInterpolator(
3439 THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
3440 set.addAnimation(alpha);
3441 set.setFillBefore(true);
3442 set.setZAdjustment(Animation.ZORDER_TOP);
3443 a = set;
Michael Jurka21385cd2012-05-03 10:57:31 -07003444 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003445 }
3446 a.setFillAfter(true);
3447 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
Dianne Hackborn7f58b952012-04-18 12:59:29 -07003448 com.android.internal.R.interpolator.decelerate_quad);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003449 a.setInterpolator(interpolator);
Craig Mautner59c00972012-07-30 12:10:24 -07003450 a.initialize(displayInfo.appWidth, displayInfo.appHeight,
3451 displayInfo.appWidth, displayInfo.appHeight);
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003452 return a;
3453 }
3454
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003455 private boolean applyAnimationLocked(AppWindowToken atoken,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003456 WindowManager.LayoutParams lp, int transit, boolean enter) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003457 // Only apply an animation if the display isn't frozen. If it is
3458 // frozen, there is no reason to animate and it can cause strange
3459 // artifacts when we unfreeze the display if some different animation
3460 // is running.
Craig Mautner2fb98b12012-03-20 17:24:00 -07003461 if (okToDisplay()) {
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003462 Animation a;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003463 boolean initialized = false;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003464 if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07003465 a = loadAnimation(mNextAppTransitionPackage, enter ?
3466 mNextAppTransitionEnter : mNextAppTransitionExit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04003467 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003468 "applyAnimation: atoken=" + atoken
Craig Mautner83339b42012-05-01 22:13:23 -07003469 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003470 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003471 + " Callers=" + Debug.getCallers(3));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003472 } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) {
3473 a = createScaleUpAnimationLocked(transit, enter);
3474 initialized = true;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003475 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003476 "applyAnimation: atoken=" + atoken
Craig Mautner83339b42012-05-01 22:13:23 -07003477 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003478 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003479 + " Callers=" + Debug.getCallers(3));
Michael Jurka832cb222012-04-13 09:32:47 -07003480 } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP ||
3481 mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN) {
3482 boolean scaleUp = (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
3483 a = createThumbnailAnimationLocked(transit, enter, false, scaleUp);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07003484 initialized = true;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003485 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Michael Jurka832cb222012-04-13 09:32:47 -07003486 String animName = scaleUp ? "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003487 Slog.v(TAG, "applyAnimation: atoken=" + atoken
Michael Jurka21385cd2012-05-03 10:57:31 -07003488 + " anim=" + a + " nextAppTransition=" + animName
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003489 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003490 + " Callers=" + Debug.getCallers(3));
Michael Jurka21385cd2012-05-03 10:57:31 -07003491 }
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003492 } else {
3493 int animAttr = 0;
3494 switch (transit) {
3495 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
3496 animAttr = enter
3497 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
3498 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
3499 break;
3500 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
3501 animAttr = enter
3502 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
3503 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
3504 break;
3505 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
3506 animAttr = enter
3507 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
3508 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
3509 break;
3510 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
3511 animAttr = enter
3512 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
3513 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
3514 break;
3515 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
3516 animAttr = enter
3517 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
3518 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
3519 break;
3520 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
3521 animAttr = enter
Mitsuru Oshima5a2b91d2009-07-16 16:30:02 -07003522 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003523 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
3524 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003525 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003526 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003527 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
3528 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003529 break;
Dianne Hackborn25994b42009-09-04 14:21:19 -07003530 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003531 animAttr = enter
Dianne Hackborn25994b42009-09-04 14:21:19 -07003532 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
3533 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
3534 break;
3535 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
3536 animAttr = enter
3537 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
3538 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
3539 break;
3540 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
3541 animAttr = enter
3542 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
3543 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Dianne Hackbornf8fbdb62009-08-19 12:39:43 -07003544 break;
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003545 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07003546 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
Daniel Sandlerab886f52012-06-04 14:36:25 -04003547 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003548 "applyAnimation: atoken=" + atoken
Mitsuru Oshima0a5d2c42009-07-14 14:10:30 -07003549 + " anim=" + a
3550 + " animAttr=0x" + Integer.toHexString(animAttr)
Craig Mautnerdc5a6382012-09-13 16:34:41 -07003551 + " transit=" + transit + " isEntrance=" + enter
Craig Mautner8863cca2012-09-18 15:04:34 -07003552 + " Callers=" + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 if (a != null) {
3555 if (DEBUG_ANIM) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08003556 RuntimeException e = null;
3557 if (!HIDE_STACK_CRAWLS) {
3558 e = new RuntimeException();
3559 e.fillInStackTrace();
3560 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003561 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003562 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003563 atoken.mAppAnimator.setAnimation(a, initialized);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003564 }
3565 } else {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003566 atoken.mAppAnimator.clearAnimation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 }
3568
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003569 return atoken.mAppAnimator.animation != null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003570 }
3571
3572 // -------------------------------------------------------------
3573 // Application Window Tokens
3574 // -------------------------------------------------------------
3575
Dianne Hackbornbe707852011-11-11 14:32:10 -08003576 public void validateAppTokens(List<IBinder> tokens) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003577 int v = tokens.size()-1;
3578 int m = mAppTokens.size()-1;
3579 while (v >= 0 && m >= 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003580 AppWindowToken atoken = mAppTokens.get(m);
3581 if (atoken.removed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003582 m--;
3583 continue;
3584 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003585 if (tokens.get(v) != atoken.token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003586 Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003587 + " @ " + v + ", internal is " + atoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003588 }
3589 v--;
3590 m--;
3591 }
3592 while (v >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003593 Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 v--;
3595 }
3596 while (m >= 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003597 AppWindowToken atoken = mAppTokens.get(m);
3598 if (!atoken.removed) {
3599 Slog.w(TAG, "Invalid internal atoken: " + atoken.token + " @ " + m);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003600 }
3601 m--;
3602 }
3603 }
3604
3605 boolean checkCallingPermission(String permission, String func) {
3606 // Quick check: if the calling permission is me, it's all okay.
3607 if (Binder.getCallingPid() == Process.myPid()) {
3608 return true;
3609 }
Romain Guy06882f82009-06-10 13:36:04 -07003610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611 if (mContext.checkCallingPermission(permission)
3612 == PackageManager.PERMISSION_GRANTED) {
3613 return true;
3614 }
3615 String msg = "Permission Denial: " + func + " from pid="
3616 + Binder.getCallingPid()
3617 + ", uid=" + Binder.getCallingUid()
3618 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003619 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 return false;
3621 }
Craig Mautner9e809442012-06-22 17:13:04 -07003622
Craig Mautner2fb98b12012-03-20 17:24:00 -07003623 boolean okToDisplay() {
3624 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
3625 }
Romain Guy06882f82009-06-10 13:36:04 -07003626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003627 AppWindowToken findAppWindowToken(IBinder token) {
3628 WindowToken wtoken = mTokenMap.get(token);
3629 if (wtoken == null) {
3630 return null;
3631 }
3632 return wtoken.appWindowToken;
3633 }
Romain Guy06882f82009-06-10 13:36:04 -07003634
Craig Mautnercf8cbbe2012-03-25 21:54:36 -07003635 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003636 public void addWindowToken(IBinder token, int type) {
3637 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3638 "addWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003639 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640 }
Romain Guy06882f82009-06-10 13:36:04 -07003641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 synchronized(mWindowMap) {
3643 WindowToken wtoken = mTokenMap.get(token);
3644 if (wtoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003645 Slog.w(TAG, "Attempted to add existing input method token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 return;
3647 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003648 wtoken = new WindowToken(this, token, type, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 mTokenMap.put(token, wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003650 if (type == TYPE_WALLPAPER) {
3651 mWallpaperTokens.add(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003652 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 }
3655 }
Romain Guy06882f82009-06-10 13:36:04 -07003656
Craig Mautner9e809442012-06-22 17:13:04 -07003657 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 public void removeWindowToken(IBinder token) {
3659 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3660 "removeWindowToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003661 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 }
3663
3664 final long origId = Binder.clearCallingIdentity();
3665 synchronized(mWindowMap) {
3666 WindowToken wtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 if (wtoken != null) {
3668 boolean delayed = false;
3669 if (!wtoken.hidden) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 final int N = wtoken.windows.size();
3671 boolean changed = false;
Romain Guy06882f82009-06-10 13:36:04 -07003672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 for (int i=0; i<N; i++) {
3674 WindowState win = wtoken.windows.get(i);
3675
Craig Mautnera2c77052012-03-26 12:14:43 -07003676 if (win.mWinAnimator.isAnimating()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 delayed = true;
3678 }
Romain Guy06882f82009-06-10 13:36:04 -07003679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 if (win.isVisibleNow()) {
Craig Mautner59c00972012-07-30 12:10:24 -07003681 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
3682 false);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07003683 scheduleNotifyWindowTranstionIfNeededLocked(win,
3684 WindowManagerPolicy.TRANSIT_EXIT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07003686 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 }
3688 }
3689
Craig Mautner4b5aa782012-10-02 18:11:25 -07003690 wtoken.hidden = true;
3691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 if (changed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003693 performLayoutAndPlaceSurfacesLocked();
Jeff Brown3a22cd92011-01-21 13:59:04 -08003694 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3695 false /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 }
Romain Guy06882f82009-06-10 13:36:04 -07003697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003698 if (delayed) {
3699 mExitingTokens.add(wtoken);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07003700 } else if (wtoken.windowType == TYPE_WALLPAPER) {
3701 mWallpaperTokens.remove(wtoken);
Craig Mautner918b53b2012-07-09 14:15:54 -07003702 updateLayoutToAnimWallpaperTokens();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003703 }
3704 }
Romain Guy06882f82009-06-10 13:36:04 -07003705
Jeff Brown2e44b072011-01-24 15:21:56 -08003706 mInputMonitor.updateInputWindowsLw(true /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003708 Slog.w(TAG, "Attempted to remove non-existing token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 }
3710 }
3711 Binder.restoreCallingIdentity(origId);
3712 }
3713
Craig Mautneref25d7a2012-05-15 23:01:47 -07003714 /**
3715 * Find the location to insert a new AppWindowToken into the window-ordered app token list.
3716 * Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
3717 * @param addPos The location the token was inserted into in mAppTokens.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003718 * @param atoken The token to insert.
Craig Mautneref25d7a2012-05-15 23:01:47 -07003719 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003720 private void addAppTokenToAnimating(final int addPos, final AppWindowToken atoken) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07003721 if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
3722 // It was inserted into the beginning or end of mAppTokens. Honor that.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003723 mAnimatingAppTokens.add(addPos, atoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07003724 return;
3725 }
3726 // Find the item immediately above the mAppTokens insertion point and put the token
3727 // immediately below that one in mAnimatingAppTokens.
3728 final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003729 mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), atoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07003730 }
3731
3732 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 public void addAppToken(int addPos, IApplicationToken token,
Craig Mautner5962b122012-10-05 14:45:52 -07003734 int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3736 "addAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003737 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003738 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07003739
Jeff Brown349703e2010-06-22 01:27:15 -07003740 // Get the dispatching timeout here while we are not holding any locks so that it
3741 // can be cached by the AppWindowToken. The timeout value is used later by the
3742 // input dispatcher in code that does hold locks. If we did not cache the value
3743 // here we would run the chance of introducing a deadlock between the window manager
3744 // (which holds locks while updating the input dispatcher state) and the activity manager
3745 // (which holds locks while querying the application token).
3746 long inputDispatchingTimeoutNanos;
3747 try {
3748 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
3749 } catch (RemoteException ex) {
3750 Slog.w(TAG, "Could not get dispatching timeout.", ex);
3751 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3752 }
Romain Guy06882f82009-06-10 13:36:04 -07003753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003754 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003755 AppWindowToken atoken = findAppWindowToken(token.asBinder());
3756 if (atoken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003757 Slog.w(TAG, "Attempted to add existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 return;
3759 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003760 atoken = new AppWindowToken(this, token);
3761 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
3762 atoken.groupId = groupId;
3763 atoken.appFullscreen = fullscreen;
Craig Mautner5962b122012-10-05 14:45:52 -07003764 atoken.showWhenLocked = showWhenLocked;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003765 atoken.requestedOrientation = requestedOrientation;
3766 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
Craig Mautner06a94f72012-05-29 10:46:00 -07003767 + " at " + addPos);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003768 mAppTokens.add(addPos, atoken);
3769 addAppTokenToAnimating(addPos, atoken);
3770 mTokenMap.put(token.asBinder(), atoken);
Romain Guy06882f82009-06-10 13:36:04 -07003771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 // Application tokens start out hidden.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003773 atoken.hidden = true;
3774 atoken.hiddenRequested = true;
Romain Guy06882f82009-06-10 13:36:04 -07003775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 //dump();
3777 }
3778 }
Romain Guy06882f82009-06-10 13:36:04 -07003779
Craig Mautner9e809442012-06-22 17:13:04 -07003780 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003781 public void setAppGroupId(IBinder token, int groupId) {
3782 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07003783 "setAppGroupId()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003784 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785 }
3786
3787 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003788 AppWindowToken atoken = findAppWindowToken(token);
3789 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003790 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791 return;
3792 }
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003793 atoken.groupId = groupId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 }
3795 }
Romain Guy06882f82009-06-10 13:36:04 -07003796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 public int getOrientationFromWindowsLocked() {
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003798 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3799 // If the display is frozen, some activities may be in the middle
3800 // of restarting, and thus have removed their old window. If the
3801 // window has the flag to hide the lock screen, then the lock screen
3802 // can re-appear and inflict its own orientation on us. Keep the
3803 // orientation stable until this all settles down.
3804 return mLastWindowForcedOrientation;
3805 }
3806
Craig Mautner59c00972012-07-30 12:10:24 -07003807 // TODO(multidisplay): Change to the correct display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003808 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07003809 int pos = windows.size() - 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 while (pos >= 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07003811 WindowState wtoken = windows.get(pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 pos--;
3813 if (wtoken.mAppToken != null) {
3814 // We hit an application window. so the orientation will be determined by the
3815 // app window. No point in continuing further.
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003816 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003817 }
Christopher Tateb696aee2010-04-02 19:08:30 -07003818 if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003819 continue;
3820 }
3821 int req = wtoken.mAttrs.screenOrientation;
3822 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3823 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3824 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 }
Craig Mautner9e809442012-06-22 17:13:04 -07003826
3827 return (mLastWindowForcedOrientation=req);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003828 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003829 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 }
Romain Guy06882f82009-06-10 13:36:04 -07003831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003832 public int getOrientationFromAppTokensLocked() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003833 int curGroup = 0;
3834 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3835 boolean findingBehind = false;
3836 boolean haveGroup = false;
3837 boolean lastFullscreen = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07003838 for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003839 AppWindowToken atoken = mAppTokens.get(pos);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003840
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003841 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003842
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003843 // if we're about to tear down this window and not seek for
3844 // the behind activity, don't use it for orientation
3845 if (!findingBehind
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003846 && (!atoken.hidden && atoken.hiddenRequested)) {
3847 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003848 + " -- going to hide");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003849 continue;
3850 }
3851
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003852 if (haveGroup == true && curGroup != atoken.groupId) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003853 // If we have hit a new application group, and the bottom
3854 // of the previous group didn't explicitly say to use
3855 // the orientation behind it, and the last app was
3856 // full screen, then we'll stick with the
3857 // user's orientation.
3858 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3859 && lastFullscreen) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003860 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003861 + " -- end of group, return " + lastOrientation);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003862 return lastOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003863 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 }
p134510445bc62012-04-18 15:13:26 +09003865
3866 // We ignore any hidden applications on the top.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003867 if (atoken.hiddenRequested || atoken.willBeHidden) {
3868 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
p134510445bc62012-04-18 15:13:26 +09003869 + " -- hidden on top");
3870 continue;
3871 }
3872
3873 if (!haveGroup) {
3874 haveGroup = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003875 curGroup = atoken.groupId;
3876 lastOrientation = atoken.requestedOrientation;
Craig Mautner918b53b2012-07-09 14:15:54 -07003877 }
p134510445bc62012-04-18 15:13:26 +09003878
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003879 int or = atoken.requestedOrientation;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003880 // If this application is fullscreen, and didn't explicitly say
3881 // to use the orientation behind it, then just take whatever
3882 // orientation it has and ignores whatever is under it.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003883 lastFullscreen = atoken.appFullscreen;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003884 if (lastFullscreen
3885 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003886 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003887 + " -- full screen, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003888 return or;
3889 }
3890 // If this application has requested an explicit orientation,
3891 // then use it.
Dianne Hackborne5439f22010-10-02 16:53:50 -07003892 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3893 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003894 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003895 + " -- explicitly set, return " + or);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003896 return or;
3897 }
3898 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3899 }
Dianne Hackbornbc7386c2011-06-06 17:27:54 -07003900 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003901 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 }
Romain Guy06882f82009-06-10 13:36:04 -07003903
Craig Mautner711f90a2012-07-03 18:43:52 -07003904 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 public Configuration updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07003906 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07003907 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3908 "updateOrientationFromAppTokens()")) {
3909 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3910 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08003911
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003912 Configuration config = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 long ident = Binder.clearCallingIdentity();
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003914
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003915 synchronized(mWindowMap) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003916 config = updateOrientationFromAppTokensLocked(currentConfig,
3917 freezeThisOneIfNeeded);
3918 }
3919
3920 Binder.restoreCallingIdentity(ident);
3921 return config;
3922 }
3923
3924 private Configuration updateOrientationFromAppTokensLocked(
3925 Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3926 Configuration config = null;
3927
3928 if (updateOrientationFromAppTokensLocked(false)) {
3929 if (freezeThisOneIfNeeded != null) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003930 AppWindowToken atoken = findAppWindowToken(
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003931 freezeThisOneIfNeeded);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003932 if (atoken != null) {
3933 startAppFreezingScreenLocked(atoken,
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003934 ActivityInfo.CONFIG_ORIENTATION);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003935 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003936 }
3937 config = computeNewConfigurationLocked();
3938
3939 } else if (currentConfig != null) {
3940 // No obvious action we need to take, but if our current
3941 // state mismatches the activity manager's, update it,
3942 // disregarding font scale, which should remain set to
3943 // the value of the previous configuration.
3944 mTempConfiguration.setToDefaults();
3945 mTempConfiguration.fontScale = currentConfig.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08003946 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003947 if (currentConfig.diff(mTempConfiguration) != 0) {
3948 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07003949 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07003950 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07003951 config = new Configuration(mTempConfiguration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003952 }
3953 }
3954 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003955
Dianne Hackborncfaef692009-06-15 14:24:44 -07003956 return config;
3957 }
3958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 /*
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003960 * Determine the new desired orientation of the display, returning
3961 * a non-null new Configuration if it has changed from the current
3962 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
3963 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3964 * SCREEN. This will typically be done for you if you call
3965 * sendNewConfiguration().
Craig Mautnerb47bbc32012-08-22 17:41:48 -07003966 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 * The orientation is computed from non-application windows first. If none of
3968 * the non-application windows specify orientation, the orientation is computed from
Romain Guy06882f82009-06-10 13:36:04 -07003969 * application tokens.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3971 * android.os.IBinder)
3972 */
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08003973 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003974 long ident = Binder.clearCallingIdentity();
3975 try {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003976 int req = computeForcedAppOrientationLocked();
Romain Guy06882f82009-06-10 13:36:04 -07003977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 if (req != mForcedAppOrientation) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003979 mForcedAppOrientation = req;
3980 //send a message to Policy indicating orientation change to take
3981 //action like disabling/enabling sensors etc.,
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003982 mPolicy.setCurrentOrientationLw(req);
Jeff Brown01a98dd2011-09-20 15:08:29 -07003983 if (updateRotationUncheckedLocked(inTransaction)) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003984 // changed
3985 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003986 }
3987 }
The Android Open Source Project10592532009-03-18 17:39:46 -07003988
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003989 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 } finally {
3991 Binder.restoreCallingIdentity(ident);
3992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 }
Romain Guy06882f82009-06-10 13:36:04 -07003994
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07003995 int computeForcedAppOrientationLocked() {
3996 int req = getOrientationFromWindowsLocked();
3997 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3998 req = getOrientationFromAppTokensLocked();
3999 }
4000 return req;
4001 }
Romain Guy06882f82009-06-10 13:36:04 -07004002
Craig Mautner918b53b2012-07-09 14:15:54 -07004003 @Override
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004004 public void setNewConfiguration(Configuration config) {
4005 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4006 "setNewConfiguration()")) {
4007 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
4008 }
4009
4010 synchronized(mWindowMap) {
4011 mCurConfiguration = new Configuration(config);
4012 mWaitingForConfig = false;
4013 performLayoutAndPlaceSurfacesLocked();
4014 }
4015 }
Craig Mautner918b53b2012-07-09 14:15:54 -07004016
4017 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
4019 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4020 "setAppOrientation()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004021 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004022 }
Romain Guy06882f82009-06-10 13:36:04 -07004023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004025 AppWindowToken atoken = findAppWindowToken(token.asBinder());
4026 if (atoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004027 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 return;
4029 }
Romain Guy06882f82009-06-10 13:36:04 -07004030
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004031 atoken.requestedOrientation = requestedOrientation;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 }
4033 }
Romain Guy06882f82009-06-10 13:36:04 -07004034
Craig Mautner76a71652012-09-03 23:23:58 -07004035 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004036 public int getAppOrientation(IApplicationToken token) {
4037 synchronized(mWindowMap) {
4038 AppWindowToken wtoken = findAppWindowToken(token.asBinder());
4039 if (wtoken == null) {
4040 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4041 }
Romain Guy06882f82009-06-10 13:36:04 -07004042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004043 return wtoken.requestedOrientation;
4044 }
4045 }
Romain Guy06882f82009-06-10 13:36:04 -07004046
Craig Mautner76a71652012-09-03 23:23:58 -07004047 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004048 public void setFocusedApp(IBinder token, boolean moveFocusNow) {
4049 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4050 "setFocusedApp()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004051 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 }
4053
4054 synchronized(mWindowMap) {
4055 boolean changed = false;
4056 if (token == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004057 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 changed = mFocusedApp != null;
4059 mFocusedApp = null;
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004060 if (changed) {
4061 mInputMonitor.setFocusedAppLw(null);
Jeff Brown349703e2010-06-22 01:27:15 -07004062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 } else {
4064 AppWindowToken newFocus = findAppWindowToken(token);
4065 if (newFocus == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004066 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 return;
4068 }
4069 changed = mFocusedApp != newFocus;
4070 mFocusedApp = newFocus;
Craig Mautner812d2ca2012-09-27 15:35:34 -07004071 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp
4072 + " moveFocusNow=" + moveFocusNow);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004073 if (changed) {
4074 mInputMonitor.setFocusedAppLw(newFocus);
Jeff Brown349703e2010-06-22 01:27:15 -07004075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 }
4077
4078 if (moveFocusNow && changed) {
4079 final long origId = Binder.clearCallingIdentity();
Jeff Brown3a22cd92011-01-21 13:59:04 -08004080 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004081 Binder.restoreCallingIdentity(origId);
4082 }
4083 }
4084 }
4085
Craig Mautner76a71652012-09-03 23:23:58 -07004086 @Override
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08004087 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004088 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4089 "prepareAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004090 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 }
Romain Guy06882f82009-06-10 13:36:04 -07004092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004094 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004095 TAG, "Prepare app transition: transit=" + transit
Craig Mautner0afddcb2012-05-08 15:38:00 -07004096 + " mNextAppTransition=" + mNextAppTransition
Craig Mautner1d961d42012-05-27 12:02:11 -07004097 + " alwaysKeepCurrent=" + alwaysKeepCurrent
Craig Mautneref25d7a2012-05-15 23:01:47 -07004098 + " Callers=" + Debug.getCallers(3));
Craig Mautner2fb98b12012-03-20 17:24:00 -07004099 if (okToDisplay()) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004100 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
4101 || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 mNextAppTransition = transit;
Dianne Hackborn7da6ac32010-12-09 19:22:04 -08004103 } else if (!alwaysKeepCurrent) {
4104 if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
4105 && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
4106 // Opening a new task always supersedes a close for the anim.
4107 mNextAppTransition = transit;
4108 } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
4109 && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
4110 // Opening a new activity always supersedes a close for the anim.
4111 mNextAppTransition = transit;
4112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004113 }
4114 mAppTransitionReady = false;
4115 mAppTransitionTimeout = false;
4116 mStartingIconInTransition = false;
4117 mSkipAppTransitionAnimation = false;
4118 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
4119 mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
4120 5000);
4121 }
4122 }
4123 }
4124
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004125 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 public int getPendingAppTransition() {
4127 return mNextAppTransition;
4128 }
Romain Guy06882f82009-06-10 13:36:04 -07004129
Dianne Hackborn84375872012-06-01 19:03:50 -07004130 private void scheduleAnimationCallback(IRemoteCallback cb) {
4131 if (cb != null) {
4132 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, cb));
4133 }
4134 }
4135
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004136 @Override
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004137 public void overridePendingAppTransition(String packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07004138 int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
4139 synchronized(mWindowMap) {
4140 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
4141 mNextAppTransitionType = ActivityOptions.ANIM_CUSTOM;
4142 mNextAppTransitionPackage = packageName;
4143 mNextAppTransitionThumbnail = null;
4144 mNextAppTransitionEnter = enterAnim;
4145 mNextAppTransitionExit = exitAnim;
4146 scheduleAnimationCallback(mNextAppTransitionCallback);
4147 mNextAppTransitionCallback = startedCallback;
4148 } else {
4149 scheduleAnimationCallback(startedCallback);
4150 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004151 }
4152 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004153
Craig Mautnera91f9e22012-09-14 16:22:08 -07004154 @Override
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07004155 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
4156 int startHeight) {
Dianne Hackborn84375872012-06-01 19:03:50 -07004157 synchronized(mWindowMap) {
4158 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
4159 mNextAppTransitionType = ActivityOptions.ANIM_SCALE_UP;
4160 mNextAppTransitionPackage = null;
4161 mNextAppTransitionThumbnail = null;
4162 mNextAppTransitionStartX = startX;
4163 mNextAppTransitionStartY = startY;
4164 mNextAppTransitionStartWidth = startWidth;
4165 mNextAppTransitionStartHeight = startHeight;
4166 scheduleAnimationCallback(mNextAppTransitionCallback);
4167 mNextAppTransitionCallback = null;
4168 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07004169 }
4170 }
4171
Craig Mautnera91f9e22012-09-14 16:22:08 -07004172 @Override
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004173 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
Michael Jurka832cb222012-04-13 09:32:47 -07004174 int startY, IRemoteCallback startedCallback, boolean scaleUp) {
Dianne Hackborn84375872012-06-01 19:03:50 -07004175 synchronized(mWindowMap) {
4176 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Michael Jurka832cb222012-04-13 09:32:47 -07004177 mNextAppTransitionType = scaleUp
4178 ? ActivityOptions.ANIM_THUMBNAIL_SCALE_UP : ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
Dianne Hackborn84375872012-06-01 19:03:50 -07004179 mNextAppTransitionPackage = null;
4180 mNextAppTransitionThumbnail = srcThumb;
Michael Jurka832cb222012-04-13 09:32:47 -07004181 mNextAppTransitionScaleUp = scaleUp;
Dianne Hackborn84375872012-06-01 19:03:50 -07004182 mNextAppTransitionStartX = startX;
4183 mNextAppTransitionStartY = startY;
4184 scheduleAnimationCallback(mNextAppTransitionCallback);
4185 mNextAppTransitionCallback = startedCallback;
4186 } else {
4187 scheduleAnimationCallback(startedCallback);
4188 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004189 }
4190 }
4191
Craig Mautnera91f9e22012-09-14 16:22:08 -07004192 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 public void executeAppTransition() {
4194 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4195 "executeAppTransition()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004196 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 }
Romain Guy06882f82009-06-10 13:36:04 -07004198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 synchronized(mWindowMap) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004200 if (DEBUG_APP_TRANSITIONS) {
4201 RuntimeException e = new RuntimeException("here");
4202 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004203 Slog.w(TAG, "Execute app transition: mNextAppTransition="
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07004204 + mNextAppTransition, e);
4205 }
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004206 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 mAppTransitionReady = true;
4208 final long origId = Binder.clearCallingIdentity();
4209 performLayoutAndPlaceSurfacesLocked();
4210 Binder.restoreCallingIdentity(origId);
4211 }
4212 }
4213 }
4214
Craig Mautnere6f7d5052012-10-08 10:34:17 -07004215 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 public void setAppStartingWindow(IBinder token, String pkg,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004217 int theme, CompatibilityInfo compatInfo,
4218 CharSequence nonLocalizedLabel, int labelRes, int icon,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004219 int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner6fbda632012-07-03 09:26:39 -07004221 "setAppStartingWindow()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004222 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004223 }
4224
4225 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004226 if (DEBUG_STARTING_WINDOW) Slog.v(
Craig Mautner8863cca2012-09-18 15:04:34 -07004227 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 + " transferFrom=" + transferFrom);
Romain Guy06882f82009-06-10 13:36:04 -07004229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004230 AppWindowToken wtoken = findAppWindowToken(token);
4231 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004232 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004233 return;
4234 }
4235
4236 // If the display is frozen, we won't do anything until the
4237 // actual window is displayed so there is no reason to put in
4238 // the starting window.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004239 if (!okToDisplay()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 return;
4241 }
Romain Guy06882f82009-06-10 13:36:04 -07004242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004243 if (wtoken.startingData != null) {
4244 return;
4245 }
Romain Guy06882f82009-06-10 13:36:04 -07004246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004247 if (transferFrom != null) {
4248 AppWindowToken ttoken = findAppWindowToken(transferFrom);
4249 if (ttoken != null) {
4250 WindowState startingWindow = ttoken.startingWindow;
4251 if (startingWindow != null) {
4252 if (mStartingIconInTransition) {
4253 // In this case, the starting icon has already
4254 // been displayed, so start letting windows get
4255 // shown immediately without any more transitions.
4256 mSkipAppTransitionAnimation = true;
4257 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004258 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07004259 "Moving existing starting " + startingWindow + " from " + ttoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004260 + " to " + wtoken);
4261 final long origId = Binder.clearCallingIdentity();
Romain Guy06882f82009-06-10 13:36:04 -07004262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004263 // Transfer the starting window over to the new
4264 // token.
4265 wtoken.startingData = ttoken.startingData;
4266 wtoken.startingView = ttoken.startingView;
Craig Mautnerf4120952012-06-21 18:25:39 -07004267 wtoken.startingDisplayed = ttoken.startingDisplayed;
Craig Mautner8863cca2012-09-18 15:04:34 -07004268 ttoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 wtoken.startingWindow = startingWindow;
Craig Mautnerf4120952012-06-21 18:25:39 -07004270 wtoken.reportedVisible = ttoken.reportedVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004271 ttoken.startingData = null;
4272 ttoken.startingView = null;
4273 ttoken.startingWindow = null;
4274 ttoken.startingMoved = true;
4275 startingWindow.mToken = wtoken;
Dianne Hackbornef49c572009-03-24 19:27:32 -07004276 startingWindow.mRootToken = wtoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 startingWindow.mAppToken = wtoken;
Craig Mautner8863cca2012-09-18 15:04:34 -07004278 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
4279
Craig Mautner6fbda632012-07-03 09:26:39 -07004280 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
4281 Slog.v(TAG, "Removing starting window: " + startingWindow);
4282 }
Craig Mautner59c00972012-07-30 12:10:24 -07004283 startingWindow.getWindowList().remove(startingWindow);
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004284 mWindowsChanged = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07004285 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
4286 "Removing starting " + startingWindow + " from " + ttoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004287 ttoken.windows.remove(startingWindow);
4288 ttoken.allAppWindows.remove(startingWindow);
4289 addWindowToListInOrderLocked(startingWindow, true);
Romain Guy06882f82009-06-10 13:36:04 -07004290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 // Propagate other interesting state between the
4292 // tokens. If the old token is displayed, we should
4293 // immediately force the new one to be displayed. If
4294 // it is animating, we need to move that animation to
4295 // the new one.
4296 if (ttoken.allDrawn) {
4297 wtoken.allDrawn = true;
4298 }
4299 if (ttoken.firstWindowDrawn) {
4300 wtoken.firstWindowDrawn = true;
4301 }
4302 if (!ttoken.hidden) {
4303 wtoken.hidden = false;
4304 wtoken.hiddenRequested = false;
4305 wtoken.willBeHidden = false;
4306 }
4307 if (wtoken.clientHidden != ttoken.clientHidden) {
4308 wtoken.clientHidden = ttoken.clientHidden;
4309 wtoken.sendAppVisibilityToClients();
4310 }
Craig Mautner59431632012-04-04 11:56:44 -07004311 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4312 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4313 if (tAppAnimator.animation != null) {
4314 wAppAnimator.animation = tAppAnimator.animation;
4315 wAppAnimator.animating = tAppAnimator.animating;
4316 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4317 tAppAnimator.animation = null;
4318 tAppAnimator.animLayerAdjustment = 0;
4319 wAppAnimator.updateLayers();
4320 tAppAnimator.updateLayers();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 }
Romain Guy06882f82009-06-10 13:36:04 -07004322
Jeff Brown3a22cd92011-01-21 13:59:04 -08004323 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4324 true /*updateInputWindows*/);
Craig Mautner5c0e78c2012-09-12 16:45:36 -07004325 getDefaultDisplayContentLocked().layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 performLayoutAndPlaceSurfacesLocked();
4327 Binder.restoreCallingIdentity(origId);
4328 return;
4329 } else if (ttoken.startingData != null) {
4330 // The previous app was getting ready to show a
4331 // starting window, but hasn't yet done so. Steal it!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004332 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004333 "Moving pending starting from " + ttoken
4334 + " to " + wtoken);
4335 wtoken.startingData = ttoken.startingData;
4336 ttoken.startingData = null;
4337 ttoken.startingMoved = true;
4338 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4339 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4340 // want to process the message ASAP, before any other queued
4341 // messages.
4342 mH.sendMessageAtFrontOfQueue(m);
4343 return;
4344 }
Craig Mautner59431632012-04-04 11:56:44 -07004345 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4346 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4347 if (tAppAnimator.thumbnail != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004348 // The old token is animating with a thumbnail, transfer
4349 // that to the new token.
Craig Mautner59431632012-04-04 11:56:44 -07004350 if (wAppAnimator.thumbnail != null) {
4351 wAppAnimator.thumbnail.destroy();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004352 }
Craig Mautner59431632012-04-04 11:56:44 -07004353 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4354 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4355 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4356 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4357 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4358 tAppAnimator.thumbnail = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07004359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 }
4361 }
4362
4363 // There is no existing starting window, and the caller doesn't
4364 // want us to create one, so that's it!
4365 if (!createIfNeeded) {
4366 return;
4367 }
Romain Guy06882f82009-06-10 13:36:04 -07004368
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004369 // If this is a translucent window, then don't
Dianne Hackborn284ac932009-08-28 10:34:25 -07004370 // show a starting window -- the current effect (a full-screen
4371 // opaque starting window that fades away to the real contents
4372 // when it is ready) does not work for this.
Craig Mautner6fbda632012-07-03 09:26:39 -07004373 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4374 + Integer.toHexString(theme));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004375 if (theme != 0) {
4376 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
4377 com.android.internal.R.styleable.Window);
Dianne Hackborn0b800192012-06-21 15:29:36 -07004378 if (ent == null) {
4379 // Whoops! App doesn't exist. Um. Okay. We'll just
4380 // pretend like we didn't see that.
4381 return;
4382 }
Craig Mautner6fbda632012-07-03 09:26:39 -07004383 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4384 + ent.array.getBoolean(
4385 com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4386 + " Floating="
4387 + ent.array.getBoolean(
4388 com.android.internal.R.styleable.Window_windowIsFloating, false)
4389 + " ShowWallpaper="
4390 + ent.array.getBoolean(
4391 com.android.internal.R.styleable.Window_windowShowWallpaper, false));
Dianne Hackborn284ac932009-08-28 10:34:25 -07004392 if (ent.array.getBoolean(
4393 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4394 return;
4395 }
4396 if (ent.array.getBoolean(
Dianne Hackborn6136b7e2009-09-18 01:53:49 -07004397 com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4398 return;
4399 }
4400 if (ent.array.getBoolean(
Dianne Hackborn284ac932009-08-28 10:34:25 -07004401 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004402 if (mWallpaperTarget == null) {
4403 // If this theme is requesting a wallpaper, and the wallpaper
4404 // is not curently visible, then this effectively serves as
4405 // an opaque window and our starting window transition animation
4406 // can still work. We just need to make sure the starting window
4407 // is also showing the wallpaper.
Craig Mautner65d11b32012-10-01 13:59:52 -07004408 windowFlags |= FLAG_SHOW_WALLPAPER;
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08004409 } else {
4410 return;
4411 }
Dianne Hackborn284ac932009-08-28 10:34:25 -07004412 }
4413 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004414
Craig Mautner6fbda632012-07-03 09:26:39 -07004415 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 mStartingIconInTransition = true;
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004417 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
Dianne Hackborn7eec10e2010-11-12 18:03:47 -08004418 labelRes, icon, windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4420 // Note: we really want to do sendMessageAtFrontOfQueue() because we
4421 // want to process the message ASAP, before any other queued
4422 // messages.
Craig Mautner6fbda632012-07-03 09:26:39 -07004423 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424 mH.sendMessageAtFrontOfQueue(m);
4425 }
4426 }
4427
4428 public void setAppWillBeHidden(IBinder token) {
4429 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4430 "setAppWillBeHidden()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004431 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004432 }
4433
4434 AppWindowToken wtoken;
4435
4436 synchronized(mWindowMap) {
4437 wtoken = findAppWindowToken(token);
4438 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004439 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 -08004440 return;
4441 }
4442 wtoken.willBeHidden = true;
4443 }
4444 }
Romain Guy06882f82009-06-10 13:36:04 -07004445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004447 boolean visible, int transit, boolean performLayout) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004448 boolean delayed = false;
4449
4450 if (wtoken.clientHidden == visible) {
4451 wtoken.clientHidden = !visible;
4452 wtoken.sendAppVisibilityToClients();
4453 }
Romain Guy06882f82009-06-10 13:36:04 -07004454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004455 wtoken.willBeHidden = false;
4456 if (wtoken.hidden == visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004457 boolean changed = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004458 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004459 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4460 + " performLayout=" + performLayout);
Romain Guy06882f82009-06-10 13:36:04 -07004461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004462 boolean runningAppAnimation = false;
Romain Guy06882f82009-06-10 13:36:04 -07004463
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004464 if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
Craig Mautnerfbf378c2012-04-23 17:24:21 -07004465 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -07004466 wtoken.mAppAnimator.animation = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004467 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004468 if (applyAnimationLocked(wtoken, lp, transit, visible)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 delayed = runningAppAnimation = true;
4470 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004471 WindowState window = wtoken.findMainWindow();
4472 if (window != null) {
4473 scheduleNotifyWindowTranstionIfNeededLocked(window, transit);
4474 }
Craig Mautnerf20588f2012-04-11 17:06:21 -07004475 changed = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 }
Romain Guy06882f82009-06-10 13:36:04 -07004477
Craig Mautnerf20588f2012-04-11 17:06:21 -07004478 final int N = wtoken.allAppWindows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 for (int i=0; i<N; i++) {
4480 WindowState win = wtoken.allAppWindows.get(i);
4481 if (win == wtoken.startingWindow) {
4482 continue;
4483 }
4484
Joe Onorato8a9b2202010-02-26 18:56:32 -08004485 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 //win.dump(" ");
4487 if (visible) {
4488 if (!win.isVisibleNow()) {
4489 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004490 win.mWinAnimator.applyAnimationLocked(
4491 WindowManagerPolicy.TRANSIT_ENTER, true);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004492 scheduleNotifyWindowTranstionIfNeededLocked(win,
4493 WindowManagerPolicy.TRANSIT_ENTER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 }
4495 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004496 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 }
4498 } else if (win.isVisibleNow()) {
4499 if (!runningAppAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07004500 win.mWinAnimator.applyAnimationLocked(
4501 WindowManagerPolicy.TRANSIT_EXIT, false);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07004502 scheduleNotifyWindowTranstionIfNeededLocked(win,
4503 WindowManagerPolicy.TRANSIT_EXIT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004505 changed = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004506 win.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 }
4508 }
4509
4510 wtoken.hidden = wtoken.hiddenRequested = !visible;
4511 if (!visible) {
4512 unsetAppFreezingScreenLocked(wtoken, true, true);
4513 } else {
4514 // If we are being set visible, and the starting window is
4515 // not yet displayed, then make sure it doesn't get displayed.
4516 WindowState swin = wtoken.startingWindow;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07004517 if (swin != null && !swin.isDrawnLw()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004518 swin.mPolicyVisibility = false;
4519 swin.mPolicyVisibilityAfterAnim = false;
4520 }
4521 }
Romain Guy06882f82009-06-10 13:36:04 -07004522
Joe Onorato8a9b2202010-02-26 18:56:32 -08004523 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004524 + ": hidden=" + wtoken.hidden + " hiddenRequested="
4525 + wtoken.hiddenRequested);
Romain Guy06882f82009-06-10 13:36:04 -07004526
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004527 if (changed) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004528 mInputMonitor.setUpdateInputWindowsNeededLw();
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004529 if (performLayout) {
Jeff Brown3a22cd92011-01-21 13:59:04 -08004530 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4531 false /*updateInputWindows*/);
Dianne Hackborn9b52a212009-12-11 14:51:35 -08004532 performLayoutAndPlaceSurfacesLocked();
4533 }
Jeff Brown2e44b072011-01-24 15:21:56 -08004534 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 }
4536 }
4537
Craig Mautner59431632012-04-04 11:56:44 -07004538 if (wtoken.mAppAnimator.animation != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 delayed = true;
4540 }
Romain Guy06882f82009-06-10 13:36:04 -07004541
Craig Mautnerf20588f2012-04-11 17:06:21 -07004542 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4543 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4544 delayed = true;
4545 }
4546 }
4547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004548 return delayed;
4549 }
4550
4551 public void setAppVisibility(IBinder token, boolean visible) {
4552 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4553 "setAppVisibility()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004554 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004555 }
4556
4557 AppWindowToken wtoken;
4558
4559 synchronized(mWindowMap) {
4560 wtoken = findAppWindowToken(token);
4561 if (wtoken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004562 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 return;
4564 }
4565
4566 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004567 RuntimeException e = null;
4568 if (!HIDE_STACK_CRAWLS) {
4569 e = new RuntimeException();
4570 e.fillInStackTrace();
4571 }
Craig Mautner0afddcb2012-05-08 15:38:00 -07004572 Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 + "): mNextAppTransition=" + mNextAppTransition
4574 + " hidden=" + wtoken.hidden
4575 + " hiddenRequested=" + wtoken.hiddenRequested, e);
4576 }
Romain Guy06882f82009-06-10 13:36:04 -07004577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 // If we are preparing an app transition, then delay changing
4579 // the visibility of this token until we execute that transition.
Craig Mautner2fb98b12012-03-20 17:24:00 -07004580 if (okToDisplay() && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 // Already in requested state, don't do anything more.
4582 if (wtoken.hiddenRequested != visible) {
4583 return;
4584 }
4585 wtoken.hiddenRequested = !visible;
Romain Guy06882f82009-06-10 13:36:04 -07004586
Craig Mautnerf4120952012-06-21 18:25:39 -07004587 if (!wtoken.startingDisplayed) {
Craig Mautner8863cca2012-09-18 15:04:34 -07004588 if (DEBUG_APP_TRANSITIONS) Slog.v(
4589 TAG, "Setting dummy animation on: " + wtoken);
Craig Mautnerf4120952012-06-21 18:25:39 -07004590 wtoken.mAppAnimator.setDummyAnimation();
4591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004592 mOpeningApps.remove(wtoken);
4593 mClosingApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004594 wtoken.waitingToShow = wtoken.waitingToHide = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 wtoken.inPendingTransaction = true;
4596 if (visible) {
4597 mOpeningApps.add(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 wtoken.startingMoved = false;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004599
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004600 // If the token is currently hidden (should be the
4601 // common case), then we need to set up to wait for
4602 // its windows to be ready.
4603 if (wtoken.hidden) {
4604 wtoken.allDrawn = false;
4605 wtoken.waitingToShow = true;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004606
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004607 if (wtoken.clientHidden) {
4608 // In the case where we are making an app visible
4609 // but holding off for a transition, we still need
4610 // to tell the client to make its windows visible so
4611 // they get drawn. Otherwise, we will wait on
4612 // performing the transition until all windows have
4613 // been drawn, they never will be, and we are sad.
4614 wtoken.clientHidden = false;
4615 wtoken.sendAppVisibilityToClients();
4616 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004617 }
4618 } else {
4619 mClosingApps.add(wtoken);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08004620
Dianne Hackborn195f6a02009-11-24 11:26:00 -08004621 // If the token is currently visible (should be the
4622 // common case), then set up to wait for it to be hidden.
4623 if (!wtoken.hidden) {
4624 wtoken.waitingToHide = true;
4625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 }
4627 return;
4628 }
Romain Guy06882f82009-06-10 13:36:04 -07004629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004630 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004631 setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004632 true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004633 wtoken.updateReportedVisibilityLocked();
4634 Binder.restoreCallingIdentity(origId);
4635 }
4636 }
4637
4638 void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4639 boolean unfreezeSurfaceNow, boolean force) {
Craig Mautner59431632012-04-04 11:56:44 -07004640 if (wtoken.mAppAnimator.freezingScreen) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004641 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 + " force=" + force);
4643 final int N = wtoken.allAppWindows.size();
4644 boolean unfrozeWindows = false;
4645 for (int i=0; i<N; i++) {
4646 WindowState w = wtoken.allAppWindows.get(i);
4647 if (w.mAppFreezing) {
4648 w.mAppFreezing = false;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07004649 if (w.mHasSurface && !w.mOrientationChanging) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07004650 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07004652 mInnerFields.mOrientationChangeComplete = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004653 }
4654 unfrozeWindows = true;
Craig Mautner19d59bc2012-09-04 11:15:56 -07004655 w.mDisplayContent.layoutNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 }
4657 }
4658 if (force || unfrozeWindows) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004659 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07004660 wtoken.mAppAnimator.freezingScreen = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 mAppsFreezingScreen--;
4662 }
4663 if (unfreezeSurfaceNow) {
4664 if (unfrozeWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004665 performLayoutAndPlaceSurfacesLocked();
4666 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004667 stopFreezingDisplayLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004668 }
4669 }
4670 }
Romain Guy06882f82009-06-10 13:36:04 -07004671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004672 public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4673 int configChanges) {
4674 if (DEBUG_ORIENTATION) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08004675 RuntimeException e = null;
4676 if (!HIDE_STACK_CRAWLS) {
4677 e = new RuntimeException();
4678 e.fillInStackTrace();
4679 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004680 Slog.i(TAG, "Set freezing of " + wtoken.appToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 + ": hidden=" + wtoken.hidden + " freezing="
Craig Mautner59431632012-04-04 11:56:44 -07004682 + wtoken.mAppAnimator.freezingScreen, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004683 }
4684 if (!wtoken.hiddenRequested) {
Craig Mautner59431632012-04-04 11:56:44 -07004685 if (!wtoken.mAppAnimator.freezingScreen) {
4686 wtoken.mAppAnimator.freezingScreen = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 mAppsFreezingScreen++;
4688 if (mAppsFreezingScreen == 1) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07004689 startFreezingDisplayLocked(false, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4691 mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
4692 5000);
4693 }
4694 }
4695 final int N = wtoken.allAppWindows.size();
4696 for (int i=0; i<N; i++) {
4697 WindowState w = wtoken.allAppWindows.get(i);
4698 w.mAppFreezing = true;
4699 }
4700 }
4701 }
Romain Guy06882f82009-06-10 13:36:04 -07004702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004703 public void startAppFreezingScreen(IBinder token, int configChanges) {
4704 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4705 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004706 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004707 }
4708
4709 synchronized(mWindowMap) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07004710 if (configChanges == 0 && okToDisplay()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004711 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 return;
4713 }
Romain Guy06882f82009-06-10 13:36:04 -07004714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 AppWindowToken wtoken = findAppWindowToken(token);
4716 if (wtoken == null || wtoken.appToken == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004717 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 return;
4719 }
4720 final long origId = Binder.clearCallingIdentity();
4721 startAppFreezingScreenLocked(wtoken, configChanges);
4722 Binder.restoreCallingIdentity(origId);
4723 }
4724 }
Romain Guy06882f82009-06-10 13:36:04 -07004725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004726 public void stopAppFreezingScreen(IBinder token, boolean force) {
4727 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4728 "setAppFreezingScreen()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004729 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004730 }
4731
4732 synchronized(mWindowMap) {
4733 AppWindowToken wtoken = findAppWindowToken(token);
4734 if (wtoken == null || wtoken.appToken == null) {
4735 return;
4736 }
4737 final long origId = Binder.clearCallingIdentity();
Joe Onorato8a9b2202010-02-26 18:56:32 -08004738 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
Craig Mautner59431632012-04-04 11:56:44 -07004739 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 unsetAppFreezingScreenLocked(wtoken, true, force);
4741 Binder.restoreCallingIdentity(origId);
4742 }
4743 }
Romain Guy06882f82009-06-10 13:36:04 -07004744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 public void removeAppToken(IBinder token) {
4746 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4747 "removeAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004748 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749 }
4750
4751 AppWindowToken wtoken = null;
4752 AppWindowToken startingToken = null;
4753 boolean delayed = false;
4754
4755 final long origId = Binder.clearCallingIdentity();
4756 synchronized(mWindowMap) {
4757 WindowToken basewtoken = mTokenMap.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004758 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004759 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004760 delayed = setTokenVisibilityLocked(wtoken, null, false,
Dianne Hackbornffb3d932011-05-17 17:44:51 -07004761 WindowManagerPolicy.TRANSIT_UNSET, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 wtoken.inPendingTransaction = false;
4763 mOpeningApps.remove(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004764 wtoken.waitingToShow = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004765 if (mClosingApps.contains(wtoken)) {
4766 delayed = true;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07004767 } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004768 mClosingApps.add(wtoken);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004769 wtoken.waitingToHide = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 delayed = true;
4771 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004772 if (DEBUG_APP_TRANSITIONS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 TAG, "Removing app " + wtoken + " delayed=" + delayed
Craig Mautner59431632012-04-04 11:56:44 -07004774 + " animation=" + wtoken.mAppAnimator.animation
4775 + " animating=" + wtoken.mAppAnimator.animating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 if (delayed) {
4777 // set the token aside because it has an active animation to be finished
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004778 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4779 "removeAppToken make exiting: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004780 mExitingAppTokens.add(wtoken);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004781 } else {
4782 // Make sure there is no animation running on this token,
4783 // so any windows associated with it will be removed as
4784 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07004785 wtoken.mAppAnimator.clearAnimation();
4786 wtoken.mAppAnimator.animating = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004787 }
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004788 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4789 "removeAppToken: " + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004790 mAppTokens.remove(wtoken);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004791 mAnimatingAppTokens.remove(wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792 wtoken.removed = true;
4793 if (wtoken.startingData != null) {
4794 startingToken = wtoken;
4795 }
4796 unsetAppFreezingScreenLocked(wtoken, true, true);
4797 if (mFocusedApp == wtoken) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004798 if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 mFocusedApp = null;
Jeff Brown3a22cd92011-01-21 13:59:04 -08004800 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Jeff Brown00fa7bd2010-07-02 15:37:36 -07004801 mInputMonitor.setFocusedAppLw(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 }
4803 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004804 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004805 }
Romain Guy06882f82009-06-10 13:36:04 -07004806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004807 if (!delayed && wtoken != null) {
4808 wtoken.updateReportedVisibilityLocked();
4809 }
4810 }
4811 Binder.restoreCallingIdentity(origId);
4812
4813 if (startingToken != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004814 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Schedule remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004815 + startingToken + ": app token removed");
4816 Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
4817 mH.sendMessage(m);
4818 }
4819 }
4820
4821 private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4822 final int NW = token.windows.size();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004823 if (NW > 0) {
4824 mWindowsChanged = true;
4825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004826 for (int i=0; i<NW; i++) {
4827 WindowState win = token.windows.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004828 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
Craig Mautner59c00972012-07-30 12:10:24 -07004829 win.getWindowList().remove(win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830 int j = win.mChildWindows.size();
4831 while (j > 0) {
4832 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004833 WindowState cwin = win.mChildWindows.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004834 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004835 "Tmp removing child window " + cwin);
Craig Mautner59c00972012-07-30 12:10:24 -07004836 cwin.getWindowList().remove(cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004837 }
4838 }
4839 return NW > 0;
4840 }
4841
4842 void dumpAppTokensLocked() {
4843 for (int i=mAppTokens.size()-1; i>=0; i--) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004844 Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004845 }
4846 }
Romain Guy06882f82009-06-10 13:36:04 -07004847
Craig Mautneref25d7a2012-05-15 23:01:47 -07004848 void dumpAnimatingAppTokensLocked() {
4849 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
4850 Slog.v(TAG, " #" + i + ": " + mAnimatingAppTokens.get(i).token);
4851 }
4852 }
4853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 void dumpWindowsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07004855 int i = 0;
4856 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
4857 while (iterator.hasNext()) {
4858 final WindowState w = iterator.next();
4859 Slog.v(TAG, " #" + i++ + ": " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860 }
4861 }
Romain Guy06882f82009-06-10 13:36:04 -07004862
Craig Mautner59c00972012-07-30 12:10:24 -07004863 private int findWindowOffsetLocked(WindowList windows, int tokenPos) {
4864 final int NW = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004865
Craig Mautneref25d7a2012-05-15 23:01:47 -07004866 if (tokenPos >= mAnimatingAppTokens.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004867 int i = NW;
4868 while (i > 0) {
4869 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07004870 WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004871 if (win.getAppToken() != null) {
4872 return i+1;
4873 }
4874 }
4875 }
4876
4877 while (tokenPos > 0) {
4878 // Find the first app token below the new position that has
4879 // a window displayed.
Craig Mautner59c00972012-07-30 12:10:24 -07004880 final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004881 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 + tokenPos + " -- " + wtoken.token);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004883 if (wtoken.sendingToBottom) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004884 if (DEBUG_REORDER) Slog.v(TAG,
Dianne Hackborna8f60182009-09-01 19:01:50 -07004885 "Skipping token -- currently sending to bottom");
4886 tokenPos--;
4887 continue;
4888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 int i = wtoken.windows.size();
4890 while (i > 0) {
4891 i--;
4892 WindowState win = wtoken.windows.get(i);
4893 int j = win.mChildWindows.size();
4894 while (j > 0) {
4895 j--;
Jeff Browne33348b2010-07-15 23:54:05 -07004896 WindowState cwin = win.mChildWindows.get(j);
Dianne Hackborna8f60182009-09-01 19:01:50 -07004897 if (cwin.mSubLayer >= 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004899 if (windows.get(pos) == cwin) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004900 if (DEBUG_REORDER) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901 "Found child win @" + (pos+1));
4902 return pos+1;
4903 }
4904 }
4905 }
4906 }
4907 for (int pos=NW-1; pos>=0; pos--) {
Craig Mautner59c00972012-07-30 12:10:24 -07004908 if (windows.get(pos) == win) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004909 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 return pos+1;
4911 }
4912 }
4913 }
4914 tokenPos--;
4915 }
4916
4917 return 0;
4918 }
4919
4920 private final int reAddWindowLocked(int index, WindowState win) {
Craig Mautner59c00972012-07-30 12:10:24 -07004921 final WindowList windows = win.getWindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 final int NCW = win.mChildWindows.size();
4923 boolean added = false;
4924 for (int j=0; j<NCW; j++) {
Jeff Browne33348b2010-07-15 23:54:05 -07004925 WindowState cwin = win.mChildWindows.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004926 if (!added && cwin.mSubLayer >= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004927 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004928 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004929 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004930 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004931 index++;
4932 added = true;
4933 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004934 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004935 + index + ": " + cwin);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004936 cwin.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004937 windows.add(index, cwin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 index++;
4939 }
4940 if (!added) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004941 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07004942 + index + ": " + win);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004943 win.mRebuilding = false;
Craig Mautner59c00972012-07-30 12:10:24 -07004944 windows.add(index, win);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 index++;
4946 }
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07004947 mWindowsChanged = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004948 return index;
4949 }
Romain Guy06882f82009-06-10 13:36:04 -07004950
Craig Mautner59c00972012-07-30 12:10:24 -07004951 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4952 WindowToken token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004953 final int NW = token.windows.size();
4954 for (int i=0; i<NW; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07004955 final WindowState win = token.windows.get(i);
4956 if (win.mDisplayContent == displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07004957 index = reAddWindowLocked(index, win);
Craig Mautner59c00972012-07-30 12:10:24 -07004958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 }
4960 return index;
4961 }
4962
4963 public void moveAppToken(int index, IBinder token) {
4964 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4965 "moveAppToken()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07004966 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004967 }
4968
4969 synchronized(mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004970 if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 if (DEBUG_REORDER) dumpAppTokensLocked();
4972 final AppWindowToken wtoken = findAppWindowToken(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07004973 final int oldIndex = mAppTokens.indexOf(wtoken);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004974 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
4975 "Start moving token " + wtoken + " initially at "
Craig Mautneref25d7a2012-05-15 23:01:47 -07004976 + oldIndex);
4977 if (oldIndex > index && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET
4978 && !mAppTransitionRunning) {
4979 // animation towards back has not started, copy old list for duration of animation.
4980 mAnimatingAppTokens.clear();
4981 mAnimatingAppTokens.addAll(mAppTokens);
4982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004983 if (wtoken == null || !mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004984 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985 + token + " (" + wtoken + ")");
4986 return;
4987 }
4988 mAppTokens.add(index, wtoken);
Joe Onorato8a9b2202010-02-26 18:56:32 -08004989 if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08004990 else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004991 if (DEBUG_REORDER) dumpAppTokensLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07004992 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET && !mAppTransitionRunning) {
4993 // Not animating, bring animating app list in line with mAppTokens.
4994 mAnimatingAppTokens.clear();
4995 mAnimatingAppTokens.addAll(mAppTokens);
Romain Guy06882f82009-06-10 13:36:04 -07004996
Craig Mautneref25d7a2012-05-15 23:01:47 -07004997 // Bring window ordering, window focus and input window in line with new app token
4998 final long origId = Binder.clearCallingIdentity();
4999 if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07005001 if (tmpRemoveAppWindowsLocked(wtoken)) {
5002 if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
5003 if (DEBUG_REORDER) dumpWindowsLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005004 DisplayContentsIterator iterator = new DisplayContentsIterator();
5005 while(iterator.hasNext()) {
5006 final DisplayContent displayContent = iterator.next();
5007 final WindowList windows = displayContent.getWindowList();
5008 final int pos = findWindowOffsetLocked(windows, index);
Craig Mautner19d59bc2012-09-04 11:15:56 -07005009 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
5010 if (pos != newPos) {
5011 displayContent.layoutNeeded = true;
5012 }
Craig Mautner59c00972012-07-30 12:10:24 -07005013 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07005014 if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
5015 if (DEBUG_REORDER) dumpWindowsLocked();
5016 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
5017 false /*updateInputWindows*/);
Craig Mautneref25d7a2012-05-15 23:01:47 -07005018 mInputMonitor.setUpdateInputWindowsNeededLw();
5019 performLayoutAndPlaceSurfacesLocked();
5020 mInputMonitor.updateInputWindowsLw(false /*force*/);
5021 }
5022 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 }
5025 }
5026
5027 private void removeAppTokensLocked(List<IBinder> tokens) {
5028 // XXX This should be done more efficiently!
5029 // (take advantage of the fact that both lists should be
5030 // ordered in the same way.)
5031 int N = tokens.size();
5032 for (int i=0; i<N; i++) {
5033 IBinder token = tokens.get(i);
5034 final AppWindowToken wtoken = findAppWindowToken(token);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005035 if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
5036 "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005037 if (!mAppTokens.remove(wtoken)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005038 Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005039 + token + " (" + wtoken + ")");
5040 i--;
5041 N--;
5042 }
5043 }
5044 }
5045
Dianne Hackborna8f60182009-09-01 19:01:50 -07005046 private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos,
5047 boolean updateFocusAndLayout) {
5048 // First remove all of the windows from the list.
5049 tmpRemoveAppWindowsLocked(wtoken);
5050
Dianne Hackborna8f60182009-09-01 19:01:50 -07005051 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07005052 DisplayContentsIterator iterator = new DisplayContentsIterator();
5053 while (iterator.hasNext()) {
5054 final DisplayContent displayContent = iterator.next();
5055 final WindowList windows = displayContent.getWindowList();
5056 final int pos = findWindowOffsetLocked(windows, tokenPos);
Craig Mautner19d59bc2012-09-04 11:15:56 -07005057 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
5058 if (pos != newPos) {
5059 displayContent.layoutNeeded = true;
5060 }
Craig Mautner59c00972012-07-30 12:10:24 -07005061
Craig Mautner4f67ba62012-08-02 11:23:00 -07005062 if (updateFocusAndLayout && !updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Craig Mautner59c00972012-07-30 12:10:24 -07005063 false /*updateInputWindows*/)) {
5064 assignLayersLocked(windows);
5065 }
5066 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07005067
5068 if (updateFocusAndLayout) {
Jeff Brown2e44b072011-01-24 15:21:56 -08005069 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07005070
5071 // Note that the above updateFocusedWindowLocked conditional used to sit here.
5072
Craig Mautneref25d7a2012-05-15 23:01:47 -07005073 if (!mInLayout) {
5074 performLayoutAndPlaceSurfacesLocked();
5075 }
Jeff Brown2e44b072011-01-24 15:21:56 -08005076 mInputMonitor.updateInputWindowsLw(false /*force*/);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005077 }
5078 }
5079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005080 private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
5081 // First remove all of the windows from the list.
5082 final int N = tokens.size();
5083 int i;
5084 for (i=0; i<N; i++) {
5085 WindowToken token = mTokenMap.get(tokens.get(i));
5086 if (token != null) {
5087 tmpRemoveAppWindowsLocked(token);
5088 }
5089 }
5090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 // And now add them back at the correct place.
Craig Mautner59c00972012-07-30 12:10:24 -07005092 DisplayContentsIterator iterator = new DisplayContentsIterator();
5093 while (iterator.hasNext()) {
5094 final DisplayContent displayContent = iterator.next();
5095 final WindowList windows = displayContent.getWindowList();
5096 // Where to start adding?
5097 int pos = findWindowOffsetLocked(windows, tokenPos);
5098 for (i=0; i<N; i++) {
5099 WindowToken token = mTokenMap.get(tokens.get(i));
5100 if (token != null) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07005101 final int newPos = reAddAppWindowsLocked(displayContent, pos, token);
5102 if (newPos != pos) {
5103 displayContent.layoutNeeded = true;
5104 }
5105 pos = newPos;
Craig Mautner59c00972012-07-30 12:10:24 -07005106 }
5107 }
5108 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
5109 false /*updateInputWindows*/)) {
5110 assignLayersLocked(windows);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005111 }
5112 }
5113
Jeff Brown2e44b072011-01-24 15:21:56 -08005114 mInputMonitor.setUpdateInputWindowsNeededLw();
Craig Mautner59c00972012-07-30 12:10:24 -07005115
Craig Mautner4f67ba62012-08-02 11:23:00 -07005116 // Note that the above updateFocusedWindowLocked used to sit here.
Craig Mautner59c00972012-07-30 12:10:24 -07005117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005118 performLayoutAndPlaceSurfacesLocked();
Jeff Brown2e44b072011-01-24 15:21:56 -08005119 mInputMonitor.updateInputWindowsLw(false /*force*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005120
5121 //dump();
5122 }
5123
5124 public void moveAppTokensToTop(List<IBinder> tokens) {
5125 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5126 "moveAppTokensToTop()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005127 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005128 }
5129
5130 final long origId = Binder.clearCallingIdentity();
5131 synchronized(mWindowMap) {
5132 removeAppTokensLocked(tokens);
5133 final int N = tokens.size();
5134 for (int i=0; i<N; i++) {
5135 AppWindowToken wt = findAppWindowToken(tokens.get(i));
5136 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005137 if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
5138 "Adding next to top: " + wt);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005139 mAppTokens.add(wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07005140 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07005141 wt.sendingToBottom = false;
Dianne Hackborna8f60182009-09-01 19:01:50 -07005142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005143 }
5144 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005145
Craig Mautner06a94f72012-05-29 10:46:00 -07005146 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005147 mAnimatingAppTokens.clear();
5148 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005149 moveAppWindowsLocked(tokens, mAppTokens.size());
5150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005151 }
5152 Binder.restoreCallingIdentity(origId);
5153 }
5154
Craig Mautneref25d7a2012-05-15 23:01:47 -07005155 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156 public void moveAppTokensToBottom(List<IBinder> tokens) {
5157 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
5158 "moveAppTokensToBottom()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005159 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005160 }
5161
5162 final long origId = Binder.clearCallingIdentity();
5163 synchronized(mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005164 final int N = tokens.size();
Craig Mautner06a94f72012-05-29 10:46:00 -07005165 if (N > 0 && !mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005166 // animating towards back, hang onto old list for duration of animation.
5167 mAnimatingAppTokens.clear();
5168 mAnimatingAppTokens.addAll(mAppTokens);
5169 }
5170 removeAppTokensLocked(tokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005171 int pos = 0;
5172 for (int i=0; i<N; i++) {
5173 AppWindowToken wt = findAppWindowToken(tokens.get(i));
5174 if (wt != null) {
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08005175 if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
5176 "Adding next to bottom: " + wt + " at " + pos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005177 mAppTokens.add(pos, wt);
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07005178 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Dianne Hackborna8f60182009-09-01 19:01:50 -07005179 wt.sendingToBottom = true;
5180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 pos++;
5182 }
5183 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005184
Craig Mautner06a94f72012-05-29 10:46:00 -07005185 if (!mAppTransitionRunning) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07005186 mAnimatingAppTokens.clear();
5187 mAnimatingAppTokens.addAll(mAppTokens);
Dianne Hackborna8f60182009-09-01 19:01:50 -07005188 moveAppWindowsLocked(tokens, 0);
5189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005190 }
5191 Binder.restoreCallingIdentity(origId);
5192 }
5193
5194 // -------------------------------------------------------------
5195 // Misc IWindowSession methods
5196 // -------------------------------------------------------------
Romain Guy06882f82009-06-10 13:36:04 -07005197
Craig Mautner5642a482012-08-23 12:16:53 -07005198 @Override
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07005199 public void startFreezingScreen(int exitAnim, int enterAnim) {
5200 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5201 "startFreezingScreen()")) {
5202 throw new SecurityException("Requires FREEZE_SCREEN permission");
5203 }
5204
5205 synchronized(mWindowMap) {
5206 if (!mClientFreezingScreen) {
5207 mClientFreezingScreen = true;
5208 final long origId = Binder.clearCallingIdentity();
5209 try {
5210 startFreezingDisplayLocked(false, exitAnim, enterAnim);
5211 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
5212 mH.sendMessageDelayed(mH.obtainMessage(H.CLIENT_FREEZE_TIMEOUT),
5213 5000);
5214 } finally {
5215 Binder.restoreCallingIdentity(origId);
5216 }
5217 }
5218 }
5219 }
5220
5221 @Override
5222 public void stopFreezingScreen() {
5223 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
5224 "stopFreezingScreen()")) {
5225 throw new SecurityException("Requires FREEZE_SCREEN permission");
5226 }
5227
5228 synchronized(mWindowMap) {
5229 if (mClientFreezingScreen) {
5230 mClientFreezingScreen = false;
5231 final long origId = Binder.clearCallingIdentity();
5232 try {
5233 stopFreezingDisplayLocked();
5234 } finally {
5235 Binder.restoreCallingIdentity(origId);
5236 }
5237 }
5238 }
5239 }
5240
5241 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 public void disableKeyguard(IBinder token, String tag) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005243 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 != PackageManager.PERMISSION_GRANTED) {
5245 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5246 }
Jim Millerd6b57052010-06-07 17:52:42 -07005247
Craig Mautner5642a482012-08-23 12:16:53 -07005248 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5249 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005250 }
5251
Craig Mautner5642a482012-08-23 12:16:53 -07005252 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005253 public void reenableKeyguard(IBinder token) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005254 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005255 != PackageManager.PERMISSION_GRANTED) {
5256 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005258
Craig Mautner5642a482012-08-23 12:16:53 -07005259 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5260 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 }
5262
5263 /**
5264 * @see android.app.KeyguardManager#exitKeyguardSecurely
5265 */
5266 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
Mike Lockwood733fdf32009-09-28 19:08:53 -04005267 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005268 != PackageManager.PERMISSION_GRANTED) {
5269 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5270 }
5271 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
5272 public void onKeyguardExitResult(boolean success) {
5273 try {
5274 callback.onKeyguardExitResult(success);
5275 } catch (RemoteException e) {
5276 // Client has died, we don't care.
5277 }
5278 }
5279 });
5280 }
5281
5282 public boolean inKeyguardRestrictedInputMode() {
5283 return mPolicy.inKeyguardRestrictedKeyInputMode();
5284 }
Romain Guy06882f82009-06-10 13:36:04 -07005285
Mike Lockwood520d8bc2011-02-18 13:23:13 -05005286 public boolean isKeyguardLocked() {
5287 return mPolicy.isKeyguardLocked();
5288 }
5289
5290 public boolean isKeyguardSecure() {
5291 return mPolicy.isKeyguardSecure();
5292 }
5293
Dianne Hackborn90c52de2011-09-23 12:57:44 -07005294 public void dismissKeyguard() {
5295 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5296 != PackageManager.PERMISSION_GRANTED) {
5297 throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5298 }
5299 synchronized(mWindowMap) {
5300 mPolicy.dismissKeyguardLw();
5301 }
5302 }
5303
Dianne Hackbornffa42482009-09-23 22:20:11 -07005304 public void closeSystemDialogs(String reason) {
5305 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07005306 final AllWindowsIterator iterator = new AllWindowsIterator();
5307 while (iterator.hasNext()) {
5308 final WindowState w = iterator.next();
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005309 if (w.mHasSurface) {
Dianne Hackbornffa42482009-09-23 22:20:11 -07005310 try {
5311 w.mClient.closeSystemDialogs(reason);
5312 } catch (RemoteException e) {
5313 }
5314 }
5315 }
5316 }
5317 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08005318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005319 static float fixScale(float scale) {
5320 if (scale < 0) scale = 0;
5321 else if (scale > 20) scale = 20;
5322 return Math.abs(scale);
5323 }
Romain Guy06882f82009-06-10 13:36:04 -07005324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005325 public void setAnimationScale(int which, float scale) {
5326 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5327 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005328 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005329 }
5330
5331 if (scale < 0) scale = 0;
5332 else if (scale > 20) scale = 20;
5333 scale = Math.abs(scale);
5334 switch (which) {
5335 case 0: mWindowAnimationScale = fixScale(scale); break;
5336 case 1: mTransitionAnimationScale = fixScale(scale); break;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005337 case 2: mAnimatorDurationScale = fixScale(scale); break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005338 }
Romain Guy06882f82009-06-10 13:36:04 -07005339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005340 // Persist setting
5341 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5342 }
Romain Guy06882f82009-06-10 13:36:04 -07005343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005344 public void setAnimationScales(float[] scales) {
5345 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5346 "setAnimationScale()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07005347 throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 }
5349
5350 if (scales != null) {
5351 if (scales.length >= 1) {
5352 mWindowAnimationScale = fixScale(scales[0]);
5353 }
5354 if (scales.length >= 2) {
5355 mTransitionAnimationScale = fixScale(scales[1]);
5356 }
Chet Haasec38fa1f2012-02-01 16:37:46 -08005357 if (scales.length >= 3) {
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005358 setAnimatorDurationScale(fixScale(scales[2]));
Chet Haasec38fa1f2012-02-01 16:37:46 -08005359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005360 }
Romain Guy06882f82009-06-10 13:36:04 -07005361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005362 // Persist setting
5363 mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
5364 }
Romain Guy06882f82009-06-10 13:36:04 -07005365
Jeff Brownff7e6ef2012-08-15 02:05:18 -07005366 private void setAnimatorDurationScale(float scale) {
5367 mAnimatorDurationScale = scale;
5368 ValueAnimator.setDurationScale(scale);
5369 }
5370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 public float getAnimationScale(int which) {
5372 switch (which) {
5373 case 0: return mWindowAnimationScale;
5374 case 1: return mTransitionAnimationScale;
Chet Haasec38fa1f2012-02-01 16:37:46 -08005375 case 2: return mAnimatorDurationScale;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 }
5377 return 0;
5378 }
Romain Guy06882f82009-06-10 13:36:04 -07005379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005380 public float[] getAnimationScales() {
Chet Haasec38fa1f2012-02-01 16:37:46 -08005381 return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5382 mAnimatorDurationScale };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005383 }
Romain Guy06882f82009-06-10 13:36:04 -07005384
Jeff Brownac143512012-04-05 18:57:33 -07005385 // Called by window manager policy. Not exposed externally.
5386 @Override
5387 public int getLidState() {
Jeff Brownc458ce92012-04-30 14:58:40 -07005388 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5389 InputManagerService.SW_LID);
Jeff Brownac143512012-04-05 18:57:33 -07005390 if (sw > 0) {
Jeff Brown27fd3422012-04-09 11:05:16 -07005391 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
Jeff Brownac143512012-04-05 18:57:33 -07005392 return LID_CLOSED;
Jeff Brown27fd3422012-04-09 11:05:16 -07005393 } else if (sw == 0) {
5394 // Switch state: AKEY_STATE_UP.
5395 return LID_OPEN;
Jeff Brownac143512012-04-05 18:57:33 -07005396 } else {
Jeff Brown27fd3422012-04-09 11:05:16 -07005397 // Switch state: AKEY_STATE_UNKNOWN.
Jeff Brownac143512012-04-05 18:57:33 -07005398 return LID_ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 }
Romain Guy06882f82009-06-10 13:36:04 -07005401
Jeff Brownac143512012-04-05 18:57:33 -07005402 // Called by window manager policy. Not exposed externally.
5403 @Override
Jeff Browna41ca772010-08-11 14:46:32 -07005404 public InputChannel monitorInput(String inputChannelName) {
Jeff Browna41ca772010-08-11 14:46:32 -07005405 return mInputManager.monitorInput(inputChannelName);
5406 }
5407
Jeff Brown7304c342012-05-11 18:42:42 -07005408 // Called by window manager policy. Not exposed externally.
5409 @Override
Jeff Browncf39bdf2012-05-18 14:41:19 -07005410 public void switchKeyboardLayout(int deviceId, int direction) {
5411 mInputManager.switchKeyboardLayout(deviceId, direction);
5412 }
5413
5414 // Called by window manager policy. Not exposed externally.
5415 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005416 public void shutdown(boolean confirm) {
5417 ShutdownThread.shutdown(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005418 }
5419
5420 // Called by window manager policy. Not exposed externally.
5421 @Override
Jeff Brown9a538ee2012-08-20 14:56:57 -07005422 public void rebootSafeMode(boolean confirm) {
5423 ShutdownThread.rebootSafeMode(mContext, confirm);
Jeff Brown7304c342012-05-11 18:42:42 -07005424 }
5425
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07005426 public void setInputFilter(IInputFilter filter) {
5427 if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
5428 throw new SecurityException("Requires FILTER_EVENTS permission");
5429 }
Jeff Brown0029c662011-03-30 02:25:18 -07005430 mInputManager.setInputFilter(filter);
5431 }
5432
Craig Mautnerf1b67412012-09-19 13:18:29 -07005433 public void setCurrentUser(final int newUserId) {
5434 synchronized (mWindowMap) {
5435 mCurrentUserId = newUserId;
5436 mPolicy.setCurrentUserLw(newUserId);
Craig Mautner88400d32012-09-30 12:35:45 -07005437
5438 // Hide windows that should not be seen by the new user.
5439 DisplayContentsIterator iterator = new DisplayContentsIterator();
5440 while (iterator.hasNext()) {
5441 final WindowList windows = iterator.next().getWindowList();
5442 for (int i = 0; i < windows.size(); i++) {
5443 final WindowState win = windows.get(i);
Craig Mautner5962b122012-10-05 14:45:52 -07005444 if (win.isHiddenFromUserLocked()) {
Craig Mautner88400d32012-09-30 12:35:45 -07005445 Slog.w(TAG, "current user violation " + newUserId + " hiding "
5446 + win + ", attrs=" + win.mAttrs.type + ", belonging to "
5447 + win.mOwnerUid);
5448 win.hideLw(false);
5449 }
5450 }
5451 }
5452 performLayoutAndPlaceSurfacesLocked();
Craig Mautnerf1b67412012-09-19 13:18:29 -07005453 }
5454 }
5455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 public void enableScreenAfterBoot() {
5457 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005458 if (DEBUG_BOOT) {
5459 RuntimeException here = new RuntimeException("here");
5460 here.fillInStackTrace();
5461 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5462 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5463 + " mShowingBootMessages=" + mShowingBootMessages
5464 + " mSystemBooted=" + mSystemBooted, here);
5465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 if (mSystemBooted) {
5467 return;
5468 }
5469 mSystemBooted = true;
Dianne Hackborn661cd522011-08-22 00:26:20 -07005470 hideBootMessagesLocked();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005471 // If the screen still doesn't come up after 30 seconds, give
5472 // up and turn it on.
5473 Message msg = mH.obtainMessage(H.BOOT_TIMEOUT);
5474 mH.sendMessageDelayed(msg, 30*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005475 }
Romain Guy06882f82009-06-10 13:36:04 -07005476
Dianne Hackbornba24e4d2011-09-01 11:17:06 -07005477 mPolicy.systemBooted();
5478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005479 performEnableScreen();
5480 }
Romain Guy06882f82009-06-10 13:36:04 -07005481
Dianne Hackborn661cd522011-08-22 00:26:20 -07005482 void enableScreenIfNeededLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005483 if (DEBUG_BOOT) {
5484 RuntimeException here = new RuntimeException("here");
5485 here.fillInStackTrace();
5486 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5487 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5488 + " mShowingBootMessages=" + mShowingBootMessages
5489 + " mSystemBooted=" + mSystemBooted, here);
5490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005491 if (mDisplayEnabled) {
5492 return;
5493 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005494 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 return;
5496 }
5497 mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
5498 }
Romain Guy06882f82009-06-10 13:36:04 -07005499
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005500 public void performBootTimeout() {
5501 synchronized(mWindowMap) {
Mike Lockwoodd747dc82011-09-13 16:28:22 -04005502 if (mDisplayEnabled || mHeadless) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005503 return;
5504 }
5505 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5506 mForceDisplayEnabled = true;
5507 }
5508 performEnableScreen();
5509 }
5510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005511 public void performEnableScreen() {
5512 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005513 if (DEBUG_BOOT) {
5514 RuntimeException here = new RuntimeException("here");
5515 here.fillInStackTrace();
5516 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5517 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5518 + " mShowingBootMessages=" + mShowingBootMessages
Jeff Brown780c46f2012-06-24 12:15:38 -07005519 + " mSystemBooted=" + mSystemBooted
5520 + " mOnlyCore=" + mOnlyCore, here);
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005521 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522 if (mDisplayEnabled) {
5523 return;
5524 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005525 if (!mSystemBooted && !mShowingBootMessages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005526 return;
5527 }
Romain Guy06882f82009-06-10 13:36:04 -07005528
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005529 if (!mForceDisplayEnabled) {
5530 // Don't enable the screen until all existing windows
5531 // have been drawn.
5532 boolean haveBootMsg = false;
5533 boolean haveApp = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005534 // if the wallpaper service is disabled on the device, we're never going to have
5535 // wallpaper, don't bother waiting for it
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005536 boolean haveWallpaper = false;
Justin Mattson4233f262012-04-09 18:23:16 -07005537 boolean wallpaperEnabled = mContext.getResources().getBoolean(
Jeff Brown780c46f2012-06-24 12:15:38 -07005538 com.android.internal.R.bool.config_enableWallpaperService)
5539 && !mOnlyCore;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005540 boolean haveKeyguard = true;
Craig Mautner59c00972012-07-30 12:10:24 -07005541 // TODO(multidisplay): Expand to all displays?
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005542 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07005543 final int N = windows.size();
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005544 for (int i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07005545 WindowState w = windows.get(i);
Craig Mautner65d11b32012-10-01 13:59:52 -07005546 if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005547 // Only if there is a keyguard attached to the window manager
5548 // will we consider ourselves as having a keyguard. If it
5549 // isn't attached, we don't know if it wants to be shown or
5550 // hidden. If it is attached, we will say we have a keyguard
5551 // if the window doesn't want to be visible, because in that
5552 // case it explicitly doesn't want to be shown so we should
5553 // not delay turning the screen on for it.
5554 boolean vis = w.mViewVisibility == View.VISIBLE
5555 && w.mPolicyVisibility;
5556 haveKeyguard = !vis;
5557 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005558 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5559 return;
5560 }
5561 if (w.isDrawnLw()) {
Craig Mautner65d11b32012-10-01 13:59:52 -07005562 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005563 haveBootMsg = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005564 } else if (w.mAttrs.type == TYPE_APPLICATION) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005565 haveApp = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005566 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005567 haveWallpaper = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07005568 } else if (w.mAttrs.type == TYPE_KEYGUARD) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005569 haveKeyguard = true;
5570 }
5571 }
5572 }
5573
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005574 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005575 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5576 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
Justin Mattson4233f262012-04-09 18:23:16 -07005577 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5578 + " haveKeyguard=" + haveKeyguard);
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07005579 }
5580
5581 // If we are turning on the screen to show the boot message,
5582 // don't do it until the boot message is actually displayed.
5583 if (!mSystemBooted && !haveBootMsg) {
5584 return;
5585 }
5586
5587 // If we are turning on the screen after the boot is completed
5588 // normally, don't do so until we have the application and
5589 // wallpaper.
Justin Mattson4233f262012-04-09 18:23:16 -07005590 if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5591 (wallpaperEnabled && !haveWallpaper))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 return;
5593 }
5594 }
Romain Guy06882f82009-06-10 13:36:04 -07005595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005596 mDisplayEnabled = true;
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005597 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005598 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005599 StringWriter sw = new StringWriter();
5600 PrintWriter pw = new PrintWriter(sw);
5601 this.dump(null, pw, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005602 Slog.i(TAG, sw.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005603 }
5604 try {
5605 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5606 if (surfaceFlinger != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005607 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005608 Parcel data = Parcel.obtain();
5609 data.writeInterfaceToken("android.ui.ISurfaceComposer");
Jeff Brownc042ee22012-05-08 13:03:42 -07005610 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005611 data, null, 0);
5612 data.recycle();
5613 }
5614 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005615 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005616 }
Jeff Brown08a746a2012-06-24 12:14:49 -07005617
5618 // Enable input dispatch.
5619 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005620 }
Romain Guy06882f82009-06-10 13:36:04 -07005621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 mPolicy.enableScreenAfterBoot();
Romain Guy06882f82009-06-10 13:36:04 -07005623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005624 // Make sure the last requested orientation has been applied.
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005625 updateRotationUnchecked(false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005626 }
Romain Guy06882f82009-06-10 13:36:04 -07005627
Dianne Hackborn661cd522011-08-22 00:26:20 -07005628 public void showBootMessage(final CharSequence msg, final boolean always) {
5629 boolean first = false;
5630 synchronized(mWindowMap) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005631 if (DEBUG_BOOT) {
5632 RuntimeException here = new RuntimeException("here");
5633 here.fillInStackTrace();
5634 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5635 + " mAllowBootMessages=" + mAllowBootMessages
5636 + " mShowingBootMessages=" + mShowingBootMessages
5637 + " mSystemBooted=" + mSystemBooted, here);
5638 }
Dianne Hackborn58f42a52011-10-10 13:46:34 -07005639 if (!mAllowBootMessages) {
5640 return;
5641 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005642 if (!mShowingBootMessages) {
5643 if (!always) {
5644 return;
5645 }
5646 first = true;
5647 }
5648 if (mSystemBooted) {
5649 return;
5650 }
5651 mShowingBootMessages = true;
5652 mPolicy.showBootMessage(msg, always);
5653 }
5654 if (first) {
5655 performEnableScreen();
5656 }
5657 }
5658
5659 public void hideBootMessagesLocked() {
Dianne Hackborn38cc8962011-10-13 11:33:55 -07005660 if (DEBUG_BOOT) {
5661 RuntimeException here = new RuntimeException("here");
5662 here.fillInStackTrace();
5663 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5664 + " mForceDisplayEnabled=" + mForceDisplayEnabled
5665 + " mShowingBootMessages=" + mShowingBootMessages
5666 + " mSystemBooted=" + mSystemBooted, here);
5667 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07005668 if (mShowingBootMessages) {
5669 mShowingBootMessages = false;
5670 mPolicy.hideBootMessages();
5671 }
5672 }
5673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 public void setInTouchMode(boolean mode) {
5675 synchronized(mWindowMap) {
5676 mInTouchMode = mode;
5677 }
5678 }
5679
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005680 // TODO: more accounting of which pid(s) turned it on, keep count,
5681 // only allow disables from pids which have count on, etc.
Craig Mautner0447a812012-05-22 16:01:31 -07005682 @Override
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005683 public void showStrictModeViolation(boolean on) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005684 if (mHeadless) return;
Chris Craik3198ef32012-10-10 14:52:30 -07005685 int pid = Binder.getCallingPid();
5686 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
Craig Mautner0447a812012-05-22 16:01:31 -07005687 }
Mike Lockwood3a74bd32011-08-12 13:55:22 -07005688
Chris Craik3198ef32012-10-10 14:52:30 -07005689 private void showStrictModeViolation(int arg, int pid) {
Craig Mautner0447a812012-05-22 16:01:31 -07005690 final boolean on = arg != 0;
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005691 synchronized(mWindowMap) {
5692 // Ignoring requests to enable the red border from clients
5693 // which aren't on screen. (e.g. Broadcast Receivers in
5694 // the background..)
5695 if (on) {
5696 boolean isVisible = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005697 final AllWindowsIterator iterator = new AllWindowsIterator();
5698 while (iterator.hasNext()) {
5699 final WindowState ws = iterator.next();
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005700 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5701 isVisible = true;
5702 break;
5703 }
5704 }
5705 if (!isVisible) {
5706 return;
5707 }
5708 }
5709
Dianne Hackborn36991742011-10-11 21:35:26 -07005710 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5711 ">>> OPEN TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005712 Surface.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005713 try {
Jeff Browne215f262012-09-10 16:01:14 -07005714 // TODO(multi-display): support multiple displays
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005715 if (mStrictModeFlash == null) {
Jeff Browne215f262012-09-10 16:01:14 -07005716 mStrictModeFlash = new StrictModeFlash(
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005717 getDefaultDisplayContentLocked().getDisplay(), mFxSession);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08005718 }
5719 mStrictModeFlash.setVisibility(on);
5720 } finally {
5721 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -07005722 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5723 "<<< CLOSE TRANSACTION showStrictModeViolation");
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005724 }
Brad Fitzpatrick68044332010-11-22 18:19:48 -08005725 }
5726 }
5727
Brad Fitzpatrickc1a968a2010-11-24 08:56:40 -08005728 public void setStrictModeVisualIndicatorPreference(String value) {
5729 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5730 }
5731
Jim Millere70d5062011-03-08 21:38:39 -08005732 /**
5733 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
5734 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5735 * of the target image.
5736 *
Craig Mautner59c00972012-07-30 12:10:24 -07005737 * @param displayId the Display to take a screenshot of.
Jim Millere70d5062011-03-08 21:38:39 -08005738 * @param width the width of the target bitmap
5739 * @param height the height of the target bitmap
5740 */
Craig Mautner2d5618c2012-10-18 13:55:47 -07005741 @Override
Craig Mautner59c00972012-07-30 12:10:24 -07005742 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005743 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5744 "screenshotApplications()")) {
5745 throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5746 }
5747
5748 Bitmap rawss;
5749
Dianne Hackbornd2835932010-12-13 16:28:46 -08005750 int maxLayer = 0;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005751 final Rect frame = new Rect();
5752
5753 float scale;
Jim Millere70d5062011-03-08 21:38:39 -08005754 int dw, dh;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005755 int rot;
5756
5757 synchronized(mWindowMap) {
5758 long ident = Binder.clearCallingIdentity();
5759
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005760 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07005761 if (displayContent == null) {
5762 return null;
5763 }
Craig Mautner59c00972012-07-30 12:10:24 -07005764 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5765 dw = displayInfo.logicalWidth;
5766 dh = displayInfo.logicalHeight;
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005767
Craig Mautner65d11b32012-10-01 13:59:52 -07005768 int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5769 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005770 aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5771
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005772 boolean isImeTarget = mInputMethodTarget != null
5773 && mInputMethodTarget.mAppToken != null
5774 && mInputMethodTarget.mAppToken.appToken != null
5775 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5776
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005777 // Figure out the part of the screen that is actually the app.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005778 boolean including = false;
Craig Mautner59c00972012-07-30 12:10:24 -07005779 final WindowList windows = displayContent.getWindowList();
5780 for (int i = windows.size() - 1; i >= 0; i--) {
5781 WindowState ws = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07005782 if (!ws.mHasSurface) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005783 continue;
5784 }
5785 if (ws.mLayer >= aboveAppLayer) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08005786 continue;
5787 }
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005788 // When we will skip windows: when we are not including
5789 // ones behind a window we didn't skip, and we are actually
5790 // taking a screenshot of a specific app.
5791 if (!including && appToken != null) {
5792 // Also, we can possibly skip this window if it is not
5793 // an IME target or the application for the screenshot
5794 // is not the current IME target.
5795 if (!ws.mIsImWindow || !isImeTarget) {
5796 // And finally, this window is of no interest if it
5797 // is not associated with the screenshot app.
5798 if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5799 continue;
5800 }
5801 }
5802 }
5803
5804 // We keep on including windows until we go past a full-screen
5805 // window.
5806 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
5807
Craig Mautner88165682012-05-31 14:25:31 -07005808 if (maxLayer < ws.mWinAnimator.mSurfaceLayer) {
5809 maxLayer = ws.mWinAnimator.mSurfaceLayer;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005810 }
Jim Miller2aded182011-03-08 15:32:42 -08005811
5812 // Don't include wallpaper in bounds calculation
5813 if (!ws.mIsWallpaper) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07005814 final Rect wf = ws.mFrame;
Jim Miller2aded182011-03-08 15:32:42 -08005815 final Rect cr = ws.mContentInsets;
5816 int left = wf.left + cr.left;
5817 int top = wf.top + cr.top;
5818 int right = wf.right - cr.right;
5819 int bottom = wf.bottom - cr.bottom;
5820 frame.union(left, top, right, bottom);
5821 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005822 }
5823 Binder.restoreCallingIdentity(ident);
5824
Dianne Hackborndd962ee2011-02-02 11:11:50 -08005825 // Constrain frame to the screen size.
5826 frame.intersect(0, 0, dw, dh);
Jim Millere70d5062011-03-08 21:38:39 -08005827
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005828 if (frame.isEmpty() || maxLayer == 0) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005829 return null;
5830 }
5831
5832 // The screenshot API does not apply the current screen rotation.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005833 rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005834 int fw = frame.width();
5835 int fh = frame.height();
5836
Jim Miller28637ba2011-07-06 19:57:05 -07005837 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5838 // of thumbnail is the same as the screen (in landscape) or square.
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005839 float targetWidthScale = width / (float) fw;
5840 float targetHeightScale = height / (float) fh;
Jim Miller28637ba2011-07-06 19:57:05 -07005841 if (dw <= dh) {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005842 scale = targetWidthScale;
5843 // If aspect of thumbnail is the same as the screen (in landscape),
5844 // select the slightly larger value so we fill the entire bitmap
5845 if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5846 scale = targetHeightScale;
5847 }
Jim Miller28637ba2011-07-06 19:57:05 -07005848 } else {
Michael Jurkabfd24ac2011-11-13 13:50:38 -08005849 scale = targetHeightScale;
5850 // If aspect of thumbnail is the same as the screen (in landscape),
5851 // select the slightly larger value so we fill the entire bitmap
5852 if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5853 scale = targetWidthScale;
5854 }
Jim Miller28637ba2011-07-06 19:57:05 -07005855 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005856
5857 // The screen shot will contain the entire screen.
Dianne Hackborn428ecb62011-01-26 14:53:23 -08005858 dw = (int)(dw*scale);
5859 dh = (int)(dh*scale);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005860 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5861 int tmp = dw;
5862 dw = dh;
5863 dh = tmp;
5864 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5865 }
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005866 if (DEBUG_SCREENSHOT) {
5867 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
Craig Mautner59c00972012-07-30 12:10:24 -07005868 for (int i = 0; i < windows.size(); i++) {
5869 WindowState win = windows.get(i);
5870 Slog.i(TAG, win + ": " + win.mLayer
5871 + " animLayer=" + win.mWinAnimator.mAnimLayer
5872 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
Dianne Hackborncfb9f2b2011-08-24 10:51:49 -07005873 }
5874 }
Dianne Hackbornd2835932010-12-13 16:28:46 -08005875 rawss = Surface.screenshot(dw, dh, 0, maxLayer);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005876 }
5877
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005878 if (rawss == null) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07005879 Slog.w(TAG, "Failure taking screenshot for (" + dw + "x" + dh
Dianne Hackborn88b03bd2010-12-16 11:15:18 -08005880 + ") to layer " + maxLayer);
Dianne Hackborncb8f0e02010-12-16 11:15:18 -08005881 return null;
5882 }
Jim Millere70d5062011-03-08 21:38:39 -08005883
5884 Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005885 Matrix matrix = new Matrix();
5886 ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
Michael Jurka4accb6a2012-03-26 09:18:46 -07005887 matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005888 Canvas canvas = new Canvas(bm);
5889 canvas.drawBitmap(rawss, matrix, null);
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07005890 canvas.setBitmap(null);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08005891
5892 rawss.recycle();
5893 return bm;
5894 }
5895
Jeff Brown01a98dd2011-09-20 15:08:29 -07005896 /**
5897 * Freeze rotation changes. (Enable "rotation lock".)
5898 * Persists across reboots.
Jeff Brown4dfce202011-10-05 12:00:10 -07005899 * @param rotation The desired rotation to freeze to, or -1 to use the
5900 * current rotation.
Jeff Brown01a98dd2011-09-20 15:08:29 -07005901 */
Jeff Brown4dfce202011-10-05 12:00:10 -07005902 public void freezeRotation(int rotation) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005903 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005904 "freezeRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005905 throw new SecurityException("Requires SET_ORIENTATION permission");
5906 }
Jeff Brown4dfce202011-10-05 12:00:10 -07005907 if (rotation < -1 || rotation > Surface.ROTATION_270) {
5908 throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5909 + "rotation constant.");
5910 }
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005911
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005912 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5913
Jeff Brown4dfce202011-10-05 12:00:10 -07005914 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5915 rotation == -1 ? mRotation : rotation);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005916 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005917 }
5918
Jeff Brown01a98dd2011-09-20 15:08:29 -07005919 /**
5920 * Thaw rotation changes. (Disable "rotation lock".)
5921 * Persists across reboots.
5922 */
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005923 public void thawRotation() {
5924 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005925 "thawRotation()")) {
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005926 throw new SecurityException("Requires SET_ORIENTATION permission");
5927 }
5928
Daniel Sandler2ed6ad62011-02-22 14:54:17 -05005929 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5930
5931 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005932 updateRotationUnchecked(false, false);
Daniel Sandlerb73617d2010-08-17 00:41:00 -04005933 }
5934
Jeff Brown01a98dd2011-09-20 15:08:29 -07005935 /**
5936 * Recalculate the current rotation.
5937 *
5938 * Called by the window manager policy whenever the state of the system changes
5939 * such that the current rotation might need to be updated, such as when the
5940 * device is docked or rotated into a new posture.
5941 */
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005942 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5943 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
Jeff Brown01a98dd2011-09-20 15:08:29 -07005944 }
5945
5946 /**
5947 * Temporarily pauses rotation changes until resumed.
5948 *
5949 * This can be used to prevent rotation changes from occurring while the user is
5950 * performing certain operations, such as drag and drop.
5951 *
5952 * This call nests and must be matched by an equal number of calls to {@link #resumeRotation}.
5953 */
5954 void pauseRotationLocked() {
5955 mDeferredRotationPauseCount += 1;
5956 }
5957
5958 /**
5959 * Resumes normal rotation changes after being paused.
5960 */
5961 void resumeRotationLocked() {
5962 if (mDeferredRotationPauseCount > 0) {
5963 mDeferredRotationPauseCount -= 1;
5964 if (mDeferredRotationPauseCount == 0) {
5965 boolean changed = updateRotationUncheckedLocked(false);
5966 if (changed) {
5967 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5968 }
5969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005970 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005971 }
Romain Guy06882f82009-06-10 13:36:04 -07005972
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005973 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005974 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5975 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
Romain Guy06882f82009-06-10 13:36:04 -07005976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005977 long origId = Binder.clearCallingIdentity();
5978 boolean changed;
5979 synchronized(mWindowMap) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07005980 changed = updateRotationUncheckedLocked(false);
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005981 if (!changed || forceRelayout) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07005982 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackbornf87d1962012-04-04 12:48:24 -07005983 performLayoutAndPlaceSurfacesLocked();
5984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005985 }
Romain Guy06882f82009-06-10 13:36:04 -07005986
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005987 if (changed || alwaysSendConfiguration) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005988 sendNewConfiguration();
5989 }
Romain Guy06882f82009-06-10 13:36:04 -07005990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005991 Binder.restoreCallingIdentity(origId);
5992 }
Romain Guy06882f82009-06-10 13:36:04 -07005993
Craig Mautner59c00972012-07-30 12:10:24 -07005994 // TODO(multidisplay): Rotate any display?
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005995 /**
Jeff Brown01a98dd2011-09-20 15:08:29 -07005996 * Updates the current rotation.
5997 *
5998 * Returns true if the rotation has been changed. In this case YOU
5999 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006000 */
Jeff Brown01a98dd2011-09-20 15:08:29 -07006001 public boolean updateRotationUncheckedLocked(boolean inTransaction) {
6002 if (mDeferredRotationPauseCount > 0) {
6003 // Rotation updates have been paused temporarily. Defer the update until
6004 // updates have been resumed.
6005 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
Christopher Tateccd24de2011-01-12 15:02:55 -08006006 return false;
6007 }
6008
Craig Mautnera91f9e22012-09-14 16:22:08 -07006009 ScreenRotationAnimation screenRotationAnimation =
6010 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
6011 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
Jeff Brown01a98dd2011-09-20 15:08:29 -07006012 // Rotation updates cannot be performed while the previous rotation change
6013 // animation is still in progress. Skip this update. We will try updating
6014 // again after the animation is finished and the display is unfrozen.
6015 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
6016 return false;
6017 }
6018
6019 if (!mDisplayEnabled) {
6020 // No point choosing a rotation if the display is not enabled.
6021 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
6022 return false;
6023 }
6024
6025 // TODO: Implement forced rotation changes.
6026 // Set mAltOrientation to indicate that the application is receiving
6027 // an orientation that has different metrics than it expected.
6028 // eg. Portrait instead of Landscape.
6029
6030 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
6031 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
6032 mForcedAppOrientation, rotation);
6033
6034 if (DEBUG_ORIENTATION) {
6035 Slog.v(TAG, "Application requested orientation "
6036 + mForcedAppOrientation + ", got rotation " + rotation
6037 + " which has " + (altOrientation ? "incompatible" : "compatible")
6038 + " metrics");
6039 }
6040
6041 if (mRotation == rotation && mAltOrientation == altOrientation) {
6042 // No change.
6043 return false;
6044 }
6045
6046 if (DEBUG_ORIENTATION) {
6047 Slog.v(TAG,
6048 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
6049 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
6050 + ", forceApp=" + mForcedAppOrientation);
6051 }
6052
6053 mRotation = rotation;
6054 mAltOrientation = altOrientation;
Jeff Brownc0347aa2011-09-23 17:26:09 -07006055 mPolicy.setRotationLw(mRotation);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006056
6057 mWindowsFreezingScreen = true;
6058 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
Craig Mautner7dfcb012012-10-10 10:24:47 -07006059 mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
6060 WINDOW_FREEZE_TIMEOUT_DURATION);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006061 mWaitingForConfig = true;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006062 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07006063 startFreezingDisplayLocked(inTransaction, 0, 0);
Craig Mautnera91f9e22012-09-14 16:22:08 -07006064 // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
6065 screenRotationAnimation =
6066 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006067
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006068 // We need to update our screen size information to match the new
6069 // rotation. Note that this is redundant with the later call to
6070 // sendNewConfiguration() that must be called after this function
6071 // returns... however we need to do the screen size part of that
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006072 // before then so we have the correct size to use when initializing
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006073 // the rotation animation for the new rotation.
6074 computeScreenConfigurationLocked(null);
6075
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006076 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006077 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006078 if (!inTransaction) {
6079 if (SHOW_TRANSACTIONS) {
6080 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
6081 }
6082 Surface.openTransaction();
6083 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006084 try {
6085 // NOTE: We disable the rotation in the emulator because
6086 // it doesn't support hardware OpenGL emulation yet.
Craig Mautnera91f9e22012-09-14 16:22:08 -07006087 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
6088 && screenRotationAnimation.hasScreenshot()) {
6089 if (screenRotationAnimation.setRotationInTransaction(
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006090 rotation, mFxSession,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006091 MAX_ANIMATION_DURATION, mTransitionAnimationScale,
Craig Mautner59c00972012-07-30 12:10:24 -07006092 displayInfo.logicalWidth, displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -07006093 updateLayoutToAnimationLocked();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006094 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006095 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006096
6097 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
Jamie Gennise2909e12011-10-10 15:48:06 -07006098 } finally {
6099 if (!inTransaction) {
6100 Surface.closeTransaction();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07006101 if (SHOW_LIGHT_TRANSACTIONS) {
6102 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
6103 }
Jamie Gennise2909e12011-10-10 15:48:06 -07006104 }
6105 }
6106
Craig Mautner59c00972012-07-30 12:10:24 -07006107 final WindowList windows = displayContent.getWindowList();
6108 for (int i = windows.size() - 1; i >= 0; i--) {
6109 WindowState w = windows.get(i);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07006110 if (w.mHasSurface) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07006111 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
Jeff Brown01a98dd2011-09-20 15:08:29 -07006112 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07006113 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006114 }
6115 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006116
Jeff Brown01a98dd2011-09-20 15:08:29 -07006117 for (int i=mRotationWatchers.size()-1; i>=0; i--) {
6118 try {
6119 mRotationWatchers.get(i).onRotationChanged(rotation);
6120 } catch (RemoteException e) {
6121 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006122 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006123
6124 scheduleNotifyRotationChangedIfNeededLocked(displayContent, rotation);
6125
Jeff Brown01a98dd2011-09-20 15:08:29 -07006126 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006127 }
Romain Guy06882f82009-06-10 13:36:04 -07006128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006129 public int getRotation() {
6130 return mRotation;
6131 }
6132
6133 public int watchRotation(IRotationWatcher watcher) {
6134 final IBinder watcherBinder = watcher.asBinder();
6135 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
6136 public void binderDied() {
6137 synchronized (mWindowMap) {
6138 for (int i=0; i<mRotationWatchers.size(); i++) {
6139 if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07006140 IRotationWatcher removed = mRotationWatchers.remove(i);
6141 if (removed != null) {
6142 removed.asBinder().unlinkToDeath(this, 0);
6143 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006144 i--;
6145 }
6146 }
6147 }
6148 }
6149 };
Romain Guy06882f82009-06-10 13:36:04 -07006150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 synchronized (mWindowMap) {
6152 try {
6153 watcher.asBinder().linkToDeath(dr, 0);
6154 mRotationWatchers.add(watcher);
6155 } catch (RemoteException e) {
6156 // Client died, no cleanup needed.
6157 }
Romain Guy06882f82009-06-10 13:36:04 -07006158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006159 return mRotation;
6160 }
6161 }
6162
6163 /**
Adam Powelldfee59a2011-08-05 20:48:30 -07006164 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
6165 * theme attribute) on devices that feature a physical options menu key attempt to position
6166 * their menu panel window along the edge of the screen nearest the physical menu key.
6167 * This lowers the travel distance between invoking the menu panel and selecting
6168 * a menu option.
6169 *
6170 * This method helps control where that menu is placed. Its current implementation makes
6171 * assumptions about the menu key and its relationship to the screen based on whether
6172 * the device's natural orientation is portrait (width < height) or landscape.
6173 *
6174 * The menu key is assumed to be located along the bottom edge of natural-portrait
6175 * devices and along the right edge of natural-landscape devices. If these assumptions
6176 * do not hold for the target device, this method should be changed to reflect that.
6177 *
6178 * @return A {@link Gravity} value for placing the options menu window
6179 */
6180 public int getPreferredOptionsPanelGravity() {
6181 synchronized (mWindowMap) {
6182 final int rotation = getRotation();
6183
Craig Mautner59c00972012-07-30 12:10:24 -07006184 // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006185 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006186 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
Adam Powelldfee59a2011-08-05 20:48:30 -07006187 // On devices with a natural orientation of portrait
6188 switch (rotation) {
6189 default:
6190 case Surface.ROTATION_0:
6191 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6192 case Surface.ROTATION_90:
Adam Powell67ed6c72011-08-28 13:21:56 -07006193 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006194 case Surface.ROTATION_180:
Adam Powell67ed6c72011-08-28 13:21:56 -07006195 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006196 case Surface.ROTATION_270:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006197 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006198 }
6199 } else {
6200 // On devices with a natural orientation of landscape
6201 switch (rotation) {
6202 default:
6203 case Surface.ROTATION_0:
Adam Powell67ed6c72011-08-28 13:21:56 -07006204 return Gravity.RIGHT | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006205 case Surface.ROTATION_90:
6206 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6207 case Surface.ROTATION_180:
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07006208 return Gravity.START | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006209 case Surface.ROTATION_270:
Adam Powell67ed6c72011-08-28 13:21:56 -07006210 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
Adam Powelldfee59a2011-08-05 20:48:30 -07006211 }
6212 }
6213 }
6214 }
6215
6216 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006217 * Starts the view server on the specified port.
6218 *
6219 * @param port The port to listener to.
6220 *
6221 * @return True if the server was successfully started, false otherwise.
6222 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006223 * @see com.android.server.wm.ViewServer
6224 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006225 */
6226 public boolean startViewServer(int port) {
Romain Guy06882f82009-06-10 13:36:04 -07006227 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006228 return false;
6229 }
6230
6231 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
6232 return false;
6233 }
6234
6235 if (port < 1024) {
6236 return false;
6237 }
6238
6239 if (mViewServer != null) {
6240 if (!mViewServer.isRunning()) {
6241 try {
6242 return mViewServer.start();
6243 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006244 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006245 }
6246 }
6247 return false;
6248 }
6249
6250 try {
6251 mViewServer = new ViewServer(this, port);
6252 return mViewServer.start();
6253 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006254 Slog.w(TAG, "View server did not start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 }
6256 return false;
6257 }
6258
Romain Guy06882f82009-06-10 13:36:04 -07006259 private boolean isSystemSecure() {
6260 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6261 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6262 }
6263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006264 /**
6265 * Stops the view server if it exists.
6266 *
6267 * @return True if the server stopped, false if it wasn't started or
6268 * couldn't be stopped.
6269 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006270 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006271 */
6272 public boolean stopViewServer() {
Romain Guy06882f82009-06-10 13:36:04 -07006273 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006274 return false;
6275 }
6276
6277 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6278 return false;
6279 }
6280
6281 if (mViewServer != null) {
6282 return mViewServer.stop();
6283 }
6284 return false;
6285 }
6286
6287 /**
6288 * Indicates whether the view server is running.
6289 *
6290 * @return True if the server is running, false otherwise.
6291 *
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08006292 * @see com.android.server.wm.ViewServer
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006293 */
6294 public boolean isViewServerRunning() {
Romain Guy06882f82009-06-10 13:36:04 -07006295 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 return false;
6297 }
6298
6299 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6300 return false;
6301 }
6302
6303 return mViewServer != null && mViewServer.isRunning();
6304 }
6305
6306 /**
6307 * Lists all availble windows in the system. The listing is written in the
6308 * specified Socket's output stream with the following syntax:
6309 * windowHashCodeInHexadecimal windowName
6310 * Each line of the ouput represents a different window.
6311 *
6312 * @param client The remote client to send the listing to.
6313 * @return False if an error occured, true otherwise.
6314 */
6315 boolean viewServerListWindows(Socket client) {
Romain Guy06882f82009-06-10 13:36:04 -07006316 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 return false;
6318 }
6319
6320 boolean result = true;
6321
Craig Mautner59c00972012-07-30 12:10:24 -07006322 WindowList windows = new WindowList();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006323 synchronized (mWindowMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006324 //noinspection unchecked
Craig Mautner59c00972012-07-30 12:10:24 -07006325 DisplayContentsIterator iterator = new DisplayContentsIterator();
6326 while(iterator.hasNext()) {
6327 windows.addAll(iterator.next().getWindowList());
6328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006329 }
6330
6331 BufferedWriter out = null;
6332
6333 // Any uncaught exception will crash the system process
6334 try {
6335 OutputStream clientStream = client.getOutputStream();
6336 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6337
Craig Mautner59c00972012-07-30 12:10:24 -07006338 final int count = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 for (int i = 0; i < count; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07006340 final WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006341 out.write(Integer.toHexString(System.identityHashCode(w)));
6342 out.write(' ');
6343 out.append(w.mAttrs.getTitle());
6344 out.write('\n');
6345 }
6346
6347 out.write("DONE.\n");
6348 out.flush();
6349 } catch (Exception e) {
6350 result = false;
6351 } finally {
6352 if (out != null) {
6353 try {
6354 out.close();
6355 } catch (IOException e) {
6356 result = false;
6357 }
6358 }
6359 }
6360
6361 return result;
6362 }
6363
Craig Mautner59c00972012-07-30 12:10:24 -07006364 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006365 /**
Konstantin Lopyrevf9624762010-07-14 17:02:37 -07006366 * Returns the focused window in the following format:
6367 * windowHashCodeInHexadecimal windowName
6368 *
6369 * @param client The remote client to send the listing to.
6370 * @return False if an error occurred, true otherwise.
6371 */
6372 boolean viewServerGetFocusedWindow(Socket client) {
6373 if (isSystemSecure()) {
6374 return false;
6375 }
6376
6377 boolean result = true;
6378
6379 WindowState focusedWindow = getFocusedWindow();
6380
6381 BufferedWriter out = null;
6382
6383 // Any uncaught exception will crash the system process
6384 try {
6385 OutputStream clientStream = client.getOutputStream();
6386 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6387
6388 if(focusedWindow != null) {
6389 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6390 out.write(' ');
6391 out.append(focusedWindow.mAttrs.getTitle());
6392 }
6393 out.write('\n');
6394 out.flush();
6395 } catch (Exception e) {
6396 result = false;
6397 } finally {
6398 if (out != null) {
6399 try {
6400 out.close();
6401 } catch (IOException e) {
6402 result = false;
6403 }
6404 }
6405 }
6406
6407 return result;
6408 }
6409
6410 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006411 * Sends a command to a target window. The result of the command, if any, will be
6412 * written in the output stream of the specified socket.
6413 *
6414 * The parameters must follow this syntax:
6415 * windowHashcode extra
6416 *
6417 * Where XX is the length in characeters of the windowTitle.
6418 *
6419 * The first parameter is the target window. The window with the specified hashcode
6420 * will be the target. If no target can be found, nothing happens. The extra parameters
6421 * will be delivered to the target window and as parameters to the command itself.
6422 *
6423 * @param client The remote client to sent the result, if any, to.
6424 * @param command The command to execute.
6425 * @param parameters The command parameters.
6426 *
6427 * @return True if the command was successfully delivered, false otherwise. This does
6428 * not indicate whether the command itself was successful.
6429 */
6430 boolean viewServerWindowCommand(Socket client, String command, String parameters) {
Romain Guy06882f82009-06-10 13:36:04 -07006431 if (isSystemSecure()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 return false;
6433 }
6434
6435 boolean success = true;
6436 Parcel data = null;
6437 Parcel reply = null;
6438
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006439 BufferedWriter out = null;
6440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 // Any uncaught exception will crash the system process
6442 try {
6443 // Find the hashcode of the window
6444 int index = parameters.indexOf(' ');
6445 if (index == -1) {
6446 index = parameters.length();
6447 }
6448 final String code = parameters.substring(0, index);
Romain Guy236092a2009-12-14 15:31:48 -08006449 int hashCode = (int) Long.parseLong(code, 16);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450
6451 // Extract the command's parameter after the window description
6452 if (index < parameters.length()) {
6453 parameters = parameters.substring(index + 1);
6454 } else {
6455 parameters = "";
6456 }
6457
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08006458 final WindowState window = findWindow(hashCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 if (window == null) {
6460 return false;
6461 }
6462
6463 data = Parcel.obtain();
6464 data.writeInterfaceToken("android.view.IWindow");
6465 data.writeString(command);
6466 data.writeString(parameters);
6467 data.writeInt(1);
6468 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6469
6470 reply = Parcel.obtain();
6471
6472 final IBinder binder = window.mClient.asBinder();
6473 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6474 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6475
6476 reply.readException();
6477
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006478 if (!client.isOutputShutdown()) {
6479 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6480 out.write("DONE\n");
6481 out.flush();
6482 }
6483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006485 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006486 success = false;
6487 } finally {
6488 if (data != null) {
6489 data.recycle();
6490 }
6491 if (reply != null) {
6492 reply.recycle();
6493 }
Konstantin Lopyrev43b9b482010-08-24 22:00:12 -07006494 if (out != null) {
6495 try {
6496 out.close();
6497 } catch (IOException e) {
6498
6499 }
6500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006501 }
6502
6503 return success;
6504 }
6505
Craig Mautner2d5618c2012-10-18 13:55:47 -07006506 @Override
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006507 public void addDisplayContentChangeListener(int displayId,
6508 IDisplayContentChangeListener listener) {
6509 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6510 "addDisplayContentChangeListener()")) {
6511 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission");
6512 }
6513 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006514 DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07006515 if (displayContent != null) {
6516 if (displayContent.mDisplayContentChangeListeners == null) {
6517 displayContent.mDisplayContentChangeListeners =
6518 new RemoteCallbackList<IDisplayContentChangeListener>();
6519 displayContent.mDisplayContentChangeListeners.register(listener);
6520 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006521 }
6522 }
6523 }
6524
Craig Mautner2d5618c2012-10-18 13:55:47 -07006525 @Override
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006526 public void removeDisplayContentChangeListener(int displayId,
6527 IDisplayContentChangeListener listener) {
6528 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6529 "removeDisplayContentChangeListener()")) {
6530 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission");
6531 }
6532 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006533 DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07006534 if (displayContent != null) {
6535 if (displayContent.mDisplayContentChangeListeners != null) {
6536 displayContent.mDisplayContentChangeListeners.unregister(listener);
6537 if (displayContent.mDisplayContentChangeListeners
6538 .getRegisteredCallbackCount() == 0) {
6539 displayContent.mDisplayContentChangeListeners = null;
6540 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006541 }
6542 }
6543 }
6544 }
6545
6546 void scheduleNotifyWindowTranstionIfNeededLocked(WindowState window, int transition) {
6547 DisplayContent displayContent = window.mDisplayContent;
6548 if (displayContent.mDisplayContentChangeListeners != null) {
6549 WindowInfo info = getWindowInfoForWindowStateLocked(window);
6550 mH.obtainMessage(H.NOTIFY_WINDOW_TRANSITION, transition, 0, info).sendToTarget();
6551 }
6552 }
6553
6554 private void handleNotifyWindowTranstion(int transition, WindowInfo info) {
6555 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
6556 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006557 DisplayContent displayContent = getDisplayContentLocked(info.displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006558 if (displayContent == null) {
6559 return;
6560 }
6561 callbacks = displayContent.mDisplayContentChangeListeners;
6562 if (callbacks == null) {
6563 return;
6564 }
6565 }
6566 final int callbackCount = callbacks.beginBroadcast();
6567 try {
6568 for (int i = 0; i < callbackCount; i++) {
6569 try {
6570 callbacks.getBroadcastItem(i).onWindowTransition(info.displayId,
6571 transition, info);
6572 } catch (RemoteException re) {
6573 /* ignore */
6574 }
6575 }
6576 } finally {
6577 callbacks.finishBroadcast();
6578 }
6579 }
6580
6581 private void scheduleNotifyRotationChangedIfNeededLocked(DisplayContent displayContent,
6582 int rotation) {
6583 if (displayContent.mDisplayContentChangeListeners != null
6584 && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
6585 mH.obtainMessage(H.NOTIFY_ROTATION_CHANGED, displayContent.getDisplayId(),
6586 rotation).sendToTarget();
6587 }
6588 }
6589
6590 private void handleNotifyRotationChanged(int displayId, int rotation) {
6591 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
6592 synchronized (mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006593 DisplayContent displayContent = getDisplayContentLocked(displayId);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07006594 if (displayContent == null) {
6595 return;
6596 }
6597 callbacks = displayContent.mDisplayContentChangeListeners;
6598 if (callbacks == null) {
6599 return;
6600 }
6601 }
6602 try {
6603 final int watcherCount = callbacks.beginBroadcast();
6604 for (int i = 0; i < watcherCount; i++) {
6605 try {
6606 callbacks.getBroadcastItem(i).onRotationChanged(rotation);
6607 } catch (RemoteException re) {
6608 /* ignore */
6609 }
6610 }
6611 } finally {
6612 callbacks.finishBroadcast();
6613 }
6614 }
6615
Svetoslav Ganov55468c62012-10-15 15:09:02 -07006616 private void scheduleNotifyWindowLayersChangedIfNeededLocked(DisplayContent displayContent) {
6617 if (displayContent.mDisplayContentChangeListeners != null
6618 && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) {
6619 mH.obtainMessage(H.NOTIFY_WINDOW_LAYERS_CHANGED, displayContent) .sendToTarget();
6620 }
6621 }
6622
6623 private void handleNotifyWindowLayersChanged(DisplayContent displayContent) {
6624 RemoteCallbackList<IDisplayContentChangeListener> callbacks = null;
6625 synchronized (mWindowMap) {
6626 callbacks = displayContent.mDisplayContentChangeListeners;
6627 if (callbacks == null) {
6628 return;
6629 }
6630 }
6631 try {
6632 final int watcherCount = callbacks.beginBroadcast();
6633 for (int i = 0; i < watcherCount; i++) {
6634 try {
6635 callbacks.getBroadcastItem(i).onWindowLayersChanged(
6636 displayContent.getDisplayId());
6637 } catch (RemoteException re) {
6638 /* ignore */
6639 }
6640 }
6641 } finally {
6642 callbacks.finishBroadcast();
6643 }
6644 }
6645
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07006646 public void addWindowChangeListener(WindowChangeListener listener) {
6647 synchronized(mWindowMap) {
6648 mWindowChangeListeners.add(listener);
6649 }
6650 }
6651
6652 public void removeWindowChangeListener(WindowChangeListener listener) {
6653 synchronized(mWindowMap) {
6654 mWindowChangeListeners.remove(listener);
6655 }
6656 }
6657
6658 private void notifyWindowsChanged() {
6659 WindowChangeListener[] windowChangeListeners;
6660 synchronized(mWindowMap) {
6661 if(mWindowChangeListeners.isEmpty()) {
6662 return;
6663 }
6664 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6665 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6666 }
6667 int N = windowChangeListeners.length;
6668 for(int i = 0; i < N; i++) {
6669 windowChangeListeners[i].windowsChanged();
6670 }
6671 }
6672
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07006673 private void notifyFocusChanged() {
6674 WindowChangeListener[] windowChangeListeners;
6675 synchronized(mWindowMap) {
6676 if(mWindowChangeListeners.isEmpty()) {
6677 return;
6678 }
6679 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6680 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6681 }
6682 int N = windowChangeListeners.length;
6683 for(int i = 0; i < N; i++) {
6684 windowChangeListeners[i].focusChanged();
6685 }
6686 }
6687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006688 private WindowState findWindow(int hashCode) {
6689 if (hashCode == -1) {
Craig Mautner59c00972012-07-30 12:10:24 -07006690 // TODO(multidisplay): Extend to multiple displays.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006691 return getFocusedWindow();
6692 }
6693
6694 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -07006695 final AllWindowsIterator iterator = new AllWindowsIterator();
6696 while (iterator.hasNext()) {
6697 final WindowState w = iterator.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 if (System.identityHashCode(w) == hashCode) {
6699 return w;
6700 }
6701 }
6702 }
6703
6704 return null;
6705 }
6706
6707 /*
6708 * Instruct the Activity Manager to fetch the current configuration and broadcast
6709 * that to config-changed listeners if appropriate.
6710 */
6711 void sendNewConfiguration() {
6712 try {
6713 mActivityManager.updateConfiguration(null);
6714 } catch (RemoteException e) {
6715 }
6716 }
Romain Guy06882f82009-06-10 13:36:04 -07006717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006718 public Configuration computeNewConfiguration() {
6719 synchronized (mWindowMap) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006720 Configuration config = computeNewConfigurationLocked();
6721 if (config == null && mWaitingForConfig) {
6722 // Nothing changed but we are waiting for something... stop that!
6723 mWaitingForConfig = false;
6724 performLayoutAndPlaceSurfacesLocked();
6725 }
6726 return config;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006727 }
6728 }
Romain Guy06882f82009-06-10 13:36:04 -07006729
Dianne Hackbornc485a602009-03-24 22:39:49 -07006730 Configuration computeNewConfigurationLocked() {
6731 Configuration config = new Configuration();
Dianne Hackborn09e5b9d2011-10-04 16:32:01 -07006732 config.fontScale = 0;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006733 if (!computeScreenConfigurationLocked(config)) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006734 return null;
6735 }
Dianne Hackbornc485a602009-03-24 22:39:49 -07006736 return config;
6737 }
Romain Guy06882f82009-06-10 13:36:04 -07006738
Craig Mautner59c00972012-07-30 12:10:24 -07006739 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006740 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006741 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006742 if (width < displayInfo.smallestNominalAppWidth) {
6743 displayInfo.smallestNominalAppWidth = width;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006744 }
Craig Mautner59c00972012-07-30 12:10:24 -07006745 if (width > displayInfo.largestNominalAppWidth) {
6746 displayInfo.largestNominalAppWidth = width;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006747 }
6748 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006749 if (height < displayInfo.smallestNominalAppHeight) {
6750 displayInfo.smallestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006751 }
Craig Mautner59c00972012-07-30 12:10:24 -07006752 if (height > displayInfo.largestNominalAppHeight) {
6753 displayInfo.largestNominalAppHeight = height;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -07006754 }
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006755 }
6756
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006757 private int reduceConfigLayout(int curLayout, int rotation, float density,
6758 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006759 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006760 // Get the app screen size at this rotation.
6761 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6762 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6763
6764 // Compute the screen layout size class for this rotation.
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006765 int longSize = w;
6766 int shortSize = h;
6767 if (longSize < shortSize) {
6768 int tmp = longSize;
6769 longSize = shortSize;
6770 shortSize = tmp;
6771 }
6772 longSize = (int)(longSize/density);
6773 shortSize = (int)(shortSize/density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006774 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006775 }
6776
Craig Mautner59c00972012-07-30 12:10:24 -07006777 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6778 int dw, int dh, float density, Configuration outConfig) {
Craig Mautner69b08182012-09-05 13:07:13 -07006779 // TODO: Multidisplay: for now only use with default display.
6780
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006781 // We need to determine the smallest width that will occur under normal
6782 // operation. To this, start with the base screen size and compute the
6783 // width under the different possible rotations. We need to un-rotate
6784 // the current screen dimensions before doing this.
6785 int unrotDw, unrotDh;
6786 if (rotated) {
6787 unrotDw = dh;
6788 unrotDh = dw;
6789 } else {
6790 unrotDw = dw;
6791 unrotDh = dh;
6792 }
Craig Mautner59c00972012-07-30 12:10:24 -07006793 displayInfo.smallestNominalAppWidth = 1<<30;
6794 displayInfo.smallestNominalAppHeight = 1<<30;
6795 displayInfo.largestNominalAppWidth = 0;
6796 displayInfo.largestNominalAppHeight = 0;
6797 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6798 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6799 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6800 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006801 int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
Dianne Hackborn56b53b52011-11-10 11:19:57 -08006802 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6803 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6804 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6805 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
Craig Mautner59c00972012-07-30 12:10:24 -07006806 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07006807 outConfig.screenLayout = sl;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006808 }
6809
Dianne Hackborn48a76512011-06-08 21:51:44 -07006810 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6811 int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006812 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn1f903c32011-09-13 19:18:06 -07006813 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6814 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006815 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
Dianne Hackborn2b31d532011-06-23 11:58:50 -07006816 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006817 if (curSize == 0 || size < curSize) {
6818 curSize = size;
6819 }
6820 return curSize;
6821 }
6822
6823 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
Craig Mautner69b08182012-09-05 13:07:13 -07006824 // TODO: Multidisplay: for now only use with default display.
Dianne Hackborn48a76512011-06-08 21:51:44 -07006825 mTmpDisplayMetrics.setTo(dm);
Craig Mautner69b08182012-09-05 13:07:13 -07006826 final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6827 final int unrotDw, unrotDh;
Dianne Hackborn48a76512011-06-08 21:51:44 -07006828 if (rotated) {
6829 unrotDw = dh;
6830 unrotDh = dw;
6831 } else {
6832 unrotDw = dw;
6833 unrotDh = dh;
6834 }
Craig Mautner69b08182012-09-05 13:07:13 -07006835 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6836 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6837 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6838 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
Dianne Hackborn48a76512011-06-08 21:51:44 -07006839 return sw;
6840 }
6841
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006842 boolean computeScreenConfigurationLocked(Configuration config) {
Jeff Browne215f262012-09-10 16:01:14 -07006843 if (!mDisplayReady) {
Dianne Hackbornc485a602009-03-24 22:39:49 -07006844 return false;
6845 }
Christopher Tateb696aee2010-04-02 19:08:30 -07006846
Craig Mautner59c00972012-07-30 12:10:24 -07006847 // TODO(multidisplay): For now, apply Configuration to main screen only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07006848 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07006849
Christopher Tateb696aee2010-04-02 19:08:30 -07006850 // Use the effective "visual" dimensions based on current rotation
6851 final boolean rotated = (mRotation == Surface.ROTATION_90
6852 || mRotation == Surface.ROTATION_270);
Craig Mautner59c00972012-07-30 12:10:24 -07006853 final int realdw = rotated ?
6854 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6855 final int realdh = rotated ?
6856 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
Jeff Brownfa25bf52012-07-23 19:26:30 -07006857 int dw = realdw;
6858 int dh = realdh;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006859
Jeff Brownfa25bf52012-07-23 19:26:30 -07006860 if (mAltOrientation) {
6861 if (realdw > realdh) {
6862 // Turn landscape into portrait.
6863 int maxw = (int)(realdh/1.3f);
6864 if (maxw < realdw) {
6865 dw = maxw;
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006866 }
6867 } else {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006868 // Turn portrait into landscape.
6869 int maxh = (int)(realdw/1.3f);
6870 if (maxh < realdh) {
6871 dh = maxh;
6872 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006873 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006874 }
6875
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006876 if (config != null) {
Jeff Browne215f262012-09-10 16:01:14 -07006877 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6878 Configuration.ORIENTATION_LANDSCAPE;
Dianne Hackbornc485a602009-03-24 22:39:49 -07006879 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08006880
Jeff Brownbc68a592011-07-25 12:58:12 -07006881 // Update application display metrics.
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006882 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6883 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
Craig Mautner59c00972012-07-30 12:10:24 -07006884 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6885 synchronized(displayContent.mDisplaySizeLock) {
6886 displayInfo.rotation = mRotation;
6887 displayInfo.logicalWidth = dw;
6888 displayInfo.logicalHeight = dh;
Dianne Hackborndde331c2012-08-03 14:01:57 -07006889 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
Craig Mautner59c00972012-07-30 12:10:24 -07006890 displayInfo.appWidth = appWidth;
6891 displayInfo.appHeight = appHeight;
6892 displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
6893 displayInfo.getAppMetrics(mDisplayMetrics, null);
Jeff Brownbd6e1502012-08-28 03:27:37 -07006894 mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
6895 displayContent.getDisplayId(), displayInfo);
Jeff Brownfa25bf52012-07-23 19:26:30 -07006896
6897 mAnimator.setDisplayDimensions(dw, dh, appWidth, appHeight);
Dianne Hackborn1fbee792011-11-30 11:29:58 -08006898 }
Dianne Hackborn36991742011-10-11 21:35:26 -07006899 if (false) {
Jeff Brownfa25bf52012-07-23 19:26:30 -07006900 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
Dianne Hackborn36991742011-10-11 21:35:26 -07006901 }
Dianne Hackborndacea8c2011-04-21 17:26:39 -07006902
Jeff Brownfa25bf52012-07-23 19:26:30 -07006903 final DisplayMetrics dm = mDisplayMetrics;
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006904 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6905 mCompatDisplayMetrics);
Mitsuru Oshima1ecf5d22009-07-06 17:20:38 -07006906
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006907 if (config != null) {
6908 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6909 / dm.density);
6910 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6911 / dm.density);
Craig Mautner59c00972012-07-30 12:10:24 -07006912 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07006913
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006914 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6915 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6916 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
Dianne Hackborndde331c2012-08-03 14:01:57 -07006917 config.densityDpi = displayContent.mBaseDisplayDensity;
Dianne Hackborn69cb8752011-05-19 18:13:32 -07006918
Jeff Browndaa37532012-05-01 15:54:03 -07006919 // Update the configuration based on available input devices, lid switch,
6920 // and platform configuration.
6921 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6922 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6923 config.navigation = Configuration.NAVIGATION_NONAV;
6924
6925 int keyboardPresence = 0;
6926 int navigationPresence = 0;
Craig Mautner1d961d42012-05-27 12:02:11 -07006927 final InputDevice[] devices = mInputManager.getInputDevices();
6928 final int len = devices.length;
6929 for (int i = 0; i < len; i++) {
6930 InputDevice device = devices[i];
Jeff Browndaa37532012-05-01 15:54:03 -07006931 if (!device.isVirtual()) {
6932 final int sources = device.getSources();
6933 final int presenceFlag = device.isExternal() ?
6934 WindowManagerPolicy.PRESENCE_EXTERNAL :
6935 WindowManagerPolicy.PRESENCE_INTERNAL;
6936
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006937 if (mIsTouchDevice) {
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006938 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6939 InputDevice.SOURCE_TOUCHSCREEN) {
Dianne Hackborn0cf2c8a2012-05-17 17:29:49 -07006940 config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6941 }
6942 } else {
6943 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browndaa37532012-05-01 15:54:03 -07006944 }
6945
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006946 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
Jeff Browndaa37532012-05-01 15:54:03 -07006947 config.navigation = Configuration.NAVIGATION_TRACKBALL;
6948 navigationPresence |= presenceFlag;
Jeff Brown7e4ff4b2012-05-30 14:32:16 -07006949 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
Jeff Browndaa37532012-05-01 15:54:03 -07006950 && config.navigation == Configuration.NAVIGATION_NONAV) {
6951 config.navigation = Configuration.NAVIGATION_DPAD;
6952 navigationPresence |= presenceFlag;
6953 }
6954
6955 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6956 config.keyboard = Configuration.KEYBOARD_QWERTY;
6957 keyboardPresence |= presenceFlag;
6958 }
6959 }
6960 }
6961
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006962 // Determine whether a hard keyboard is available and enabled.
6963 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6964 if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6965 mHardKeyboardAvailable = hardKeyboardAvailable;
6966 mHardKeyboardEnabled = hardKeyboardAvailable;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006967 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6968 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6969 }
6970 if (!mHardKeyboardEnabled) {
6971 config.keyboard = Configuration.KEYBOARD_NOKEYS;
6972 }
6973
Jeff Browndaa37532012-05-01 15:54:03 -07006974 // Let the policy update hidden states.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08006975 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6976 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6977 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
Jeff Browndaa37532012-05-01 15:54:03 -07006978 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
Jeff Brown2992ea72011-01-28 22:04:14 -08006979 }
Jeff Brown597eec82011-01-31 17:12:25 -08006980
Dianne Hackbornc485a602009-03-24 22:39:49 -07006981 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006982 }
Christopher Tatea53146c2010-09-07 11:57:52 -07006983
Jeff Brown2992ea72011-01-28 22:04:14 -08006984 public boolean isHardKeyboardAvailable() {
6985 synchronized (mWindowMap) {
6986 return mHardKeyboardAvailable;
6987 }
6988 }
6989
6990 public boolean isHardKeyboardEnabled() {
6991 synchronized (mWindowMap) {
6992 return mHardKeyboardEnabled;
6993 }
6994 }
6995
6996 public void setHardKeyboardEnabled(boolean enabled) {
6997 synchronized (mWindowMap) {
6998 if (mHardKeyboardEnabled != enabled) {
6999 mHardKeyboardEnabled = enabled;
7000 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7001 }
7002 }
7003 }
7004
7005 public void setOnHardKeyboardStatusChangeListener(
7006 OnHardKeyboardStatusChangeListener listener) {
7007 synchronized (mWindowMap) {
7008 mHardKeyboardStatusChangeListener = listener;
7009 }
7010 }
7011
7012 void notifyHardKeyboardStatusChange() {
7013 final boolean available, enabled;
7014 final OnHardKeyboardStatusChangeListener listener;
7015 synchronized (mWindowMap) {
7016 listener = mHardKeyboardStatusChangeListener;
7017 available = mHardKeyboardAvailable;
7018 enabled = mHardKeyboardEnabled;
7019 }
7020 if (listener != null) {
7021 listener.onHardKeyboardStatusChange(available, enabled);
7022 }
7023 }
7024
Christopher Tatea53146c2010-09-07 11:57:52 -07007025 // -------------------------------------------------------------
7026 // Drag and drop
7027 // -------------------------------------------------------------
7028
7029 IBinder prepareDragSurface(IWindow window, SurfaceSession session,
Christopher Tate02d2b3b2011-01-10 20:43:53 -08007030 int flags, int width, int height, Surface outSurface) {
Christopher Tatea53146c2010-09-07 11:57:52 -07007031 if (DEBUG_DRAG) {
7032 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
Christopher Tate02d2b3b2011-01-10 20:43:53 -08007033 + " flags=" + Integer.toHexString(flags) + " win=" + window
Christopher Tatea53146c2010-09-07 11:57:52 -07007034 + " asbinder=" + window.asBinder());
7035 }
7036
7037 final int callerPid = Binder.getCallingPid();
7038 final long origId = Binder.clearCallingIdentity();
7039 IBinder token = null;
7040
7041 try {
7042 synchronized (mWindowMap) {
7043 try {
Christopher Tatea53146c2010-09-07 11:57:52 -07007044 if (mDragState == null) {
Jeff Browne215f262012-09-10 16:01:14 -07007045 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007046 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007047 final Display display = displayContent.getDisplay();
Jeff Brown64a55af2012-08-26 02:47:39 -07007048 Surface surface = new Surface(session, "drag surface",
Christopher Tatea53146c2010-09-07 11:57:52 -07007049 width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07007050 surface.setLayerStack(display.getLayerStack());
Dianne Hackbornac1471a2011-02-03 13:46:06 -08007051 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
7052 + surface + ": CREATE");
Christopher Tatea53146c2010-09-07 11:57:52 -07007053 outSurface.copyFrom(surface);
Chris Tate7b362e42010-11-04 16:02:52 -07007054 final IBinder winBinder = window.asBinder();
Christopher Tatea53146c2010-09-07 11:57:52 -07007055 token = new Binder();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007056 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07007057 token = mDragState.mToken = new Binder();
7058
7059 // 5 second timeout for this window to actually begin the drag
Chris Tate7b362e42010-11-04 16:02:52 -07007060 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
7061 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
Christopher Tatea53146c2010-09-07 11:57:52 -07007062 mH.sendMessageDelayed(msg, 5000);
7063 } else {
7064 Slog.w(TAG, "Drag already in progress");
7065 }
7066 } catch (Surface.OutOfResourcesException e) {
7067 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
7068 if (mDragState != null) {
7069 mDragState.reset();
7070 mDragState = null;
7071 }
Christopher Tatea53146c2010-09-07 11:57:52 -07007072 }
7073 }
7074 } finally {
7075 Binder.restoreCallingIdentity(origId);
7076 }
7077
7078 return token;
7079 }
7080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007081 // -------------------------------------------------------------
7082 // Input Events and Focus Management
7083 // -------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -07007084
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007085 final InputMonitor mInputMonitor = new InputMonitor(this);
Jeff Brown08a746a2012-06-24 12:14:49 -07007086 private boolean mEventDispatchingEnabled;
7087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 public void pauseKeyDispatching(IBinder _token) {
7089 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
7090 "pauseKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007091 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007092 }
7093
7094 synchronized (mWindowMap) {
7095 WindowToken token = mTokenMap.get(_token);
7096 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007097 mInputMonitor.pauseDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 }
7099 }
7100 }
7101
7102 public void resumeKeyDispatching(IBinder _token) {
7103 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
7104 "resumeKeyDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007105 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007106 }
7107
7108 synchronized (mWindowMap) {
7109 WindowToken token = mTokenMap.get(_token);
7110 if (token != null) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -07007111 mInputMonitor.resumeDispatchingLw(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007112 }
7113 }
7114 }
7115
7116 public void setEventDispatching(boolean enabled) {
7117 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007118 "setEventDispatching()")) {
Dianne Hackborncfaef692009-06-15 14:24:44 -07007119 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007120 }
7121
7122 synchronized (mWindowMap) {
Jeff Brown08a746a2012-06-24 12:14:49 -07007123 mEventDispatchingEnabled = enabled;
7124 if (mDisplayEnabled) {
7125 mInputMonitor.setEventDispatchingLw(enabled);
7126 }
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007127 sendScreenStatusToClientsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007128 }
7129 }
Romain Guy06882f82009-06-10 13:36:04 -07007130
Svetoslav Ganovc9c9a482012-07-16 08:46:07 -07007131 public IBinder getFocusedWindowToken() {
7132 if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
7133 "getFocusedWindowToken()")) {
7134 throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
7135 }
Svetoslav Ganove15ccb92012-05-16 15:48:55 -07007136 synchronized (mWindowMap) {
7137 WindowState windowState = getFocusedWindowLocked();
7138 if (windowState != null) {
7139 return windowState.mClient.asBinder();
7140 }
7141 return null;
7142 }
7143 }
7144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007145 private WindowState getFocusedWindow() {
7146 synchronized (mWindowMap) {
7147 return getFocusedWindowLocked();
7148 }
7149 }
7150
7151 private WindowState getFocusedWindowLocked() {
7152 return mCurrentFocus;
7153 }
Romain Guy06882f82009-06-10 13:36:04 -07007154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007155 public boolean detectSafeMode() {
Jeff Brownb09abc12011-01-13 21:08:27 -08007156 if (!mInputMonitor.waitForInputDevicesReady(
7157 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
7158 Slog.w(TAG, "Devices still not ready after waiting "
Jeff Brownac143512012-04-05 18:57:33 -07007159 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
7160 + " milliseconds before attempting to detect safe mode.");
Jeff Brownb09abc12011-01-13 21:08:27 -08007161 }
7162
Jeff Brownac143512012-04-05 18:57:33 -07007163 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
7164 KeyEvent.KEYCODE_MENU);
7165 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
7166 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
7167 KeyEvent.KEYCODE_DPAD_CENTER);
7168 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
Jeff Brownc458ce92012-04-30 14:58:40 -07007169 InputManagerService.BTN_MOUSE);
Jeff Brownac143512012-04-05 18:57:33 -07007170 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
7171 KeyEvent.KEYCODE_VOLUME_DOWN);
7172 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
7173 || volumeDownState > 0;
Dianne Hackborn19caadc2012-04-20 17:49:10 -07007174 try {
7175 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
7176 mSafeMode = true;
7177 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
7178 }
7179 } catch (IllegalArgumentException e) {
7180 }
Jeff Brownac143512012-04-05 18:57:33 -07007181 if (mSafeMode) {
7182 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
7183 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
7184 } else {
7185 Log.i(TAG, "SAFE MODE not enabled");
7186 }
7187 mPolicy.setSafeMode(mSafeMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 return mSafeMode;
7189 }
Romain Guy06882f82009-06-10 13:36:04 -07007190
Dianne Hackborn661cd522011-08-22 00:26:20 -07007191 public void displayReady() {
Jeff Browne215f262012-09-10 16:01:14 -07007192 displayReady(Display.DEFAULT_DISPLAY);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007193
7194 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007195 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007196 readForcedDisplaySizeAndDensityLocked(displayContent);
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007197
Jeff Browne215f262012-09-10 16:01:14 -07007198 mDisplayReady = true;
Craig Mautner4f67ba62012-08-02 11:23:00 -07007199 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
Jeff Browne215f262012-09-10 16:01:14 -07007200 PackageManager.FEATURE_TOUCHSCREEN);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007201
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007202 final DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
Jeff Browne215f262012-09-10 16:01:14 -07007203 mAnimator.setDisplayDimensions(
7204 displayInfo.logicalWidth, displayInfo.logicalHeight,
7205 displayInfo.appWidth, displayInfo.appHeight);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007206
Jeff Browne215f262012-09-10 16:01:14 -07007207 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7208 displayContent.mInitialDisplayWidth,
7209 displayContent.mInitialDisplayHeight,
7210 displayContent.mInitialDisplayDensity);
Craig Mautner4f67ba62012-08-02 11:23:00 -07007211 }
Dianne Hackborn5a052a42012-08-15 18:49:23 -07007212
7213 try {
7214 mActivityManager.updateConfiguration(null);
7215 } catch (RemoteException e) {
7216 }
Craig Mautner59c00972012-07-30 12:10:24 -07007217 }
7218
Craig Mautner2d5618c2012-10-18 13:55:47 -07007219 private void displayReady(int displayId) {
Dianne Hackborn5132b372010-07-29 12:51:35 -07007220 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007221 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007222 if (displayContent != null) {
7223 mAnimator.addDisplayLocked(displayId);
7224 synchronized(displayContent.mDisplaySizeLock) {
7225 // Bootstrap the default logical display from the display manager.
7226 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
7227 DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
7228 if (newDisplayInfo != null) {
7229 displayInfo.copyFrom(newDisplayInfo);
7230 }
7231 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
7232 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
7233 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
7234 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
7235 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
7236 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
Jeff Brownbd6e1502012-08-28 03:27:37 -07007237 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007238 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007239 }
Dianne Hackborn5132b372010-07-29 12:51:35 -07007240 }
7241
Dianne Hackborn661cd522011-08-22 00:26:20 -07007242 public void systemReady() {
7243 mPolicy.systemReady();
7244 }
7245
Craig Mautner59c00972012-07-30 12:10:24 -07007246 // TODO(multidisplay): Call isScreenOn for each display.
Craig Mautner3d7b7d52012-05-24 11:28:26 -07007247 private void sendScreenStatusToClientsLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07007248 final boolean on = mPowerManager.isScreenOn();
7249 final AllWindowsIterator iterator = new AllWindowsIterator();
7250 while (iterator.hasNext()) {
Romain Guy7e4e5612012-03-05 14:37:29 -08007251 try {
Craig Mautner59c00972012-07-30 12:10:24 -07007252 iterator.next().mClient.dispatchScreenState(on);
Romain Guy7e4e5612012-03-05 14:37:29 -08007253 } catch (RemoteException e) {
7254 // Ignored
7255 }
7256 }
7257 }
7258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 // -------------------------------------------------------------
7260 // Async Handler
7261 // -------------------------------------------------------------
7262
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007263 final class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 public static final int REPORT_FOCUS_CHANGE = 2;
7265 public static final int REPORT_LOSING_FOCUS = 3;
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007266 public static final int DO_TRAVERSAL = 4;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007267 public static final int ADD_STARTING = 5;
7268 public static final int REMOVE_STARTING = 6;
7269 public static final int FINISHED_STARTING = 7;
7270 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007271 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007272 public static final int WINDOW_FREEZE_TIMEOUT = 11;
Craig Mautner259328c2012-08-21 19:30:58 -07007273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007274 public static final int APP_TRANSITION_TIMEOUT = 13;
7275 public static final int PERSIST_ANIMATION_SCALE = 14;
7276 public static final int FORCE_GC = 15;
7277 public static final int ENABLE_SCREEN = 16;
7278 public static final int APP_FREEZE_TIMEOUT = 17;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007279 public static final int SEND_NEW_CONFIGURATION = 18;
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007280 public static final int REPORT_WINDOWS_CHANGE = 19;
Christopher Tatea53146c2010-09-07 11:57:52 -07007281 public static final int DRAG_START_TIMEOUT = 20;
Chris Tated4533f12010-10-19 15:15:08 -07007282 public static final int DRAG_END_TIMEOUT = 21;
Jeff Brown2992ea72011-01-28 22:04:14 -08007283 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007284 public static final int BOOT_TIMEOUT = 23;
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007285 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
Craig Mautner01cd0e72012-06-18 10:19:11 -07007286 public static final int UPDATE_ANIM_PARAMETERS = 25;
Craig Mautner0447a812012-05-22 16:01:31 -07007287 public static final int SHOW_STRICT_MODE_VIOLATION = 26;
Dianne Hackborn84375872012-06-01 19:03:50 -07007288 public static final int DO_ANIMATION_CALLBACK = 27;
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007289 public static final int NOTIFY_ROTATION_CHANGED = 28;
7290 public static final int NOTIFY_WINDOW_TRANSITION = 29;
7291 public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007292 public static final int NOTIFY_WINDOW_LAYERS_CHANGED = 31;
Romain Guy06882f82009-06-10 13:36:04 -07007293
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007294 public static final int DO_DISPLAY_ADDED = 32;
7295 public static final int DO_DISPLAY_REMOVED = 33;
7296 public static final int DO_DISPLAY_CHANGED = 34;
Craig Mautner722285e2012-09-07 13:55:58 -07007297
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007298 public static final int CLIENT_FREEZE_TIMEOUT = 35;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007299
Craig Mautner48ba1e72012-04-02 13:18:16 -07007300 public static final int ANIMATOR_WHAT_OFFSET = 100000;
7301 public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
Craig Mautner12670b52012-07-03 19:15:35 -07007302 public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
Craig Mautner48ba1e72012-04-02 13:18:16 -07007303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007304 public H() {
7305 }
Romain Guy06882f82009-06-10 13:36:04 -07007306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007307 @Override
7308 public void handleMessage(Message msg) {
Craig Mautner7d8df392012-04-06 15:26:23 -07007309 if (DEBUG_WINDOW_TRACE) {
7310 Slog.v(TAG, "handleMessage: entry what=" + msg.what);
7311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007312 switch (msg.what) {
7313 case REPORT_FOCUS_CHANGE: {
7314 WindowState lastFocus;
7315 WindowState newFocus;
Romain Guy06882f82009-06-10 13:36:04 -07007316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007317 synchronized(mWindowMap) {
7318 lastFocus = mLastFocus;
7319 newFocus = mCurrentFocus;
7320 if (lastFocus == newFocus) {
7321 // Focus is not changing, so nothing to do.
7322 return;
7323 }
7324 mLastFocus = newFocus;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007325 //Slog.i(TAG, "Focus moving from " + lastFocus
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 // + " to " + newFocus);
7327 if (newFocus != null && lastFocus != null
7328 && !newFocus.isDisplayedLw()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007329 //Slog.i(TAG, "Delaying loss of focus...");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007330 mLosingFocus.add(lastFocus);
7331 lastFocus = null;
7332 }
7333 }
7334
7335 if (lastFocus != newFocus) {
7336 //System.out.println("Changing focus from " + lastFocus
7337 // + " to " + newFocus);
7338 if (newFocus != null) {
7339 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007340 //Slog.i(TAG, "Gaining focus: " + newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007341 newFocus.mClient.windowFocusChanged(true, mInTouchMode);
7342 } catch (RemoteException e) {
7343 // Ignore if process has died.
7344 }
Konstantin Lopyrev5e7833a2010-08-09 17:01:11 -07007345 notifyFocusChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007346 }
7347
7348 if (lastFocus != null) {
7349 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007350 //Slog.i(TAG, "Losing focus: " + lastFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007351 lastFocus.mClient.windowFocusChanged(false, mInTouchMode);
7352 } catch (RemoteException e) {
7353 // Ignore if process has died.
7354 }
7355 }
7356 }
7357 } break;
7358
7359 case REPORT_LOSING_FOCUS: {
7360 ArrayList<WindowState> losers;
Romain Guy06882f82009-06-10 13:36:04 -07007361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007362 synchronized(mWindowMap) {
7363 losers = mLosingFocus;
7364 mLosingFocus = new ArrayList<WindowState>();
7365 }
7366
7367 final int N = losers.size();
7368 for (int i=0; i<N; i++) {
7369 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007370 //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 losers.get(i).mClient.windowFocusChanged(false, mInTouchMode);
7372 } catch (RemoteException e) {
7373 // Ignore if process has died.
7374 }
7375 }
7376 } break;
7377
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007378 case DO_TRAVERSAL: {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007379 synchronized(mWindowMap) {
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08007380 mTraversalScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007381 performLayoutAndPlaceSurfacesLocked();
7382 }
7383 } break;
7384
7385 case ADD_STARTING: {
7386 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7387 final StartingData sd = wtoken.startingData;
7388
7389 if (sd == null) {
7390 // Animation has been canceled... do nothing.
7391 return;
7392 }
Romain Guy06882f82009-06-10 13:36:04 -07007393
Joe Onorato8a9b2202010-02-26 18:56:32 -08007394 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007395 + wtoken + ": pkg=" + sd.pkg);
Romain Guy06882f82009-06-10 13:36:04 -07007396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007397 View view = null;
7398 try {
7399 view = mPolicy.addStartingWindow(
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07007400 wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
7401 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007403 Slog.w(TAG, "Exception when adding starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007404 }
7405
7406 if (view != null) {
7407 boolean abort = false;
7408
7409 synchronized(mWindowMap) {
7410 if (wtoken.removed || wtoken.startingData == null) {
7411 // If the window was successfully added, then
7412 // we need to remove it.
7413 if (wtoken.startingWindow != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007414 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007415 "Aborted starting " + wtoken
7416 + ": removed=" + wtoken.removed
7417 + " startingData=" + wtoken.startingData);
7418 wtoken.startingWindow = null;
7419 wtoken.startingData = null;
7420 abort = true;
7421 }
7422 } else {
7423 wtoken.startingView = view;
7424 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007425 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007426 "Added starting " + wtoken
7427 + ": startingWindow="
7428 + wtoken.startingWindow + " startingView="
7429 + wtoken.startingView);
7430 }
7431
7432 if (abort) {
7433 try {
7434 mPolicy.removeStartingWindow(wtoken.token, view);
7435 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007436 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007437 }
7438 }
7439 }
7440 } break;
7441
7442 case REMOVE_STARTING: {
7443 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7444 IBinder token = null;
7445 View view = null;
7446 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007447 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007448 + wtoken + ": startingWindow="
7449 + wtoken.startingWindow + " startingView="
7450 + wtoken.startingView);
7451 if (wtoken.startingWindow != null) {
7452 view = wtoken.startingView;
7453 token = wtoken.token;
7454 wtoken.startingData = null;
7455 wtoken.startingView = null;
7456 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007457 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007458 }
7459 }
7460 if (view != null) {
7461 try {
7462 mPolicy.removeStartingWindow(token, view);
7463 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007464 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007465 }
7466 }
7467 } break;
7468
7469 case FINISHED_STARTING: {
7470 IBinder token = null;
7471 View view = null;
7472 while (true) {
7473 synchronized (mWindowMap) {
7474 final int N = mFinishedStarting.size();
7475 if (N <= 0) {
7476 break;
7477 }
7478 AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7479
Joe Onorato8a9b2202010-02-26 18:56:32 -08007480 if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007481 "Finished starting " + wtoken
7482 + ": startingWindow=" + wtoken.startingWindow
7483 + " startingView=" + wtoken.startingView);
7484
7485 if (wtoken.startingWindow == null) {
7486 continue;
7487 }
7488
7489 view = wtoken.startingView;
7490 token = wtoken.token;
7491 wtoken.startingData = null;
7492 wtoken.startingView = null;
7493 wtoken.startingWindow = null;
Craig Mautner38b24782012-07-02 16:21:28 -07007494 wtoken.startingDisplayed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007495 }
7496
7497 try {
7498 mPolicy.removeStartingWindow(token, view);
7499 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007500 Slog.w(TAG, "Exception when removing starting window", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007501 }
7502 }
7503 } break;
7504
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07007505 case REPORT_APPLICATION_TOKEN_DRAWN: {
7506 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7507
7508 try {
7509 if (DEBUG_VISIBILITY) Slog.v(
7510 TAG, "Reporting drawn in " + wtoken);
7511 wtoken.appToken.windowsDrawn();
7512 } catch (RemoteException ex) {
7513 }
7514 } break;
7515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007516 case REPORT_APPLICATION_TOKEN_WINDOWS: {
7517 final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7518
7519 boolean nowVisible = msg.arg1 != 0;
7520 boolean nowGone = msg.arg2 != 0;
7521
7522 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007523 if (DEBUG_VISIBILITY) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 TAG, "Reporting visible in " + wtoken
7525 + " visible=" + nowVisible
7526 + " gone=" + nowGone);
7527 if (nowVisible) {
7528 wtoken.appToken.windowsVisible();
7529 } else {
7530 wtoken.appToken.windowsGone();
7531 }
7532 } catch (RemoteException ex) {
7533 }
7534 } break;
Romain Guy06882f82009-06-10 13:36:04 -07007535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007536 case WINDOW_FREEZE_TIMEOUT: {
Craig Mautner59c00972012-07-30 12:10:24 -07007537 // TODO(multidisplay): Can non-default displays rotate?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 synchronized (mWindowMap) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007539 Slog.w(TAG, "Window freeze timeout expired.");
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007540 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07007541 int i = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007542 while (i > 0) {
7543 i--;
Craig Mautner59c00972012-07-30 12:10:24 -07007544 WindowState w = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 if (w.mOrientationChanging) {
7546 w.mOrientationChanging = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -08007547 Slog.w(TAG, "Force clearing orientation change: " + w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007548 }
7549 }
7550 performLayoutAndPlaceSurfacesLocked();
7551 }
7552 break;
7553 }
Romain Guy06882f82009-06-10 13:36:04 -07007554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007555 case APP_TRANSITION_TIMEOUT: {
7556 synchronized (mWindowMap) {
Dianne Hackbornbfe319e2009-09-21 00:34:05 -07007557 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007558 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 "*** APP TRANSITION TIMEOUT");
7560 mAppTransitionReady = true;
7561 mAppTransitionTimeout = true;
Craig Mautneref25d7a2012-05-15 23:01:47 -07007562 mAnimatingAppTokens.clear();
7563 mAnimatingAppTokens.addAll(mAppTokens);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007564 performLayoutAndPlaceSurfacesLocked();
7565 }
7566 }
7567 break;
7568 }
Romain Guy06882f82009-06-10 13:36:04 -07007569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007570 case PERSIST_ANIMATION_SCALE: {
Jeff Sharkey6e2bee72012-10-01 13:39:08 -07007571 Settings.Global.putFloat(mContext.getContentResolver(),
7572 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7573 Settings.Global.putFloat(mContext.getContentResolver(),
7574 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7575 Settings.Global.putFloat(mContext.getContentResolver(),
7576 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007577 break;
7578 }
Romain Guy06882f82009-06-10 13:36:04 -07007579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007580 case FORCE_GC: {
Craig Mautner1caa3992012-06-22 09:46:48 -07007581 synchronized (mWindowMap) {
7582 synchronized (mAnimator) {
7583 // Since we're holding both mWindowMap and mAnimator we don't need to
7584 // hold mAnimator.mLayoutToAnim.
Craig Mautner711f90a2012-07-03 18:43:52 -07007585 if (mAnimator.mAnimating || mLayoutToAnim.mAnimationScheduled) {
Craig Mautner1caa3992012-06-22 09:46:48 -07007586 // If we are animating, don't do the gc now but
7587 // delay a bit so we don't interrupt the animation.
7588 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
7589 2000);
7590 return;
7591 }
7592 // If we are currently rotating the display, it will
7593 // schedule a new message when done.
7594 if (mDisplayFrozen) {
7595 return;
7596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007597 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007598 }
7599 Runtime.getRuntime().gc();
7600 break;
7601 }
Romain Guy06882f82009-06-10 13:36:04 -07007602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007603 case ENABLE_SCREEN: {
7604 performEnableScreen();
7605 break;
7606 }
Romain Guy06882f82009-06-10 13:36:04 -07007607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007608 case APP_FREEZE_TIMEOUT: {
7609 synchronized (mWindowMap) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007610 synchronized (mAnimator) {
7611 Slog.w(TAG, "App freeze timeout expired.");
7612 int i = mAppTokens.size();
7613 while (i > 0) {
7614 i--;
7615 AppWindowToken tok = mAppTokens.get(i);
Craig Mautner59431632012-04-04 11:56:44 -07007616 if (tok.mAppAnimator.freezingScreen) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007617 Slog.w(TAG, "Force clearing freeze: " + tok);
7618 unsetAppFreezingScreenLocked(tok, true, true);
7619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007620 }
7621 }
7622 }
7623 break;
7624 }
Romain Guy06882f82009-06-10 13:36:04 -07007625
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07007626 case CLIENT_FREEZE_TIMEOUT: {
7627 synchronized (mWindowMap) {
7628 if (mClientFreezingScreen) {
7629 mClientFreezingScreen = false;
7630 stopFreezingDisplayLocked();
7631 }
7632 }
7633 break;
7634 }
7635
Dianne Hackborne36d6e22010-02-17 19:46:25 -08007636 case SEND_NEW_CONFIGURATION: {
7637 removeMessages(SEND_NEW_CONFIGURATION);
7638 sendNewConfiguration();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07007639 break;
7640 }
Romain Guy06882f82009-06-10 13:36:04 -07007641
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07007642 case REPORT_WINDOWS_CHANGE: {
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07007643 if (mWindowsChanged) {
7644 synchronized (mWindowMap) {
7645 mWindowsChanged = false;
7646 }
7647 notifyWindowsChanged();
7648 }
7649 break;
7650 }
7651
Christopher Tatea53146c2010-09-07 11:57:52 -07007652 case DRAG_START_TIMEOUT: {
7653 IBinder win = (IBinder)msg.obj;
7654 if (DEBUG_DRAG) {
7655 Slog.w(TAG, "Timeout starting drag by win " + win);
7656 }
7657 synchronized (mWindowMap) {
7658 // !!! TODO: ANR the app that has failed to start the drag in time
7659 if (mDragState != null) {
Chris Tated4533f12010-10-19 15:15:08 -07007660 mDragState.unregister();
Jeff Brown2e44b072011-01-24 15:21:56 -08007661 mInputMonitor.updateInputWindowsLw(true /*force*/);
Christopher Tatea53146c2010-09-07 11:57:52 -07007662 mDragState.reset();
7663 mDragState = null;
7664 }
7665 }
Chris Tated4533f12010-10-19 15:15:08 -07007666 break;
Christopher Tatea53146c2010-09-07 11:57:52 -07007667 }
7668
Chris Tated4533f12010-10-19 15:15:08 -07007669 case DRAG_END_TIMEOUT: {
7670 IBinder win = (IBinder)msg.obj;
7671 if (DEBUG_DRAG) {
7672 Slog.w(TAG, "Timeout ending drag to win " + win);
7673 }
7674 synchronized (mWindowMap) {
7675 // !!! TODO: ANR the drag-receiving app
Christopher Tated9be36c2011-08-16 16:09:33 -07007676 if (mDragState != null) {
7677 mDragState.mDragResult = false;
7678 mDragState.endDragLw();
7679 }
Chris Tated4533f12010-10-19 15:15:08 -07007680 }
7681 break;
7682 }
Jeff Brown2992ea72011-01-28 22:04:14 -08007683
7684 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7685 notifyHardKeyboardStatusChange();
7686 break;
7687 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -07007688
7689 case BOOT_TIMEOUT: {
7690 performBootTimeout();
7691 break;
7692 }
7693
7694 case WAITING_FOR_DRAWN_TIMEOUT: {
7695 Pair<WindowState, IRemoteCallback> pair;
7696 synchronized (mWindowMap) {
7697 pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7698 Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7699 if (!mWaitingForDrawn.remove(pair)) {
7700 return;
7701 }
7702 }
7703 try {
7704 pair.second.sendResult(null);
7705 } catch (RemoteException e) {
7706 }
7707 break;
7708 }
Craig Mautnera608b882012-03-30 13:03:49 -07007709
Craig Mautner01cd0e72012-06-18 10:19:11 -07007710 case UPDATE_ANIM_PARAMETERS: {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07007711 // Used to send multiple changes from the animation side to the layout side.
Craig Mautnera608b882012-03-30 13:03:49 -07007712 synchronized (mWindowMap) {
Craig Mautner322e4032012-07-13 13:35:20 -07007713 if (copyAnimToLayoutParamsLocked()) {
7714 mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
7715 performLayoutAndPlaceSurfacesLocked();
Craig Mautner73850cb2012-04-10 12:56:27 -07007716 }
Craig Mautnera608b882012-03-30 13:03:49 -07007717 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07007718 break;
7719 }
7720
Craig Mautner0447a812012-05-22 16:01:31 -07007721 case SHOW_STRICT_MODE_VIOLATION: {
Chris Craik3198ef32012-10-10 14:52:30 -07007722 showStrictModeViolation(msg.arg1, msg.arg2);
Craig Mautner0447a812012-05-22 16:01:31 -07007723 break;
7724 }
7725
Craig Mautner48ba1e72012-04-02 13:18:16 -07007726 // Animation messages. Move to Window{State}Animator
7727 case SET_TRANSPARENT_REGION: {
Craig Mautnerbec53f72012-04-05 11:49:05 -07007728 Pair<WindowStateAnimator, Region> pair =
Craig Mautner48ba1e72012-04-02 13:18:16 -07007729 (Pair<WindowStateAnimator, Region>) msg.obj;
Craig Mautnerbec53f72012-04-05 11:49:05 -07007730 final WindowStateAnimator winAnimator = pair.first;
7731 winAnimator.setTransparentRegionHint(pair.second);
Craig Mautner48ba1e72012-04-02 13:18:16 -07007732 break;
7733 }
7734
Craig Mautner4d7349b2012-04-20 14:52:47 -07007735 case CLEAR_PENDING_ACTIONS: {
7736 mAnimator.clearPendingActions();
7737 break;
7738 }
Dianne Hackborn84375872012-06-01 19:03:50 -07007739
7740 case DO_ANIMATION_CALLBACK: {
7741 try {
7742 ((IRemoteCallback)msg.obj).sendResult(null);
7743 } catch (RemoteException e) {
7744 }
7745 break;
7746 }
Craig Mautner722285e2012-09-07 13:55:58 -07007747
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007748 case NOTIFY_ROTATION_CHANGED: {
7749 final int displayId = msg.arg1;
7750 final int rotation = msg.arg2;
7751 handleNotifyRotationChanged(displayId, rotation);
7752 break;
7753 }
Craig Mautner722285e2012-09-07 13:55:58 -07007754
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007755 case NOTIFY_WINDOW_TRANSITION: {
7756 final int transition = msg.arg1;
7757 WindowInfo info = (WindowInfo) msg.obj;
7758 handleNotifyWindowTranstion(transition, info);
7759 break;
7760 }
Craig Mautner722285e2012-09-07 13:55:58 -07007761
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07007762 case NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {
7763 final int displayId = msg.arg1;
7764 final boolean immediate = (msg.arg2 == 1);
7765 Rect rectangle = (Rect) msg.obj;
7766 handleNotifyRectangleOnScreenRequested(displayId, rectangle, immediate);
7767 break;
7768 }
Craig Mautner722285e2012-09-07 13:55:58 -07007769
Svetoslav Ganov55468c62012-10-15 15:09:02 -07007770 case NOTIFY_WINDOW_LAYERS_CHANGED: {
7771 DisplayContent displayContent = (DisplayContent) msg.obj;
7772 handleNotifyWindowLayersChanged(displayContent);
7773 break;
7774 }
7775
Craig Mautner722285e2012-09-07 13:55:58 -07007776 case DO_DISPLAY_ADDED:
7777 synchronized (mWindowMap) {
7778 handleDisplayAddedLocked(msg.arg1);
7779 }
7780 break;
7781
7782 case DO_DISPLAY_REMOVED:
7783 synchronized (mWindowMap) {
7784 handleDisplayRemovedLocked(msg.arg1);
7785 }
7786 break;
7787
7788 case DO_DISPLAY_CHANGED:
7789 synchronized (mWindowMap) {
7790 handleDisplayChangedLocked(msg.arg1);
7791 }
7792 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007793 }
Craig Mautner7d8df392012-04-06 15:26:23 -07007794 if (DEBUG_WINDOW_TRACE) {
7795 Slog.v(TAG, "handleMessage: exit");
7796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007797 }
7798 }
7799
7800 // -------------------------------------------------------------
7801 // IWindowManager API
7802 // -------------------------------------------------------------
7803
Craig Mautner7d8df392012-04-06 15:26:23 -07007804 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007805 public IWindowSession openSession(IInputMethodClient client,
7806 IInputContext inputContext) {
7807 if (client == null) throw new IllegalArgumentException("null client");
7808 if (inputContext == null) throw new IllegalArgumentException("null inputContext");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08007809 Session session = new Session(this, client, inputContext);
Jeff Brown46b9ac02010-04-22 18:58:52 -07007810 return session;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007811 }
7812
Craig Mautner7d8df392012-04-06 15:26:23 -07007813 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007814 public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7815 synchronized (mWindowMap) {
7816 // The focus for the client is the window immediately below
7817 // where we would place the input method window.
7818 int idx = findDesiredInputMethodWindowIndexLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007819 if (idx > 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07007820 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007821 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
Dianne Hackbornac920872012-05-22 11:49:49 -07007822 if (DEBUG_INPUT_METHOD) {
7823 Slog.i(TAG, "Desired input method target: " + imFocus);
Craig Mautner59c00972012-07-30 12:10:24 -07007824 Slog.i(TAG, "Current focus: " + mCurrentFocus);
7825 Slog.i(TAG, "Last focus: " + mLastFocus);
Dianne Hackbornac920872012-05-22 11:49:49 -07007826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007827 if (imFocus != null) {
Dianne Hackborne75d8722011-01-27 19:37:40 -08007828 // This may be a starting window, in which case we still want
7829 // to count it as okay.
7830 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7831 && imFocus.mAppToken != null) {
7832 // The client has definitely started, so it really should
7833 // have a window in this app token. Let's look for it.
7834 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7835 WindowState w = imFocus.mAppToken.windows.get(i);
7836 if (w != imFocus) {
Dianne Hackbornac920872012-05-22 11:49:49 -07007837 Log.i(TAG, "Switching to real app window: " + w);
Dianne Hackborne75d8722011-01-27 19:37:40 -08007838 imFocus = w;
7839 break;
7840 }
7841 }
7842 }
Dianne Hackbornac920872012-05-22 11:49:49 -07007843 if (DEBUG_INPUT_METHOD) {
7844 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7845 if (imFocus.mSession.mClient != null) {
7846 Slog.i(TAG, "IM target client binder: "
7847 + imFocus.mSession.mClient.asBinder());
7848 Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7849 }
7850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007851 if (imFocus.mSession.mClient != null &&
7852 imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7853 return true;
7854 }
7855 }
7856 }
Craig Mautner59c00972012-07-30 12:10:24 -07007857
7858 // Okay, how about this... what is the current focus?
7859 // It seems in some cases we may not have moved the IM
7860 // target window, such as when it was in a pop-up window,
7861 // so let's also look at the current focus. (An example:
7862 // go to Gmail, start searching so the keyboard goes up,
7863 // press home. Sometimes the IME won't go down.)
7864 // Would be nice to fix this more correctly, but it's
7865 // way at the end of a release, and this should be good enough.
7866 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7867 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7868 return true;
7869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007870 }
7871 return false;
7872 }
Romain Guy06882f82009-06-10 13:36:04 -07007873
Craig Mautner59c00972012-07-30 12:10:24 -07007874 public void getInitialDisplaySize(int displayId, Point size) {
7875 // TODO(cmautner): Access to DisplayContent should be locked on mWindowMap. Doing that
7876 // could lead to deadlock since this is called from ActivityManager.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007877 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007878 if (displayContent != null) {
7879 synchronized(displayContent.mDisplaySizeLock) {
7880 size.x = displayContent.mInitialDisplayWidth;
7881 size.y = displayContent.mInitialDisplayHeight;
7882 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007883 }
7884 }
7885
Craig Mautner2d5618c2012-10-18 13:55:47 -07007886 @Override
Jeff Brown43aa1592012-09-10 17:36:31 -07007887 public void setForcedDisplaySize(int displayId, int width, int height) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007888 synchronized(mWindowMap) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007889 // Set some sort of reasonable bounds on the size of the display that we
7890 // will try to emulate.
7891 final int MIN_WIDTH = 200;
7892 final int MIN_HEIGHT = 200;
7893 final int MAX_SCALE = 2;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007894 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007895 if (displayContent != null) {
7896 width = Math.min(Math.max(width, MIN_WIDTH),
7897 displayContent.mInitialDisplayWidth * MAX_SCALE);
7898 height = Math.min(Math.max(height, MIN_HEIGHT),
7899 displayContent.mInitialDisplayHeight * MAX_SCALE);
7900 setForcedDisplaySizeLocked(displayContent, width, height);
7901 Settings.Global.putString(mContext.getContentResolver(),
7902 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
7903 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -07007904 }
7905 }
7906
Dianne Hackborndde331c2012-08-03 14:01:57 -07007907 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
Jeff Brown43aa1592012-09-10 17:36:31 -07007908 final String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
7909 Settings.Global.DISPLAY_SIZE_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007910 if (sizeStr != null && sizeStr.length() > 0) {
7911 final int pos = sizeStr.indexOf(',');
7912 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7913 int width, height;
7914 try {
7915 width = Integer.parseInt(sizeStr.substring(0, pos));
7916 height = Integer.parseInt(sizeStr.substring(pos+1));
7917 synchronized(displayContent.mDisplaySizeLock) {
7918 if (displayContent.mBaseDisplayWidth != width
7919 || displayContent.mBaseDisplayHeight != height) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007920 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7921 displayContent.mBaseDisplayWidth = width;
7922 displayContent.mBaseDisplayHeight = height;
7923 }
7924 }
7925 } catch (NumberFormatException ex) {
7926 }
7927 }
Joe Onorato571ae902011-05-24 13:48:43 -07007928 }
Jeff Brown43aa1592012-09-10 17:36:31 -07007929 final String densityStr = Settings.Global.getString(mContext.getContentResolver(),
7930 Settings.Global.DISPLAY_DENSITY_FORCED);
Dianne Hackborndde331c2012-08-03 14:01:57 -07007931 if (densityStr != null && densityStr.length() > 0) {
7932 int density;
7933 try {
7934 density = Integer.parseInt(densityStr);
7935 synchronized(displayContent.mDisplaySizeLock) {
7936 if (displayContent.mBaseDisplayDensity != density) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07007937 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7938 displayContent.mBaseDisplayDensity = density;
7939 }
7940 }
7941 } catch (NumberFormatException ex) {
7942 }
Joe Onorato571ae902011-05-24 13:48:43 -07007943 }
Joe Onorato571ae902011-05-24 13:48:43 -07007944 }
7945
Craig Mautner2d5618c2012-10-18 13:55:47 -07007946 // displayContent must not be null
Craig Mautner59c00972012-07-30 12:10:24 -07007947 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
Joe Onorato571ae902011-05-24 13:48:43 -07007948 Slog.i(TAG, "Using new display size: " + width + "x" + height);
7949
Craig Mautner59c00972012-07-30 12:10:24 -07007950 synchronized(displayContent.mDisplaySizeLock) {
7951 displayContent.mBaseDisplayWidth = width;
7952 displayContent.mBaseDisplayHeight = height;
Dianne Hackborn1fbee792011-11-30 11:29:58 -08007953 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007954 reconfigureDisplayLocked(displayContent);
7955 }
7956
Craig Mautner2d5618c2012-10-18 13:55:47 -07007957 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007958 public void clearForcedDisplaySize(int displayId) {
7959 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007960 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007961 if (displayContent != null) {
7962 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7963 displayContent.mInitialDisplayHeight);
7964 Settings.Global.putString(mContext.getContentResolver(),
7965 Settings.Global.DISPLAY_SIZE_FORCED, "");
7966 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007967 }
7968 }
7969
Craig Mautner2d5618c2012-10-18 13:55:47 -07007970 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007971 public void setForcedDisplayDensity(int displayId, int density) {
7972 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007973 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007974 if (displayContent != null) {
7975 setForcedDisplayDensityLocked(displayContent, density);
7976 Settings.Global.putString(mContext.getContentResolver(),
7977 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
7978 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07007979 }
7980 }
7981
Craig Mautner2d5618c2012-10-18 13:55:47 -07007982 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07007983 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7984 Slog.i(TAG, "Using new display density: " + density);
7985
7986 synchronized(displayContent.mDisplaySizeLock) {
7987 displayContent.mBaseDisplayDensity = density;
7988 }
7989 reconfigureDisplayLocked(displayContent);
7990 }
7991
Craig Mautner2d5618c2012-10-18 13:55:47 -07007992 @Override
Dianne Hackborndde331c2012-08-03 14:01:57 -07007993 public void clearForcedDisplayDensity(int displayId) {
7994 synchronized(mWindowMap) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07007995 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -07007996 if (displayContent != null) {
7997 setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity);
7998 Settings.Global.putString(mContext.getContentResolver(),
7999 Settings.Global.DISPLAY_DENSITY_FORCED, "");
8000 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07008001 }
8002 }
8003
Craig Mautner2d5618c2012-10-18 13:55:47 -07008004 // displayContent must not be null
Dianne Hackborndde331c2012-08-03 14:01:57 -07008005 private void reconfigureDisplayLocked(DisplayContent displayContent) {
Craig Mautner69b08182012-09-05 13:07:13 -07008006 // TODO: Multidisplay: for now only use with default display.
Jeff Browne215f262012-09-10 16:01:14 -07008007 mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
8008 displayContent.mBaseDisplayWidth,
8009 displayContent.mBaseDisplayHeight,
8010 displayContent.mBaseDisplayDensity);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008011
Craig Mautner19d59bc2012-09-04 11:15:56 -07008012 displayContent.layoutNeeded = true;
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008013
8014 boolean configChanged = updateOrientationFromAppTokensLocked(false);
8015 mTempConfiguration.setToDefaults();
8016 mTempConfiguration.fontScale = mCurConfiguration.fontScale;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08008017 if (computeScreenConfigurationLocked(mTempConfiguration)) {
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008018 if (mCurConfiguration.diff(mTempConfiguration) != 0) {
8019 configChanged = true;
8020 }
8021 }
8022
8023 if (configChanged) {
8024 mWaitingForConfig = true;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -07008025 startFreezingDisplayLocked(false, 0, 0);
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008026 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
8027 }
8028
Dianne Hackborn7916ac62011-05-16 20:45:48 -07008029 performLayoutAndPlaceSurfacesLocked();
8030 }
8031
Dianne Hackbornf87d1962012-04-04 12:48:24 -07008032 public boolean hasSystemNavBar() {
8033 return mPolicy.hasSystemNavBar();
Dianne Hackborn81e56d52011-05-26 00:55:58 -07008034 }
8035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036 // -------------------------------------------------------------
8037 // Internals
8038 // -------------------------------------------------------------
8039
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008040 final WindowState windowForClientLocked(Session session, IWindow client,
8041 boolean throwOnError) {
8042 return windowForClientLocked(session, client.asBinder(), throwOnError);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043 }
Romain Guy06882f82009-06-10 13:36:04 -07008044
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008045 final WindowState windowForClientLocked(Session session, IBinder client,
8046 boolean throwOnError) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047 WindowState win = mWindowMap.get(client);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008048 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008049 TAG, "Looking up client " + client + ": " + win);
8050 if (win == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008051 RuntimeException ex = new IllegalArgumentException(
8052 "Requested window " + client + " does not exist");
8053 if (throwOnError) {
8054 throw ex;
8055 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008056 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008057 return null;
8058 }
8059 if (session != null && win.mSession != session) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008060 RuntimeException ex = new IllegalArgumentException(
8061 "Requested window " + client + " is in session " +
8062 win.mSession + ", not " + session);
8063 if (throwOnError) {
8064 throw ex;
8065 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008066 Slog.w(TAG, "Failed looking up window", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008067 return null;
8068 }
8069
8070 return win;
8071 }
8072
Dianne Hackborna8f60182009-09-01 19:01:50 -07008073 final void rebuildAppWindowListLocked() {
Craig Mautner59c00972012-07-30 12:10:24 -07008074 DisplayContentsIterator iterator = new DisplayContentsIterator();
8075 while (iterator.hasNext()) {
8076 rebuildAppWindowListLocked(iterator.next());
8077 }
8078 }
8079
8080 private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
8081 final WindowList windows = displayContent.getWindowList();
8082 int NW = windows.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008083 int i;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008084 int lastBelow = -1;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008085 int numRemoved = 0;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008086
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008087 if (mRebuildTmp.length < NW) {
8088 mRebuildTmp = new WindowState[NW+10];
8089 }
8090
Dianne Hackborna8f60182009-09-01 19:01:50 -07008091 // First remove all existing app windows.
8092 i=0;
8093 while (i < NW) {
Craig Mautner59c00972012-07-30 12:10:24 -07008094 WindowState w = windows.get(i);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07008095 if (w.mAppToken != null) {
Craig Mautner59c00972012-07-30 12:10:24 -07008096 WindowState win = windows.remove(i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008097 win.mRebuilding = true;
8098 mRebuildTmp[numRemoved] = win;
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008099 mWindowsChanged = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008100 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008101 "Rebuild removing window: " + win);
Dianne Hackborna8f60182009-09-01 19:01:50 -07008102 NW--;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008103 numRemoved++;
Dianne Hackborna8f60182009-09-01 19:01:50 -07008104 continue;
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008105 } else if (lastBelow == i-1) {
Craig Mautner65d11b32012-10-01 13:59:52 -07008106 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008107 lastBelow = i;
8108 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008109 }
8110 i++;
8111 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008112
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008113 // Keep whatever windows were below the app windows still below,
8114 // by skipping them.
8115 lastBelow++;
8116 i = lastBelow;
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008117
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008118 // First add all of the exiting app tokens... these are no longer
8119 // in the main app list, but still have windows shown. We put them
8120 // in the back because now that the animation is over we no longer
8121 // will care about them.
8122 int NT = mExitingAppTokens.size();
Dianne Hackborna8f60182009-09-01 19:01:50 -07008123 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008124 i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008125 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008126
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008127 // And add in the still active app tokens in Z order.
Craig Mautneref25d7a2012-05-15 23:01:47 -07008128 NT = mAnimatingAppTokens.size();
Dianne Hackbornbdd52b22009-09-02 21:46:19 -07008129 for (int j=0; j<NT; j++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008130 i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
Dianne Hackborna8f60182009-09-01 19:01:50 -07008131 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008132
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008133 i -= lastBelow;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008134 if (i != numRemoved) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008135 Slog.w(TAG, "Rebuild removed " + numRemoved
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008136 + " windows but added " + i);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008137 for (i=0; i<numRemoved; i++) {
8138 WindowState ws = mRebuildTmp[i];
8139 if (ws.mRebuilding) {
8140 StringWriter sw = new StringWriter();
8141 PrintWriter pw = new PrintWriter(sw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07008142 ws.dump(pw, "", true);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008143 pw.flush();
8144 Slog.w(TAG, "This window was lost: " + ws);
8145 Slog.w(TAG, sw.toString());
Dianne Hackborn98129732012-11-01 16:28:16 -07008146 ws.mWinAnimator.destroySurfaceLocked(false);
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008147 }
8148 }
8149 Slog.w(TAG, "Current app token list:");
Craig Mautneref25d7a2012-05-15 23:01:47 -07008150 dumpAnimatingAppTokensLocked();
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008151 Slog.w(TAG, "Final window list:");
8152 dumpWindowsLocked();
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008153 }
Dianne Hackborna8f60182009-09-01 19:01:50 -07008154 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08008155
Craig Mautner59c00972012-07-30 12:10:24 -07008156 private final void assignLayersLocked(WindowList windows) {
8157 int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008158 int curBaseLayer = 0;
8159 int curLayer = 0;
8160 int i;
Romain Guy06882f82009-06-10 13:36:04 -07008161
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008162 if (DEBUG_LAYERS) {
8163 RuntimeException here = new RuntimeException("here");
8164 here.fillInStackTrace();
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008165 Slog.v(TAG, "Assigning layers", here);
Dianne Hackborn6c8e20f2010-11-09 18:59:09 -08008166 }
8167
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008168 boolean anyLayerChanged = false;
8169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008170 for (i=0; i<N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -07008171 final WindowState w = windows.get(i);
Craig Mautneracafd192012-05-10 10:41:02 -07008172 final WindowStateAnimator winAnimator = w.mWinAnimator;
8173 boolean layerChanged = false;
8174 int oldLayer = w.mLayer;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07008175 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8176 || (i > 0 && w.mIsWallpaper)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008177 curLayer += WINDOW_LAYER_MULTIPLIER;
8178 w.mLayer = curLayer;
8179 } else {
8180 curBaseLayer = curLayer = w.mBaseLayer;
8181 w.mLayer = curLayer;
8182 }
Craig Mautneracafd192012-05-10 10:41:02 -07008183 if (w.mLayer != oldLayer) {
8184 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008185 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008186 }
8187 oldLayer = winAnimator.mAnimLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008188 if (w.mTargetAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008189 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008190 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008191 } else if (w.mAppToken != null) {
Craig Mautneracafd192012-05-10 10:41:02 -07008192 winAnimator.mAnimLayer =
Craig Mautner59431632012-04-04 11:56:44 -07008193 w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 } else {
Craig Mautneracafd192012-05-10 10:41:02 -07008195 winAnimator.mAnimLayer = w.mLayer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008196 }
8197 if (w.mIsImWindow) {
Craig Mautneracafd192012-05-10 10:41:02 -07008198 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
Dianne Hackborn759a39e2009-08-09 17:20:27 -07008199 } else if (w.mIsWallpaper) {
Craig Mautneracafd192012-05-10 10:41:02 -07008200 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
8201 }
8202 if (winAnimator.mAnimLayer != oldLayer) {
8203 layerChanged = true;
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008204 anyLayerChanged = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008205 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008206 if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautneracafd192012-05-10 10:41:02 -07008207 // Force an animation pass just to update the mDimAnimator layer.
Craig Mautner711f90a2012-07-03 18:43:52 -07008208 updateLayoutToAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008209 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008210 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
Craig Mautner8863cca2012-09-18 15:04:34 -07008211 + "mBase=" + w.mBaseLayer
8212 + " mLayer=" + w.mLayer
8213 + (w.mAppToken == null ?
8214 "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
8215 + " =mAnimLayer=" + winAnimator.mAnimLayer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 //System.out.println(
8217 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8218 }
Svetoslav Ganov55468c62012-10-15 15:09:02 -07008219
8220 if (anyLayerChanged) {
8221 scheduleNotifyWindowLayersChangedIfNeededLocked(getDefaultDisplayContentLocked());
8222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008223 }
8224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008225 private final void performLayoutAndPlaceSurfacesLocked() {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008226 int loopCount = 6;
Craig Mautnera13a41d2012-10-16 12:53:13 -07008227 do {
8228 mTraversalScheduled = false;
8229 performLayoutAndPlaceSurfacesLockedLoop();
8230 mH.removeMessages(H.DO_TRAVERSAL);
Dianne Hackborn7ad44382012-10-18 17:46:00 -07008231 loopCount--;
8232 } while (mTraversalScheduled && loopCount > 0);
Craig Mautnera13a41d2012-10-16 12:53:13 -07008233 }
8234
8235 private boolean mInLayout = false;
8236 private final void performLayoutAndPlaceSurfacesLockedLoop() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008237 if (mInLayout) {
Dave Bortcfe65242009-04-09 14:51:04 -07008238 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008239 throw new RuntimeException("Recursive call!");
8240 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008241 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8242 + Debug.getCallers(3));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008243 return;
8244 }
8245
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008246 if (mWaitingForConfig) {
8247 // Our configuration has changed (most likely rotation), but we
8248 // don't yet have the complete configuration to report to
8249 // applications. Don't do any window layout until we have it.
8250 return;
8251 }
8252
Jeff Browne215f262012-09-10 16:01:14 -07008253 if (!mDisplayReady) {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008254 // Not yet initialized, nothing to do.
8255 return;
8256 }
8257
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008258 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008259 mInLayout = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008260 boolean recoveringMemory = false;
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008261
8262 try {
8263 if (mForceRemoves != null) {
8264 recoveringMemory = true;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08008265 // Wait a little bit for things to settle down, and off we go.
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008266 for (int i=0; i<mForceRemoves.size(); i++) {
8267 WindowState ws = mForceRemoves.get(i);
8268 Slog.i(TAG, "Force removing: " + ws);
8269 removeWindowInnerLocked(ws.mSession, ws);
8270 }
8271 mForceRemoves = null;
8272 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8273 Object tmp = new Object();
8274 synchronized (tmp) {
8275 try {
8276 tmp.wait(250);
8277 } catch (InterruptedException e) {
8278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008279 }
8280 }
Dianne Hackborn2e7ffa52011-01-12 13:21:28 -08008281 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07008282 Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008283 }
Craig Mautner59c00972012-07-30 12:10:24 -07008284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 try {
Craig Mautner76a71652012-09-03 23:23:58 -07008286 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008287
Craig Mautner59c00972012-07-30 12:10:24 -07008288 mInLayout = false;
8289
Craig Mautner19d59bc2012-09-04 11:15:56 -07008290 if (needsLayout()) {
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008291 if (++mLayoutRepeatCount < 6) {
8292 requestTraversalLocked();
8293 } else {
8294 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8295 mLayoutRepeatCount = 0;
8296 }
8297 } else {
8298 mLayoutRepeatCount = 0;
8299 }
Craig Mautnerbb1449b2012-03-23 16:11:14 -07008300
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008301 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
Konstantin Lopyrev6e0f65f2010-07-14 14:55:33 -07008302 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
8303 mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
Konstantin Lopyrevdc301012010-07-08 17:55:51 -07008304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008305 } catch (RuntimeException e) {
8306 mInLayout = false;
Dianne Hackborn89620282011-09-11 12:47:45 -07008307 Log.wtf(TAG, "Unhandled exception while laying out windows", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008308 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07008309
8310 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008311 }
8312
Craig Mautner59c00972012-07-30 12:10:24 -07008313 private final void performLayoutLockedInner(final DisplayContent displayContent,
8314 boolean initial, boolean updateInputWindows) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07008315 if (!displayContent.layoutNeeded) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008316 return;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008317 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07008318 displayContent.layoutNeeded = false;
Craig Mautner59c00972012-07-30 12:10:24 -07008319 WindowList windows = displayContent.getWindowList();
Craig Mautner69b08182012-09-05 13:07:13 -07008320 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -07008321
8322 DisplayInfo displayInfo = displayContent.getDisplayInfo();
8323 final int dw = displayInfo.logicalWidth;
8324 final int dh = displayInfo.logicalHeight;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008325
Dianne Hackborndf89e652011-10-06 22:35:11 -07008326 final int NFW = mFakeWindows.size();
8327 for (int i=0; i<NFW; i++) {
8328 mFakeWindows.get(i).layout(dw, dh);
8329 }
8330
Craig Mautner59c00972012-07-30 12:10:24 -07008331 final int N = windows.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008332 int i;
8333
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008334 if (DEBUG_LAYOUT) {
8335 Slog.v(TAG, "-------------------------------------");
8336 Slog.v(TAG, "performLayout: needed="
Craig Mautner19d59bc2012-09-04 11:15:56 -07008337 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008338 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008339
8340 WindowStateAnimator universeBackground = null;
8341
Craig Mautner69b08182012-09-05 13:07:13 -07008342 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
8343 if (isDefaultDisplay) {
8344 // Not needed on non-default displays.
8345 mSystemDecorLayer = mPolicy.getSystemDecorRectLw(mSystemDecorRect);
8346 mScreenRect.set(0, 0, dw, dh);
8347 }
Romain Guy06882f82009-06-10 13:36:04 -07008348
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008349 int seq = mLayoutSeq+1;
8350 if (seq < 0) seq = 0;
8351 mLayoutSeq = seq;
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008352
8353 boolean behindDream = false;
8354
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008355 // First perform layout of any root windows (not attached
8356 // to another window).
8357 int topAttached = -1;
8358 for (i = N-1; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008359 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008360
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008361 // Don't do layout of a window if it is not visible, or
8362 // soon won't be visible, to avoid wasting time and funky
8363 // changes while a window is animating away.
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008364 final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
8365 || win.isGoneForLayoutLw();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008366
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008367 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008368 Slog.v(TAG, "1ST PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008369 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
Craig Mautner812d2ca2012-09-27 15:35:34 -07008370 + " mLayoutAttached=" + win.mLayoutAttached
Craig Mautnera3f4bf52012-10-10 20:37:48 -07008371 + " screen changed=" + win.isConfigChanged());
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008372 final AppWindowToken atoken = win.mAppToken;
8373 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
8374 + win.mViewVisibility + " mRelayoutCalled="
8375 + win.mRelayoutCalled + " hidden="
8376 + win.mRootToken.hidden + " hiddenRequested="
8377 + (atoken != null && atoken.hiddenRequested)
8378 + " mAttachedHidden=" + win.mAttachedHidden);
8379 else Slog.v(TAG, " VIS: mViewVisibility="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008380 + win.mViewVisibility + " mRelayoutCalled="
8381 + win.mRelayoutCalled + " hidden="
8382 + win.mRootToken.hidden + " hiddenRequested="
8383 + (atoken != null && atoken.hiddenRequested)
8384 + " mAttachedHidden=" + win.mAttachedHidden);
8385 }
Craig Mautner69b08182012-09-05 13:07:13 -07008386
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008387 // If this view is GONE, then skip it -- keep the current
8388 // frame, and let the caller know so they can ignore it
8389 // if they want. (We do the normal layout for INVISIBLE
8390 // windows, since that means "perform layout as normal,
8391 // just don't display").
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008392 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Chet Haased5d11af2012-10-31 08:57:17 -07008393 || ((win.mAttrs.type == TYPE_KEYGUARD || win.mAttrs.type == TYPE_WALLPAPER) &&
8394 win.isConfigChanged())
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008395 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08008396 if (!win.mLayoutAttached) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008397 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008398 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008399 win.mContentChanged = false;
8400 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008401 if (win.mAttrs.type == TYPE_DREAM) {
8402 // Don't layout windows behind a dream, so that if it
8403 // does stuff like hide the status bar we won't get a
8404 // bad transition when it goes away.
8405 behindDream = true;
8406 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008407 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008408 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008409 mPolicy.layoutWindowLw(win, win.mAttrs, null);
8410 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008411 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008412 + win.mFrame + " mContainingFrame="
8413 + win.mContainingFrame + " mDisplayFrame="
8414 + win.mDisplayFrame);
8415 } else {
8416 if (topAttached < 0) topAttached = i;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07008417 }
Dianne Hackborn958b9ad2009-03-31 18:00:36 -07008418 }
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07008419 if (win.mViewVisibility == View.VISIBLE
8420 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8421 && universeBackground == null) {
8422 universeBackground = win.mWinAnimator;
8423 }
8424 }
8425
8426 if (mAnimator.mUniverseBackground != universeBackground) {
8427 mFocusMayChange = true;
8428 mAnimator.mUniverseBackground = universeBackground;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008429 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008430
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008431 boolean attachedBehindDream = false;
8432
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008433 // Now perform layout of attached windows, which usually
8434 // depend on the position of the window they are attached to.
8435 // XXX does not deal with windows that are attached to windows
8436 // that are themselves attached.
8437 for (i = topAttached; i >= 0; i--) {
Craig Mautner59c00972012-07-30 12:10:24 -07008438 final WindowState win = windows.get(i);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008439
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008440 if (win.mLayoutAttached) {
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008441 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008442 + " mHaveFrame=" + win.mHaveFrame
8443 + " mViewVisibility=" + win.mViewVisibility
8444 + " mRelayoutCalled=" + win.mRelayoutCalled);
Dianne Hackborn1c24e952010-11-23 00:34:30 -08008445 // If this view is GONE, then skip it -- keep the current
8446 // frame, and let the caller know so they can ignore it
8447 // if they want. (We do the normal layout for INVISIBLE
8448 // windows, since that means "perform layout as normal,
8449 // just don't display").
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008450 if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
8451 continue;
8452 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008453 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008454 || !win.mHaveFrame || win.mLayoutNeeded) {
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008455 if (initial) {
Dianne Hackborn0f761d62010-11-30 22:06:10 -08008456 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Dianne Hackborn8e11ef02010-11-18 19:47:42 -08008457 win.mContentChanged = false;
8458 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08008459 win.mLayoutNeeded = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04008460 win.prelayout();
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008461 mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8462 win.mLayoutSeq = seq;
Dianne Hackborn01b02a72012-01-12 14:05:03 -08008463 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame="
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008464 + win.mFrame + " mContainingFrame="
8465 + win.mContainingFrame + " mDisplayFrame="
8466 + win.mDisplayFrame);
8467 }
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07008468 } else if (win.mAttrs.type == TYPE_DREAM) {
8469 // Don't layout windows behind a dream, so that if it
8470 // does stuff like hide the status bar we won't get a
8471 // bad transition when it goes away.
8472 attachedBehindDream = behindDream;
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008473 }
8474 }
Jeff Brown349703e2010-06-22 01:27:15 -07008475
8476 // Window frames may have changed. Tell the input dispatcher about it.
Jeff Brown3a22cd92011-01-21 13:59:04 -08008477 mInputMonitor.setUpdateInputWindowsNeededLw();
8478 if (updateInputWindows) {
Jeff Brown2e44b072011-01-24 15:21:56 -08008479 mInputMonitor.updateInputWindowsLw(false /*force*/);
Jeff Brown3a22cd92011-01-21 13:59:04 -08008480 }
Dianne Hackbornb8b11a02010-03-10 15:53:11 -08008481
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008482 mPolicy.finishLayoutLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008483 }
Romain Guy06882f82009-06-10 13:36:04 -07008484
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008485 void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8486 // If the screen is currently frozen or off, then keep
8487 // it frozen/off until this window draws at its new
8488 // orientation.
Craig Mautner2fb98b12012-03-20 17:24:00 -07008489 if (!okToDisplay()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008490 if (DEBUG_ORIENTATION) Slog.v(TAG,
8491 "Changing surface while display frozen: " + w);
8492 w.mOrientationChanging = true;
Craig Mautner3255a282012-04-16 15:42:47 -07008493 mInnerFields.mOrientationChangeComplete = false;
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008494 if (!mWindowsFreezingScreen) {
8495 mWindowsFreezingScreen = true;
8496 // XXX should probably keep timeout from
8497 // when we first froze the display.
8498 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8499 mH.sendMessageDelayed(mH.obtainMessage(
Craig Mautner7dfcb012012-10-10 10:24:47 -07008500 H.WINDOW_FREEZE_TIMEOUT), WINDOW_FREEZE_TIMEOUT_DURATION);
Dianne Hackborn3ec891a2011-10-25 13:58:30 -07008501 }
8502 }
8503 }
8504
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008505 /**
8506 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner19d59bc2012-09-04 11:15:56 -07008507 * @param windows List of windows on default display.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008508 * @return bitmap indicating if another pass through layout must be made.
8509 */
Craig Mautner59c00972012-07-30 12:10:24 -07008510 public int handleAppTransitionReadyLocked(WindowList windows) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008511 int changes = 0;
8512 int i;
8513 int NN = mOpeningApps.size();
8514 boolean goodToGo = true;
8515 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8516 "Checking " + NN + " opening apps (frozen="
8517 + mDisplayFrozen + " timeout="
8518 + mAppTransitionTimeout + ")...");
8519 if (!mDisplayFrozen && !mAppTransitionTimeout) {
8520 // If the display isn't frozen, wait to do anything until
8521 // all of the apps are ready. Otherwise just go because
8522 // we'll unfreeze the display when everyone is ready.
8523 for (i=0; i<NN && goodToGo; i++) {
8524 AppWindowToken wtoken = mOpeningApps.get(i);
8525 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner1d961d42012-05-27 12:02:11 -07008526 "Check opening app=" + wtoken + ": allDrawn="
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008527 + wtoken.allDrawn + " startingDisplayed="
Craig Mautner7358fbf2012-04-12 21:06:33 -07008528 + wtoken.startingDisplayed + " startingMoved="
8529 + wtoken.startingMoved);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008530 if (!wtoken.allDrawn && !wtoken.startingDisplayed
8531 && !wtoken.startingMoved) {
8532 goodToGo = false;
8533 }
8534 }
8535 }
8536 if (goodToGo) {
8537 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
8538 int transit = mNextAppTransition;
8539 if (mSkipAppTransitionAnimation) {
8540 transit = WindowManagerPolicy.TRANSIT_UNSET;
8541 }
8542 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
8543 mAppTransitionReady = false;
8544 mAppTransitionRunning = true;
8545 mAppTransitionTimeout = false;
8546 mStartingIconInTransition = false;
8547 mSkipAppTransitionAnimation = false;
8548
8549 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8550
Craig Mautneref25d7a2012-05-15 23:01:47 -07008551 rebuildAppWindowListLocked();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008552
Craig Mautner0afddcb2012-05-08 15:38:00 -07008553 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
Craig Mautner83339b42012-05-01 22:13:23 -07008554 WindowState oldWallpaper =
8555 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
Craig Mautner0afddcb2012-05-08 15:38:00 -07008556 && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
Craig Mautner83339b42012-05-01 22:13:23 -07008557 ? null : mWallpaperTarget;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008558
8559 adjustWallpaperWindowsLocked();
8560 mInnerFields.mWallpaperMayChange = false;
8561
8562 // The top-most window will supply the layout params,
8563 // and we will determine it below.
8564 LayoutParams animLp = null;
8565 int bestAnimLayer = -1;
8566 boolean fullscreenAnim = false;
8567
8568 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8569 "New wallpaper target=" + mWallpaperTarget
Daniel Sandlerab886f52012-06-04 14:36:25 -04008570 + ", oldWallpaper=" + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008571 + ", lower target=" + mLowerWallpaperTarget
8572 + ", upper target=" + mUpperWallpaperTarget);
8573 int foundWallpapers = 0;
8574 // Do a first pass through the tokens for two
8575 // things:
8576 // (1) Determine if both the closing and opening
8577 // app token sets are wallpaper targets, in which
8578 // case special animations are needed
8579 // (since the wallpaper needs to stay static
8580 // behind them).
8581 // (2) Find the layout params of the top-most
8582 // application window in the tokens, which is
8583 // what will control the animation theme.
8584 final int NC = mClosingApps.size();
8585 NN = NC + mOpeningApps.size();
8586 for (i=0; i<NN; i++) {
8587 AppWindowToken wtoken;
8588 int mode;
8589 if (i < NC) {
8590 wtoken = mClosingApps.get(i);
8591 mode = 1;
8592 } else {
8593 wtoken = mOpeningApps.get(i-NC);
8594 mode = 2;
8595 }
8596 if (mLowerWallpaperTarget != null) {
8597 if (mLowerWallpaperTarget.mAppToken == wtoken
8598 || mUpperWallpaperTarget.mAppToken == wtoken) {
8599 foundWallpapers |= mode;
8600 }
8601 }
8602 if (wtoken.appFullscreen) {
8603 WindowState ws = wtoken.findMainWindow();
8604 if (ws != null) {
8605 animLp = ws.mAttrs;
8606 bestAnimLayer = ws.mLayer;
8607 fullscreenAnim = true;
8608 }
8609 } else if (!fullscreenAnim) {
8610 WindowState ws = wtoken.findMainWindow();
8611 if (ws != null) {
8612 if (ws.mLayer > bestAnimLayer) {
8613 animLp = ws.mAttrs;
8614 bestAnimLayer = ws.mLayer;
8615 }
8616 }
8617 }
8618 }
8619
8620 if (foundWallpapers == 3) {
8621 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8622 "Wallpaper animation!");
8623 switch (transit) {
8624 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
8625 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
8626 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
8627 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN;
8628 break;
8629 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
8630 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
8631 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
8632 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE;
8633 break;
8634 }
8635 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8636 "New transit: " + transit);
Daniel Sandlerab886f52012-06-04 14:36:25 -04008637 } else if ((oldWallpaper != null) && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008638 // We are transitioning from an activity with
8639 // a wallpaper to one without.
8640 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
8641 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8642 "New transit away from wallpaper: " + transit);
Craig Mautner8863cca2012-09-18 15:04:34 -07008643 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008644 // We are transitioning from an activity without
8645 // a wallpaper to now showing the wallpaper
8646 transit = WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN;
8647 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8648 "New transit into wallpaper: " + transit);
8649 }
8650
8651 // If all closing windows are obscured, then there is
8652 // no need to do an animation. This is the case, for
8653 // example, when this transition is being done behind
8654 // the lock screen.
8655 if (!mPolicy.allowAppAnimationsLw()) {
8656 animLp = null;
8657 }
8658
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008659 AppWindowToken topOpeningApp = null;
8660 int topOpeningLayer = 0;
8661
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008662 NN = mOpeningApps.size();
8663 for (i=0; i<NN; i++) {
8664 AppWindowToken wtoken = mOpeningApps.get(i);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008665 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008666 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008667 appAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008668 wtoken.reportedVisible = false;
8669 wtoken.inPendingTransaction = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008670 appAnimator.animation = null;
Craig Mautnerbec53f72012-04-05 11:49:05 -07008671 setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008672 wtoken.updateReportedVisibilityLocked();
8673 wtoken.waitingToShow = false;
Craig Mautnerbea12bd2012-08-20 10:18:34 -07008674
8675 appAnimator.mAllAppWinAnimators.clear();
8676 final int N = wtoken.allAppWindows.size();
8677 for (int j = 0; j < N; j++) {
8678 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8679 }
8680 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8681
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008682 if (animLp != null) {
8683 int layer = -1;
8684 for (int j=0; j<wtoken.windows.size(); j++) {
8685 WindowState win = wtoken.windows.get(j);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07008686 if (win.mWinAnimator.mAnimLayer > layer) {
8687 layer = win.mWinAnimator.mAnimLayer;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008688 }
8689 }
8690 if (topOpeningApp == null || layer > topOpeningLayer) {
8691 topOpeningApp = wtoken;
8692 topOpeningLayer = layer;
8693 }
8694 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008695 }
8696 NN = mClosingApps.size();
8697 for (i=0; i<NN; i++) {
8698 AppWindowToken wtoken = mClosingApps.get(i);
8699 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Craig Mautner8863cca2012-09-18 15:04:34 -07008700 "Now closing app " + wtoken);
Craig Mautner59431632012-04-04 11:56:44 -07008701 wtoken.mAppAnimator.clearThumbnail();
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008702 wtoken.inPendingTransaction = false;
Craig Mautner59431632012-04-04 11:56:44 -07008703 wtoken.mAppAnimator.animation = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008704 setTokenVisibilityLocked(wtoken, animLp, false,
8705 transit, false);
8706 wtoken.updateReportedVisibilityLocked();
8707 wtoken.waitingToHide = false;
8708 // Force the allDrawn flag, because we want to start
8709 // this guy's animations regardless of whether it's
8710 // gotten drawn.
8711 wtoken.allDrawn = true;
8712 }
8713
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008714 if (mNextAppTransitionThumbnail != null && topOpeningApp != null
Craig Mautner59431632012-04-04 11:56:44 -07008715 && topOpeningApp.mAppAnimator.animation != null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008716 // This thumbnail animation is very special, we need to have
8717 // an extra surface with the thumbnail included with the animation.
8718 Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(),
8719 mNextAppTransitionThumbnail.getHeight());
8720 try {
Jeff Browne215f262012-09-10 16:01:14 -07008721 // TODO(multi-display): support other displays
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008722 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Jeff Browne215f262012-09-10 16:01:14 -07008723 final Display display = displayContent.getDisplay();
Jeff Brown64a55af2012-08-26 02:47:39 -07008724 Surface surface = new Surface(mFxSession,
8725 "thumbnail anim",
Craig Mautner6881a102012-07-27 13:04:51 -07008726 dirty.width(), dirty.height(),
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008727 PixelFormat.TRANSLUCENT, Surface.HIDDEN);
Jeff Browne215f262012-09-10 16:01:14 -07008728 surface.setLayerStack(display.getLayerStack());
Craig Mautner59431632012-04-04 11:56:44 -07008729 topOpeningApp.mAppAnimator.thumbnail = surface;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008730 if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL "
8731 + surface + ": CREATE");
8732 Surface drawSurface = new Surface();
8733 drawSurface.copyFrom(surface);
8734 Canvas c = drawSurface.lockCanvas(dirty);
8735 c.drawBitmap(mNextAppTransitionThumbnail, 0, 0, null);
8736 drawSurface.unlockCanvasAndPost(c);
8737 drawSurface.release();
Craig Mautner59431632012-04-04 11:56:44 -07008738 topOpeningApp.mAppAnimator.thumbnailLayer = topOpeningLayer;
Michael Jurka21385cd2012-05-03 10:57:31 -07008739 Animation anim = createThumbnailAnimationLocked(
Michael Jurka832cb222012-04-13 09:32:47 -07008740 transit, true, true, mNextAppTransitionScaleUp);
Craig Mautner59431632012-04-04 11:56:44 -07008741 topOpeningApp.mAppAnimator.thumbnailAnimation = anim;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008742 anim.restrictDuration(MAX_ANIMATION_DURATION);
8743 anim.scaleCurrentDuration(mTransitionAnimationScale);
Craig Mautner59431632012-04-04 11:56:44 -07008744 topOpeningApp.mAppAnimator.thumbnailX = mNextAppTransitionStartX;
8745 topOpeningApp.mAppAnimator.thumbnailY = mNextAppTransitionStartY;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008746 } catch (Surface.OutOfResourcesException e) {
8747 Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
8748 + " h=" + dirty.height(), e);
Craig Mautner59431632012-04-04 11:56:44 -07008749 topOpeningApp.mAppAnimator.clearThumbnail();
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008750 }
8751 }
8752
Dianne Hackborneabfb3a2012-04-16 16:28:22 -07008753 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008754 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07008755 mNextAppTransitionThumbnail = null;
Dianne Hackborn84375872012-06-01 19:03:50 -07008756 scheduleAnimationCallback(mNextAppTransitionCallback);
8757 mNextAppTransitionCallback = null;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008758
8759 mOpeningApps.clear();
8760 mClosingApps.clear();
8761
8762 // This has changed the visibility of windows, so perform
8763 // a new layout to get them all up-to-date.
Craig Mautner39834192012-09-02 07:47:24 -07008764 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008765 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008766 getDefaultDisplayContentLocked().layoutNeeded = true;
Craig Mautner59c00972012-07-30 12:10:24 -07008767
8768 // TODO(multidisplay): IMEs are only supported on the default display.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07008769 if (windows == getDefaultWindowListLocked()
8770 && !moveInputMethodWindowsIfNeededLocked(true)) {
Craig Mautner59c00972012-07-30 12:10:24 -07008771 assignLayersLocked(windows);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008772 }
Craig Mautner59c00972012-07-30 12:10:24 -07008773 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008774 mFocusMayChange = false;
8775 }
8776
8777 return changes;
8778 }
8779
8780 /**
8781 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008782 * @return bitmap indicating if another pass through layout must be made.
8783 */
Craig Mautner2f995a72012-02-21 09:53:21 -08008784 private int handleAnimatingStoppedAndTransitionLocked() {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008785 int changes = 0;
8786
8787 mAppTransitionRunning = false;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008788 // Restore window app tokens to the ActivityManager views
Craig Mautner3f99fde2012-06-19 14:10:01 -07008789 for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
8790 mAnimatingAppTokens.get(i).sendingToBottom = false;
8791 }
Craig Mautneref25d7a2012-05-15 23:01:47 -07008792 mAnimatingAppTokens.clear();
8793 mAnimatingAppTokens.addAll(mAppTokens);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008794 rebuildAppWindowListLocked();
Craig Mautneref25d7a2012-05-15 23:01:47 -07008795
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008796 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
8797 mInnerFields.mAdjResult |= ADJUST_WALLPAPER_LAYERS_CHANGED;
Craig Mautneref25d7a2012-05-15 23:01:47 -07008798 moveInputMethodWindowsIfNeededLocked(true);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008799 mInnerFields.mWallpaperMayChange = true;
8800 // Since the window list has been rebuilt, focus might
8801 // have to be recomputed since the actual order of windows
8802 // might have changed again.
8803 mFocusMayChange = true;
8804
8805 return changes;
8806 }
8807
8808 /**
8809 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8810 *
8811 * @return bitmap indicating if another pass through layout must be made.
8812 */
8813 private int animateAwayWallpaperLocked() {
8814 int changes = 0;
8815 WindowState oldWallpaper = mWallpaperTarget;
8816 if (mLowerWallpaperTarget != null
8817 && mLowerWallpaperTarget.mAppToken != null) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07008818 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008819 "wallpaperForceHiding changed with lower="
8820 + mLowerWallpaperTarget);
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07008821 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008822 "hidden=" + mLowerWallpaperTarget.mAppToken.hidden +
8823 " hiddenRequested=" + mLowerWallpaperTarget.mAppToken.hiddenRequested);
8824 if (mLowerWallpaperTarget.mAppToken.hidden) {
8825 // The lower target has become hidden before we
8826 // actually started the animation... let's completely
8827 // re-evaluate everything.
8828 mLowerWallpaperTarget = mUpperWallpaperTarget = null;
8829 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
8830 }
8831 }
8832 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07008833 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "****** OLD: " + oldWallpaper
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008834 + " NEW: " + mWallpaperTarget
8835 + " LOWER: " + mLowerWallpaperTarget);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008836 return changes;
8837 }
8838
Craig Mautnere32c3072012-03-12 15:25:35 -07008839 private void updateResizingWindows(final WindowState w) {
Craig Mautnera608b882012-03-30 13:03:49 -07008840 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnerade0a9a2012-10-06 13:55:07 -07008841 if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008842 w.mContentInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008843 !w.mLastContentInsets.equals(w.mContentInsets);
Craig Mautnere32c3072012-03-12 15:25:35 -07008844 w.mVisibleInsetsChanged |=
Dianne Hackborn5c58de32012-04-28 19:52:37 -07008845 !w.mLastVisibleInsets.equals(w.mVisibleInsets);
Craig Mautner812d2ca2012-09-27 15:35:34 -07008846 boolean configChanged = w.isConfigChanged();
Craig Mautnere32c3072012-03-12 15:25:35 -07008847 if (DEBUG_CONFIGURATION && configChanged) {
8848 Slog.v(TAG, "Win " + w + " config changed: "
8849 + mCurConfiguration);
8850 }
8851 if (localLOGV) Slog.v(TAG, "Resizing " + w
8852 + ": configChanged=" + configChanged
8853 + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8854 w.mLastFrame.set(w.mFrame);
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07008855 if (w.mContentInsetsChanged
Craig Mautnere32c3072012-03-12 15:25:35 -07008856 || w.mVisibleInsetsChanged
Craig Mautnera608b882012-03-30 13:03:49 -07008857 || winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008858 || configChanged) {
8859 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8860 Slog.v(TAG, "Resize reasons: "
8861 + " contentInsetsChanged=" + w.mContentInsetsChanged
8862 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008863 + " surfaceResized=" + winAnimator.mSurfaceResized
Craig Mautnere32c3072012-03-12 15:25:35 -07008864 + " configChanged=" + configChanged);
8865 }
8866
8867 w.mLastContentInsets.set(w.mContentInsets);
8868 w.mLastVisibleInsets.set(w.mVisibleInsets);
8869 makeWindowFreezingScreenIfNeededLocked(w);
8870 // If the orientation is changing, then we need to
8871 // hold off on unfreezing the display until this
8872 // window has been redrawn; to do that, we need
8873 // to go through the process of getting informed
8874 // by the application when it has finished drawing.
8875 if (w.mOrientationChanging) {
Craig Mautneref25d7a2012-05-15 23:01:47 -07008876 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautner83339b42012-05-01 22:13:23 -07008877 "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008878 + w + ", surface " + winAnimator.mSurface);
Craig Mautner749a7bb2012-04-02 13:49:53 -07008879 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
Craig Mautnere32c3072012-03-12 15:25:35 -07008880 if (w.mAppToken != null) {
8881 w.mAppToken.allDrawn = false;
8882 }
8883 }
8884 if (!mResizingWindows.contains(w)) {
8885 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008886 "Resizing window " + w + " to " + winAnimator.mSurfaceW
8887 + "x" + winAnimator.mSurfaceH);
Craig Mautnere32c3072012-03-12 15:25:35 -07008888 mResizingWindows.add(w);
8889 }
8890 } else if (w.mOrientationChanging) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07008891 if (w.isDrawnLw()) {
Craig Mautnere32c3072012-03-12 15:25:35 -07008892 if (DEBUG_ORIENTATION) Slog.v(TAG,
8893 "Orientation not waiting for draw in "
Craig Mautneracaf9cc2012-04-17 11:45:25 -07008894 + w + ", surface " + winAnimator.mSurface);
Craig Mautnere32c3072012-03-12 15:25:35 -07008895 w.mOrientationChanging = false;
8896 }
8897 }
8898 }
8899 }
8900
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008901 /**
8902 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8903 *
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008904 * @param w WindowState this method is applied to.
8905 * @param currentTime The time which animations use for calculating transitions.
8906 * @param innerDw Width of app window.
8907 * @param innerDh Height of app window.
8908 */
8909 private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8910 final int innerDw, final int innerDh) {
8911 final WindowManager.LayoutParams attrs = w.mAttrs;
8912 final int attrFlags = attrs.flags;
8913 final boolean canBeSeen = w.isDisplayedLw();
8914
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07008915 if (w.mHasSurface) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008916 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8917 mInnerFields.mHoldScreen = w.mSession;
8918 }
8919 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8920 && mInnerFields.mScreenBrightness < 0) {
8921 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8922 }
8923 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8924 && mInnerFields.mButtonBrightness < 0) {
8925 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8926 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07008927 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8928 && mInnerFields.mUserActivityTimeout < 0) {
8929 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8930 }
8931
Craig Mautner65d11b32012-10-01 13:59:52 -07008932 final int type = attrs.type;
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008933 if (canBeSeen
Craig Mautner65d11b32012-10-01 13:59:52 -07008934 && (type == TYPE_SYSTEM_DIALOG
Craig Mautner88400d32012-09-30 12:35:45 -07008935 || type == TYPE_RECENTS_OVERLAY
Craig Mautner65d11b32012-10-01 13:59:52 -07008936 || type == TYPE_KEYGUARD
8937 || type == TYPE_SYSTEM_ERROR)) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008938 mInnerFields.mSyswin = true;
8939 }
Craig Mautner65d11b32012-10-01 13:59:52 -07008940
8941 if (canBeSeen) {
8942 if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8943 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_MIRROR;
8944 } else if (mInnerFields.mDisplayHasContent
8945 == LayoutFields.DISPLAY_CONTENT_UNKNOWN) {
8946 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNIQUE;
8947 }
8948 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008949 }
8950
8951 boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8952 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8953 // This window completely covers everything behind it,
Craig Mautner2fb98b12012-03-20 17:24:00 -07008954 // so we want to leave all of them as undimmed (for
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008955 // performance reasons).
8956 mInnerFields.mObscured = true;
Craig Mautner35af2ff2012-04-24 14:30:15 -07008957 } else if (canBeSeen && (attrFlags & FLAG_DIM_BEHIND) != 0
Craig Mautner236a35b2012-06-08 09:54:59 -07008958 && !(w.mAppToken != null && w.mAppToken.hiddenRequested)
8959 && !w.mExiting) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07008960 if (localLOGV) Slog.v(TAG, "Win " + w + " obscured=" + mInnerFields.mObscured);
8961 if (!mInnerFields.mDimming) {
8962 //Slog.i(TAG, "DIM BEHIND: " + w);
8963 mInnerFields.mDimming = true;
Craig Mautneracafd192012-05-10 10:41:02 -07008964 final WindowStateAnimator winAnimator = w.mWinAnimator;
Craig Mautnera91f9e22012-09-14 16:22:08 -07008965 if (!mAnimator.isDimmingLocked(winAnimator)) {
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008966 final int width, height;
Craig Mautner65d11b32012-10-01 13:59:52 -07008967 if (attrs.type == TYPE_BOOT_PROGRESS) {
Craig Mautner59c00972012-07-30 12:10:24 -07008968 final DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo();
8969 width = displayInfo.logicalWidth;
8970 height = displayInfo.logicalHeight;
Craig Mautnerf8d4fbb2012-04-11 09:25:53 -07008971 } else {
8972 width = innerDw;
8973 height = innerDh;
8974 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07008975 startDimmingLocked(
8976 winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, width, height);
Craig Mautner61ac6bb2012-02-02 17:29:33 -08008977 }
8978 }
8979 }
8980 }
8981
Craig Mautner6fbda632012-07-03 09:26:39 -07008982 private void updateAllDrawnLocked() {
8983 // See if any windows have been drawn, so they (and others
8984 // associated with them) can now be shown.
8985 final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
8986 final int NT = appTokens.size();
8987 for (int i=0; i<NT; i++) {
8988 AppWindowToken wtoken = appTokens.get(i);
8989 if (!wtoken.allDrawn) {
8990 int numInteresting = wtoken.numInterestingWindows;
8991 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8992 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
8993 "allDrawn: " + wtoken
8994 + " interesting=" + numInteresting
8995 + " drawn=" + wtoken.numDrawnWindows);
8996 wtoken.allDrawn = true;
8997 }
8998 }
8999 }
9000 }
9001
Brad Fitzpatrick68044332010-11-22 18:19:48 -08009002 // "Something has changed! Let's make it correct now."
Craig Mautner76a71652012-09-03 23:23:58 -07009003 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
Craig Mautner7d8df392012-04-06 15:26:23 -07009004 if (DEBUG_WINDOW_TRACE) {
Craig Mautner3255a282012-04-16 15:42:47 -07009005 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
Craig Mautnera51a9562012-04-17 17:05:26 -07009006 + Debug.getCallers(3));
Craig Mautner7d8df392012-04-06 15:26:23 -07009007 }
Joe Onorato34bcebc2010-07-07 18:05:01 -04009008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009 final long currentTime = SystemClock.uptimeMillis();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 int i;
9012
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009013 if (mFocusMayChange) {
9014 mFocusMayChange = false;
Jeff Brown3a22cd92011-01-21 13:59:04 -08009015 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
9016 false /*updateInputWindows*/);
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009017 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 // Initialize state of exiting tokens.
9020 for (i=mExitingTokens.size()-1; i>=0; i--) {
9021 mExitingTokens.get(i).hasVisible = false;
9022 }
9023
9024 // Initialize state of exiting applications.
9025 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9026 mExitingAppTokens.get(i).hasVisible = false;
9027 }
9028
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009029 mInnerFields.mHoldScreen = null;
9030 mInnerFields.mScreenBrightness = -1;
9031 mInnerFields.mButtonBrightness = -1;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009032 mInnerFields.mUserActivityTimeout = -1;
Craig Mautner65d11b32012-10-01 13:59:52 -07009033 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009034
Craig Mautner6fbda632012-07-03 09:26:39 -07009035 mTransactionSequence++;
Dianne Hackbornfb86ce92010-08-11 18:11:23 -07009036
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009037 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
Craig Mautner76a71652012-09-03 23:23:58 -07009038 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
9039 final int defaultDw = defaultInfo.logicalWidth;
9040 final int defaultDh = defaultInfo.logicalHeight;
Craig Mautner76a71652012-09-03 23:23:58 -07009041
Dianne Hackborn36991742011-10-11 21:35:26 -07009042 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
9043 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 Surface.openTransaction();
9045 try {
Craig Mautner76a71652012-09-03 23:23:58 -07009046
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009047 if (mWatermark != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07009048 mWatermark.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009049 }
9050 if (mStrictModeFlash != null) {
Craig Mautner76a71652012-09-03 23:23:58 -07009051 mStrictModeFlash.positionSurface(defaultDw, defaultDh);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009052 }
9053
Craig Mautner7358fbf2012-04-12 21:06:33 -07009054 boolean focusDisplayed = false;
Craig Mautner6fbda632012-07-03 09:26:39 -07009055 boolean updateAllDrawn = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009056
Craig Mautner76a71652012-09-03 23:23:58 -07009057 DisplayContentsIterator iterator = new DisplayContentsIterator();
9058 while (iterator.hasNext()) {
9059 final DisplayContent displayContent = iterator.next();
9060 WindowList windows = displayContent.getWindowList();
9061 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautner19d59bc2012-09-04 11:15:56 -07009062 final int displayId = displayContent.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -07009063 final int dw = displayInfo.logicalWidth;
9064 final int dh = displayInfo.logicalHeight;
9065 final int innerDw = displayInfo.appWidth;
9066 final int innerDh = displayInfo.appHeight;
Craig Mautner19d59bc2012-09-04 11:15:56 -07009067 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009068
Craig Mautner65d11b32012-10-01 13:59:52 -07009069 // Reset for each display unless we are forcing mirroring.
9070 if (mInnerFields.mDisplayHasContent != LayoutFields.DISPLAY_CONTENT_MIRROR) {
9071 mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
9072 }
9073
Craig Mautner76a71652012-09-03 23:23:58 -07009074 int repeats = 0;
9075 do {
9076 repeats++;
9077 if (repeats > 6) {
9078 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Craig Mautner76a71652012-09-03 23:23:58 -07009079 displayContent.layoutNeeded = false;
9080 break;
Craig Mautner5702d4d2012-06-30 14:10:16 -07009081 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009082
Craig Mautner76a71652012-09-03 23:23:58 -07009083 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
9084 displayContent.pendingLayoutChanges);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009085
Craig Mautner76a71652012-09-03 23:23:58 -07009086 if (isDefaultDisplay && ((displayContent.pendingLayoutChanges
9087 & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0)
9088 && ((adjustWallpaperWindowsLocked()
9089 & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0)) {
9090 assignLayersLocked(windows);
Craig Mautner76a71652012-09-03 23:23:58 -07009091 displayContent.layoutNeeded = true;
9092 }
9093
9094 if (isDefaultDisplay && (displayContent.pendingLayoutChanges
9095 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
9096 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
9097 if (updateOrientationFromAppTokensLocked(true)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009098 displayContent.layoutNeeded = true;
9099 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009100 }
9101 }
9102
Craig Mautner76a71652012-09-03 23:23:58 -07009103 if ((displayContent.pendingLayoutChanges
9104 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Craig Mautner76a71652012-09-03 23:23:58 -07009105 displayContent.layoutNeeded = true;
Craig Mautner6fbda632012-07-03 09:26:39 -07009106 }
Craig Mautner76a71652012-09-03 23:23:58 -07009107
9108 // FIRST LOOP: Perform a layout, if needed.
9109 if (repeats < 4) {
9110 performLayoutLockedInner(displayContent, repeats == 1,
9111 false /*updateInputWindows*/);
9112 } else {
9113 Slog.w(TAG, "Layout repeat skipped after too many iterations");
9114 }
9115
9116 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
9117 // it is animating.
9118 displayContent.pendingLayoutChanges = 0;
9119
9120 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
9121 + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
9122
Craig Mautner69b08182012-09-05 13:07:13 -07009123 if (isDefaultDisplay) {
9124 mPolicy.beginPostLayoutPolicyLw(dw, dh);
9125 for (i = windows.size() - 1; i >= 0; i--) {
9126 WindowState w = windows.get(i);
9127 if (w.mHasSurface) {
9128 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
9129 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009130 }
Craig Mautner69b08182012-09-05 13:07:13 -07009131 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
9132 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
9133 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
Craig Mautner76a71652012-09-03 23:23:58 -07009134 }
Craig Mautner76a71652012-09-03 23:23:58 -07009135 } while (displayContent.pendingLayoutChanges != 0);
9136
9137 mInnerFields.mObscured = false;
9138 mInnerFields.mDimming = false;
9139 mInnerFields.mSyswin = false;
9140
9141 // Only used if default window
9142 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
9143
9144 final int N = windows.size();
9145 for (i=N-1; i>=0; i--) {
9146 WindowState w = windows.get(i);
9147
9148 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
9149
9150 // Update effect.
9151 w.mObscured = mInnerFields.mObscured;
9152 if (!mInnerFields.mObscured) {
9153 handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
9154 }
9155
9156 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
9157 && w.isVisibleLw()) {
9158 // This is the wallpaper target and its obscured state
9159 // changed... make sure the current wallaper's visibility
9160 // has been updated accordingly.
9161 updateWallpaperVisibilityLocked();
9162 }
9163
9164 final WindowStateAnimator winAnimator = w.mWinAnimator;
9165
9166 // If the window has moved due to its containing
9167 // content frame changing, then we'd like to animate
9168 // it.
9169 if (w.mHasSurface && w.shouldAnimateMove()) {
9170 // Frame has moved, containing content frame
9171 // has also moved, and we're not currently animating...
9172 // let's do something.
9173 Animation a = AnimationUtils.loadAnimation(mContext,
9174 com.android.internal.R.anim.window_move_from_decor);
9175 winAnimator.setAnimation(a);
9176 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
9177 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
9178 try {
9179 w.mClient.moved(w.mFrame.left, w.mFrame.top);
9180 } catch (RemoteException e) {
9181 }
9182 }
9183
9184 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
9185 w.mContentChanged = false;
9186
9187 // Moved from updateWindowsAndWallpaperLocked().
9188 if (w.mHasSurface) {
9189 // Take care of the window being ready to display.
Craig Mautner69b08182012-09-05 13:07:13 -07009190 final boolean committed =
9191 winAnimator.commitFinishDrawingLocked(currentTime);
9192 if (isDefaultDisplay && committed) {
Dianne Hackborn7ad44382012-10-18 17:46:00 -07009193 if (w.mAttrs.type == TYPE_DREAM) {
9194 // HACK: When a dream is shown, it may at that
9195 // point hide the lock screen. So we need to
9196 // redo the layout to let the phone window manager
9197 // make this happen.
9198 displayContent.pendingLayoutChanges |=
9199 WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9200 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
9201 debugLayoutRepeats(
9202 "dream and commitFinishDrawingLocked true",
9203 displayContent.pendingLayoutChanges);
9204 }
9205 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009206 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009207 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautner76a71652012-09-03 23:23:58 -07009208 "First draw done in potential wallpaper target " + w);
9209 mInnerFields.mWallpaperMayChange = true;
9210 displayContent.pendingLayoutChanges |=
9211 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9212 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
9213 debugLayoutRepeats(
9214 "wallpaper and commitFinishDrawingLocked true",
9215 displayContent.pendingLayoutChanges);
Craig Mautner6fbda632012-07-03 09:26:39 -07009216 }
9217 }
Craig Mautner76a71652012-09-03 23:23:58 -07009218 }
9219
Craig Mautnera91f9e22012-09-14 16:22:08 -07009220 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautner76a71652012-09-03 23:23:58 -07009221
9222 final AppWindowToken atoken = w.mAppToken;
Craig Mautner65d11b32012-10-01 13:59:52 -07009223 if (DEBUG_STARTING_WINDOW && atoken != null
9224 && w == atoken.startingWindow) {
Craig Mautner76a71652012-09-03 23:23:58 -07009225 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
9226 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
9227 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
9228 }
9229 if (atoken != null
9230 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
9231 if (atoken.lastTransactionSequence != mTransactionSequence) {
9232 atoken.lastTransactionSequence = mTransactionSequence;
9233 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9234 atoken.startingDisplayed = false;
9235 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009236 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Craig Mautner76a71652012-09-03 23:23:58 -07009237 && !w.mExiting && !w.mDestroying) {
9238 if (WindowManagerService.DEBUG_VISIBILITY ||
9239 WindowManagerService.DEBUG_ORIENTATION) {
9240 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
9241 + ", isAnimating=" + winAnimator.isAnimating());
9242 if (!w.isDrawnLw()) {
9243 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
9244 + " pv=" + w.mPolicyVisibility
9245 + " mDrawState=" + winAnimator.mDrawState
9246 + " ah=" + w.mAttachedHidden
9247 + " th=" + atoken.hiddenRequested
9248 + " a=" + winAnimator.mAnimating);
Craig Mautner6fbda632012-07-03 09:26:39 -07009249 }
9250 }
Craig Mautner76a71652012-09-03 23:23:58 -07009251 if (w != atoken.startingWindow) {
9252 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
9253 atoken.numInterestingWindows++;
9254 if (w.isDrawnLw()) {
9255 atoken.numDrawnWindows++;
9256 if (WindowManagerService.DEBUG_VISIBILITY ||
9257 WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
9258 "tokenMayBeDrawn: " + atoken
9259 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
9260 + " mAppFreezing=" + w.mAppFreezing);
9261 updateAllDrawn = true;
9262 }
9263 }
9264 } else if (w.isDrawnLw()) {
9265 atoken.startingDisplayed = true;
9266 }
Craig Mautner6fbda632012-07-03 09:26:39 -07009267 }
9268 }
9269 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009270
Craig Mautner76a71652012-09-03 23:23:58 -07009271 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
9272 && w.isDisplayedLw()) {
9273 focusDisplayed = true;
9274 }
Craig Mautner51bb12b2012-04-27 14:39:53 -07009275
Craig Mautner76a71652012-09-03 23:23:58 -07009276 updateResizingWindows(w);
9277 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009278
Craig Mautner65d11b32012-10-01 13:59:52 -07009279 final boolean hasUniqueContent;
9280 switch (mInnerFields.mDisplayHasContent) {
9281 case LayoutFields.DISPLAY_CONTENT_MIRROR:
9282 hasUniqueContent = isDefaultDisplay;
9283 break;
9284 case LayoutFields.DISPLAY_CONTENT_UNIQUE:
9285 hasUniqueContent = true;
9286 break;
9287 case LayoutFields.DISPLAY_CONTENT_UNKNOWN:
9288 default:
9289 hasUniqueContent = false;
9290 break;
9291 }
9292 mDisplayManagerService.setDisplayHasContent(displayId, hasUniqueContent,
9293 true /* inTraversal, must call performTraversalInTrans... below */);
9294
Craig Mautnera91f9e22012-09-14 16:22:08 -07009295 if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
9296 stopDimmingLocked(displayId);
9297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009298 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009299
Craig Mautner6fbda632012-07-03 09:26:39 -07009300 if (updateAllDrawn) {
9301 updateAllDrawnLocked();
9302 }
9303
Craig Mautner7358fbf2012-04-12 21:06:33 -07009304 if (focusDisplayed) {
9305 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9306 }
Craig Mautner65d11b32012-10-01 13:59:52 -07009307
9308 // Give the display manager a chance to adjust properties
9309 // like display rotation if it needs to.
9310 mDisplayManagerService.performTraversalInTransactionFromWindowManager();
9311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009312 } catch (RuntimeException e) {
Dianne Hackborn89620282011-09-11 12:47:45 -07009313 Log.wtf(TAG, "Unhandled exception in Window Manager", e);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07009314 } finally {
9315 Surface.closeTransaction();
Chet Haased5d11af2012-10-31 08:57:17 -07009316 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
9317 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 }
9319
Craig Mautner76a71652012-09-03 23:23:58 -07009320 final WindowList defaultWindows = defaultDisplay.getWindowList();
9321
Craig Mautner764983d2012-03-22 11:37:36 -07009322 // If we are ready to perform an app transition, check through
9323 // all of the app tokens to be shown and see if they are ready
9324 // to go.
9325 if (mAppTransitionReady) {
Craig Mautner76a71652012-09-03 23:23:58 -07009326 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009327 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009328 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009329 }
9330
9331 mInnerFields.mAdjResult = 0;
9332
9333 if (!mAnimator.mAnimating && mAppTransitionRunning) {
9334 // We have finished the animation of an app transition. To do
9335 // this, we have delayed a lot of operations like showing and
9336 // hiding apps, moving apps in Z-order, etc. The app token list
9337 // reflects the correct Z-order, but the window list may now
9338 // be out of sync with it. So here we will just rebuild the
9339 // entire app window list. Fun!
Craig Mautner76a71652012-09-03 23:23:58 -07009340 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009341 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
Craig Mautner76a71652012-09-03 23:23:58 -07009342 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009343 }
9344
Craig Mautner76a71652012-09-03 23:23:58 -07009345 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
9346 && !mAppTransitionReady) {
Craig Mautner764983d2012-03-22 11:37:36 -07009347 // At this point, there was a window with a wallpaper that
9348 // was force hiding other windows behind it, but now it
9349 // is going away. This may be simple -- just animate
9350 // away the wallpaper and its window -- or it may be
9351 // hard -- the wallpaper now needs to be shown behind
9352 // something that was hidden.
Craig Mautner76a71652012-09-03 23:23:58 -07009353 defaultDisplay.pendingLayoutChanges |= animateAwayWallpaperLocked();
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009354 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
Craig Mautner76a71652012-09-03 23:23:58 -07009355 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009356 }
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009357 mInnerFields.mWallpaperForceHidingChanged = false;
Craig Mautner764983d2012-03-22 11:37:36 -07009358
Craig Mautnere7ae2502012-03-26 17:11:19 -07009359 if (mInnerFields.mWallpaperMayChange) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009360 if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautnere7ae2502012-03-26 17:11:19 -07009361 "Wallpaper may change! Adjusting");
9362 mInnerFields.mAdjResult |= adjustWallpaperWindowsLocked();
9363 }
9364
9365 if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009366 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautnere7ae2502012-03-26 17:11:19 -07009367 "Wallpaper layer changed: assigning layers + relayout");
Craig Mautner76a71652012-09-03 23:23:58 -07009368 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9369 assignLayersLocked(defaultWindows);
Craig Mautnere7ae2502012-03-26 17:11:19 -07009370 } else if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07009371 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Craig Mautnere7ae2502012-03-26 17:11:19 -07009372 "Wallpaper visibility changed: relayout");
Craig Mautner76a71652012-09-03 23:23:58 -07009373 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009374 }
9375
9376 if (mFocusMayChange) {
9377 mFocusMayChange = false;
9378 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
9379 false /*updateInputWindows*/)) {
Craig Mautner76a71652012-09-03 23:23:58 -07009380 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
Craig Mautnere7ae2502012-03-26 17:11:19 -07009381 mInnerFields.mAdjResult = 0;
9382 }
9383 }
Craig Mautner764983d2012-03-22 11:37:36 -07009384
Craig Mautner19d59bc2012-09-04 11:15:56 -07009385 if (needsLayout()) {
Craig Mautner76a71652012-09-03 23:23:58 -07009386 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9387 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
9388 defaultDisplay.pendingLayoutChanges);
Craig Mautner764983d2012-03-22 11:37:36 -07009389 }
9390
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009391 for (i = mResizingWindows.size() - 1; i >= 0; i--) {
9392 WindowState win = mResizingWindows.get(i);
9393 if (win.mAppFreezing) {
9394 // Don't remove this window until rotation has completed.
9395 continue;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009396 }
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009397 final WindowStateAnimator winAnimator = win.mWinAnimator;
9398 try {
9399 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
9400 "Reporting new frame to " + win + ": " + win.mCompatFrame);
9401 int diff = 0;
9402 boolean configChanged = win.isConfigChanged();
Dianne Hackborn7ff30112012-11-08 11:12:09 -08009403 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
Craig Mautnerade0a9a2012-10-06 13:55:07 -07009404 && configChanged) {
9405 Slog.i(TAG, "Sending new config to window " + win + ": "
9406 + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
9407 + " / " + mCurConfiguration + " / 0x"
9408 + Integer.toHexString(diff));
9409 }
9410 win.mConfiguration = mCurConfiguration;
9411 if (DEBUG_ORIENTATION &&
9412 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
9413 TAG, "Resizing " + win + " WITH DRAW PENDING");
9414 win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets,
9415 winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
9416 configChanged ? win.mConfiguration : null);
9417 win.mContentInsetsChanged = false;
9418 win.mVisibleInsetsChanged = false;
9419 winAnimator.mSurfaceResized = false;
9420 } catch (RemoteException e) {
9421 win.mOrientationChanging = false;
9422 }
9423 mResizingWindows.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 }
Romain Guy06882f82009-06-10 13:36:04 -07009425
Craig Mautneracaf9cc2012-04-17 11:45:25 -07009426 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9427 "With display frozen, orientationChangeComplete="
9428 + mInnerFields.mOrientationChangeComplete);
9429 if (mInnerFields.mOrientationChangeComplete) {
9430 if (mWindowsFreezingScreen) {
9431 mWindowsFreezingScreen = false;
9432 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9433 }
9434 stopFreezingDisplayLocked();
9435 }
9436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009437 // Destroy the surface of any windows that are no longer visible.
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009438 boolean wallpaperDestroyed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009439 i = mDestroySurface.size();
9440 if (i > 0) {
9441 do {
9442 i--;
9443 WindowState win = mDestroySurface.get(i);
9444 win.mDestroying = false;
9445 if (mInputMethodWindow == win) {
9446 mInputMethodWindow = null;
9447 }
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009448 if (win == mWallpaperTarget) {
9449 wallpaperDestroyed = true;
9450 }
Dianne Hackborn98129732012-11-01 16:28:16 -07009451 win.mWinAnimator.destroySurfaceLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009452 } while (i > 0);
9453 mDestroySurface.clear();
9454 }
9455
9456 // Time to remove any exiting tokens?
9457 for (i=mExitingTokens.size()-1; i>=0; i--) {
9458 WindowToken token = mExitingTokens.get(i);
9459 if (!token.hasVisible) {
9460 mExitingTokens.remove(i);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009461 if (token.windowType == TYPE_WALLPAPER) {
9462 mWallpaperTokens.remove(token);
Craig Mautner918b53b2012-07-09 14:15:54 -07009463 updateLayoutToAnimWallpaperTokens();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07009464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009465 }
9466 }
9467
9468 // Time to remove any exiting applications?
9469 for (i=mExitingAppTokens.size()-1; i>=0; i--) {
9470 AppWindowToken token = mExitingAppTokens.get(i);
9471 if (!token.hasVisible && !mClosingApps.contains(token)) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07009472 // Make sure there is no animation running on this token,
9473 // so any windows associated with it will be removed as
9474 // soon as their animations are complete
Craig Mautner59431632012-04-04 11:56:44 -07009475 token.mAppAnimator.clearAnimation();
9476 token.mAppAnimator.animating = false;
Dianne Hackbornf99f9c52011-01-12 15:49:25 -08009477 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9478 "performLayout: App token exiting now removed" + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009479 mAppTokens.remove(token);
Craig Mautneref25d7a2012-05-15 23:01:47 -07009480 mAnimatingAppTokens.remove(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009481 mExitingAppTokens.remove(i);
9482 }
9483 }
9484
Dianne Hackborn12d3a942012-04-27 14:16:30 -07009485 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9486 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9487 try {
9488 mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9489 } catch (RemoteException e) {
9490 }
9491 }
9492 mRelayoutWhileAnimating.clear();
9493 }
9494
Craig Mautner19d59bc2012-09-04 11:15:56 -07009495 if (wallpaperDestroyed && (adjustWallpaperWindowsLocked() != 0)) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009496 getDefaultDisplayContentLocked().layoutNeeded = true;
Dianne Hackborn7341d7a2009-08-14 11:37:52 -07009497 }
Craig Mautner76a71652012-09-03 23:23:58 -07009498
9499 DisplayContentsIterator iterator = new DisplayContentsIterator();
9500 while (iterator.hasNext()) {
9501 DisplayContent displayContent = iterator.next();
9502 if (displayContent.pendingLayoutChanges != 0) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009503 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009505 }
Jeff Browneb857f12010-07-16 10:06:33 -07009506
Jeff Brown3a22cd92011-01-21 13:59:04 -08009507 // Finally update all input windows now that the window changes have stabilized.
Jeff Brown2e44b072011-01-24 15:21:56 -08009508 mInputMonitor.updateInputWindowsLw(true /*force*/);
Jeff Browneb857f12010-07-16 10:06:33 -07009509
Craig Mautner259328c2012-08-21 19:30:58 -07009510 setHoldScreenLocked(mInnerFields.mHoldScreen);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009511 if (!mDisplayFrozen) {
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009512 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009513 mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009514 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009515 mPowerManager.setScreenBrightnessOverrideFromWindowManager(
9516 toBrightnessOverride(mInnerFields.mScreenBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009517 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009518 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
Jeff Brown96307042012-07-27 15:51:34 -07009519 mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009520 } else {
Jeff Brown96307042012-07-27 15:51:34 -07009521 mPowerManager.setButtonBrightnessOverrideFromWindowManager(
9522 toBrightnessOverride(mInnerFields.mButtonBrightness));
Dianne Hackborn428ecb62011-01-26 14:53:23 -08009523 }
Jeff Brown1e3b98d2012-09-30 18:58:59 -07009524 mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
9525 mInnerFields.mUserActivityTimeout);
Mike Lockwoodfb73f792009-11-20 11:31:18 -05009526 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -08009527
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009528 if (mTurnOnScreen) {
Dianne Hackbornb601ce12010-03-01 23:36:02 -08009529 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
Jeff Brown96307042012-07-27 15:51:34 -07009530 mPowerManager.wakeUp(SystemClock.uptimeMillis());
Dianne Hackborn93e462b2009-09-15 22:50:40 -07009531 mTurnOnScreen = false;
9532 }
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009533
Craig Mautnera608b882012-03-30 13:03:49 -07009534 if (mInnerFields.mUpdateRotation) {
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009535 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Craig Mautner61ac6bb2012-02-02 17:29:33 -08009536 if (updateRotationUncheckedLocked(false)) {
Dianne Hackborn3e4f9d02011-02-04 14:05:55 -08009537 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009538 } else {
Craig Mautnera608b882012-03-30 13:03:49 -07009539 mInnerFields.mUpdateRotation = false;
Dianne Hackborn89ba6752011-01-23 16:51:16 -08009540 }
9541 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009542
Craig Mautner19d59bc2012-09-04 11:15:56 -07009543 if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9544 && !mInnerFields.mUpdateRotation) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07009545 checkDrawnWindowsLocked();
9546 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009547
Craig Mautner76a71652012-09-03 23:23:58 -07009548 final int N = mPendingRemove.size();
9549 if (N > 0) {
9550 if (mPendingRemoveTmp.length < N) {
9551 mPendingRemoveTmp = new WindowState[N+10];
9552 }
9553 mPendingRemove.toArray(mPendingRemoveTmp);
9554 mPendingRemove.clear();
9555 DisplayContentList displayList = new DisplayContentList();
9556 for (i = 0; i < N; i++) {
9557 WindowState w = mPendingRemoveTmp[i];
9558 removeWindowInnerLocked(w.mSession, w);
9559 if (!displayList.contains(w.mDisplayContent)) {
9560 displayList.add(w.mDisplayContent);
9561 }
9562 }
9563
9564 for (DisplayContent displayContent : displayList) {
9565 assignLayersLocked(displayContent.getWindowList());
Craig Mautner19d59bc2012-09-04 11:15:56 -07009566 displayContent.layoutNeeded = true;
Craig Mautner76a71652012-09-03 23:23:58 -07009567 }
Craig Mautner76a71652012-09-03 23:23:58 -07009568 }
9569
Dianne Hackbornf3bea9c2009-12-09 18:26:21 -08009570 // Check to see if we are now in a state where the screen should
9571 // be enabled, because the window obscured flags have changed.
9572 enableScreenIfNeededLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009573
Craig Mautner711f90a2012-07-03 18:43:52 -07009574 updateLayoutToAnimationLocked();
Craig Mautner7d8df392012-04-06 15:26:23 -07009575
9576 if (DEBUG_WINDOW_TRACE) {
Craig Mautner19d59bc2012-09-04 11:15:56 -07009577 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9578 + mAnimator.mAnimating);
Craig Mautner7d8df392012-04-06 15:26:23 -07009579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009580 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009581
Jeff Brown96307042012-07-27 15:51:34 -07009582 private int toBrightnessOverride(float value) {
9583 return (int)(value * PowerManager.BRIGHTNESS_ON);
9584 }
9585
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009586 void checkDrawnWindowsLocked() {
9587 if (mWaitingForDrawn.size() > 0) {
9588 for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9589 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9590 WindowState win = pair.first;
9591 //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9592 // + win.mRemoved + " visible=" + win.isVisibleLw()
9593 // + " shown=" + win.mSurfaceShown);
9594 if (win.mRemoved || !win.isVisibleLw()) {
9595 // Window has been removed or made invisible; no draw
9596 // will now happen, so stop waiting.
9597 Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9598 try {
9599 pair.second.sendResult(null);
9600 } catch (RemoteException e) {
9601 }
9602 mWaitingForDrawn.remove(pair);
9603 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009604 } else if (win.mWinAnimator.mSurfaceShown) {
Dianne Hackborn38e29a62011-09-18 14:43:08 -07009605 // Window is now drawn (and shown).
9606 try {
9607 pair.second.sendResult(null);
9608 } catch (RemoteException e) {
9609 }
9610 mWaitingForDrawn.remove(pair);
9611 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9612 }
9613 }
9614 }
9615 }
9616
Jeff Brownc38c9be2012-10-04 13:16:19 -07009617 public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
9618 if (token != null && callback != null) {
9619 synchronized (mWindowMap) {
9620 WindowState win = windowForClientLocked(null, token, true);
9621 if (win != null) {
9622 Pair<WindowState, IRemoteCallback> pair =
9623 new Pair<WindowState, IRemoteCallback>(win, callback);
9624 Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9625 mH.sendMessageDelayed(m, 2000);
9626 mWaitingForDrawn.add(pair);
9627 checkDrawnWindowsLocked();
9628 return true;
9629 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009630 }
9631 }
Jeff Brownc38c9be2012-10-04 13:16:19 -07009632 return false;
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07009633 }
9634
Craig Mautner259328c2012-08-21 19:30:58 -07009635 void setHoldScreenLocked(final Session newHoldScreen) {
9636 final boolean hold = newHoldScreen != null;
9637
9638 if (hold && mHoldingScreenOn != newHoldScreen) {
9639 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9640 }
9641 mHoldingScreenOn = newHoldScreen;
9642
9643 final boolean state = mHoldingScreenWakeLock.isHeld();
9644 if (hold != state) {
9645 if (hold) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07009646 mHoldingScreenWakeLock.acquire();
Jeff Brownc38c9be2012-10-04 13:16:19 -07009647 mPolicy.keepScreenOnStartedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009648 } else {
Jeff Brownc38c9be2012-10-04 13:16:19 -07009649 mPolicy.keepScreenOnStoppedLw();
Jeff Brown46b9ac02010-04-22 18:58:52 -07009650 mHoldingScreenWakeLock.release();
9651 }
9652 }
9653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009654
Craig Mautner722285e2012-09-07 13:55:58 -07009655 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -07009656 public void requestTraversal() {
9657 synchronized (mWindowMap) {
9658 requestTraversalLocked();
9659 }
9660 }
9661
Dianne Hackborn8bcd54b2012-01-31 19:04:53 -08009662 void requestTraversalLocked() {
9663 if (!mTraversalScheduled) {
9664 mTraversalScheduled = true;
9665 mH.sendEmptyMessage(H.DO_TRAVERSAL);
9666 }
9667 }
9668
Craig Mautner711f90a2012-07-03 18:43:52 -07009669 /** Note that Locked in this case is on mLayoutToAnim */
Jeff Brown4a06c802012-02-15 15:06:01 -08009670 void scheduleAnimationLocked() {
Craig Mautner711f90a2012-07-03 18:43:52 -07009671 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
9672 if (!layoutToAnim.mAnimationScheduled) {
9673 layoutToAnim.mAnimationScheduled = true;
9674 mChoreographer.postCallback(
9675 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9676 }
9677 }
9678
9679 void updateLayoutToAnimationLocked() {
9680 final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim;
Craig Mautner1caa3992012-06-22 09:46:48 -07009681 synchronized (layoutToAnim) {
9682 // Copy local params to transfer params.
Craig Mautnera91f9e22012-09-14 16:22:08 -07009683 SparseArray<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists;
Craig Mautner59c00972012-07-30 12:10:24 -07009684 allWinAnimatorLists.clear();
9685 DisplayContentsIterator iterator = new DisplayContentsIterator();
9686 while (iterator.hasNext()) {
9687 final DisplayContent displayContent = iterator.next();
9688 WinAnimatorList winAnimatorList = new WinAnimatorList();
9689 final WindowList windows = displayContent.getWindowList();
9690 int N = windows.size();
9691 for (int i = 0; i < N; i++) {
9692 final WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
9693 if (winAnimator.mSurface != null) {
9694 winAnimatorList.add(winAnimator);
9695 }
Craig Mautner1caa3992012-06-22 09:46:48 -07009696 }
Craig Mautnera91f9e22012-09-14 16:22:08 -07009697 allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList);
Craig Mautner1caa3992012-06-22 09:46:48 -07009698 }
Craig Mautner322e4032012-07-13 13:35:20 -07009699
Dianne Hackborn98129732012-11-01 16:28:16 -07009700 if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) {
9701 if (mWallpaperTarget != layoutToAnim.mWallpaperTarget
9702 || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget
9703 || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) {
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -07009704 Slog.d(TAG, "Pushing anim wallpaper: target=" + mWallpaperTarget
9705 + " lower=" + mLowerWallpaperTarget + " upper="
9706 + mUpperWallpaperTarget + "\n" + Debug.getCallers(5, " "));
Dianne Hackborn98129732012-11-01 16:28:16 -07009707 }
9708 }
Craig Mautner1caa3992012-06-22 09:46:48 -07009709 layoutToAnim.mWallpaperTarget = mWallpaperTarget;
Craig Mautner918b53b2012-07-09 14:15:54 -07009710 layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget;
9711 layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget;
Craig Mautner322e4032012-07-13 13:35:20 -07009712
9713 final ArrayList<AppWindowAnimParams> paramList = layoutToAnim.mAppWindowAnimParams;
9714 paramList.clear();
Craig Mautner59c00972012-07-30 12:10:24 -07009715 int N = mAnimatingAppTokens.size();
Craig Mautner322e4032012-07-13 13:35:20 -07009716 for (int i = 0; i < N; i++) {
9717 paramList.add(new AppWindowAnimParams(mAnimatingAppTokens.get(i).mAppAnimator));
9718 }
9719
9720 layoutToAnim.mParamsModified = true;
Craig Mautner711f90a2012-07-03 18:43:52 -07009721 scheduleAnimationLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009722 }
9723 }
Romain Guy06882f82009-06-10 13:36:04 -07009724
Craig Mautner918b53b2012-07-09 14:15:54 -07009725 void updateLayoutToAnimWallpaperTokens() {
9726 synchronized(mLayoutToAnim) {
9727 mLayoutToAnim.mWallpaperTokens = new ArrayList<WindowToken>(mWallpaperTokens);
9728 mLayoutToAnim.mChanges |= LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
9729 }
9730 }
9731
Craig Mautnera91f9e22012-09-14 16:22:08 -07009732 void setAnimDimParams(int displayId, DimAnimator.Parameters params) {
Craig Mautnera76fdb72012-07-03 19:03:02 -07009733 synchronized (mLayoutToAnim) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009734 mLayoutToAnim.mDimParams.put(displayId, params);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009735 scheduleAnimationLocked();
9736 }
9737 }
9738
Craig Mautnera91f9e22012-09-14 16:22:08 -07009739 void startDimmingLocked(final WindowStateAnimator winAnimator, final float target,
Craig Mautnera76fdb72012-07-03 19:03:02 -07009740 final int width, final int height) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07009741 setAnimDimParams(winAnimator.mWin.getDisplayId(),
9742 new DimAnimator.Parameters(winAnimator, width, height, target));
Craig Mautnera76fdb72012-07-03 19:03:02 -07009743 }
9744
Craig Mautnera91f9e22012-09-14 16:22:08 -07009745 void stopDimmingLocked(int displayId) {
9746 setAnimDimParams(displayId, null);
Craig Mautnera76fdb72012-07-03 19:03:02 -07009747 }
9748
Craig Mautner19d59bc2012-09-04 11:15:56 -07009749 private boolean needsLayout() {
9750 DisplayContentsIterator iterator = new DisplayContentsIterator();
9751 while (iterator.hasNext()) {
9752 if (iterator.next().layoutNeeded) {
9753 return true;
9754 }
9755 }
9756 return false;
9757 }
9758
Craig Mautner322e4032012-07-13 13:35:20 -07009759 private boolean copyAnimToLayoutParamsLocked() {
9760 boolean doRequest = false;
9761 final WindowAnimator.AnimatorToLayoutParams animToLayout = mAnimator.mAnimToLayout;
9762 synchronized (animToLayout) {
9763 animToLayout.mUpdateQueued = false;
9764 final int bulkUpdateParams = animToLayout.mBulkUpdateParams;
9765 // TODO(cmautner): As the number of bits grows, use masks of bit groups to
9766 // eliminate unnecessary tests.
9767 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9768 mInnerFields.mUpdateRotation = true;
9769 doRequest = true;
9770 }
9771 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9772 mInnerFields.mWallpaperMayChange = true;
9773 doRequest = true;
9774 }
9775 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9776 mInnerFields.mWallpaperForceHidingChanged = true;
9777 doRequest = true;
9778 }
9779 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9780 mInnerFields.mOrientationChangeComplete = false;
9781 } else {
9782 mInnerFields.mOrientationChangeComplete = true;
9783 if (mWindowsFreezingScreen) {
9784 doRequest = true;
9785 }
9786 }
9787 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9788 mTurnOnScreen = true;
9789 }
9790
Craig Mautner76a71652012-09-03 23:23:58 -07009791 SparseIntArray pendingLayouts = animToLayout.mPendingLayoutChanges;
9792 final int count = pendingLayouts.size();
9793 if (count > 0) {
Craig Mautner322e4032012-07-13 13:35:20 -07009794 doRequest = true;
9795 }
Craig Mautner76a71652012-09-03 23:23:58 -07009796 for (int i = 0; i < count; ++i) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009797 final DisplayContent displayContent =
9798 getDisplayContentLocked(pendingLayouts.keyAt(i));
Craig Mautner2d5618c2012-10-18 13:55:47 -07009799 if (displayContent != null) {
9800 displayContent.pendingLayoutChanges |= pendingLayouts.valueAt(i);
9801 }
Craig Mautner76a71652012-09-03 23:23:58 -07009802 }
Craig Mautner322e4032012-07-13 13:35:20 -07009803
9804 mWindowDetachedWallpaper = animToLayout.mWindowDetachedWallpaper;
9805 }
9806 return doRequest;
9807 }
9808
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009809 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9810 boolean secure) {
9811 final Surface surface = winAnimator.mSurface;
Dianne Hackborn64825172011-03-02 21:32:58 -08009812 boolean leakedSurface = false;
9813 boolean killedApps = false;
Romain Guy06882f82009-06-10 13:36:04 -07009814
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009815 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9816 winAnimator.mSession.mPid, operation);
Romain Guy06882f82009-06-10 13:36:04 -07009817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009818 if (mForceRemoves == null) {
9819 mForceRemoves = new ArrayList<WindowState>();
9820 }
Romain Guy06882f82009-06-10 13:36:04 -07009821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009822 long callingIdentity = Binder.clearCallingIdentity();
9823 try {
9824 // There was some problem... first, do a sanity check of the
9825 // window list to make sure we haven't left any dangling surfaces
9826 // around.
Craig Mautner59c00972012-07-30 12:10:24 -07009827
9828 AllWindowsIterator iterator = new AllWindowsIterator();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009829 Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
Craig Mautner59c00972012-07-30 12:10:24 -07009830 while (iterator.hasNext()) {
9831 WindowState ws = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009832 WindowStateAnimator wsa = ws.mWinAnimator;
9833 if (wsa.mSurface != null) {
9834 if (!mSessions.contains(wsa.mSession)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009835 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009836 + ws + " surface=" + wsa.mSurface
9837 + " token=" + ws.mToken
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009838 + " pid=" + ws.mSession.mPid
9839 + " uid=" + ws.mSession.mUid);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009840 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009841 wsa.mSurface.destroy();
9842 wsa.mSurfaceShown = false;
9843 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009844 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009845 mForceRemoves.add(ws);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009846 leakedSurface = true;
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009847 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009848 Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009849 + ws + " surface=" + wsa.mSurface
9850 + " token=" + ws.mAppToken);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08009851 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009852 wsa.mSurface.destroy();
9853 wsa.mSurfaceShown = false;
9854 wsa.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009855 ws.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 leakedSurface = true;
9857 }
9858 }
9859 }
Romain Guy06882f82009-06-10 13:36:04 -07009860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009861 if (!leakedSurface) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009862 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009863 SparseIntArray pidCandidates = new SparseIntArray();
Craig Mautner59c00972012-07-30 12:10:24 -07009864 iterator = new AllWindowsIterator();
9865 while (iterator.hasNext()) {
9866 WindowState ws = iterator.next();
9867 if (mForceRemoves.contains(ws)) {
9868 continue;
9869 }
9870 WindowStateAnimator wsa = ws.mWinAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009871 if (wsa.mSurface != null) {
9872 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009873 }
9874 }
9875 if (pidCandidates.size() > 0) {
9876 int[] pids = new int[pidCandidates.size()];
9877 for (int i=0; i<pids.length; i++) {
9878 pids[i] = pidCandidates.keyAt(i);
9879 }
9880 try {
Dianne Hackborn64825172011-03-02 21:32:58 -08009881 if (mActivityManager.killPids(pids, "Free memory", secure)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 killedApps = true;
9883 }
9884 } catch (RemoteException e) {
9885 }
9886 }
9887 }
Romain Guy06882f82009-06-10 13:36:04 -07009888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009889 if (leakedSurface || killedApps) {
9890 // We managed to reclaim some memory, so get rid of the trouble
9891 // surface and ask the app to request another one.
Joe Onorato8a9b2202010-02-26 18:56:32 -08009892 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009893 if (surface != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009894 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
Dianne Hackborn5fd21692011-06-07 14:09:47 -07009895 "RECOVER DESTROY", null);
Dianne Hackborn0586a1b2009-09-06 21:08:27 -07009896 surface.destroy();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009897 winAnimator.mSurfaceShown = false;
9898 winAnimator.mSurface = null;
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07009899 winAnimator.mWin.mHasSurface = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009900 }
Romain Guy06882f82009-06-10 13:36:04 -07009901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009902 try {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07009903 winAnimator.mWin.mClient.dispatchGetNewSurface();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009904 } catch (RemoteException e) {
9905 }
9906 }
9907 } finally {
9908 Binder.restoreCallingIdentity(callingIdentity);
9909 }
Dianne Hackborn64825172011-03-02 21:32:58 -08009910
9911 return leakedSurface || killedApps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912 }
Romain Guy06882f82009-06-10 13:36:04 -07009913
Jeff Brown3a22cd92011-01-21 13:59:04 -08009914 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 WindowState newFocus = computeFocusedWindowLocked();
9916 if (mCurrentFocus != newFocus) {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009917 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009918 // This check makes sure that we don't already have the focus
9919 // change message pending.
9920 mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9921 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009922 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009923 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
9924 final WindowState oldFocus = mCurrentFocus;
9925 mCurrentFocus = newFocus;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -07009926 mAnimator.setCurrentFocus(newFocus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009927 mLosingFocus.remove(newFocus);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009928 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
Romain Guy06882f82009-06-10 13:36:04 -07009929
Craig Mautner59c00972012-07-30 12:10:24 -07009930 // TODO(multidisplay): Focused windows on default display only.
Craig Mautner5c0e78c2012-09-12 16:45:36 -07009931 final DisplayContent displayContent = getDefaultDisplayContentLocked();
Craig Mautner59c00972012-07-30 12:10:24 -07009932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933 final WindowState imWindow = mInputMethodWindow;
9934 if (newFocus != imWindow && oldFocus != imWindow) {
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009935 if (moveInputMethodWindowsIfNeededLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009937 mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
Jeff Brown20337632012-09-24 14:25:54 -07009938 displayContent.layoutNeeded = true;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009940 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009941 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009942 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009943 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9944 // Client will do the layout, but we need to assign layers
9945 // for handleNewWindowLocked() below.
Craig Mautner59c00972012-07-30 12:10:24 -07009946 assignLayersLocked(displayContent.getWindowList());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009947 }
9948 }
Dianne Hackborndf89e652011-10-06 22:35:11 -07009949
Craig Mautner39834192012-09-02 07:47:24 -07009950 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Dianne Hackborndf89e652011-10-06 22:35:11 -07009951 // The change in focus caused us to need to do a layout. Okay.
Jeff Brown20337632012-09-24 14:25:54 -07009952 displayContent.layoutNeeded = true;
Dianne Hackborndf89e652011-10-06 22:35:11 -07009953 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
Craig Mautner59c00972012-07-30 12:10:24 -07009954 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
Dianne Hackborndf89e652011-10-06 22:35:11 -07009955 }
9956 }
9957
Jeff Brown349703e2010-06-22 01:27:15 -07009958 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9959 // If we defer assigning layers, then the caller is responsible for
9960 // doing this part.
Jeff Brown3a22cd92011-01-21 13:59:04 -08009961 finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
The Android Open Source Projectc474dec2009-03-04 09:49:09 -08009962 }
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07009963
9964 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 return true;
9966 }
9967 return false;
9968 }
Jeff Brown349703e2010-06-22 01:27:15 -07009969
Jeff Brown3a22cd92011-01-21 13:59:04 -08009970 private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9971 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
Jeff Brown349703e2010-06-22 01:27:15 -07009972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009973
9974 private WindowState computeFocusedWindowLocked() {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07009975 if (mAnimator.mUniverseBackground != null
9976 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9977 return mAnimator.mUniverseBackground.mWin;
9978 }
9979
Jeff Brown20337632012-09-24 14:25:54 -07009980 final int displayCount = mDisplayContents.size();
9981 for (int i = 0; i < displayCount; i++) {
9982 final DisplayContent displayContent = mDisplayContents.valueAt(i);
9983 WindowState win = findFocusedWindowLocked(displayContent);
9984 if (win != null) {
9985 return win;
9986 }
9987 }
9988 return null;
9989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990
Jeff Brown20337632012-09-24 14:25:54 -07009991 private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
9992 int nextAppIndex = mAppTokens.size()-1;
9993 WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null;
9994
9995 final WindowList windows = displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07009996 for (int i = windows.size() - 1; i >= 0; i--) {
Jeff Brown20337632012-09-24 14:25:54 -07009997 final WindowState win = windows.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009998
Joe Onorato8a9b2202010-02-26 18:56:32 -08009999 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010000 TAG, "Looking for focus: " + i
10001 + " = " + win
10002 + ", flags=" + win.mAttrs.flags
10003 + ", canReceive=" + win.canReceiveKeys());
10004
10005 AppWindowToken thisApp = win.mAppToken;
Romain Guy06882f82009-06-10 13:36:04 -070010006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010007 // If this window's application has been removed, just skip it.
Craig Mautneref25d7a2012-05-15 23:01:47 -070010008 if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
Craig Mautner3f99fde2012-06-19 14:10:01 -070010009 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping app because " + (thisApp.removed
10010 ? "removed" : "sendingToBottom"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010011 continue;
10012 }
Romain Guy06882f82009-06-10 13:36:04 -070010013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010014 // If there is a focused app, don't allow focus to go to any
10015 // windows below it. If this is an application window, step
10016 // through the app tokens until we find its app.
10017 if (thisApp != null && nextApp != null && thisApp != nextApp
10018 && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
10019 int origAppIndex = nextAppIndex;
10020 while (nextAppIndex > 0) {
10021 if (nextApp == mFocusedApp) {
10022 // Whoops, we are below the focused app... no focus
10023 // for you!
Joe Onorato8a9b2202010-02-26 18:56:32 -080010024 if (localLOGV || DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010025 TAG, "Reached focused app: " + mFocusedApp);
10026 return null;
10027 }
10028 nextAppIndex--;
10029 nextApp = mAppTokens.get(nextAppIndex);
10030 if (nextApp == thisApp) {
10031 break;
10032 }
10033 }
10034 if (thisApp != nextApp) {
10035 // Uh oh, the app token doesn't exist! This shouldn't
10036 // happen, but if it does we can get totally hosed...
10037 // so restart at the original app.
10038 nextAppIndex = origAppIndex;
10039 nextApp = mAppTokens.get(nextAppIndex);
10040 }
10041 }
10042
10043 // Dispatch to this window if it is wants key events.
10044 if (win.canReceiveKeys()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010045 if (DEBUG_FOCUS) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010046 TAG, "Found focus @ " + i + " = " + win);
Jeff Brown20337632012-09-24 14:25:54 -070010047 return win;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 }
Jeff Brown20337632012-09-24 14:25:54 -070010050 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051 }
10052
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010053 private void startFreezingDisplayLocked(boolean inTransaction,
10054 int exitAnim, int enterAnim) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010055 if (mDisplayFrozen) {
10056 return;
10057 }
Romain Guy06882f82009-06-10 13:36:04 -070010058
Jeff Browne215f262012-09-10 16:01:14 -070010059 if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -070010060 // No need to freeze the screen before the system is ready or if
10061 // the screen is off.
10062 return;
10063 }
10064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 mScreenFrozenLock.acquire();
Romain Guy06882f82009-06-10 13:36:04 -070010066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067 mDisplayFrozen = true;
Craig Mautner7d8df392012-04-06 15:26:23 -070010068
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010069 mInputMonitor.freezeInputDispatchingLw();
Craig Mautner7d8df392012-04-06 15:26:23 -070010070
Dianne Hackborn2ea9bae2012-11-02 18:43:48 -070010071 // Clear the last input window -- that is just used for
10072 // clean transitions between IMEs, and if we are freezing
10073 // the screen then the whole world is changing behind the scenes.
10074 mPolicy.setLastInputMethodWindowLw(null, null);
10075
Dianne Hackbornbfe319e2009-09-21 00:34:05 -070010076 if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
10077 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010078 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010079 mNextAppTransitionPackage = null;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070010080 mNextAppTransitionThumbnail = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010081 mAppTransitionReady = true;
10082 }
Romain Guy06882f82009-06-10 13:36:04 -070010083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010084 if (PROFILE_ORIENTATION) {
10085 File file = new File("/data/system/frozen");
10086 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
10087 }
Dianne Hackborna1111872010-11-23 20:55:11 -080010088
10089 if (CUSTOM_SCREEN_ROTATION) {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010090 final DisplayContent displayContent = getDefaultDisplayContentLocked();
10091 final int displayId = displayContent.getDisplayId();
10092 ScreenRotationAnimation screenRotationAnimation =
10093 mAnimator.getScreenRotationAnimationLocked(displayId);
10094 if (screenRotationAnimation != null) {
10095 screenRotationAnimation.kill();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080010096 }
Craig Mautnerd87946b2012-03-29 18:00:19 -070010097
Craig Mautner59c00972012-07-30 12:10:24 -070010098 // TODO(multidisplay): rotation on main screen only.
Jeff Browne215f262012-09-10 16:01:14 -070010099 final Display display = displayContent.getDisplay();
10100 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Craig Mautnera91f9e22012-09-14 16:22:08 -070010101 screenRotationAnimation = new ScreenRotationAnimation(mContext,
Jeff Browne215f262012-09-10 16:01:14 -070010102 display, mFxSession, inTransaction, displayInfo.logicalWidth,
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010103 displayInfo.logicalHeight, display.getRotation(),
10104 exitAnim, enterAnim);
Craig Mautnera91f9e22012-09-14 16:22:08 -070010105 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackborna1111872010-11-23 20:55:11 -080010106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 }
Romain Guy06882f82009-06-10 13:36:04 -070010108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010109 private void stopFreezingDisplayLocked() {
10110 if (!mDisplayFrozen) {
10111 return;
10112 }
Romain Guy06882f82009-06-10 13:36:04 -070010113
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010114 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
10115 || mClientFreezingScreen) {
Craig Mautnerd87946b2012-03-29 18:00:19 -070010116 if (DEBUG_ORIENTATION) Slog.d(TAG,
10117 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
10118 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010119 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
10120 + ", mClientFreezingScreen=" + mClientFreezingScreen);
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010121 return;
10122 }
10123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 mDisplayFrozen = false;
10125 mH.removeMessages(H.APP_FREEZE_TIMEOUT);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010126 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010127 if (PROFILE_ORIENTATION) {
10128 Debug.stopMethodTracing();
10129 }
Dianne Hackborna1111872010-11-23 20:55:11 -080010130
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010131 boolean updateRotation = false;
Craig Mautner59c00972012-07-30 12:10:24 -070010132
Craig Mautnera91f9e22012-09-14 16:22:08 -070010133 final DisplayContent displayContent = getDefaultDisplayContentLocked();
10134 final int displayId = displayContent.getDisplayId();
10135 ScreenRotationAnimation screenRotationAnimation =
10136 mAnimator.getScreenRotationAnimationLocked(displayId);
10137 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
10138 && screenRotationAnimation.hasScreenshot()) {
Dianne Hackborn3ec891a2011-10-25 13:58:30 -070010139 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
Craig Mautner59c00972012-07-30 12:10:24 -070010140 // TODO(multidisplay): rotation on main screen only.
Craig Mautnera91f9e22012-09-14 16:22:08 -070010141 DisplayInfo displayInfo = displayContent.getDisplayInfo();
10142 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
Craig Mautner59c00972012-07-30 12:10:24 -070010143 mTransitionAnimationScale, displayInfo.logicalWidth,
10144 displayInfo.logicalHeight)) {
Craig Mautner711f90a2012-07-03 18:43:52 -070010145 updateLayoutToAnimationLocked();
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010146 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010147 screenRotationAnimation.kill();
10148 screenRotationAnimation = null;
10149 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010150 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -080010151 }
10152 } else {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010153 if (screenRotationAnimation != null) {
10154 screenRotationAnimation.kill();
10155 screenRotationAnimation = null;
10156 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -080010157 }
10158 updateRotation = true;
Dianne Hackborna1111872010-11-23 20:55:11 -080010159 }
Romain Guy06882f82009-06-10 13:36:04 -070010160
Jeff Brown00fa7bd2010-07-02 15:37:36 -070010161 mInputMonitor.thawInputDispatchingLw();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010162
Dianne Hackborn420829e2011-01-28 11:30:35 -080010163 boolean configChanged;
10164
Christopher Tateb696aee2010-04-02 19:08:30 -070010165 // While the display is frozen we don't re-compute the orientation
10166 // to avoid inconsistent states. However, something interesting
10167 // could have actually changed during that time so re-evaluate it
10168 // now to catch that.
Dianne Hackborn420829e2011-01-28 11:30:35 -080010169 configChanged = updateOrientationFromAppTokensLocked(false);
Christopher Tateb696aee2010-04-02 19:08:30 -070010170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010171 // A little kludge: a lot could have happened while the
10172 // display was frozen, so now that we are coming back we
10173 // do a gc so that any remote references the system
10174 // processes holds on others can be released if they are
10175 // no longer needed.
10176 mH.removeMessages(H.FORCE_GC);
10177 mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
10178 2000);
Romain Guy06882f82009-06-10 13:36:04 -070010179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010180 mScreenFrozenLock.release();
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010181
10182 if (updateRotation) {
10183 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Jeff Brown01a98dd2011-09-20 15:08:29 -070010184 configChanged |= updateRotationUncheckedLocked(false);
Dianne Hackborn420829e2011-01-28 11:30:35 -080010185 }
10186
10187 if (configChanged) {
10188 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
Dianne Hackborn89ba6752011-01-23 16:51:16 -080010189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010190 }
Romain Guy06882f82009-06-10 13:36:04 -070010191
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010192 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
10193 DisplayMetrics dm) {
10194 if (index < tokens.length) {
10195 String str = tokens[index];
10196 if (str != null && str.length() > 0) {
10197 try {
10198 int val = Integer.parseInt(str);
10199 return val;
10200 } catch (Exception e) {
10201 }
10202 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010203 }
10204 if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10205 return defDps;
10206 }
10207 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10208 return val;
10209 }
10210
Jeff Brown4ed8fe72012-08-30 18:18:29 -070010211 void createWatermarkInTransaction() {
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010212 if (mWatermark != null) {
10213 return;
10214 }
10215
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010216 File file = new File("/system/etc/setup.conf");
10217 FileInputStream in = null;
10218 try {
10219 in = new FileInputStream(file);
10220 DataInputStream ind = new DataInputStream(in);
10221 String line = ind.readLine();
10222 if (line != null) {
10223 String[] toks = line.split("%");
10224 if (toks != null && toks.length > 0) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010225 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
Jeff Browne215f262012-09-10 16:01:14 -070010226 mRealDisplayMetrics, mFxSession, toks);
Dianne Hackbornb9fb1702010-08-23 16:49:02 -070010227 }
10228 }
10229 } catch (FileNotFoundException e) {
10230 } catch (IOException e) {
10231 } finally {
10232 if (in != null) {
10233 try {
10234 in.close();
10235 } catch (IOException e) {
10236 }
10237 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010238 }
Dianne Hackbornfb86ce92010-08-11 18:11:23 -070010239 }
10240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010241 @Override
Joe Onorato664644d2011-01-23 17:53:23 -080010242 public void statusBarVisibilityChanged(int visibility) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010243 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
10244 != PackageManager.PERMISSION_GRANTED) {
10245 throw new SecurityException("Caller does not hold permission "
10246 + android.Manifest.permission.STATUS_BAR);
10247 }
Dianne Hackborn9a230e02011-10-06 11:51:27 -070010248
Joe Onorato664644d2011-01-23 17:53:23 -080010249 synchronized (mWindowMap) {
Dianne Hackborndf89e652011-10-06 22:35:11 -070010250 mLastStatusBarVisibility = visibility;
10251 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
10252 updateStatusBarVisibilityLocked(visibility);
10253 }
10254 }
10255
Craig Mautner59c00972012-07-30 12:10:24 -070010256 // TOOD(multidisplay): StatusBar on multiple screens?
Dianne Hackborndf89e652011-10-06 22:35:11 -070010257 void updateStatusBarVisibilityLocked(int visibility) {
10258 mInputManager.setSystemUiVisibility(visibility);
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010259 final WindowList windows = getDefaultWindowListLocked();
Craig Mautner59c00972012-07-30 12:10:24 -070010260 final int N = windows.size();
Dianne Hackborndf89e652011-10-06 22:35:11 -070010261 for (int i = 0; i < N; i++) {
Craig Mautner59c00972012-07-30 12:10:24 -070010262 WindowState ws = windows.get(i);
Dianne Hackborndf89e652011-10-06 22:35:11 -070010263 try {
10264 int curValue = ws.mSystemUiVisibility;
10265 int diff = curValue ^ visibility;
10266 // We are only interested in differences of one of the
10267 // clearable flags...
10268 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
10269 // ...if it has actually been cleared.
10270 diff &= ~visibility;
10271 int newValue = (curValue&~diff) | (visibility&diff);
10272 if (newValue != curValue) {
10273 ws.mSeq++;
10274 ws.mSystemUiVisibility = newValue;
10275 }
10276 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
10277 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
10278 visibility, newValue, diff);
10279 }
10280 } catch (RemoteException e) {
10281 // so sorry
10282 }
10283 }
10284 }
10285
10286 @Override
10287 public void reevaluateStatusBarVisibility() {
10288 synchronized (mWindowMap) {
10289 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
10290 updateStatusBarVisibilityLocked(visibility);
10291 performLayoutAndPlaceSurfacesLocked();
10292 }
10293 }
10294
10295 @Override
Jeff Brown32cbc38552011-12-01 14:01:49 -080010296 public FakeWindow addFakeWindow(Looper looper,
10297 InputEventReceiver.Factory inputEventReceiverFactory,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010298 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
10299 boolean hasFocus, boolean touchFullscreen) {
10300 synchronized (mWindowMap) {
Jeff Brown32cbc38552011-12-01 14:01:49 -080010301 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
10302 name, windowType,
Dianne Hackborndf89e652011-10-06 22:35:11 -070010303 layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
10304 int i=0;
10305 while (i<mFakeWindows.size()) {
10306 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
10307 break;
Joe Onorato664644d2011-01-23 17:53:23 -080010308 }
10309 }
Dianne Hackborndf89e652011-10-06 22:35:11 -070010310 mFakeWindows.add(i, fw);
10311 mInputMonitor.updateInputWindowsLw(true);
10312 return fw;
10313 }
10314 }
10315
10316 boolean removeFakeWindowLocked(FakeWindow window) {
10317 synchronized (mWindowMap) {
10318 if (mFakeWindows.remove(window)) {
10319 mInputMonitor.updateInputWindowsLw(true);
10320 return true;
10321 }
10322 return false;
Joe Onorato664644d2011-01-23 17:53:23 -080010323 }
10324 }
10325
satoke0a99412012-05-10 02:22:58 +090010326 // It is assumed that this method is called only by InputMethodManagerService.
10327 public void saveLastInputMethodWindowForTransition() {
10328 synchronized (mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010329 // TODO(multidisplay): Pass in the displayID.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010330 DisplayContent displayContent = getDefaultDisplayContentLocked();
satoke0a99412012-05-10 02:22:58 +090010331 if (mInputMethodWindow != null) {
10332 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
10333 }
10334 }
10335 }
10336
Daniel Sandler0c4ccff2011-10-19 16:39:14 -040010337 @Override
10338 public boolean hasNavigationBar() {
10339 return mPolicy.hasNavigationBar();
10340 }
10341
Adam Cohenf7522022012-10-03 20:03:18 -070010342 public void lockNow(Bundle options) {
10343 mPolicy.lockNow(options);
Jim Miller93c518e2012-01-17 15:55:31 -080010344 }
Jim Millerbfec0a82012-11-05 20:05:22 -080010345
10346 public boolean isSafeModeEnabled() {
10347 return mSafeMode;
10348 }
Jim Miller93c518e2012-01-17 15:55:31 -080010349
Jim Miller4eeb4f62012-11-08 00:04:29 -080010350 public void showAssistant() {
10351 // TODO: What permission?
10352 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
10353 != PackageManager.PERMISSION_GRANTED) {
10354 return;
10355 }
10356 mPolicy.showAssistant();
10357 }
10358
Jeff Brownd7a04de2012-06-17 14:17:52 -070010359 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010360 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010361 mPolicy.dump(" ", pw, args);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010362 }
10363
Dianne Hackborn529e7442012-11-01 14:22:28 -070010364 void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
10365 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
10366 mAnimator.dumpLocked(pw, " ", dumpAll);
10367 }
10368
Jeff Brownd7a04de2012-06-17 14:17:52 -070010369 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010370 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
10371 if (mTokenMap.size() > 0) {
10372 pw.println(" All tokens:");
10373 Iterator<WindowToken> it = mTokenMap.values().iterator();
10374 while (it.hasNext()) {
10375 WindowToken token = it.next();
Dianne Hackbornef03a7f2012-10-29 18:46:52 -070010376 pw.print(" "); pw.print(token);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010377 if (dumpAll) {
10378 pw.println(':');
10379 token.dump(pw, " ");
10380 } else {
10381 pw.println();
10382 }
10383 }
10384 }
10385 if (mWallpaperTokens.size() > 0) {
10386 pw.println();
10387 pw.println(" Wallpaper tokens:");
10388 for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10389 WindowToken token = mWallpaperTokens.get(i);
10390 pw.print(" Wallpaper #"); pw.print(i);
10391 pw.print(' '); pw.print(token);
10392 if (dumpAll) {
10393 pw.println(':');
10394 token.dump(pw, " ");
10395 } else {
10396 pw.println();
10397 }
10398 }
10399 }
10400 if (mAppTokens.size() > 0) {
10401 pw.println();
10402 pw.println(" Application tokens in Z order:");
10403 for (int i=mAppTokens.size()-1; i>=0; i--) {
Dianne Hackbornef03a7f2012-10-29 18:46:52 -070010404 pw.print(" App #"); pw.print(i);
10405 pw.print(' '); pw.print(mAppTokens.get(i)); pw.println(":");
10406 mAppTokens.get(i).dump(pw, " ");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010407 }
10408 }
10409 if (mFinishedStarting.size() > 0) {
10410 pw.println();
10411 pw.println(" Finishing start of application tokens:");
10412 for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10413 WindowToken token = mFinishedStarting.get(i);
10414 pw.print(" Finished Starting #"); pw.print(i);
10415 pw.print(' '); pw.print(token);
10416 if (dumpAll) {
10417 pw.println(':');
10418 token.dump(pw, " ");
10419 } else {
10420 pw.println();
10421 }
10422 }
10423 }
10424 if (mExitingTokens.size() > 0) {
10425 pw.println();
10426 pw.println(" Exiting tokens:");
10427 for (int i=mExitingTokens.size()-1; i>=0; i--) {
10428 WindowToken token = mExitingTokens.get(i);
10429 pw.print(" Exiting #"); pw.print(i);
10430 pw.print(' '); pw.print(token);
10431 if (dumpAll) {
10432 pw.println(':');
10433 token.dump(pw, " ");
10434 } else {
10435 pw.println();
10436 }
10437 }
10438 }
10439 if (mExitingAppTokens.size() > 0) {
10440 pw.println();
10441 pw.println(" Exiting application tokens:");
10442 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
10443 WindowToken token = mExitingAppTokens.get(i);
10444 pw.print(" Exiting App #"); pw.print(i);
10445 pw.print(' '); pw.print(token);
10446 if (dumpAll) {
10447 pw.println(':');
10448 token.dump(pw, " ");
10449 } else {
10450 pw.println();
10451 }
10452 }
10453 }
Craig Mautneref25d7a2012-05-15 23:01:47 -070010454 if (mAppTransitionRunning && mAnimatingAppTokens.size() > 0) {
10455 pw.println();
10456 pw.println(" Application tokens during animation:");
10457 for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
10458 WindowToken token = mAnimatingAppTokens.get(i);
10459 pw.print(" App moving to bottom #"); pw.print(i);
10460 pw.print(' '); pw.print(token);
10461 if (dumpAll) {
10462 pw.println(':');
10463 token.dump(pw, " ");
10464 } else {
10465 pw.println();
10466 }
10467 }
10468 }
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010469 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10470 pw.println();
10471 if (mOpeningApps.size() > 0) {
10472 pw.print(" mOpeningApps="); pw.println(mOpeningApps);
10473 }
10474 if (mClosingApps.size() > 0) {
10475 pw.print(" mClosingApps="); pw.println(mClosingApps);
10476 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010477 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010478 }
10479
Jeff Brownd7a04de2012-06-17 14:17:52 -070010480 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010481 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10482 if (mSessions.size() > 0) {
10483 Iterator<Session> it = mSessions.iterator();
10484 while (it.hasNext()) {
10485 Session s = it.next();
10486 pw.print(" Session "); pw.print(s); pw.println(':');
10487 s.dump(pw, " ");
10488 }
10489 }
10490 }
10491
Jeff Brownd7a04de2012-06-17 14:17:52 -070010492 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010493 ArrayList<WindowState> windows) {
10494 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010495 dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10496 }
10497
10498 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10499 ArrayList<WindowState> windows) {
Craig Mautner59c00972012-07-30 12:10:24 -070010500 int j = 0;
10501 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10502 while (iterator.hasNext()) {
10503 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010504 if (windows == null || windows.contains(w)) {
Craig Mautner59c00972012-07-30 12:10:24 -070010505 pw.print(" Window #"); pw.print(j++); pw.print(' ');
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010506 pw.print(w); pw.println(":");
Dianne Hackborn89620282011-09-11 12:47:45 -070010507 w.dump(pw, " ", dumpAll || windows != null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010508 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010509 }
10510 if (mInputMethodDialogs.size() > 0) {
10511 pw.println();
10512 pw.println(" Input method dialogs:");
10513 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10514 WindowState w = mInputMethodDialogs.get(i);
10515 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010516 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010517 }
10518 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010519 }
10520 if (mPendingRemove.size() > 0) {
10521 pw.println();
10522 pw.println(" Remove pending for:");
10523 for (int i=mPendingRemove.size()-1; i>=0; i--) {
10524 WindowState w = mPendingRemove.get(i);
10525 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010526 pw.print(" Remove #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010527 pw.print(w);
10528 if (dumpAll) {
10529 pw.println(":");
10530 w.dump(pw, " ", true);
10531 } else {
10532 pw.println();
10533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010534 }
10535 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010536 }
10537 if (mForceRemoves != null && mForceRemoves.size() > 0) {
10538 pw.println();
10539 pw.println(" Windows force removing:");
10540 for (int i=mForceRemoves.size()-1; i>=0; i--) {
10541 WindowState w = mForceRemoves.get(i);
10542 pw.print(" Removing #"); pw.print(i); pw.print(' ');
10543 pw.print(w);
10544 if (dumpAll) {
10545 pw.println(":");
10546 w.dump(pw, " ", true);
10547 } else {
10548 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010549 }
10550 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010551 }
10552 if (mDestroySurface.size() > 0) {
10553 pw.println();
10554 pw.println(" Windows waiting to destroy their surface:");
10555 for (int i=mDestroySurface.size()-1; i>=0; i--) {
10556 WindowState w = mDestroySurface.get(i);
10557 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010558 pw.print(" Destroy #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010559 pw.print(w);
10560 if (dumpAll) {
10561 pw.println(":");
10562 w.dump(pw, " ", true);
10563 } else {
10564 pw.println();
10565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 }
10567 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010568 }
10569 if (mLosingFocus.size() > 0) {
10570 pw.println();
10571 pw.println(" Windows losing focus:");
10572 for (int i=mLosingFocus.size()-1; i>=0; i--) {
10573 WindowState w = mLosingFocus.get(i);
10574 if (windows == null || windows.contains(w)) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010575 pw.print(" Losing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010576 pw.print(w);
10577 if (dumpAll) {
10578 pw.println(":");
10579 w.dump(pw, " ", true);
10580 } else {
10581 pw.println();
10582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010583 }
10584 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010585 }
10586 if (mResizingWindows.size() > 0) {
10587 pw.println();
10588 pw.println(" Windows waiting to resize:");
10589 for (int i=mResizingWindows.size()-1; i>=0; i--) {
10590 WindowState w = mResizingWindows.get(i);
10591 if (windows == null || windows.contains(w)) {
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010592 pw.print(" Resizing #"); pw.print(i); pw.print(' ');
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010593 pw.print(w);
10594 if (dumpAll) {
10595 pw.println(":");
10596 w.dump(pw, " ", true);
10597 } else {
10598 pw.println();
10599 }
Dianne Hackborn0586a1b2009-09-06 21:08:27 -070010600 }
10601 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010602 }
Dianne Hackborn38e29a62011-09-18 14:43:08 -070010603 if (mWaitingForDrawn.size() > 0) {
10604 pw.println();
10605 pw.println(" Clients waiting for these windows to be drawn:");
10606 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10607 Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10608 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10609 pw.print(": "); pw.println(pair.second);
10610 }
10611 }
Dianne Hackborn77119bc2012-10-23 14:32:48 -070010612 pw.println();
10613 pw.println(" DisplayContents:");
Jeff Browne215f262012-09-10 16:01:14 -070010614 if (mDisplayReady) {
Craig Mautner59c00972012-07-30 12:10:24 -070010615 DisplayContentsIterator dCIterator = new DisplayContentsIterator();
10616 while (dCIterator.hasNext()) {
Craig Mautnera91f9e22012-09-14 16:22:08 -070010617 dCIterator.next().dump(" ", pw);
Craig Mautner59c00972012-07-30 12:10:24 -070010618 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010619 } else {
10620 pw.println(" NO DISPLAY");
10621 }
10622 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration);
10623 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
10624 if (mLastFocus != mCurrentFocus) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010625 pw.print(" mLastFocus="); pw.println(mLastFocus);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010626 }
10627 pw.print(" mFocusedApp="); pw.println(mFocusedApp);
10628 if (mInputMethodTarget != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010629 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010630 }
10631 pw.print(" mInTouchMode="); pw.print(mInTouchMode);
10632 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
10633 if (dumpAll) {
Dianne Hackborn85afd1b2012-05-13 13:31:06 -070010634 pw.print(" mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -070010635 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
10636 pw.print(" mScreenRecr="); pw.println(mScreenRect.toShortString());
Dianne Hackborndf89e652011-10-06 22:35:11 -070010637 if (mLastStatusBarVisibility != 0) {
10638 pw.print(" mLastStatusBarVisibility=0x");
10639 pw.println(Integer.toHexString(mLastStatusBarVisibility));
10640 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010641 if (mInputMethodWindow != null) {
10642 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow);
10643 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -070010644 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010645 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -070010646 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10647 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10648 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010649 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX);
10650 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10651 if (mInputMethodAnimLayerAdjustment != 0 ||
10652 mWallpaperAnimLayerAdjustment != 0) {
10653 pw.print(" mInputMethodAnimLayerAdjustment=");
10654 pw.print(mInputMethodAnimLayerAdjustment);
10655 pw.print(" mWallpaperAnimLayerAdjustment=");
10656 pw.println(mWallpaperAnimLayerAdjustment);
10657 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010658 pw.print(" mSystemBooted="); pw.print(mSystemBooted);
10659 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
Craig Mautner19d59bc2012-09-04 11:15:56 -070010660 if (needsLayout()) {
10661 pw.print(" layoutNeeded on displays=");
10662 DisplayContentsIterator dcIterator = new DisplayContentsIterator();
10663 while (dcIterator.hasNext()) {
10664 final DisplayContent displayContent = dcIterator.next();
10665 if (displayContent.layoutNeeded) {
10666 pw.print(displayContent.getDisplayId());
10667 }
10668 }
10669 pw.println();
10670 }
Craig Mautner69b08182012-09-05 13:07:13 -070010671 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010672 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070010673 pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10674 pw.print(" client="); pw.print(mClientFreezingScreen);
10675 pw.print(" apps="); pw.print(mAppsFreezingScreen);
10676 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010677 pw.print(" mRotation="); pw.print(mRotation);
Dianne Hackborndacea8c2011-04-21 17:26:39 -070010678 pw.print(" mAltOrientation="); pw.println(mAltOrientation);
Craig Mautnerf20588f2012-04-11 17:06:21 -070010679 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
Dianne Hackbornbc7386c2011-06-06 17:27:54 -070010680 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
Jeff Brown01a98dd2011-09-20 15:08:29 -070010681 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010682 pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10683 pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
Chet Haasec38fa1f2012-02-01 16:37:46 -080010684 pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
Dianne Hackborn4dcece82012-02-10 14:50:32 -080010685 pw.print(" mTraversalScheduled="); pw.print(mTraversalScheduled);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010686 pw.print(" mNextAppTransition=0x");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010687 pw.print(Integer.toHexString(mNextAppTransition));
Dianne Hackborn9d132642011-04-21 17:26:39 -070010688 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
10689 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010690 pw.print(" mAppTransitionTimeout="); pw.println(mAppTransitionTimeout);
10691 if (mNextAppTransitionType != ActivityOptions.ANIM_NONE) {
10692 pw.print(" mNextAppTransitionType="); pw.println(mNextAppTransitionType);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -070010693 }
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010694 switch (mNextAppTransitionType) {
10695 case ActivityOptions.ANIM_CUSTOM:
10696 pw.print(" mNextAppTransitionPackage=");
Dianne Hackborn84375872012-06-01 19:03:50 -070010697 pw.println(mNextAppTransitionPackage);
10698 pw.print(" mNextAppTransitionEnter=0x");
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010699 pw.print(Integer.toHexString(mNextAppTransitionEnter));
10700 pw.print(" mNextAppTransitionExit=0x");
Dianne Hackborn84375872012-06-01 19:03:50 -070010701 pw.println(Integer.toHexString(mNextAppTransitionExit));
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010702 break;
10703 case ActivityOptions.ANIM_SCALE_UP:
10704 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
10705 pw.print(" mNextAppTransitionStartY=");
10706 pw.println(mNextAppTransitionStartY);
10707 pw.print(" mNextAppTransitionStartWidth=");
10708 pw.print(mNextAppTransitionStartWidth);
10709 pw.print(" mNextAppTransitionStartHeight=");
10710 pw.println(mNextAppTransitionStartHeight);
10711 break;
Michael Jurka832cb222012-04-13 09:32:47 -070010712 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
10713 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010714 pw.print(" mNextAppTransitionThumbnail=");
10715 pw.print(mNextAppTransitionThumbnail);
Dianne Hackborn84375872012-06-01 19:03:50 -070010716 pw.print(" mNextAppTransitionStartX=");
10717 pw.print(mNextAppTransitionStartX);
10718 pw.print(" mNextAppTransitionStartY=");
10719 pw.println(mNextAppTransitionStartY);
Michael Jurka832cb222012-04-13 09:32:47 -070010720 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
Dianne Hackborneabfb3a2012-04-16 16:28:22 -070010721 break;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070010722 }
Dianne Hackborn84375872012-06-01 19:03:50 -070010723 if (mNextAppTransitionCallback != null) {
10724 pw.print(" mNextAppTransitionCallback=");
10725 pw.println(mNextAppTransitionCallback);
10726 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010727 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010728 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
Dianne Hackborn529e7442012-11-01 14:22:28 -070010729 pw.println(" mLayoutToAnim:");
10730 pw.print(" mParamsModified="); pw.print(mLayoutToAnim.mParamsModified);
10731 pw.print(" mAnimationScheduled="); pw.print(mLayoutToAnim.mAnimationScheduled);
10732 pw.print(" mChanges=0x");
10733 pw.println(Long.toHexString(mLayoutToAnim.mChanges));
10734 pw.print(" mWallpaperTarget="); pw.println(mLayoutToAnim.mWallpaperTarget);
10735 if (mLayoutToAnim.mLowerWallpaperTarget != null
10736 || mLayoutToAnim.mUpperWallpaperTarget != null) {
10737 pw.print(" mLowerWallpaperTarget=");
10738 pw.println(mLayoutToAnim.mLowerWallpaperTarget);
10739 pw.print(" mUpperWallpaperTarget=");
10740 pw.println(mLayoutToAnim.mUpperWallpaperTarget);
10741 }
10742 for (int i=0; i<mLayoutToAnim.mWinAnimatorLists.size(); i++) {
10743 pw.print(" Win Animator List #");
10744 pw.print(mLayoutToAnim.mWinAnimatorLists.keyAt(i)); pw.println(":");
10745 WinAnimatorList wanim = mLayoutToAnim.mWinAnimatorLists.valueAt(i);
10746 for (int wi=0; wi<wanim.size(); wi++) {
10747 pw.print(" "); pw.println(wanim.get(wi));
10748 }
10749 }
10750 for (int i=0; i<mLayoutToAnim.mWallpaperTokens.size(); i++) {
10751 pw.print(" Wallpaper Token #"); pw.print(i); pw.print(": ");
10752 pw.println(mLayoutToAnim.mWallpaperTokens.get(i));
10753 }
10754 // XXX also need to print mDimParams and mAppWindowAnimParams. I am lazy.
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010755 }
10756 }
10757
Jeff Brownd7a04de2012-06-17 14:17:52 -070010758 boolean dumpWindows(PrintWriter pw, String name, String[] args,
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010759 int opti, boolean dumpAll) {
Craig Mautner722285e2012-09-07 13:55:58 -070010760 WindowList windows = new WindowList();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010761 if ("visible".equals(name)) {
10762 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010763 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10764 while (iterator.hasNext()) {
10765 final WindowState w = iterator.next();
Craig Mautnerc2f9be02012-03-27 17:32:29 -070010766 if (w.mWinAnimator.mSurfaceShown) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010767 windows.add(w);
10768 }
10769 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010770 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010771 } else {
10772 int objectId = 0;
10773 // See if this is an object ID.
10774 try {
10775 objectId = Integer.parseInt(name, 16);
10776 name = null;
10777 } catch (RuntimeException e) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070010778 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010779 synchronized(mWindowMap) {
Craig Mautner59c00972012-07-30 12:10:24 -070010780 final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
10781 while (iterator.hasNext()) {
10782 final WindowState w = iterator.next();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010783 if (name != null) {
10784 if (w.mAttrs.getTitle().toString().contains(name)) {
10785 windows.add(w);
10786 }
10787 } else if (System.identityHashCode(w) == objectId) {
10788 windows.add(w);
10789 }
10790 }
Dianne Hackborna8f60182009-09-01 19:01:50 -070010791 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010792 }
10793
10794 if (windows.size() <= 0) {
10795 return false;
10796 }
10797
10798 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010799 dumpWindowsLocked(pw, dumpAll, windows);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010800 }
10801 return true;
10802 }
10803
Jeff Brownd7a04de2012-06-17 14:17:52 -070010804 void dumpLastANRLocked(PrintWriter pw) {
10805 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10806 if (mLastANRState == null) {
10807 pw.println(" <no ANR has occurred since boot>");
10808 } else {
10809 pw.println(mLastANRState);
10810 }
10811 }
10812
10813 /**
10814 * Saves information about the state of the window manager at
10815 * the time an ANR occurred before anything else in the system changes
10816 * in response.
10817 *
Jeff Brownee172412012-06-18 12:58:03 -070010818 * @param appWindowToken The application that ANR'd, may be null.
Jeff Brownd7a04de2012-06-17 14:17:52 -070010819 * @param windowState The window that ANR'd, may be null.
10820 */
10821 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
10822 StringWriter sw = new StringWriter();
10823 PrintWriter pw = new PrintWriter(sw);
10824 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date()));
Jeff Brownee172412012-06-18 12:58:03 -070010825 if (appWindowToken != null) {
10826 pw.println(" Application at fault: " + appWindowToken.stringName);
10827 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010828 if (windowState != null) {
10829 pw.println(" Window at fault: " + windowState.mAttrs.getTitle());
10830 }
10831 pw.println();
10832 dumpWindowsNoHeaderLocked(pw, true, null);
10833 pw.close();
10834 mLastANRState = sw.toString();
10835 }
10836
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010837 @Override
10838 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10839 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10840 != PackageManager.PERMISSION_GRANTED) {
10841 pw.println("Permission Denial: can't dump WindowManager from from pid="
10842 + Binder.getCallingPid()
10843 + ", uid=" + Binder.getCallingUid());
10844 return;
10845 }
10846
10847 boolean dumpAll = false;
10848
10849 int opti = 0;
10850 while (opti < args.length) {
10851 String opt = args[opti];
10852 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10853 break;
Dianne Hackborna8f60182009-09-01 19:01:50 -070010854 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010855 opti++;
10856 if ("-a".equals(opt)) {
10857 dumpAll = true;
10858 } else if ("-h".equals(opt)) {
10859 pw.println("Window manager dump options:");
10860 pw.println(" [-a] [-h] [cmd] ...");
10861 pw.println(" cmd may be one of:");
Jeff Brownd7a04de2012-06-17 14:17:52 -070010862 pw.println(" l[astanr]: last ANR information");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010863 pw.println(" p[policy]: policy state");
Dianne Hackborn529e7442012-11-01 14:22:28 -070010864 pw.println(" a[animator]: animator state");
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010865 pw.println(" s[essions]: active sessions");
10866 pw.println(" t[okens]: token list");
10867 pw.println(" w[indows]: window list");
10868 pw.println(" cmd may also be a NAME to dump windows. NAME may");
10869 pw.println(" be a partial substring in a window name, a");
10870 pw.println(" Window hex object identifier, or");
10871 pw.println(" \"all\" for all windows, or");
10872 pw.println(" \"visible\" for the visible windows.");
10873 pw.println(" -a: include all available server state.");
10874 return;
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010875 } else {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010876 pw.println("Unknown argument: " + opt + "; use -h for help");
Dianne Hackborn87fc3082010-12-03 13:09:12 -080010877 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010878 }
10879
10880 // Is the caller requesting to dump a particular piece of data?
10881 if (opti < args.length) {
10882 String cmd = args[opti];
10883 opti++;
Jeff Brownd7a04de2012-06-17 14:17:52 -070010884 if ("lastanr".equals(cmd) || "l".equals(cmd)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010885 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010886 dumpLastANRLocked(pw);
10887 }
10888 return;
10889 } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10890 synchronized(mWindowMap) {
10891 dumpPolicyLocked(pw, args, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010892 }
10893 return;
Dianne Hackborn529e7442012-11-01 14:22:28 -070010894 } else if ("animator".equals(cmd) || "a".equals(cmd)) {
10895 synchronized(mWindowMap) {
10896 dumpAnimatorLocked(pw, args, true);
10897 }
10898 return;
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010899 } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10900 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010901 dumpSessionsLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010902 }
10903 return;
10904 } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10905 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010906 dumpTokensLocked(pw, true);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010907 }
10908 return;
10909 } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10910 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010911 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010912 }
10913 return;
10914 } else if ("all".equals(cmd) || "a".equals(cmd)) {
10915 synchronized(mWindowMap) {
Jeff Brownd7a04de2012-06-17 14:17:52 -070010916 dumpWindowsLocked(pw, true, null);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010917 }
10918 return;
10919 } else {
10920 // Dumping a single name?
Jeff Brownd7a04de2012-06-17 14:17:52 -070010921 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010922 pw.println("Bad window command, or no windows match: " + cmd);
10923 pw.println("Use -h for help.");
10924 }
10925 return;
10926 }
10927 }
10928
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010929 synchronized(mWindowMap) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -070010930 pw.println();
10931 if (dumpAll) {
10932 pw.println("-------------------------------------------------------------------------------");
10933 }
10934 dumpLastANRLocked(pw);
10935 pw.println();
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010936 if (dumpAll) {
10937 pw.println("-------------------------------------------------------------------------------");
10938 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010939 dumpPolicyLocked(pw, args, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010940 pw.println();
10941 if (dumpAll) {
10942 pw.println("-------------------------------------------------------------------------------");
10943 }
Dianne Hackborn529e7442012-11-01 14:22:28 -070010944 dumpAnimatorLocked(pw, args, dumpAll);
10945 pw.println();
10946 if (dumpAll) {
10947 pw.println("-------------------------------------------------------------------------------");
10948 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010949 dumpSessionsLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010950 pw.println();
10951 if (dumpAll) {
10952 pw.println("-------------------------------------------------------------------------------");
10953 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010954 dumpTokensLocked(pw, dumpAll);
Dianne Hackborna44abeb2011-08-08 19:24:01 -070010955 pw.println();
10956 if (dumpAll) {
10957 pw.println("-------------------------------------------------------------------------------");
10958 }
Jeff Brownd7a04de2012-06-17 14:17:52 -070010959 dumpWindowsLocked(pw, dumpAll, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010960 }
10961 }
10962
Jeff Brown349703e2010-06-22 01:27:15 -070010963 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010964 public void monitor() {
10965 synchronized (mWindowMap) { }
Dianne Hackbornddca3ee2009-07-23 19:01:31 -070010966 }
Doug Zongkerab5c49c2009-12-04 10:31:43 -080010967
Jeff Brown2992ea72011-01-28 22:04:14 -080010968 public interface OnHardKeyboardStatusChangeListener {
10969 public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10970 }
Craig Mautnera2c77052012-03-26 12:14:43 -070010971
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010972 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010973 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070010974 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10975 Integer.toHexString(pendingLayoutChanges));
Craig Mautnercf8cbbe2012-03-25 21:54:36 -070010976 }
10977 }
Craig Mautner59c00972012-07-30 12:10:24 -070010978
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010979 public void createDisplayContentLocked(final Display display) {
Craig Mautner722285e2012-09-07 13:55:58 -070010980 if (display == null) {
10981 throw new IllegalArgumentException("getDisplayContent: display must not be null");
10982 }
10983 final DisplayContent displayContent = new DisplayContent(display);
10984 mDisplayContents.put(display.getDisplayId(), displayContent);
10985 }
10986
Craig Mautner2d5618c2012-10-18 13:55:47 -070010987 /**
10988 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
10989 * there is a Display for the displayId.
10990 * @param displayId The display the caller is interested in.
10991 * @return The DisplayContent associated with displayId or null if there is no Display for it.
10992 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070010993 public DisplayContent getDisplayContentLocked(final int displayId) {
Craig Mautner59c00972012-07-30 12:10:24 -070010994 DisplayContent displayContent = mDisplayContents.get(displayId);
10995 if (displayContent == null) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070010996 final Display display = mDisplayManager.getDisplay(displayId);
10997 if (display != null) {
10998 displayContent = new DisplayContent(display);
10999 mDisplayContents.put(displayId, displayContent);
11000 }
Craig Mautner59c00972012-07-30 12:10:24 -070011001 }
11002 return displayContent;
11003 }
11004
11005 class DisplayContentsIterator implements Iterator<DisplayContent> {
11006 private int cur;
11007
11008 @Override
11009 public boolean hasNext() {
11010 return cur < mDisplayContents.size();
11011 }
11012
11013 @Override
11014 public DisplayContent next() {
11015 if (hasNext()) {
11016 return mDisplayContents.valueAt(cur++);
11017 }
11018 throw new NoSuchElementException();
11019 }
11020
11021 @Override
11022 public void remove() {
11023 throw new IllegalArgumentException("AllDisplayContentIterator.remove not implemented");
11024 }
11025 }
11026
Jeff Brown83d616a2012-09-09 20:33:43 -070011027 final static boolean REVERSE_ITERATOR = true;
Craig Mautner59c00972012-07-30 12:10:24 -070011028 class AllWindowsIterator implements Iterator<WindowState> {
11029 private DisplayContent mDisplayContent;
11030 private DisplayContentsIterator mDisplayContentsIterator;
11031 private WindowList mWindowList;
11032 private int mWindowListIndex;
11033 private boolean mReverse;
11034
11035 AllWindowsIterator() {
11036 mDisplayContentsIterator = new DisplayContentsIterator();
11037 mDisplayContent = mDisplayContentsIterator.next();
11038 mWindowList = mDisplayContent.getWindowList();
11039 }
11040
11041 AllWindowsIterator(boolean reverse) {
11042 this();
11043 mReverse = reverse;
11044 mWindowListIndex = reverse ? mWindowList.size() - 1 : 0;
11045 }
11046
11047 @Override
11048 public boolean hasNext() {
11049 if (mReverse) {
11050 return mWindowListIndex >= 0;
11051 }
11052 return mWindowListIndex < mWindowList.size();
11053 }
11054
11055 @Override
11056 public WindowState next() {
11057 if (hasNext()) {
11058 WindowState win = mWindowList.get(mWindowListIndex);
11059 if (mReverse) {
11060 mWindowListIndex--;
11061 if (mWindowListIndex < 0 && mDisplayContentsIterator.hasNext()) {
11062 mDisplayContent = mDisplayContentsIterator.next();
11063 mWindowList = mDisplayContent.getWindowList();
11064 mWindowListIndex = mWindowList.size() - 1;
11065 }
11066 } else {
11067 mWindowListIndex++;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070011068 if (mWindowListIndex >= mWindowList.size()
11069 && mDisplayContentsIterator.hasNext()) {
Craig Mautner59c00972012-07-30 12:10:24 -070011070 mDisplayContent = mDisplayContentsIterator.next();
11071 mWindowList = mDisplayContent.getWindowList();
11072 mWindowListIndex = 0;
11073 }
11074 }
11075 return win;
11076 }
11077 throw new NoSuchElementException();
11078 }
11079
11080 @Override
11081 public void remove() {
11082 throw new IllegalArgumentException("AllWindowsIterator.remove not implemented");
11083 }
11084 }
11085
Craig Mautner2d5618c2012-10-18 13:55:47 -070011086 // There is an inherent assumption that this will never return null.
Craig Mautner5c0e78c2012-09-12 16:45:36 -070011087 public DisplayContent getDefaultDisplayContentLocked() {
11088 return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
Craig Mautner59c00972012-07-30 12:10:24 -070011089 }
11090
Craig Mautner5c0e78c2012-09-12 16:45:36 -070011091 public WindowList getDefaultWindowListLocked() {
11092 return getDefaultDisplayContentLocked().getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -070011093 }
11094
Craig Mautner5c0e78c2012-09-12 16:45:36 -070011095 public DisplayInfo getDefaultDisplayInfoLocked() {
11096 return getDefaultDisplayContentLocked().getDisplayInfo();
Craig Mautner59c00972012-07-30 12:10:24 -070011097 }
11098
Craig Mautner2d5618c2012-10-18 13:55:47 -070011099 /**
11100 * Return the list of WindowStates associated on the passed display.
11101 * @param display The screen to return windows from.
11102 * @return The list of WindowStates on the screen, or null if the there is no screen.
11103 */
Craig Mautner5c0e78c2012-09-12 16:45:36 -070011104 public WindowList getWindowListLocked(final Display display) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070011105 final DisplayContent displayContent = getDisplayContentLocked(display.getDisplayId());
11106 return displayContent != null ? displayContent.getWindowList() : null;
Craig Mautner39834192012-09-02 07:47:24 -070011107 }
Craig Mautner722285e2012-09-07 13:55:58 -070011108
11109 @Override
11110 public void onDisplayAdded(int displayId) {
11111 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
11112 }
11113
11114 private void handleDisplayAddedLocked(int displayId) {
Craig Mautner2d5618c2012-10-18 13:55:47 -070011115 final Display display = mDisplayManager.getDisplay(displayId);
11116 if (display != null) {
11117 createDisplayContentLocked(display);
11118 displayReady(displayId);
11119 }
Craig Mautner722285e2012-09-07 13:55:58 -070011120 }
11121
11122 @Override
11123 public void onDisplayRemoved(int displayId) {
11124 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
11125 }
11126
11127 private void handleDisplayRemovedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070011128 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner2d5618c2012-10-18 13:55:47 -070011129 if (displayContent != null) {
11130 mDisplayContents.delete(displayId);
11131 WindowList windows = displayContent.getWindowList();
11132 while (!windows.isEmpty()) {
11133 final WindowState win = windows.get(windows.size() - 1);
11134 removeWindowLocked(win.mSession, win);
11135 }
Craig Mautner722285e2012-09-07 13:55:58 -070011136 }
Craig Mautnera91f9e22012-09-14 16:22:08 -070011137 mAnimator.removeDisplayLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070011138 }
11139
11140 @Override
11141 public void onDisplayChanged(int displayId) {
11142 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
11143 }
11144
11145 private void handleDisplayChangedLocked(int displayId) {
Craig Mautner5c0e78c2012-09-12 16:45:36 -070011146 final DisplayContent displayContent = getDisplayContentLocked(displayId);
Craig Mautner722285e2012-09-07 13:55:58 -070011147 if (displayContent != null) {
11148 displayContent.updateDisplayInfo();
11149 }
11150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011151}